mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-20 13:57:43 +00:00
Compare commits
88 Commits
main
...
dev/cazamo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0c63b9281 | ||
|
|
cfccd1f4be | ||
|
|
2ee29177ba | ||
|
|
edf18a2255 | ||
|
|
f97cddcdd6 | ||
|
|
c84651b0f1 | ||
|
|
eb6deaf67c | ||
|
|
6c1b73ef9c | ||
|
|
b7701c909d | ||
|
|
0c621d11d8 | ||
|
|
e42b3020b0 | ||
|
|
89b2295a8c | ||
|
|
56718992ac | ||
|
|
5f38be735b | ||
|
|
054afcc59d | ||
|
|
0fe41d7db8 | ||
|
|
03dfed4d54 | ||
|
|
84390c5b27 | ||
|
|
b0c1611673 | ||
|
|
5a45c8d7e4 | ||
|
|
fa0f2a7e16 | ||
|
|
56aa5fc73f | ||
|
|
fa2d052ccd | ||
|
|
3ee13c679f | ||
|
|
76f89bff04 | ||
|
|
a7aefad0ba | ||
|
|
bf2cb051b4 | ||
|
|
fbfc761450 | ||
|
|
74b740cf0c | ||
|
|
2fba2ee281 | ||
|
|
87d9fdb1da | ||
|
|
e8a5c32612 | ||
|
|
7cbfb5784a | ||
|
|
afe42d456f | ||
|
|
12e2daaeb9 | ||
|
|
b9896f51e4 | ||
|
|
79d681e394 | ||
|
|
00aa707825 | ||
|
|
30020752ca | ||
|
|
dc27359f56 | ||
|
|
8f4aa8e635 | ||
|
|
e82fe2e548 | ||
|
|
f15a9305fe | ||
|
|
d5d4f99673 | ||
|
|
7dd7783aff | ||
|
|
ee1601e405 | ||
|
|
071963420e | ||
|
|
07a4f3acfc | ||
|
|
042eb5b1a9 | ||
|
|
611f5a31b4 | ||
|
|
cdb99bbe8b | ||
|
|
fbec4ee41f | ||
|
|
cab78edde0 | ||
|
|
b044fd661d | ||
|
|
234838075f | ||
|
|
4e6209247f | ||
|
|
a07dba52ef | ||
|
|
fcaf3daa8d | ||
|
|
68fccb5efb | ||
|
|
6c2b796253 | ||
|
|
d4ff09f82e | ||
|
|
19286b7043 | ||
|
|
8868dfa6ee | ||
|
|
04f6273e4b | ||
|
|
f483eae7a9 | ||
|
|
0856bce421 | ||
|
|
582ffb615e | ||
|
|
da00f8863b | ||
|
|
62727bf6d1 | ||
|
|
15ce2fd513 | ||
|
|
6c88741e26 | ||
|
|
54009e1305 | ||
|
|
0c0a16e10a | ||
|
|
fe650d0c27 | ||
|
|
b53ccb853e | ||
|
|
ac400756e8 | ||
|
|
7378b8ac8c | ||
|
|
9f2dcfd5ee | ||
|
|
ab2514b9cc | ||
|
|
b21ba2b053 | ||
|
|
5279226646 | ||
|
|
c7a51c978c | ||
|
|
44456be4eb | ||
|
|
5f3db13e5f | ||
|
|
9df166efec | ||
|
|
aeb531f666 | ||
|
|
c23e507c20 | ||
|
|
c49bc1a789 |
5
.github/actions/spelling/expect/expect.txt
vendored
5
.github/actions/spelling/expect/expect.txt
vendored
@@ -17,6 +17,7 @@ ADDSTRING
|
||||
ADDTOOL
|
||||
adml
|
||||
admx
|
||||
Affordance
|
||||
AFill
|
||||
AFX
|
||||
AHelper
|
||||
@@ -1075,7 +1076,6 @@ NOCONTEXTHELP
|
||||
NOCOPYBITS
|
||||
nodiscard
|
||||
NODUP
|
||||
NODEFAULT
|
||||
noexcepts
|
||||
NOFONT
|
||||
NOHIDDENTEXT
|
||||
@@ -1106,7 +1106,6 @@ NOSIZE
|
||||
NOSNAPSHOT
|
||||
NOTHOUSANDS
|
||||
NOTICKS
|
||||
notif
|
||||
NOTIMEOUTIFNOTHUNG
|
||||
NOTIMPL
|
||||
NOTOPMOST
|
||||
@@ -1562,7 +1561,6 @@ SMARTQUOTE
|
||||
SMTO
|
||||
snapcx
|
||||
snapcy
|
||||
SND
|
||||
snk
|
||||
SOLIDBOX
|
||||
Solutiondir
|
||||
@@ -1757,6 +1755,7 @@ UPKEY
|
||||
upss
|
||||
uregex
|
||||
URegular
|
||||
urxvt
|
||||
usebackq
|
||||
USECALLBACK
|
||||
USECOLOR
|
||||
|
||||
@@ -479,6 +479,7 @@
|
||||
"toggleReadOnlyMode",
|
||||
"toggleShaderEffects",
|
||||
"toggleSplitOrientation",
|
||||
"workspaces",
|
||||
"wt",
|
||||
"unbound"
|
||||
],
|
||||
@@ -2040,6 +2041,11 @@
|
||||
"unfocusedFrame": {
|
||||
"description": "The color of the window frame when the window is inactive. This only works on Windows 11",
|
||||
"$ref": "#/$defs/ThemeColor"
|
||||
},
|
||||
"showWindowsButton": {
|
||||
"description": "When set to true, the workspace/windows button will be shown in the tab row.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2794,6 +2800,11 @@
|
||||
"description": "When set to true, VT applications will be allowed to set the contents of the local clipboard using OSC 52 (Manipulate Selection Data).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"compatibility.allowOSC777": {
|
||||
"default": false,
|
||||
"description": "When set to true, applications can send OSC 777 escape sequences to trigger desktop toast notifications with a custom title and body.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"unfocusedAppearance": {
|
||||
"$ref": "#/$defs/AppearanceConfig",
|
||||
"description": "Sets the appearance of the terminal when it is unfocused.",
|
||||
@@ -2869,6 +2880,85 @@
|
||||
"description": "Sets the sound played when the application emits a BEL. When set to an array, the terminal will pick one of those sounds at random.",
|
||||
"$ref": "#/$defs/BellSound"
|
||||
},
|
||||
"notifyOnActivity": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification",
|
||||
"all",
|
||||
"none"
|
||||
]
|
||||
}
|
||||
],
|
||||
"description": "Controls how you are notified when an inactive tab produces new output."
|
||||
},
|
||||
"notifyOnNextPrompt": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"taskbar",
|
||||
"audible",
|
||||
"tab",
|
||||
"notification",
|
||||
"all",
|
||||
"none"
|
||||
]
|
||||
}
|
||||
],
|
||||
"description": "Controls how you are notified when a new shell prompt is detected. Requires shell integration."
|
||||
},
|
||||
"notifyOnActivityThreshold": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"default": 5,
|
||||
"description": "Minimum number of seconds between consecutive activity notifications for this profile. Use this to suppress repeated notifications from chatty processes. The first notification after the pane has been silent always fires; subsequent notifications within this window are suppressed. Use 0 to always notify."
|
||||
},
|
||||
"notifyOnNextPromptThreshold": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"default": 5,
|
||||
"description": "Suppress the next-prompt notification unless the just-finished command ran for at least this many seconds. Requires shell integration. Use 0 to always notify."
|
||||
},
|
||||
"autoDetectRunningCommand": {
|
||||
"default": false,
|
||||
"description": "Automatically detect when a command is running and show a progress indicator in the tab and taskbar.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"closeOnExit": {
|
||||
"default": "automatic",
|
||||
"description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"automatic\" (behave as \"graceful\" only for processes launched by terminal, behave as \"always\" otherwise)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.",
|
||||
|
||||
@@ -938,6 +938,27 @@ namespace winrt::TerminalApp::implementation
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Launch `wt -w <name>` so the monarch can either summon an existing
|
||||
// window with that name or restore a persisted workspace.
|
||||
safe_void_coroutine TerminalPage::_OpenWorkspaceWindow(const winrt::hstring name)
|
||||
{
|
||||
co_await winrt::resume_background();
|
||||
|
||||
const auto exePath{ GetWtExePath() };
|
||||
const auto cmdline = fmt::format(FMT_COMPILE(L"-w {}"), std::wstring_view{ name });
|
||||
|
||||
SHELLEXECUTEINFOW seInfo{ 0 };
|
||||
seInfo.cbSize = sizeof(seInfo);
|
||||
seInfo.fMask = SEE_MASK_NOASYNC;
|
||||
seInfo.lpVerb = L"open";
|
||||
seInfo.lpFile = exePath.c_str();
|
||||
seInfo.lpParameters = cmdline.c_str();
|
||||
seInfo.nShow = SW_SHOWNORMAL;
|
||||
LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&seInfo));
|
||||
|
||||
co_return;
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleNewWindow(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& actionArgs)
|
||||
{
|
||||
@@ -1058,6 +1079,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Fun!
|
||||
// WindowRenamerTextBox().Focus(FocusState::Programmatic);
|
||||
_renamerLayoutUpdatedRevoker.revoke();
|
||||
_renamerLayoutCount = 0;
|
||||
_renamerLayoutUpdatedRevoker = WindowRenamerTextBox().LayoutUpdated(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (auto self{ weakThis.get() })
|
||||
{
|
||||
@@ -1633,4 +1655,35 @@ namespace winrt::TerminalApp::implementation
|
||||
args.Handled(handled);
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleOpenWorkspace(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
// Open (or summon) a named window. We launch a new `wt -w <name>`
|
||||
// process which the monarch will route to the correct live window or
|
||||
// restore from a persisted workspace.
|
||||
if (args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<OpenWorkspaceArgs>())
|
||||
{
|
||||
const auto name = realArgs.Name();
|
||||
if (!name.empty())
|
||||
{
|
||||
_OpenWorkspaceWindow(name);
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleWorkspaces(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (_workspaceFlyout && _workspaceDropdown)
|
||||
{
|
||||
_workspaceFlyout.ShowAt(_workspaceDropdown);
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -231,6 +231,12 @@
|
||||
Glyph=""
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).BellIndicator, Mode=OneWay}" />
|
||||
|
||||
<FontIcon Margin="0,0,8,0"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="8"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind Item.(local:TabPaletteItem.TabStatus).ActivityIndicator, Mode=OneWay}" />
|
||||
|
||||
<FontIcon Margin="0,0,8,0"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="12"
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// When the user activates (clicks) the toast, fire the callback.
|
||||
if (activatedFunc)
|
||||
{
|
||||
toast.Activated([activatedFunc](const auto& /*sender*/, const auto& /*eventArgs*/) {
|
||||
toast.Activated([activatedFunc = std::move(activatedFunc)](const auto& /*sender*/, const auto& /*eventArgs*/) {
|
||||
activatedFunc();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace TerminalApp
|
||||
{
|
||||
String Title { get; };
|
||||
String Body { get; };
|
||||
Microsoft.Terminal.Control.OutputNotificationStyle Style { get; };
|
||||
Boolean AlwaysNotify { get; };
|
||||
};
|
||||
|
||||
interface IPaneContent
|
||||
@@ -31,7 +33,7 @@ namespace TerminalApp
|
||||
Windows.Foundation.Size MinimumSize { get; };
|
||||
|
||||
String Title { get; };
|
||||
UInt64 TaskbarState { get; };
|
||||
Microsoft.Terminal.Control.TaskbarState TaskbarState { get; };
|
||||
UInt64 TaskbarProgress { get; };
|
||||
Boolean ReadOnly { get; };
|
||||
String Icon { get; };
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(BuildStartupKind kind) const;
|
||||
|
||||
winrt::hstring Title() { return _filePath; }
|
||||
uint64_t TaskbarState() { return 0; }
|
||||
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState() { return winrt::Microsoft::Terminal::Control::TaskbarState::Clear; }
|
||||
uint64_t TaskbarProgress() { return 0; }
|
||||
bool ReadOnly() { return false; }
|
||||
winrt::hstring Icon() const;
|
||||
|
||||
@@ -31,10 +31,14 @@ Pane::Pane(IPaneContent content, const bool lastFocused) :
|
||||
_lastActive{ lastFocused }
|
||||
{
|
||||
_setPaneContent(std::move(content));
|
||||
_root.Children().Append(_borderFirst);
|
||||
_CreatePaneHeader();
|
||||
|
||||
const auto& control{ _content.GetRoot() };
|
||||
_borderFirst.Child(control);
|
||||
|
||||
// Set up leaf layout: header in _root row 0, content in _borderFirst row 1.
|
||||
// The TermControl stays as the direct child of _borderFirst (no Grid wrapper)
|
||||
// so the SwapChainPanel renders correctly.
|
||||
_SetupLeafLayout(control);
|
||||
|
||||
// Register an event with the control to have it inform us when it gains focus.
|
||||
if (control)
|
||||
@@ -92,6 +96,10 @@ INewContentArgs Pane::GetTerminalArgsForPane(BuildStartupKind kind) const
|
||||
{
|
||||
// Leaves are the only things that have controls
|
||||
assert(_IsLeaf());
|
||||
if (!_content)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return _content.GetNewTerminalArgs(kind);
|
||||
}
|
||||
|
||||
@@ -1228,6 +1236,12 @@ void Pane::UpdateVisuals()
|
||||
const auto& brush{ _ComputeBorderColor() };
|
||||
_borderFirst.BorderBrush(brush);
|
||||
_borderSecond.BorderBrush(brush);
|
||||
|
||||
// Update pane header color to match focus state
|
||||
if (_paneHeaderBorder && _paneHeaderBorder.Visibility() == winrt::Windows::UI::Xaml::Visibility::Visible)
|
||||
{
|
||||
_paneHeaderBorder.Background(brush);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1450,9 +1464,9 @@ void Pane::_CloseChild(const bool closeFirst)
|
||||
_root.RowDefinitions().Clear();
|
||||
|
||||
// Reattach the TermControl to our grid.
|
||||
_root.Children().Append(_borderFirst);
|
||||
_CreatePaneHeader();
|
||||
const auto& control{ _content.GetRoot() };
|
||||
_borderFirst.Child(control);
|
||||
_SetupLeafLayout(control);
|
||||
|
||||
// Make sure to set our _splitState before focusing the control. If you
|
||||
// fail to do this, when the tab handles the GotFocus event and asks us
|
||||
@@ -1755,7 +1769,92 @@ void Pane::_setPaneContent(IPaneContent content)
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets up row/column definitions for this pane. There are three total
|
||||
// - Creates the pane header UI elements (title bar shown above the content).
|
||||
// The header is initially collapsed and only shown via ShowPaneHeaders().
|
||||
void Pane::_CreatePaneHeader()
|
||||
{
|
||||
namespace WUX = winrt::Windows::UI::Xaml;
|
||||
|
||||
_paneHeaderText = Controls::TextBlock{};
|
||||
_paneHeaderText.FontSize(12);
|
||||
_paneHeaderText.Padding({ 8, 2, 8, 2 });
|
||||
_paneHeaderText.IsTextSelectionEnabled(false);
|
||||
_paneHeaderText.TextTrimming(WUX::TextTrimming::CharacterEllipsis);
|
||||
if (_content)
|
||||
{
|
||||
_paneHeaderText.Text(_content.Title());
|
||||
_titleChangedRevoker = _content.TitleChanged(winrt::auto_revoke, [this](auto&&, auto&&) {
|
||||
_paneHeaderBorder.Dispatcher().RunAsync(
|
||||
winrt::Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
[this]() {
|
||||
if (_content && _paneHeaderText)
|
||||
{
|
||||
_paneHeaderText.Text(_content.Title());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_paneHeaderBorder = Controls::Border{};
|
||||
_paneHeaderBorder.Padding({ 0, 0, 0, 0 });
|
||||
_paneHeaderBorder.Child(_paneHeaderText);
|
||||
_paneHeaderBorder.Visibility(WUX::Visibility::Collapsed);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets up the leaf pane layout in _root: a header row (auto-sized) and a
|
||||
// content row (star-sized). The TermControl stays as the direct child of
|
||||
// _borderFirst so the SwapChainPanel renders correctly.
|
||||
void Pane::_SetupLeafLayout(const winrt::Windows::UI::Xaml::UIElement& control)
|
||||
{
|
||||
auto headerRow = Controls::RowDefinition{};
|
||||
headerRow.Height(GridLengthHelper::Auto());
|
||||
auto contentRow = Controls::RowDefinition{};
|
||||
contentRow.Height(GridLengthHelper::FromValueAndType(1, GridUnitType::Star));
|
||||
_root.RowDefinitions().Append(headerRow);
|
||||
_root.RowDefinitions().Append(contentRow);
|
||||
|
||||
Controls::Grid::SetRow(_paneHeaderBorder, 0);
|
||||
Controls::Grid::SetRow(_borderFirst, 1);
|
||||
|
||||
_root.Children().Append(_paneHeaderBorder);
|
||||
_root.Children().Append(_borderFirst);
|
||||
|
||||
if (control)
|
||||
{
|
||||
_borderFirst.Child(control);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Show or hide the pane header title bar on all leaf panes in the tree.
|
||||
// Called by Tab when the number of panes changes.
|
||||
void Pane::ShowPaneHeaders(bool show)
|
||||
{
|
||||
if (_IsLeaf())
|
||||
{
|
||||
if (_paneHeaderBorder)
|
||||
{
|
||||
namespace WUX = winrt::Windows::UI::Xaml;
|
||||
_paneHeaderBorder.Visibility(show ? WUX::Visibility::Visible : WUX::Visibility::Collapsed);
|
||||
|
||||
if (show)
|
||||
{
|
||||
const auto& brush = _ComputeBorderColor();
|
||||
_paneHeaderBorder.Background(brush);
|
||||
_paneHeaderText.Foreground(winrt::Windows::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::White()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_firstChild->ShowPaneHeaders(show);
|
||||
_secondChild->ShowPaneHeaders(show);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets up row/column definitions for this pane.There are three total
|
||||
// row/cols. The middle one is for the separator. The first and third are for
|
||||
// each of the child panes, and are given a size in pixels, based off the
|
||||
// available space, and the percent of the space they respectively consume,
|
||||
@@ -2321,6 +2420,10 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
|
||||
_root.RowDefinitions().Clear();
|
||||
_CreateRowColDefinitions();
|
||||
|
||||
// Reset Grid.Row on _borderFirst — it may have been set to row 1 in the
|
||||
// leaf layout (header=row0, content=row1).
|
||||
Controls::Grid::SetRow(_borderFirst, 0);
|
||||
|
||||
_borderFirst.Child(_firstChild->GetRootElement());
|
||||
_borderSecond.Child(_secondChild->GetRootElement());
|
||||
|
||||
|
||||
@@ -150,6 +150,7 @@ public:
|
||||
bool ContainsReadOnly() const;
|
||||
|
||||
void EnableBroadcast(bool enabled);
|
||||
void ShowPaneHeaders(bool show);
|
||||
void BroadcastKey(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const WORD vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers, const bool keyDown);
|
||||
void BroadcastChar(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const wchar_t vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers);
|
||||
void BroadcastString(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const winrt::hstring& text);
|
||||
@@ -235,6 +236,11 @@ private:
|
||||
winrt::Windows::UI::Xaml::Controls::Border _borderFirst{};
|
||||
winrt::Windows::UI::Xaml::Controls::Border _borderSecond{};
|
||||
|
||||
// Per-pane title header (visible when there are split panes)
|
||||
winrt::Windows::UI::Xaml::Controls::Border _paneHeaderBorder{ nullptr };
|
||||
winrt::Windows::UI::Xaml::Controls::TextBlock _paneHeaderText{ nullptr };
|
||||
winrt::TerminalApp::IPaneContent::TitleChanged_revoker _titleChangedRevoker;
|
||||
|
||||
PaneResources _themeResources;
|
||||
|
||||
#pragma region Properties that need to be transferred between child / parent panes upon splitting / closing
|
||||
@@ -266,6 +272,8 @@ private:
|
||||
void _SetupChildCloseHandlers();
|
||||
winrt::TerminalApp::IPaneContent _takePaneContent();
|
||||
void _setPaneContent(winrt::TerminalApp::IPaneContent content);
|
||||
void _CreatePaneHeader();
|
||||
void _SetupLeafLayout(const winrt::Windows::UI::Xaml::UIElement& control);
|
||||
bool _HasChild(const std::shared_ptr<Pane> child);
|
||||
winrt::TerminalApp::TerminalPaneContent _getTerminalContent() const;
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ namespace winrt::TerminalApp::implementation
|
||||
WINRT_PROPERTY(TerminalApp::CommandlineArgs, Command, nullptr);
|
||||
WINRT_PROPERTY(winrt::hstring, Content);
|
||||
WINRT_PROPERTY(Windows::Foundation::IReference<Windows::Foundation::Rect>, InitialBounds);
|
||||
WINRT_PROPERTY(winrt::Microsoft::Terminal::Settings::Model::WindowLayout, PersistedLayout, nullptr);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -51,5 +51,6 @@ namespace TerminalApp
|
||||
CommandlineArgs Command { get; };
|
||||
String Content { get; };
|
||||
Windows.Foundation.IReference<Windows.Foundation.Rect> InitialBounds { get; };
|
||||
Microsoft.Terminal.Settings.Model.WindowLayout PersistedLayout;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -743,6 +743,38 @@
|
||||
<value>unnamed window</value>
|
||||
<comment>text used to identify when a window hasn't been assigned a name by the user</comment>
|
||||
</data>
|
||||
<data name="NameThisWindowMenuItem" xml:space="preserve">
|
||||
<value>Name this window…</value>
|
||||
<comment>Menu item text shown when the current window has no name assigned</comment>
|
||||
</data>
|
||||
<data name="RenameThisWindowMenuItem" xml:space="preserve">
|
||||
<value>Rename this window…</value>
|
||||
<comment>Menu item text shown when the current window already has a name</comment>
|
||||
</data>
|
||||
<data name="WindowListUnnamedEntry" xml:space="preserve">
|
||||
<value>#{0} (unnamed)</value>
|
||||
<comment>{0} is the window ID number. Shown in the workspace flyout for windows that have no name assigned.</comment>
|
||||
</data>
|
||||
<data name="DeleteWorkspaceMenuItem" xml:space="preserve">
|
||||
<value>Delete workspace?</value>
|
||||
<comment>Menu item text shown in the right-click context menu on a saved workspace</comment>
|
||||
</data>
|
||||
<data name="OpenWorkspaceMenuItem" xml:space="preserve">
|
||||
<value>Open workspace</value>
|
||||
<comment>Menu item text for opening a saved workspace</comment>
|
||||
</data>
|
||||
<data name="ConfirmDeleteWorkspaceTitle" xml:space="preserve">
|
||||
<value>Are you sure you want to delete the workspace "{0}"?</value>
|
||||
<comment>{0} is the workspace name. Shown in a confirmation dialog when the user tries to delete a saved workspace.</comment>
|
||||
</data>
|
||||
<data name="ConfirmDeleteWorkspaceDelete" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
<comment>Primary button text on the delete workspace confirmation dialog</comment>
|
||||
</data>
|
||||
<data name="ConfirmDeleteWorkspaceCancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
<comment>Cancel button text on the delete workspace confirmation dialog</comment>
|
||||
</data>
|
||||
<data name="WindowRenamer.Subtitle" xml:space="preserve">
|
||||
<value>Enter a new name:</value>
|
||||
</data>
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(BuildStartupKind kind) const;
|
||||
|
||||
winrt::hstring Title() { return L"Scratchpad"; }
|
||||
uint64_t TaskbarState() { return 0; }
|
||||
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState() { return winrt::Microsoft::Terminal::Control::TaskbarState::Clear; }
|
||||
uint64_t TaskbarProgress() { return 0; }
|
||||
bool ReadOnly() { return false; }
|
||||
winrt::hstring Icon() const;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(const BuildStartupKind kind) const;
|
||||
|
||||
winrt::hstring Title() { return RS_(L"SettingsTab"); }
|
||||
uint64_t TaskbarState() { return 0; }
|
||||
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState() { return winrt::Microsoft::Terminal::Control::TaskbarState::Clear; }
|
||||
uint64_t TaskbarProgress() { return 0; }
|
||||
bool ReadOnly() { return false; }
|
||||
winrt::hstring Icon() const;
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(BuildStartupKind kind) const;
|
||||
|
||||
winrt::hstring Title() { return RS_(L"SnippetPaneTitle/Text"); }
|
||||
uint64_t TaskbarState() { return 0; }
|
||||
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState() { return winrt::Microsoft::Terminal::Control::TaskbarState::Clear; }
|
||||
uint64_t TaskbarProgress() { return 0; }
|
||||
bool ReadOnly() { return false; }
|
||||
winrt::hstring Icon() const;
|
||||
|
||||
@@ -123,6 +123,12 @@ namespace winrt::TerminalApp::implementation
|
||||
_bellIndicatorTimer.Stop();
|
||||
}
|
||||
|
||||
void Tab::_ActivityIndicatorTimerTick(const Windows::Foundation::IInspectable& /*sender*/, const Windows::Foundation::IInspectable& /*e*/)
|
||||
{
|
||||
ShowActivityIndicator(false);
|
||||
_activityIndicatorTimer.Stop();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Initializes a TabViewItem for this Tab instance.
|
||||
// Arguments:
|
||||
@@ -329,6 +335,10 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
ShowBellIndicator(false);
|
||||
}
|
||||
if (_tabStatus.ActivityIndicator())
|
||||
{
|
||||
ShowActivityIndicator(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,6 +371,10 @@ namespace winrt::TerminalApp::implementation
|
||||
// The tabWidthMode may have changed, update the header control accordingly
|
||||
_UpdateHeaderControlMaxWidth();
|
||||
|
||||
// Refresh pane header visibility based on the current setting
|
||||
const auto showHeaders = settings.GlobalSettings().ShowPaneHeaders() && _rootPane->GetLeafPaneCount() > 1;
|
||||
_rootPane->ShowPaneHeaders(showHeaders);
|
||||
|
||||
// Update the settings on all our panes.
|
||||
_rootPane->WalkTree([&](const auto& pane) {
|
||||
pane->UpdateSettings(settings);
|
||||
@@ -459,6 +473,26 @@ namespace winrt::TerminalApp::implementation
|
||||
_bellIndicatorTimer.Start();
|
||||
}
|
||||
|
||||
void Tab::ShowActivityIndicator(const bool show)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_tabStatus.ActivityIndicator(show);
|
||||
}
|
||||
|
||||
void Tab::ActivateActivityIndicatorTimer()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
if (!_activityIndicatorTimer)
|
||||
{
|
||||
_activityIndicatorTimer.Interval(std::chrono::milliseconds(2000));
|
||||
_activityIndicatorTimer.Tick({ get_weak(), &Tab::_ActivityIndicatorTimerTick });
|
||||
}
|
||||
|
||||
_activityIndicatorTimer.Start();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the title string of the last focused terminal control in our tree.
|
||||
// Returns the empty string if there is no such control.
|
||||
@@ -646,6 +680,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// After split, Close Pane Menu Item should be visible
|
||||
_closePaneMenuItem.Visibility(WUX::Visibility::Visible);
|
||||
|
||||
// Show pane headers now that we have multiple panes (if the setting is enabled)
|
||||
try
|
||||
{
|
||||
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
|
||||
_rootPane->ShowPaneHeaders(settings.GlobalSettings().ShowPaneHeaders());
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
// The active pane has an id if it is a leaf
|
||||
if (activePaneId)
|
||||
{
|
||||
@@ -1181,8 +1223,45 @@ namespace winrt::TerminalApp::implementation
|
||||
co_await wil::resume_foreground(dispatcher);
|
||||
if (const auto tab{ weakThisCopy.get() })
|
||||
{
|
||||
const auto title = notifArgs.Title().empty() ? tab->Title() : notifArgs.Title();
|
||||
tab->TabToastNotificationRequested.raise(title, notifArgs.Body(), sender);
|
||||
const auto activeContent = tab->GetActiveContent();
|
||||
const auto isActivePaneContent = activeContent && activeContent == sender;
|
||||
|
||||
if (!notifArgs.AlwaysNotify() && isActivePaneContent &&
|
||||
tab->_focusState != WUX::FocusState::Unfocused)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
const auto style = notifArgs.Style();
|
||||
|
||||
if (WI_IsFlagSet(style, OutputNotificationStyle::Taskbar))
|
||||
{
|
||||
tab->TabRaiseVisualBell.raise();
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Audible))
|
||||
{
|
||||
if (const auto termContent{ sender.try_as<TerminalApp::TerminalPaneContent>() })
|
||||
{
|
||||
termContent.PlayNotificationSound();
|
||||
}
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Tab))
|
||||
{
|
||||
tab->ShowActivityIndicator(true);
|
||||
|
||||
if (tab->_focusState != WUX::FocusState::Unfocused)
|
||||
{
|
||||
tab->ActivateActivityIndicatorTimer();
|
||||
}
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Notification))
|
||||
{
|
||||
const auto title = notifArgs.Title().empty() ? tab->Title() : notifArgs.Title();
|
||||
tab->TabToastNotificationRequested.raise(title, notifArgs.Body(), sender);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1242,11 +1321,10 @@ namespace winrt::TerminalApp::implementation
|
||||
const auto taskbarState = state.State();
|
||||
// The progress of the control changed, but not necessarily the progress of the tab.
|
||||
// Set the tab's progress ring to the active pane's progress
|
||||
if (taskbarState > 0)
|
||||
if (taskbarState != winrt::Microsoft::Terminal::Control::TaskbarState::Clear)
|
||||
{
|
||||
if (taskbarState == 3)
|
||||
if (taskbarState == winrt::Microsoft::Terminal::Control::TaskbarState::Indeterminate)
|
||||
{
|
||||
// 3 is the indeterminate state, set the progress ring as such
|
||||
_tabStatus.IsProgressRingIndeterminate(true);
|
||||
}
|
||||
else
|
||||
@@ -1337,6 +1415,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (_rootPane->GetLeafPaneCount() == 1)
|
||||
{
|
||||
_closePaneMenuItem.Visibility(WUX::Visibility::Collapsed);
|
||||
_rootPane->ShowPaneHeaders(false);
|
||||
}
|
||||
|
||||
_RecalculateAndApplyReadOnly();
|
||||
@@ -1422,6 +1501,10 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
tab->ShowBellIndicator(false);
|
||||
}
|
||||
if (tab->_tabStatus.ActivityIndicator())
|
||||
{
|
||||
tab->ShowActivityIndicator(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ namespace winrt::TerminalApp::implementation
|
||||
void ShowBellIndicator(const bool show);
|
||||
void ActivateBellIndicatorTimer();
|
||||
|
||||
void ShowActivityIndicator(const bool show);
|
||||
void ActivateActivityIndicatorTimer();
|
||||
|
||||
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
||||
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> PreCalculateCanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
|
||||
const float splitSize,
|
||||
@@ -215,6 +218,9 @@ namespace winrt::TerminalApp::implementation
|
||||
SafeDispatcherTimer _bellIndicatorTimer;
|
||||
void _BellIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
SafeDispatcherTimer _activityIndicatorTimer;
|
||||
void _ActivityIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _UpdateHeaderControlMaxWidth();
|
||||
|
||||
void _CreateContextMenu();
|
||||
|
||||
@@ -32,6 +32,12 @@
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind TabStatus.BellIndicator, Mode=OneWay}" />
|
||||
<FontIcon x:Name="HeaderActivityIndicator"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="8"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind TabStatus.ActivityIndicator, Mode=OneWay}" />
|
||||
<FontIcon x:Name="HeaderZoomIcon"
|
||||
Margin="0,0,8,0"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
|
||||
@@ -450,6 +450,21 @@ namespace winrt::TerminalApp::implementation
|
||||
auto actions = t->BuildStartupActions(BuildStartupKind::None);
|
||||
_AddPreviouslyClosedPaneOrTab(std::move(actions));
|
||||
|
||||
// If this is the last tab in a named window, persist the workspace
|
||||
// layout now while tab content is still alive. After tab.Close()
|
||||
// the pane content will be torn down by the time _RemoveTab runs.
|
||||
if (_tabs.Size() == 1)
|
||||
{
|
||||
const auto& windowName = _WindowProperties.WindowName();
|
||||
if (!windowName.empty())
|
||||
{
|
||||
if (const auto layout = GetWindowLayout())
|
||||
{
|
||||
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tab.Close();
|
||||
}
|
||||
|
||||
@@ -471,6 +486,13 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
const auto focusedTabIndex{ _GetFocusedTabIndex() };
|
||||
|
||||
// NOTE: Workspace persistence for named windows used to live here,
|
||||
// but by the time _RemoveTab runs the pane content may already be
|
||||
// torn down (e.g. from the close-pane path). Instead, workspace
|
||||
// saves are handled earlier:
|
||||
// - Close-pane (last pane): in _HandleClosePaneRequested
|
||||
// - Close-tab: in _HandleCloseTabRequested
|
||||
|
||||
// Removing the tab from the collection should destroy its control and disconnect its connection,
|
||||
// but it doesn't always do so. The UI tree may still be holding the control and preventing its destruction.
|
||||
tab.Shutdown();
|
||||
@@ -798,6 +820,28 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
_AddPreviouslyClosedPaneOrTab(std::move(state.args));
|
||||
|
||||
// If this is the last pane on the last tab of a named window, persist
|
||||
// the workspace layout now while the pane content is still alive.
|
||||
// We can't wait until _RemoveTab, because pane->Close() below will
|
||||
// destroy the content before _RemoveTab is reached.
|
||||
if (_tabs.Size() == 1)
|
||||
{
|
||||
if (const auto activeTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
if (activeTab->GetLeafPaneCount() == 1)
|
||||
{
|
||||
const auto& windowName = _WindowProperties.WindowName();
|
||||
if (!windowName.empty())
|
||||
{
|
||||
if (const auto layout = GetWindowLayout())
|
||||
{
|
||||
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If specified, detach before closing to directly update the pane structure
|
||||
pane->Close();
|
||||
}
|
||||
@@ -1353,7 +1397,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// Use the Tab object's identity hash as a stable toast tag.
|
||||
// This survives tab reordering and cross-window moves.
|
||||
const auto tabHash = std::hash<winrt::Windows::Foundation::IUnknown>{}(*tab);
|
||||
#ifdef _WIN64
|
||||
const hstring tabTag{ fmt::format(FMT_COMPILE(L"wt-tab-{:016x}"), tabHash) };
|
||||
#else
|
||||
const hstring tabTag{ fmt::format(FMT_COMPILE(L"wt-tab-{:08x}"), tabHash) };
|
||||
#endif
|
||||
|
||||
const implementation::DesktopNotificationArgs args{
|
||||
.Title = notificationTitle,
|
||||
@@ -1366,8 +1414,8 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// The toast Activated callback runs on a background thread.
|
||||
// Marshal to the UI thread for tab focus and window summon.
|
||||
page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakPage{ page->get_weak() }, weakTab, weakContent]() {
|
||||
if (const auto p{ weakPage.get() })
|
||||
page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis, weakTab, weakContent]() {
|
||||
if (const auto p{ weakThis.get() })
|
||||
{
|
||||
if (const auto t{ weakTab.get() })
|
||||
{
|
||||
|
||||
@@ -25,6 +25,15 @@ namespace winrt::TerminalApp::implementation
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
void TabRowControl::WorkspaceName(const winrt::hstring& value)
|
||||
{
|
||||
if (_WorkspaceName != value)
|
||||
{
|
||||
_WorkspaceName = value;
|
||||
PropertyChanged.raise(*this, WUX::Data::PropertyChangedEventArgs{ L"WorkspaceName" });
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Bound in the Xaml editor to the [+] button.
|
||||
// Arguments:
|
||||
|
||||
@@ -19,6 +19,14 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ShowElevationShield, PropertyChanged.raise, false);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ShowWindowsButton, PropertyChanged.raise, true);
|
||||
|
||||
public:
|
||||
winrt::hstring WorkspaceName() const noexcept { return _WorkspaceName; }
|
||||
void WorkspaceName(const winrt::hstring& value);
|
||||
|
||||
private:
|
||||
winrt::hstring _WorkspaceName{};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -9,5 +9,7 @@ namespace TerminalApp
|
||||
TabRowControl();
|
||||
Microsoft.UI.Xaml.Controls.TabView TabView { get; };
|
||||
Boolean ShowElevationShield;
|
||||
Boolean ShowWindowsButton;
|
||||
String WorkspaceName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
Background="{ThemeResource TabViewBackground}"
|
||||
mc:Ignorable="d">
|
||||
@@ -35,14 +36,44 @@
|
||||
TabWidthMode="Equal">
|
||||
|
||||
<mux:TabView.TabStripHeader>
|
||||
<!-- EA18 is the "Shield" glyph -->
|
||||
<FontIcon x:Uid="ElevationShield"
|
||||
Margin="9,4,0,4"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="16"
|
||||
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind ShowElevationShield, Mode=OneWay}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!-- EA18 is the "Shield" glyph -->
|
||||
<FontIcon x:Uid="ElevationShield"
|
||||
Margin="9,4,0,4"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="16"
|
||||
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind ShowElevationShield, Mode=OneWay}" />
|
||||
|
||||
<!-- Workspace/windows button -->
|
||||
<Button x:Name="WorkspaceDropdown"
|
||||
Margin="4,0,0,4"
|
||||
Padding="8,0,0,0"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Visibility="{x:Bind ShowWindowsButton, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<!-- EE40 is the "TaskViewSettings" glyph -->
|
||||
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="12"
|
||||
Glyph="" />
|
||||
<TextBlock x:Name="WorkspaceNameText"
|
||||
Padding="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Text="{x:Bind WorkspaceName, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(WorkspaceName), Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<MenuFlyout x:Name="WorkspaceFlyout" />
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</mux:TabView.TabStripHeader>
|
||||
|
||||
<mux:TabView.TabStripFooter>
|
||||
|
||||
@@ -9,27 +9,28 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Default to unset, 0%.
|
||||
TaskbarState::TaskbarState() :
|
||||
TaskbarState(0, 0) {};
|
||||
TaskbarState(winrt::Microsoft::Terminal::Control::TaskbarState::Clear, 0) {};
|
||||
|
||||
TaskbarState::TaskbarState(const uint64_t dispatchTypesState, const uint64_t progressParam) :
|
||||
_State{ dispatchTypesState },
|
||||
TaskbarState::TaskbarState(const winrt::Microsoft::Terminal::Control::TaskbarState state, const uint64_t progressParam) :
|
||||
_State{ state },
|
||||
_Progress{ progressParam } {}
|
||||
|
||||
uint64_t TaskbarState::Priority() const
|
||||
{
|
||||
// This seemingly nonsensical ordering is from
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group
|
||||
using TbState = winrt::Microsoft::Terminal::Control::TaskbarState;
|
||||
switch (_State)
|
||||
{
|
||||
case 0: // Clear = 0,
|
||||
case TbState::Clear:
|
||||
return 5;
|
||||
case 1: // Set = 1,
|
||||
case TbState::Set:
|
||||
return 3;
|
||||
case 2: // Error = 2,
|
||||
case TbState::Error:
|
||||
return 1;
|
||||
case 3: // Indeterminate = 3,
|
||||
case TbState::Indeterminate:
|
||||
return 4;
|
||||
case 4: // Paused = 4
|
||||
case TbState::Paused:
|
||||
return 2;
|
||||
}
|
||||
// Here, return 6, to definitely be greater than all the other valid values.
|
||||
|
||||
@@ -16,13 +16,13 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
public:
|
||||
TaskbarState();
|
||||
TaskbarState(const uint64_t dispatchTypesState, const uint64_t progress);
|
||||
TaskbarState(const winrt::Microsoft::Terminal::Control::TaskbarState state, const uint64_t progress);
|
||||
|
||||
static int ComparePriority(const winrt::TerminalApp::TaskbarState& lhs, const winrt::TerminalApp::TaskbarState& rhs);
|
||||
|
||||
uint64_t Priority() const;
|
||||
|
||||
WINRT_PROPERTY(uint64_t, State, 0);
|
||||
WINRT_PROPERTY(winrt::Microsoft::Terminal::Control::TaskbarState, State, winrt::Microsoft::Terminal::Control::TaskbarState::Clear);
|
||||
WINRT_PROPERTY(uint64_t, Progress, 0);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ namespace TerminalApp
|
||||
[default_interface] runtimeclass TaskbarState
|
||||
{
|
||||
TaskbarState();
|
||||
TaskbarState(UInt64 dispatchTypesState, UInt64 progress);
|
||||
TaskbarState(Microsoft.Terminal.Control.TaskbarState state, UInt64 progress);
|
||||
|
||||
UInt64 State{ get; };
|
||||
Microsoft.Terminal.Control.TaskbarState State{ get; };
|
||||
UInt64 Progress{ get; };
|
||||
UInt64 Priority { get; };
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "TerminalSettingsCache.h"
|
||||
|
||||
#include "LaunchPositionRequest.g.cpp"
|
||||
#include "WindowListEntry.g.cpp"
|
||||
#include "WindowListRequest.g.cpp"
|
||||
#include "RenameWindowRequestedArgs.g.cpp"
|
||||
#include "RequestMoveContentArgs.g.cpp"
|
||||
#include "TerminalPage.g.cpp"
|
||||
@@ -334,6 +336,21 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
auto tabRowImpl = winrt::get_self<implementation::TabRowControl>(_tabRow);
|
||||
_newTabButton = tabRowImpl->NewTabButton();
|
||||
_workspaceFlyout = tabRowImpl->WorkspaceFlyout();
|
||||
_workspaceDropdown = tabRowImpl->WorkspaceDropdown();
|
||||
|
||||
// Set the initial workspace name from the window name.
|
||||
// Use raw WindowName() so unnamed windows show no text.
|
||||
_tabRow.WorkspaceName(_WindowProperties.WindowName());
|
||||
|
||||
// Rebuild the workspace flyout each time it opens so it always
|
||||
// reflects the latest set of persisted workspaces.
|
||||
_workspaceFlyout.Opening([weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->_PopulateWorkspaceFlyout();
|
||||
}
|
||||
});
|
||||
|
||||
if (_settings.GlobalSettings().ShowTabsInTitlebar())
|
||||
{
|
||||
@@ -443,6 +460,12 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||
|
||||
// Apply the ShowWindowsButton theme setting.
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme())
|
||||
{
|
||||
_tabRow.ShowWindowsButton(theme.Window() ? theme.Window().ShowWindowsButton() : true);
|
||||
}
|
||||
|
||||
_adjustProcessPriorityThrottled = std::make_shared<ThrottledFunc<>>(
|
||||
DispatcherQueue::GetForCurrentThread(),
|
||||
til::throttled_func_options{
|
||||
@@ -2285,14 +2308,14 @@ namespace winrt::TerminalApp::implementation
|
||||
QuitRequested.raise(nullptr, nullptr);
|
||||
}
|
||||
|
||||
void TerminalPage::PersistState()
|
||||
WindowLayout TerminalPage::GetWindowLayout()
|
||||
{
|
||||
// This method may be called for a window even if it hasn't had a tab yet or lost all of them.
|
||||
// We shouldn't persist such windows.
|
||||
const auto tabCount = _tabs.Size();
|
||||
if (_startupState != StartupState::Initialized || tabCount == 0)
|
||||
{
|
||||
return;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<ActionAndArgs> actions;
|
||||
@@ -2307,7 +2330,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Avoid persisting a window with zero tabs, because `BuildStartupActions` happened to return an empty vector.
|
||||
if (actions.empty())
|
||||
{
|
||||
return;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// if the focused tab was not the last tab, restore that
|
||||
@@ -2356,7 +2379,49 @@ namespace winrt::TerminalApp::implementation
|
||||
RequestLaunchPosition.raise(*this, launchPosRequest);
|
||||
layout.InitialPosition(launchPosRequest.Position());
|
||||
|
||||
ApplicationState::SharedInstance().AppendPersistedWindowLayout(layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
void TerminalPage::PersistState()
|
||||
{
|
||||
// There are two persistence mechanisms in play here:
|
||||
// * PersistedWindowLayouts (vector) — consumed on next startup to
|
||||
// re-open a matching set of windows. Cleared after restore.
|
||||
// * PersistedWorkspaces (name-keyed map) — the full tab/buffer
|
||||
// state of a named window, claimed by name on demand via
|
||||
// ApplicationState::TakeWorkspace.
|
||||
//
|
||||
// For named windows we save the full layout into the workspace map
|
||||
// and drop a lightweight `openWorkspace` stub into the generic vector,
|
||||
// so the generic restore path re-opens the named window which in
|
||||
// turn claims its own workspace. Unnamed windows don't have a stable
|
||||
// key, so their full layout is stored directly in the vector.
|
||||
if (const auto layout = GetWindowLayout())
|
||||
{
|
||||
const auto& windowName = _WindowProperties.WindowName();
|
||||
if (!windowName.empty())
|
||||
{
|
||||
// Persist the full layout into the workspace collection.
|
||||
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
|
||||
|
||||
// Build a minimal layout with just an openWorkspace action
|
||||
// so the generic restore path re-opens this workspace by name.
|
||||
std::vector<ActionAndArgs> actions;
|
||||
ActionAndArgs action;
|
||||
action.Action(ShortcutAction::OpenWorkspace);
|
||||
OpenWorkspaceArgs args{ windowName };
|
||||
action.Args(args);
|
||||
actions.emplace_back(std::move(action));
|
||||
|
||||
WindowLayout stub;
|
||||
stub.TabLayout(winrt::single_threaded_vector<ActionAndArgs>(std::move(actions)));
|
||||
ApplicationState::SharedInstance().AppendPersistedWindowLayout(stub);
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplicationState::SharedInstance().AppendPersistedWindowLayout(layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -4057,6 +4122,12 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||
|
||||
// Apply the ShowWindowsButton theme setting.
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme())
|
||||
{
|
||||
_tabRow.ShowWindowsButton(theme.Window() ? theme.Window().ShowWindowsButton() : true);
|
||||
}
|
||||
|
||||
Media::SolidColorBrush transparent{ Windows::UI::Colors::Transparent() };
|
||||
_tabView.Background(transparent);
|
||||
|
||||
@@ -5697,6 +5768,199 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild the workspace flyout contents. Called every time the flyout opens
|
||||
// Rebuild the workspace flyout contents. Called every time the flyout opens
|
||||
// so it reflects the current set of persisted workspaces.
|
||||
void TerminalPage::_PopulateWorkspaceFlyout()
|
||||
{
|
||||
if (!_workspaceFlyout)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_workspaceFlyout.Items().Clear();
|
||||
|
||||
// --- "Name / Rename this window" ---
|
||||
{
|
||||
MenuFlyoutItem item{};
|
||||
item.Text(_WindowProperties.WindowName().empty() ? RS_(L"NameThisWindowMenuItem") : RS_(L"RenameThisWindowMenuItem"));
|
||||
|
||||
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE8AC"); // Rename glyph
|
||||
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
|
||||
item.Icon(iconElement);
|
||||
|
||||
item.Click([weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->_actionDispatch->DoAction(ActionAndArgs{ ShortcutAction::OpenWindowRenamer, nullptr });
|
||||
}
|
||||
});
|
||||
_workspaceFlyout.Items().Append(item);
|
||||
}
|
||||
|
||||
// --- Gather open window info first so we can filter workspaces ---
|
||||
const auto windowListReq{ winrt::make<WindowListRequest>() };
|
||||
RequestWindowList.raise(*this, windowListReq);
|
||||
const auto windowEntries = windowListReq.Entries();
|
||||
|
||||
std::set<winrt::hstring> openWindowNames;
|
||||
if (windowEntries)
|
||||
{
|
||||
for (const auto& entry : windowEntries)
|
||||
{
|
||||
const auto& name = entry.Name();
|
||||
if (!name.empty())
|
||||
{
|
||||
openWindowNames.emplace(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Saved workspaces section (only those not currently open) ---
|
||||
// Collect workspace names that aren't currently open so we can show
|
||||
// them both as top-level "open" items and inside the delete sub-menu.
|
||||
const auto workspaces = ApplicationState::SharedInstance().AllPersistedWorkspaces();
|
||||
if (workspaces && workspaces.Size() > 0)
|
||||
{
|
||||
bool addedSeparator = false;
|
||||
|
||||
for (const auto& pair : workspaces)
|
||||
{
|
||||
const auto name = pair.Key();
|
||||
|
||||
// Skip workspaces that correspond to a currently-open window.
|
||||
if (openWindowNames.count(name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addedSeparator)
|
||||
{
|
||||
_workspaceFlyout.Items().Append(MenuFlyoutSeparator{});
|
||||
addedSeparator = true;
|
||||
}
|
||||
|
||||
MenuFlyoutItem item{};
|
||||
item.Text(name);
|
||||
|
||||
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE8F1"); // SwitchApps glyph
|
||||
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
|
||||
item.Icon(iconElement);
|
||||
|
||||
item.Click([weakThis{ get_weak() }, name](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->_OpenWorkspaceWindow(name);
|
||||
}
|
||||
});
|
||||
|
||||
// Right-click to delete: attach a context flyout with a
|
||||
// "Delete workspace?" item that opens a confirmation dialog.
|
||||
{
|
||||
WUX::Controls::MenuFlyout deleteFlyout{};
|
||||
deleteFlyout.Placement(WUX::Controls::Primitives::FlyoutPlacementMode::BottomEdgeAlignedRight);
|
||||
|
||||
WUX::Controls::MenuFlyoutItem deleteItem{};
|
||||
deleteItem.Text(RS_(L"DeleteWorkspaceMenuItem"));
|
||||
|
||||
WUX::Controls::FontIcon trashIcon{};
|
||||
trashIcon.Glyph(L"\xE74D"); // Delete glyph
|
||||
trashIcon.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
deleteItem.Icon(trashIcon);
|
||||
|
||||
deleteItem.Click([weakThis{ get_weak() }, name](auto&&, auto&&) -> safe_void_coroutine {
|
||||
auto page{ weakThis.get() };
|
||||
if (!page)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Build and show a confirmation ContentDialog.
|
||||
ContentDialog dialog{};
|
||||
dialog.Title(winrt::box_value(winrt::hstring{ RS_fmt(L"ConfirmDeleteWorkspaceTitle", name) }));
|
||||
dialog.PrimaryButtonText(RS_(L"ConfirmDeleteWorkspaceDelete"));
|
||||
dialog.CloseButtonText(RS_(L"ConfirmDeleteWorkspaceCancel"));
|
||||
dialog.DefaultButton(ContentDialogButton::Close);
|
||||
|
||||
if (auto presenter{ page->_dialogPresenter.get() })
|
||||
{
|
||||
const auto result = co_await presenter.ShowDialog(dialog);
|
||||
// Re-check after co_await
|
||||
page = weakThis.get();
|
||||
if (!page)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
if (result == ContentDialogResult::Primary)
|
||||
{
|
||||
ApplicationState::SharedInstance().RemoveWorkspace(name);
|
||||
page->_PopulateWorkspaceFlyout();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
deleteFlyout.Items().Append(deleteItem);
|
||||
WUX::Controls::Primitives::FlyoutBase::SetAttachedFlyout(item, deleteFlyout);
|
||||
item.ContextRequested([item](auto&&, auto&&) {
|
||||
WUX::Controls::Primitives::FlyoutBase::ShowAttachedFlyout(item);
|
||||
});
|
||||
}
|
||||
|
||||
_workspaceFlyout.Items().Append(item);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Open windows section ---
|
||||
if (windowEntries && windowEntries.Size() > 0)
|
||||
{
|
||||
_workspaceFlyout.Items().Append(MenuFlyoutSeparator{});
|
||||
|
||||
const auto thisWindowId = _WindowProperties.WindowId();
|
||||
|
||||
for (const auto& entry : windowEntries)
|
||||
{
|
||||
const auto id = entry.Id();
|
||||
const auto& name = entry.Name();
|
||||
|
||||
winrt::hstring displayText;
|
||||
if (name.empty())
|
||||
{
|
||||
displayText = winrt::hstring{ RS_fmt(L"WindowListUnnamedEntry", id) };
|
||||
}
|
||||
else
|
||||
{
|
||||
displayText = winrt::hstring{ fmt::format(FMT_COMPILE(L"#{}: {}"), id, name) };
|
||||
}
|
||||
|
||||
MenuFlyoutItem item{};
|
||||
item.Text(displayText);
|
||||
|
||||
if (id == thisWindowId)
|
||||
{
|
||||
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE73E"); // CheckMark glyph
|
||||
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
|
||||
item.Icon(iconElement);
|
||||
item.IsEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE737"); // ChromeRestore glyph
|
||||
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
|
||||
item.Icon(iconElement);
|
||||
|
||||
item.Click([weakThis{ get_weak() }, id](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->SummonWindowByIdRequested.raise(*page, winrt::make<SummonWindowByIdRequestedArgs>(id));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_workspaceFlyout.Items().Append(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handler for our WindowProperties's PropertyChanged event. We'll use this
|
||||
// to pop the "Identify Window" toast when the user renames our window.
|
||||
void TerminalPage::_windowPropertyChanged(const IInspectable& /*sender*/, const WUX::Data::PropertyChangedEventArgs& args)
|
||||
@@ -5706,6 +5970,10 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep the workspace dropdown label in sync with the window name.
|
||||
// Use raw WindowName() so clearing the name hides the text.
|
||||
_tabRow.WorkspaceName(_WindowProperties.WindowName());
|
||||
|
||||
// DON'T display the confirmation if this is the name we were
|
||||
// given on startup!
|
||||
if (_startupState == StartupState::Initialized)
|
||||
|
||||
@@ -10,8 +10,11 @@
|
||||
#include "AppKeyBindings.h"
|
||||
#include "AppCommandlineArgs.h"
|
||||
#include "RenameWindowRequestedArgs.g.h"
|
||||
#include "SummonWindowByIdRequestedArgs.g.h"
|
||||
#include "RequestMoveContentArgs.g.h"
|
||||
#include "LaunchPositionRequest.g.h"
|
||||
#include "WindowListEntry.g.h"
|
||||
#include "WindowListRequest.g.h"
|
||||
#include "Toast.h"
|
||||
|
||||
#include "WindowsPackageManagerFactory.h"
|
||||
@@ -73,6 +76,15 @@ namespace winrt::TerminalApp::implementation
|
||||
_ProposedName{ name } {};
|
||||
};
|
||||
|
||||
struct SummonWindowByIdRequestedArgs : SummonWindowByIdRequestedArgsT<SummonWindowByIdRequestedArgs>
|
||||
{
|
||||
WINRT_PROPERTY(uint64_t, WindowId);
|
||||
|
||||
public:
|
||||
SummonWindowByIdRequestedArgs(uint64_t id) :
|
||||
_WindowId{ id } {};
|
||||
};
|
||||
|
||||
struct RequestMoveContentArgs : RequestMoveContentArgsT<RequestMoveContentArgs>
|
||||
{
|
||||
WINRT_PROPERTY(winrt::hstring, Window);
|
||||
@@ -94,6 +106,25 @@ namespace winrt::TerminalApp::implementation
|
||||
til::property<winrt::Microsoft::Terminal::Settings::Model::LaunchPosition> Position;
|
||||
};
|
||||
|
||||
struct WindowListEntry : WindowListEntryT<WindowListEntry>
|
||||
{
|
||||
WindowListEntry() = default;
|
||||
|
||||
til::property<uint64_t> Id;
|
||||
til::property<winrt::hstring> Name;
|
||||
};
|
||||
|
||||
struct WindowListRequest : WindowListRequestT<WindowListRequest>
|
||||
{
|
||||
WindowListRequest() :
|
||||
_Entries{ winrt::single_threaded_vector<winrt::TerminalApp::WindowListEntry>() } {}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::WindowListEntry> Entries() const { return _Entries; }
|
||||
|
||||
private:
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::WindowListEntry> _Entries;
|
||||
};
|
||||
|
||||
struct WinGetSearchParams
|
||||
{
|
||||
winrt::Microsoft::Management::Deployment::PackageMatchField Field;
|
||||
@@ -132,6 +163,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
safe_void_coroutine RequestQuit();
|
||||
safe_void_coroutine CloseWindow();
|
||||
winrt::Microsoft::Terminal::Settings::Model::WindowLayout GetWindowLayout();
|
||||
void PersistState();
|
||||
std::vector<IPaneContent> Panes() const;
|
||||
|
||||
@@ -203,6 +235,7 @@ namespace winrt::TerminalApp::implementation
|
||||
til::typed_event<IInspectable, IInspectable> IdentifyWindowsRequested;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
til::typed_event<IInspectable, IInspectable> SummonWindowRequested;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::SummonWindowByIdRequestedArgs> SummonWindowByIdRequested;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::Tab> FocusTabRequested;
|
||||
til::typed_event<IInspectable, winrt::Microsoft::Terminal::Control::WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
@@ -215,6 +248,7 @@ namespace winrt::TerminalApp::implementation
|
||||
til::typed_event<Windows::Foundation::IInspectable, winrt::TerminalApp::RequestReceiveContentArgs> RequestReceiveContent;
|
||||
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::LaunchPositionRequest> RequestLaunchPosition;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::WindowListRequest> RequestWindowList;
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::Media::Brush, TitlebarBrush, PropertyChanged.raise, nullptr);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::Media::Brush, FrameBrush, PropertyChanged.raise, nullptr);
|
||||
@@ -237,6 +271,8 @@ namespace winrt::TerminalApp::implementation
|
||||
TerminalApp::TabRowControl _tabRow{ nullptr };
|
||||
Windows::UI::Xaml::Controls::Grid _tabContent{ nullptr };
|
||||
Microsoft::UI::Xaml::Controls::SplitButton _newTabButton{ nullptr };
|
||||
Windows::UI::Xaml::Controls::MenuFlyout _workspaceFlyout{ nullptr };
|
||||
Windows::UI::Xaml::Controls::Button _workspaceDropdown{ nullptr };
|
||||
winrt::TerminalApp::ColorPickupFlyout _tabColorPicker{ nullptr };
|
||||
|
||||
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
|
||||
@@ -335,6 +371,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _restartPaneConnection(const TerminalApp::TerminalPaneContent&, const winrt::Windows::Foundation::IInspectable&);
|
||||
|
||||
safe_void_coroutine _OpenNewWindow(const Microsoft::Terminal::Settings::Model::INewContentArgs newContentArgs);
|
||||
safe_void_coroutine _OpenWorkspaceWindow(const winrt::hstring name);
|
||||
|
||||
void _OpenNewTerminalViaDropdown(const Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
|
||||
|
||||
@@ -577,6 +614,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _PopulateContextMenu(const Microsoft::Terminal::Control::TermControl& control, const Microsoft::UI::Xaml::Controls::CommandBarFlyout& sender, const bool withSelection);
|
||||
void _PopulateQuickFixMenu(const Microsoft::Terminal::Control::TermControl& control, const Windows::UI::Xaml::Controls::MenuFlyout& sender);
|
||||
void _PopulateWorkspaceFlyout();
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyout _CreateRunAsAdminFlyout(int profileIndex);
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _senderOrActiveControl(const winrt::Windows::Foundation::IInspectable& sender);
|
||||
@@ -603,4 +641,5 @@ namespace winrt::TerminalApp::implementation
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(TerminalPage);
|
||||
BASIC_FACTORY(WindowListEntry);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@ namespace TerminalApp
|
||||
{
|
||||
String ProposedName { get; };
|
||||
};
|
||||
[default_interface] runtimeclass SummonWindowByIdRequestedArgs
|
||||
{
|
||||
UInt64 WindowId { get; };
|
||||
};
|
||||
[default_interface] runtimeclass RequestMoveContentArgs
|
||||
{
|
||||
String Window { get; };
|
||||
@@ -50,6 +54,20 @@ namespace TerminalApp
|
||||
Microsoft.Terminal.Settings.Model.LaunchPosition Position;
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass WindowListEntry
|
||||
{
|
||||
WindowListEntry();
|
||||
UInt64 Id;
|
||||
String Name;
|
||||
}
|
||||
|
||||
// Raised by TerminalPage when it needs the list of open windows.
|
||||
// The handler (AppHost) fills Entries synchronously.
|
||||
[default_interface] runtimeclass WindowListRequest
|
||||
{
|
||||
Windows.Foundation.Collections.IVector<WindowListEntry> Entries { get; };
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
|
||||
{
|
||||
TerminalPage(WindowProperties properties, ContentManager manager);
|
||||
@@ -93,6 +111,7 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SummonWindowByIdRequestedArgs> SummonWindowByIdRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Control.WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
|
||||
@@ -103,5 +122,6 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, RequestReceiveContentArgs> RequestReceiveContent;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, LaunchPositionRequest> RequestLaunchPosition;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WindowListRequest> RequestWindowList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
||||
#include "BellEventArgs.g.cpp"
|
||||
#include "NotificationEventArgs.g.cpp"
|
||||
#include "TerminalPaneContent.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
@@ -34,6 +35,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
_controlEvents._ConnectionStateChanged = _control.ConnectionStateChanged(winrt::auto_revoke, { this, &TerminalPaneContent::_controlConnectionStateChangedHandler });
|
||||
_controlEvents._WarningBell = _control.WarningBell(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlWarningBellHandler });
|
||||
_controlEvents._PromptStarted = _control.PromptStarted(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlPromptStartedHandler });
|
||||
_controlEvents._CloseTerminalRequested = _control.CloseTerminalRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_closeTerminalRequestedHandler });
|
||||
_controlEvents._RestartTerminalRequested = _control.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_restartTerminalRequestedHandler });
|
||||
|
||||
@@ -42,6 +44,9 @@ namespace winrt::TerminalApp::implementation
|
||||
_controlEvents._SetTaskbarProgress = _control.SetTaskbarProgress(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlSetTaskbarProgress });
|
||||
_controlEvents._ReadOnlyChanged = _control.ReadOnlyChanged(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlReadOnlyChanged });
|
||||
_controlEvents._FocusFollowMouseRequested = _control.FocusFollowMouseRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlFocusFollowMouseRequested });
|
||||
_controlEvents._ShowNotification = _control.ShowNotification(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlShowNotification });
|
||||
_controlEvents._OutputStarted = _control.OutputStarted(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlOutputStartedHandler });
|
||||
_controlEvents._OutputBurstEnded = _control.OutputIdle(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlOutputBurstEndedHandler });
|
||||
}
|
||||
void TerminalPaneContent::_removeControlEvents()
|
||||
{
|
||||
@@ -71,6 +76,18 @@ namespace winrt::TerminalApp::implementation
|
||||
_removeControlEvents();
|
||||
|
||||
_control.Close();
|
||||
|
||||
// Clear out our media player callbacks, and stop any playing media. This
|
||||
// will prevent the callback from being triggered after we've closed, and
|
||||
// also make sure that our sound stops when we're closed.
|
||||
if (_bellPlayer)
|
||||
{
|
||||
_bellPlayer.Pause();
|
||||
_bellPlayer.Source(nullptr);
|
||||
_bellPlayer.Close();
|
||||
_bellPlayer = nullptr;
|
||||
_bellPlayerCreated = false;
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring TerminalPaneContent::Icon() const
|
||||
@@ -161,6 +178,16 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TaskbarState TerminalPaneContent::TaskbarState()
|
||||
{
|
||||
return _control.TaskbarState();
|
||||
}
|
||||
|
||||
uint64_t TerminalPaneContent::TaskbarProgress()
|
||||
{
|
||||
return _control.TaskbarProgress();
|
||||
}
|
||||
void TerminalPaneContent::_controlReadOnlyChanged(const IInspectable&, const IInspectable&)
|
||||
{
|
||||
ReadOnlyChanged.raise(*this, nullptr);
|
||||
@@ -170,6 +197,11 @@ namespace winrt::TerminalApp::implementation
|
||||
FocusRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlShowNotification(const IInspectable& /*sender*/, const ShowNotificationEventArgs& args)
|
||||
{
|
||||
NotificationRequested.raise(*this, winrt::make<implementation::NotificationEventArgs>(OutputNotificationStyle::Notification, true, args.Title(), args.Body()));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when our attached control is closed. Triggers listeners to our close
|
||||
// event, if we're a leaf pane.
|
||||
@@ -249,6 +281,25 @@ namespace winrt::TerminalApp::implementation
|
||||
// has the 'visual' flag set
|
||||
// Arguments:
|
||||
// - <unused>
|
||||
void TerminalPaneContent::PlayNotificationSound()
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
auto sounds{ _profile.BellSound() };
|
||||
if (sounds && sounds.Size() > 0)
|
||||
{
|
||||
winrt::hstring soundPath{ sounds.GetAt(rand() % sounds.Size()).Resolved() };
|
||||
winrt::Windows::Foundation::Uri uri{ soundPath };
|
||||
_playBellSound(uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
|
||||
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
@@ -260,19 +311,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
|
||||
{
|
||||
// Audible is set, play the sound
|
||||
auto sounds{ _profile.BellSound() };
|
||||
if (sounds && sounds.Size() > 0)
|
||||
{
|
||||
// Sound paths are resolved and validated by CascadiaSettings
|
||||
// before we reach this point.
|
||||
auto soundPath{ sounds.GetAt(rand() % sounds.Size()).Resolved() };
|
||||
PlaySoundW(soundPath.c_str(), nullptr, SND_FILENAME | SND_ASYNC | SND_SENTRY | SND_NODEFAULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto soundAlias = reinterpret_cast<LPCWSTR>(SND_ALIAS_SYSTEMHAND);
|
||||
PlaySoundW(soundAlias, nullptr, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
|
||||
}
|
||||
PlayNotificationSound();
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
|
||||
@@ -289,6 +328,95 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlPromptStartedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
const auto notifyStyle = _profile.NotifyOnNextPrompt();
|
||||
if (notifyStyle != OutputNotificationStyle::None)
|
||||
{
|
||||
if (const auto thresholdInSeconds = _profile.NotifyOnNextPromptThreshold(); thresholdInSeconds > 0)
|
||||
{
|
||||
if (_lastOutputStartedAt == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (const auto elapsedMs = GetTickCount64() - _lastOutputStartedAt; elapsedMs < (static_cast<uint64_t>(thresholdInSeconds) * 1000))
|
||||
{
|
||||
_lastOutputStartedAt = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
_lastOutputStartedAt = 0;
|
||||
|
||||
NotificationRequested.raise(*this,
|
||||
*winrt::make_self<TerminalApp::implementation::NotificationEventArgs>(notifyStyle, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPaneContent::_controlOutputStartedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
_lastOutputStartedAt = GetTickCount64();
|
||||
}
|
||||
|
||||
// The underlying TermControl::OutputIdle event is fired on the trailing
|
||||
// edge of a 100ms-debounced output burst (see ControlCore::Initialize).
|
||||
// When "notifyOnActivity" is enabled, we get one event per burst of
|
||||
// output, which naturally coalesces a stream of output into a single notification.
|
||||
void TerminalPaneContent::_controlOutputBurstEndedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
|
||||
{
|
||||
if (_profile)
|
||||
{
|
||||
const auto notifyStyle = _profile.NotifyOnActivity();
|
||||
if (notifyStyle != OutputNotificationStyle::None)
|
||||
{
|
||||
const auto now = GetTickCount64();
|
||||
const auto thresholdSeconds = _profile.NotifyOnActivityThreshold();
|
||||
if (thresholdSeconds > 0 &&
|
||||
_lastActivityNotificationAt != 0 &&
|
||||
(now - _lastActivityNotificationAt) < (static_cast<uint64_t>(thresholdSeconds) * 1000))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_lastActivityNotificationAt = now;
|
||||
|
||||
NotificationRequested.raise(*this,
|
||||
*winrt::make_self<TerminalApp::implementation::NotificationEventArgs>(notifyStyle, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
safe_void_coroutine TerminalPaneContent::_playBellSound(winrt::Windows::Foundation::Uri uri)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
co_await wil::resume_foreground(_control.Dispatcher());
|
||||
if (auto pane{ weakThis.get() })
|
||||
{
|
||||
if (!_bellPlayerCreated)
|
||||
{
|
||||
// The MediaPlayer might not exist on Windows N SKU.
|
||||
try
|
||||
{
|
||||
_bellPlayerCreated = true;
|
||||
_bellPlayer = winrt::Windows::Media::Playback::MediaPlayer();
|
||||
// GH#12258: The media keys (like play/pause) should have no effect on our bell sound.
|
||||
_bellPlayer.CommandManager().IsEnabled(false);
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
if (_bellPlayer)
|
||||
{
|
||||
const auto source{ winrt::Windows::Media::Core::MediaSource::CreateFromUri(uri) };
|
||||
const auto item{ winrt::Windows::Media::Playback::MediaPlaybackItem(source) };
|
||||
_bellPlayer.Source(item);
|
||||
_bellPlayer.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
void TerminalPaneContent::_closeTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const winrt::Windows::Foundation::IInspectable& /*args*/)
|
||||
{
|
||||
|
||||
@@ -24,9 +24,11 @@ namespace winrt::TerminalApp::implementation
|
||||
struct NotificationEventArgs : public NotificationEventArgsT<NotificationEventArgs>
|
||||
{
|
||||
public:
|
||||
NotificationEventArgs(const winrt::hstring& title = {}, const winrt::hstring& body = {}) :
|
||||
Title(title), Body(body) {}
|
||||
NotificationEventArgs(winrt::Microsoft::Terminal::Control::OutputNotificationStyle style, bool alwaysNotify = true, const winrt::hstring& title = {}, const winrt::hstring& body = {}) :
|
||||
Style(style), AlwaysNotify(alwaysNotify), Title(title), Body(body) {}
|
||||
|
||||
til::property<winrt::Microsoft::Terminal::Control::OutputNotificationStyle> Style;
|
||||
til::property<bool> AlwaysNotify;
|
||||
til::property<winrt::hstring> Title;
|
||||
til::property<winrt::hstring> Body;
|
||||
};
|
||||
@@ -48,6 +50,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
|
||||
|
||||
void MarkAsDefterm();
|
||||
void PlayNotificationSound();
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile GetProfile() const
|
||||
{
|
||||
@@ -55,8 +58,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
winrt::hstring Title() { return _control.Title(); }
|
||||
uint64_t TaskbarState() { return _control.TaskbarState(); }
|
||||
uint64_t TaskbarProgress() { return _control.TaskbarProgress(); }
|
||||
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState();
|
||||
uint64_t TaskbarProgress();
|
||||
bool ReadOnly() { return _control.ReadOnly(); }
|
||||
winrt::hstring Icon() const;
|
||||
Windows::Foundation::IReference<winrt::Windows::UI::Color> TabColor() const noexcept;
|
||||
@@ -76,10 +79,21 @@ namespace winrt::TerminalApp::implementation
|
||||
std::shared_ptr<TerminalSettingsCache> _cache{};
|
||||
bool _isDefTermSession{ false };
|
||||
|
||||
winrt::Windows::Media::Playback::MediaPlayer _bellPlayer{ nullptr };
|
||||
bool _bellPlayerCreated{ false };
|
||||
|
||||
// Tracks the GetTickCount64() for NotifyOnActivityThreshold
|
||||
// and NotifyOnNextPromptThreshold respectively.
|
||||
uint64_t _lastActivityNotificationAt{ 0 };
|
||||
uint64_t _lastOutputStartedAt{ 0 };
|
||||
|
||||
struct ControlEventTokens
|
||||
{
|
||||
winrt::Microsoft::Terminal::Control::TermControl::ConnectionStateChanged_revoker _ConnectionStateChanged;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::WarningBell_revoker _WarningBell;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::PromptStarted_revoker _PromptStarted;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::OutputStarted_revoker _OutputStarted;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::OutputIdle_revoker _OutputBurstEnded;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::CloseTerminalRequested_revoker _CloseTerminalRequested;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::RestartTerminalRequested_revoker _RestartTerminalRequested;
|
||||
|
||||
@@ -88,14 +102,20 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Control::TermControl::SetTaskbarProgress_revoker _SetTaskbarProgress;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::ReadOnlyChanged_revoker _ReadOnlyChanged;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::FocusFollowMouseRequested_revoker _FocusFollowMouseRequested;
|
||||
winrt::Microsoft::Terminal::Control::TermControl::ShowNotification_revoker _ShowNotification;
|
||||
|
||||
} _controlEvents;
|
||||
void _setupControlEvents();
|
||||
void _removeControlEvents();
|
||||
|
||||
safe_void_coroutine _playBellSound(winrt::Windows::Foundation::Uri uri);
|
||||
|
||||
safe_void_coroutine _controlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
void _controlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& e);
|
||||
void _controlPromptStartedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& eventArgs);
|
||||
void _controlOutputStartedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& eventArgs);
|
||||
void _controlOutputBurstEndedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& eventArgs);
|
||||
void _controlReadOnlyChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _controlTitleChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
@@ -103,6 +123,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _controlSetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _controlReadOnlyChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _controlFocusFollowMouseRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
void _controlShowNotification(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Microsoft::Terminal::Control::ShowNotificationEventArgs& args);
|
||||
|
||||
void _closeTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
void _restartTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace TerminalApp
|
||||
Microsoft.Terminal.Control.TermControl GetTermControl();
|
||||
|
||||
void MarkAsDefterm();
|
||||
void PlayNotificationSound();
|
||||
|
||||
Microsoft.Terminal.Settings.Model.Profile GetProfile();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace winrt::TerminalApp::implementation
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsProgressRingActive, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsProgressRingIndeterminate, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, BellIndicator, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ActivityIndicator, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsReadOnlyActive, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(uint32_t, ProgressValue, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsInputBroadcastActive, PropertyChanged.raise);
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace TerminalApp
|
||||
Boolean IsProgressRingActive { get; set; };
|
||||
Boolean IsProgressRingIndeterminate { get; set; };
|
||||
Boolean BellIndicator { get; set; };
|
||||
Boolean ActivityIndicator { get; set; };
|
||||
UInt32 ProgressValue { get; set; };
|
||||
Boolean IsReadOnlyActive { get; set; };
|
||||
Boolean IsInputBroadcastActive { get; set; };
|
||||
|
||||
@@ -258,6 +258,15 @@ namespace winrt::TerminalApp::implementation
|
||||
AppLogic::Current()->NotifyRootInitialized();
|
||||
}
|
||||
|
||||
WindowLayout TerminalWindow::GetWindowLayout()
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
return _root->GetWindowLayout();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TerminalWindow::PersistState()
|
||||
{
|
||||
if (_root)
|
||||
@@ -1103,6 +1112,11 @@ namespace winrt::TerminalApp::implementation
|
||||
_initialContentArgs = wil::to_vector(args);
|
||||
}
|
||||
|
||||
void TerminalWindow::SetPersistedLayout(const winrt::Microsoft::Terminal::Settings::Model::WindowLayout& layout)
|
||||
{
|
||||
_cachedLayout = layout;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Parse the provided commandline arguments into actions, and try to
|
||||
// perform them immediately.
|
||||
@@ -1223,7 +1237,14 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalWindow::WindowName(const winrt::hstring& name)
|
||||
{
|
||||
const auto oldIsQuakeMode = _WindowProperties->IsQuakeWindow();
|
||||
const auto oldName = _WindowProperties->WindowName();
|
||||
_WindowProperties->WindowName(name);
|
||||
// If this window had a persisted workspace under the old name, rename
|
||||
// that entry too so we don't leave a stale copy behind.
|
||||
if (!oldName.empty() && !name.empty() && oldName != name)
|
||||
{
|
||||
ApplicationState::SharedInstance().RenameWorkspace(oldName, name);
|
||||
}
|
||||
if (!_root)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -71,6 +71,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void Create();
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::WindowLayout GetWindowLayout();
|
||||
void PersistState();
|
||||
|
||||
void UpdateSettings(winrt::TerminalApp::SettingsLoadEventArgs args);
|
||||
@@ -79,6 +80,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
int32_t SetStartupCommandline(TerminalApp::CommandlineArgs args);
|
||||
void SetStartupContent(const winrt::hstring& content, const Windows::Foundation::IReference<Windows::Foundation::Rect>& contentBounds);
|
||||
void SetPersistedLayout(const winrt::Microsoft::Terminal::Settings::Model::WindowLayout& layout);
|
||||
int32_t ExecuteCommandline(TerminalApp::CommandlineArgs args);
|
||||
void SetSettingsStartupArgs(const std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs>& actions);
|
||||
|
||||
@@ -222,6 +224,7 @@ namespace winrt::TerminalApp::implementation
|
||||
FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
|
||||
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
|
||||
FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested);
|
||||
FORWARDED_TYPED_EVENT(SummonWindowByIdRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::SummonWindowByIdRequestedArgs, _root, SummonWindowByIdRequested);
|
||||
FORWARDED_TYPED_EVENT(FocusTabRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::Tab, _root, FocusTabRequested);
|
||||
FORWARDED_TYPED_EVENT(OpenSystemMenu, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, OpenSystemMenu);
|
||||
FORWARDED_TYPED_EVENT(QuitRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, QuitRequested);
|
||||
@@ -231,6 +234,7 @@ namespace winrt::TerminalApp::implementation
|
||||
FORWARDED_TYPED_EVENT(RequestReceiveContent, Windows::Foundation::IInspectable, winrt::TerminalApp::RequestReceiveContentArgs, _root, RequestReceiveContent);
|
||||
|
||||
FORWARDED_TYPED_EVENT(RequestLaunchPosition, Windows::Foundation::IInspectable, winrt::TerminalApp::LaunchPositionRequest, _root, RequestLaunchPosition);
|
||||
FORWARDED_TYPED_EVENT(RequestWindowList, Windows::Foundation::IInspectable, winrt::TerminalApp::WindowListRequest, _root, RequestWindowList);
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend class TerminalAppLocalTests::CommandlineTest;
|
||||
|
||||
@@ -56,11 +56,13 @@ namespace TerminalApp
|
||||
|
||||
Int32 SetStartupCommandline(CommandlineArgs args);
|
||||
void SetStartupContent(String json, Windows.Foundation.IReference<Windows.Foundation.Rect> bounds);
|
||||
void SetPersistedLayout(Microsoft.Terminal.Settings.Model.WindowLayout layout);
|
||||
Int32 ExecuteCommandline(CommandlineArgs args);
|
||||
|
||||
Boolean ShouldImmediatelyHandoffToElevated();
|
||||
void HandoffToElevated();
|
||||
|
||||
Microsoft.Terminal.Settings.Model.WindowLayout GetWindowLayout();
|
||||
void PersistState();
|
||||
|
||||
Windows.UI.Xaml.UIElement GetRoot();
|
||||
@@ -128,6 +130,7 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SummonWindowByIdRequestedArgs> SummonWindowByIdRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, TerminalApp.Tab> FocusTabRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;
|
||||
@@ -140,6 +143,7 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, RequestMoveContentArgs> RequestMoveContent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, RequestReceiveContentArgs> RequestReceiveContent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, LaunchPositionRequest> RequestLaunchPosition;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WindowListRequest> RequestWindowList;
|
||||
|
||||
void AttachContent(String content, UInt32 tabIndex);
|
||||
void SendContentToOther(RequestReceiveContentArgs args);
|
||||
|
||||
@@ -139,6 +139,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto pfnSearchMissingCommand = [this](auto&& PH1, auto&& PH2) { _terminalSearchMissingCommand(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2)); };
|
||||
_terminal->SetSearchMissingCommandCallback(pfnSearchMissingCommand);
|
||||
|
||||
auto pfnShowNotification = [this](auto&& PH1, auto&& PH2) { _terminalShowNotification(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2)); };
|
||||
_terminal->SetShowNotificationCallback(pfnShowNotification);
|
||||
|
||||
auto pfnPromptStarted = [this] { _terminalPromptStarted(); };
|
||||
_terminal->SetPromptStartedCallback(pfnPromptStarted);
|
||||
|
||||
auto pfnOutputStarted = [this] { _terminalOutputStarted(); };
|
||||
_terminal->SetOutputStartedCallback(pfnOutputStarted);
|
||||
|
||||
auto pfnClearQuickFix = [this] { ClearQuickFix(); };
|
||||
_terminal->SetClearQuickFixCallback(pfnClearQuickFix);
|
||||
|
||||
@@ -913,6 +922,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_hasUnfocusedAppearance = static_cast<bool>(newAppearance);
|
||||
_unfocusedAppearance = _hasUnfocusedAppearance ? newAppearance : settings;
|
||||
|
||||
// Cache the auto-detect setting in an atomic so the off-thread output/prompt
|
||||
// callbacks can read it without synchronizing with _settings. If the effective
|
||||
// taskbar state changes (because a command is currently active and the setting
|
||||
// toggled), notify listeners.
|
||||
const auto nowEnabled = _settings.AutoDetectRunningCommand();
|
||||
const auto wasEnabled = _autoDetectCommandActivity.exchange(nowEnabled, std::memory_order_relaxed);
|
||||
if (wasEnabled != nowEnabled && _commandActive.load(std::memory_order_relaxed))
|
||||
{
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
const auto lock = _terminal->LockForWriting();
|
||||
|
||||
_builtinGlyphs = _settings.EnableBuiltinGlyphs();
|
||||
@@ -925,7 +945,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// Manually turn off acrylic if they turn off transparency.
|
||||
_runtimeUseAcrylic = _settings.Opacity() < 1.0 && _settings.UseAcrylic();
|
||||
|
||||
const auto sizeChanged = _setFontSizeUnderLock(_settings.FontSize() + _accumulatedFontSizeDelta);
|
||||
const auto sizeChanged = _setFontSizeUnderLock(_settings.FontSize());
|
||||
|
||||
// Update the terminal core with its new Core settings
|
||||
_terminal->UpdateSettings(_settings);
|
||||
@@ -1163,10 +1183,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - none
|
||||
void ControlCore::ResetFontSize()
|
||||
{
|
||||
if (std::exchange(_accumulatedFontSizeDelta, 0.f) != 0.f)
|
||||
const auto lock = _terminal->LockForWriting();
|
||||
|
||||
if (_setFontSizeUnderLock(_settings.FontSize()))
|
||||
{
|
||||
// No point in doing this if there was no delta.
|
||||
AdjustFontSize(0);
|
||||
_refreshSizeUnderLock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1176,11 +1197,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - fontSizeDelta: The amount to increase or decrease the font size by.
|
||||
void ControlCore::AdjustFontSize(float fontSizeDelta)
|
||||
{
|
||||
_accumulatedFontSizeDelta += fontSizeDelta;
|
||||
|
||||
const auto lock = _terminal->LockForWriting();
|
||||
|
||||
if (_setFontSizeUnderLock(_settings.FontSize() + _accumulatedFontSizeDelta))
|
||||
if (_setFontSizeUnderLock(_desiredFont.GetFontSize() + fontSizeDelta))
|
||||
{
|
||||
_refreshSizeUnderLock();
|
||||
}
|
||||
@@ -1548,10 +1567,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - Gets the internal taskbar state value
|
||||
// Return Value:
|
||||
// - The taskbar state of this control
|
||||
const size_t ControlCore::TaskbarState() const noexcept
|
||||
const Control::TaskbarState ControlCore::TaskbarState() const noexcept
|
||||
{
|
||||
const auto lock = _terminal->LockForReading();
|
||||
return _terminal->GetTaskbarState();
|
||||
const auto vtState = static_cast<Control::TaskbarState>(_terminal->GetTaskbarState());
|
||||
if (vtState == Control::TaskbarState::Clear &&
|
||||
_autoDetectCommandActivity.load(std::memory_order_relaxed) &&
|
||||
_commandActive.load(std::memory_order_relaxed))
|
||||
{
|
||||
return Control::TaskbarState::Indeterminate;
|
||||
}
|
||||
return vtState;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1581,6 +1607,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _terminal->GetViewport().Height();
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Gets the width of the terminal in columns. This is just the
|
||||
// width of the viewport.
|
||||
// Return Value:
|
||||
// - The width of the terminal in columns
|
||||
int ControlCore::ViewWidth() const
|
||||
{
|
||||
const auto lock = _terminal->LockForReading();
|
||||
return _terminal->GetViewport().Width();
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Gets the height of the terminal in lines of text. This includes the
|
||||
// history AND the viewport.
|
||||
@@ -1600,6 +1637,26 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
WarningBell.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ControlCore::_terminalPromptStarted()
|
||||
{
|
||||
if (_commandActive.exchange(false, std::memory_order_relaxed) &&
|
||||
_autoDetectCommandActivity.load(std::memory_order_relaxed))
|
||||
{
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
PromptStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ControlCore::_terminalOutputStarted()
|
||||
{
|
||||
if (!_commandActive.exchange(true, std::memory_order_relaxed) &&
|
||||
_autoDetectCommandActivity.load(std::memory_order_relaxed))
|
||||
{
|
||||
TaskbarProgressChanged.raise(*this, nullptr);
|
||||
}
|
||||
OutputStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called for the Terminal's TitleChanged callback. This will re-raise
|
||||
// a new winrt TypedEvent that can be listened to.
|
||||
@@ -1692,6 +1749,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
SearchMissingCommand.raise(*this, make<implementation::SearchMissingCommandEventArgs>(hstring{ missingCommand }, bufferRow));
|
||||
}
|
||||
|
||||
void ControlCore::_terminalShowNotification(std::wstring_view title, std::wstring_view body)
|
||||
{
|
||||
ShowNotification.raise(*this, make<implementation::ShowNotificationEventArgs>(hstring{ title }, hstring{ body }));
|
||||
}
|
||||
|
||||
void ControlCore::OpenCWD()
|
||||
{
|
||||
const auto workingDirectory = WorkingDirectory();
|
||||
@@ -2339,6 +2401,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
_terminal->Write(sequence);
|
||||
|
||||
// Clear scroll marks so they don't remain stale in the scrollbar.
|
||||
// The Scrollback case is already handled by the \x1b[3J path (TextBuffer::ClearScrollback).
|
||||
if (clearType != ClearBufferType::Scrollback)
|
||||
{
|
||||
_terminal->ClearAllMarks();
|
||||
}
|
||||
}
|
||||
|
||||
if (clearType == Control::ClearBufferType::Screen || clearType == Control::ClearBufferType::All)
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void OpenCWD();
|
||||
|
||||
#pragma region ICoreState
|
||||
const size_t TaskbarState() const noexcept;
|
||||
const Control::TaskbarState TaskbarState() const noexcept;
|
||||
const size_t TaskbarProgress() const noexcept;
|
||||
|
||||
hstring Title();
|
||||
@@ -172,6 +172,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
int ScrollOffset();
|
||||
int ViewHeight() const;
|
||||
int ViewWidth() const;
|
||||
int BufferHeight() const;
|
||||
|
||||
bool HasSelection() const;
|
||||
@@ -275,6 +276,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, Control::TitleChangedEventArgs> TitleChanged;
|
||||
til::typed_event<IInspectable, Control::WriteToClipboardEventArgs> WriteToClipboard;
|
||||
til::typed_event<> WarningBell;
|
||||
til::typed_event<> PromptStarted;
|
||||
til::typed_event<> OutputStarted;
|
||||
til::typed_event<> TabColorChanged;
|
||||
til::typed_event<> BackgroundColorChanged;
|
||||
til::typed_event<IInspectable, Control::ScrollPositionChangedArgs> ScrollPositionChanged;
|
||||
@@ -292,6 +295,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, Control::OpenHyperlinkEventArgs> OpenHyperlink;
|
||||
til::typed_event<IInspectable, Control::CompletionsChangedEventArgs> CompletionsChanged;
|
||||
til::typed_event<IInspectable, Control::SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
til::typed_event<IInspectable, Control::ShowNotificationEventArgs> ShowNotification;
|
||||
til::typed_event<> RefreshQuickFixUI;
|
||||
til::typed_event<IInspectable, Control::WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
@@ -323,6 +327,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
#pragma region TerminalCoreCallbacks
|
||||
void _terminalWarningBell();
|
||||
void _terminalPromptStarted();
|
||||
void _terminalOutputStarted();
|
||||
void _terminalTitleChanged(std::wstring_view wstr);
|
||||
void _terminalScrollPositionChanged(const int viewTop,
|
||||
const int viewHeight,
|
||||
@@ -333,6 +339,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const int velocity,
|
||||
const std::chrono::microseconds duration);
|
||||
void _terminalSearchMissingCommand(std::wstring_view missingCommand, const til::CoordType& bufferRow);
|
||||
void _terminalShowNotification(std::wstring_view title, std::wstring_view body);
|
||||
void _terminalWindowSizeChanged(int32_t width, int32_t height);
|
||||
|
||||
void _terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength);
|
||||
@@ -391,7 +398,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool _colorGlyphs = true;
|
||||
CSSLengthPercentage _cellWidth;
|
||||
CSSLengthPercentage _cellHeight;
|
||||
float _accumulatedFontSizeDelta = 0.f; // Preserved across reloads to prevent user zoom from being overwritten.
|
||||
|
||||
// Rendering stuff.
|
||||
winrt::handle _lastSwapChainHandle{ nullptr };
|
||||
@@ -420,6 +426,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
std::optional<til::point> _lastHoveredCell;
|
||||
uint16_t _lastHoveredId{ 0 };
|
||||
std::atomic<bool> _initializedTerminal{ false };
|
||||
std::atomic<bool> _autoDetectCommandActivity{ false };
|
||||
std::atomic<bool> _commandActive{ false };
|
||||
bool _isReadOnly{ false };
|
||||
bool _closing{ false };
|
||||
|
||||
|
||||
@@ -192,12 +192,15 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WriteToClipboardEventArgs> WriteToClipboard;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> PromptStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OutputStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> BackgroundColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TaskbarProgressChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RendererEnteredErrorState;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowWindowArgs> ShowWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowNotificationEventArgs> ShowNotification;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RefreshQuickFixUI;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "CharSentEventArgs.g.h"
|
||||
#include "StringSentEventArgs.g.h"
|
||||
#include "SearchMissingCommandEventArgs.g.h"
|
||||
#include "ShowNotificationEventArgs.g.h"
|
||||
#include "WindowSizeChangedEventArgs.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
@@ -252,6 +253,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::property<til::CoordType> BufferRow;
|
||||
};
|
||||
|
||||
struct ShowNotificationEventArgs : public ShowNotificationEventArgsT<ShowNotificationEventArgs>
|
||||
{
|
||||
public:
|
||||
ShowNotificationEventArgs(const winrt::hstring& title, const winrt::hstring& body) :
|
||||
Title(title),
|
||||
Body(body) {}
|
||||
|
||||
til::property<winrt::hstring> Title;
|
||||
til::property<winrt::hstring> Body;
|
||||
};
|
||||
|
||||
struct WindowSizeChangedEventArgs : public WindowSizeChangedEventArgsT<WindowSizeChangedEventArgs>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -160,6 +160,12 @@ namespace Microsoft.Terminal.Control
|
||||
Int32 BufferRow { get; };
|
||||
}
|
||||
|
||||
runtimeclass ShowNotificationEventArgs
|
||||
{
|
||||
String Title { get; };
|
||||
String Body { get; };
|
||||
}
|
||||
|
||||
runtimeclass WindowSizeChangedEventArgs
|
||||
{
|
||||
Int32 Width;
|
||||
|
||||
@@ -29,6 +29,30 @@ namespace Microsoft.Terminal.Control
|
||||
MinGW,
|
||||
};
|
||||
|
||||
[flags]
|
||||
enum OutputNotificationStyle
|
||||
{
|
||||
None = 0,
|
||||
Taskbar = 0x1,
|
||||
Audible = 0x2,
|
||||
Tab = 0x4,
|
||||
Notification = 0x8,
|
||||
All = 0xffffffff
|
||||
};
|
||||
|
||||
// Mirrors Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState
|
||||
// (which is shared with conhost and lives outside the WinRT projection).
|
||||
// Values must remain numerically identical so the conversion at the
|
||||
// ControlCore boundary is a 1:1 cast.
|
||||
enum TaskbarState
|
||||
{
|
||||
Clear = 0,
|
||||
Set = 1,
|
||||
Error = 2,
|
||||
Indeterminate = 3,
|
||||
Paused = 4,
|
||||
};
|
||||
|
||||
// Class Description:
|
||||
// TerminalSettings encapsulates all settings that control the
|
||||
// TermControl's behavior. In these settings there is both the entirety
|
||||
@@ -78,6 +102,12 @@ namespace Microsoft.Terminal.Control
|
||||
PathTranslationStyle PathTranslationStyle { get; };
|
||||
String DragDropDelimiter { get; };
|
||||
|
||||
OutputNotificationStyle NotifyOnActivity { get; };
|
||||
OutputNotificationStyle NotifyOnNextPrompt { get; };
|
||||
Int32 NotifyOnActivityThreshold { get; };
|
||||
Int32 NotifyOnNextPromptThreshold { get; };
|
||||
Boolean AutoDetectRunningCommand { get; };
|
||||
|
||||
// NOTE! When adding something here, make sure to update ControlProperties.h too!
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "IControlSettings.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Control
|
||||
{
|
||||
enum MarkCategory
|
||||
@@ -31,7 +33,7 @@ namespace Microsoft.Terminal.Control
|
||||
interface ICoreState
|
||||
{
|
||||
String Title { get; };
|
||||
UInt64 TaskbarState { get; };
|
||||
Microsoft.Terminal.Control.TaskbarState TaskbarState { get; };
|
||||
UInt64 TaskbarProgress { get; };
|
||||
|
||||
String WorkingDirectory { get; };
|
||||
|
||||
@@ -328,6 +328,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_revokers.CompletionsChanged = _core.CompletionsChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleCompletionsChanged });
|
||||
_revokers.RestartTerminalRequested = _core.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleRestartTerminalRequested });
|
||||
_revokers.SearchMissingCommand = _core.SearchMissingCommand(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleSearchMissingCommand });
|
||||
_revokers.ShowNotification = _core.ShowNotification(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleShowNotification });
|
||||
_revokers.WindowSizeChanged = _core.WindowSizeChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWindowSizeChanged });
|
||||
_revokers.WriteToClipboard = _core.WriteToClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWriteToClipboard });
|
||||
|
||||
@@ -393,6 +394,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// attached content before we set up the throttled func, and that'll A/V
|
||||
_revokers.coreScrollPositionChanged = _core.ScrollPositionChanged(winrt::auto_revoke, { get_weak(), &TermControl::_ScrollPositionChanged });
|
||||
_revokers.WarningBell = _core.WarningBell(winrt::auto_revoke, { get_weak(), &TermControl::_coreWarningBell });
|
||||
_revokers.PromptStarted = _core.PromptStarted(winrt::auto_revoke, { get_weak(), &TermControl::_corePromptStarted });
|
||||
_revokers.OutputStarted = _core.OutputStarted(winrt::auto_revoke, { get_weak(), &TermControl::_coreOutputStarted });
|
||||
|
||||
static constexpr auto AutoScrollUpdateInterval = std::chrono::microseconds(static_cast<int>(1.0 / 30.0 * 1000000));
|
||||
_autoScrollTimer.Interval(AutoScrollUpdateInterval);
|
||||
@@ -2456,6 +2459,46 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
_automationPeer.UpdateControlBounds();
|
||||
}
|
||||
|
||||
// Show resize overlay with columns x rows
|
||||
_ShowResizeOverlay();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Shows a centered overlay with the current terminal dimensions (columns x rows).
|
||||
// Used during window resize and font size changes. Skipped for disabled controls
|
||||
// (e.g. the Settings preview terminal) to avoid visual noise.
|
||||
void TermControl::_ShowResizeOverlay()
|
||||
{
|
||||
// Don't show the overlay in the Settings preview control
|
||||
if (!IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto coreImpl = winrt::get_self<ControlCore>(_core);
|
||||
const auto cols = coreImpl->ViewWidth();
|
||||
const auto rows = coreImpl->ViewHeight();
|
||||
if (cols > 0 && rows > 0)
|
||||
{
|
||||
ResizeOverlayText().Text(fmt::format(FMT_COMPILE(L"{} \u00D7 {}"), cols, rows));
|
||||
ResizeOverlay().Visibility(Visibility::Visible);
|
||||
|
||||
if (!_resizeOverlayTimer)
|
||||
{
|
||||
_resizeOverlayTimer.emplace();
|
||||
_resizeOverlayTimer->Interval(std::chrono::milliseconds(750));
|
||||
_resizeOverlayTimer->Tick([weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (auto self = weakThis.get())
|
||||
{
|
||||
self->ResizeOverlay().Visibility(Visibility::Collapsed);
|
||||
self->_resizeOverlayTimer->Stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_resizeOverlayTimer->Start();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -3356,7 +3399,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - Gets the internal taskbar state value
|
||||
// Return Value:
|
||||
// - The taskbar state of this control
|
||||
const uint64_t TermControl::TaskbarState() const noexcept
|
||||
const Control::TaskbarState TermControl::TaskbarState() const noexcept
|
||||
{
|
||||
return _core.TaskbarState();
|
||||
}
|
||||
@@ -3726,6 +3769,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_playWarningBell->Run();
|
||||
}
|
||||
|
||||
void TermControl::_corePromptStarted(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
PromptStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TermControl::_coreOutputStarted(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
OutputStarted.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
hstring TermControl::ReadEntireBuffer() const
|
||||
{
|
||||
return _core.ReadEntireBuffer();
|
||||
@@ -3843,6 +3896,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void TermControl::_coreOutputIdle(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
_refreshSearch();
|
||||
OutputIdle.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void TermControl::OwningHwnd(uint64_t owner)
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void ColorSelection(Control::SelectionColor fg, Control::SelectionColor bg, Core::MatchMode matchMode);
|
||||
|
||||
#pragma region ICoreState
|
||||
const uint64_t TaskbarState() const noexcept;
|
||||
const Control::TaskbarState TaskbarState() const noexcept;
|
||||
const uint64_t TaskbarProgress() const noexcept;
|
||||
|
||||
hstring Title();
|
||||
@@ -211,6 +211,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, IInspectable> FocusFollowMouseRequested;
|
||||
til::typed_event<Control::TermControl, Windows::UI::Xaml::RoutedEventArgs> Initialized;
|
||||
til::typed_event<> WarningBell;
|
||||
til::typed_event<> PromptStarted;
|
||||
til::typed_event<> OutputStarted;
|
||||
til::typed_event<> OutputIdle;
|
||||
til::typed_event<IInspectable, Control::KeySentEventArgs> KeySent;
|
||||
til::typed_event<IInspectable, Control::CharSentEventArgs> CharSent;
|
||||
til::typed_event<IInspectable, Control::StringSentEventArgs> StringSent;
|
||||
@@ -230,6 +233,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(RestartTerminalRequested, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(WriteToClipboard, IInspectable, Control::WriteToClipboardEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(ShowNotification, IInspectable, Control::ShowNotificationEventArgs);
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -316,6 +320,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
winrt::hstring _restorePath;
|
||||
bool _showMarksInScrollbar{ false };
|
||||
|
||||
std::optional<SafeDispatcherTimer> _resizeOverlayTimer;
|
||||
void _ShowResizeOverlay();
|
||||
|
||||
bool _isBackgroundLight{ false };
|
||||
bool _detached{ false };
|
||||
til::CoordType _searchScrollOffset = 0;
|
||||
@@ -424,6 +431,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _coreTransparencyChanged(IInspectable sender, Control::TransparencyChangedEventArgs args);
|
||||
void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args);
|
||||
void _coreWarningBell(const IInspectable& sender, const IInspectable& args);
|
||||
void _corePromptStarted(const IInspectable& sender, const IInspectable& args);
|
||||
void _coreOutputStarted(const IInspectable& sender, const IInspectable& args);
|
||||
void _coreOutputIdle(const IInspectable& sender, const IInspectable& args);
|
||||
|
||||
winrt::Windows::Foundation::Point _toPosInDips(const Core::Point terminalCellPos);
|
||||
@@ -449,6 +458,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
Control::ControlCore::ScrollPositionChanged_revoker coreScrollPositionChanged;
|
||||
Control::ControlCore::WarningBell_revoker WarningBell;
|
||||
Control::ControlCore::PromptStarted_revoker PromptStarted;
|
||||
Control::ControlCore::OutputStarted_revoker OutputStarted;
|
||||
Control::ControlCore::RendererEnteredErrorState_revoker RendererEnteredErrorState;
|
||||
Control::ControlCore::BackgroundColorChanged_revoker BackgroundColorChanged;
|
||||
Control::ControlCore::FontSizeChanged_revoker FontSizeChanged;
|
||||
@@ -468,6 +479,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Control::ControlCore::CompletionsChanged_revoker CompletionsChanged;
|
||||
Control::ControlCore::RestartTerminalRequested_revoker RestartTerminalRequested;
|
||||
Control::ControlCore::SearchMissingCommand_revoker SearchMissingCommand;
|
||||
Control::ControlCore::ShowNotification_revoker ShowNotification;
|
||||
Control::ControlCore::RefreshQuickFixUI_revoker RefreshQuickFixUI;
|
||||
Control::ControlCore::WindowSizeChanged_revoker WindowSizeChanged;
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
|
||||
event Windows.Foundation.TypedEventHandler<Object, NoticeEventArgs> RaiseNotice;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> PromptStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OutputStarted;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OutputIdle;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> HidePointerCursor;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RestorePointerCursor;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||
@@ -82,6 +85,7 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, CharSentEventArgs> CharSent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, StringSentEventArgs> StringSent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowNotificationEventArgs> ShowNotification;
|
||||
|
||||
|
||||
Microsoft.UI.Xaml.Controls.CommandBarFlyout ContextMenu { get; };
|
||||
|
||||
@@ -1365,6 +1365,24 @@
|
||||
|
||||
</Grid>
|
||||
|
||||
<!-- Resize overlay: shows columns x rows when terminal is resized -->
|
||||
<Border x:Name="ResizeOverlay"
|
||||
Padding="16,8,16,8"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
||||
BorderBrush="{ThemeResource SystemAccentColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{ThemeResource OverlayCornerRadius}"
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock x:Name="ResizeOverlayText"
|
||||
FontSize="18"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
|
||||
TextAlignment="Center" />
|
||||
</Border>
|
||||
|
||||
<Grid x:Name="RendererFailedNotice"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
|
||||
@@ -124,6 +124,7 @@ namespace Microsoft.Terminal.Core
|
||||
Boolean AllowKittyKeyboardMode { get; };
|
||||
Boolean AllowVtChecksumReport { get; };
|
||||
Boolean AllowVtClipboardWrite { get; };
|
||||
Boolean AllowOscNotifications { get; };
|
||||
Boolean TrimBlockSelection { get; };
|
||||
Boolean DetectURLs { get; };
|
||||
|
||||
|
||||
@@ -267,6 +267,7 @@ void Terminal::SetOptionalFeatures(winrt::Microsoft::Terminal::Core::ICoreSettin
|
||||
auto features = til::enumset<ITermDispatch::OptionalFeature>{};
|
||||
features.set(ITermDispatch::OptionalFeature::ChecksumReport, settings.AllowVtChecksumReport());
|
||||
features.set(ITermDispatch::OptionalFeature::ClipboardWrite, settings.AllowVtClipboardWrite());
|
||||
features.set(ITermDispatch::OptionalFeature::DesktopNotification, settings.AllowOscNotifications());
|
||||
engine.Dispatch().SetOptionalFeatures(features);
|
||||
}
|
||||
|
||||
@@ -767,6 +768,11 @@ TerminalInput::OutputType Terminal::SendCharEvent(const wchar_t ch, const WORD s
|
||||
// This changed the scrollbar marks - raise a notification to update them
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
// regardless, notify that we started command output
|
||||
if (_pfnOutputStarted)
|
||||
{
|
||||
_pfnOutputStarted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1252,7 +1258,7 @@ const std::optional<til::color> Terminal::GetTabColor() const
|
||||
// - Gets the internal taskbar state value
|
||||
// Return Value:
|
||||
// - The taskbar state
|
||||
const size_t Microsoft::Terminal::Core::Terminal::GetTaskbarState() const noexcept
|
||||
const Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState Microsoft::Terminal::Core::Terminal::GetTaskbarState() const noexcept
|
||||
{
|
||||
return _taskbarState;
|
||||
}
|
||||
@@ -1276,11 +1282,26 @@ void Microsoft::Terminal::Core::Terminal::SetSearchMissingCommandCallback(std::f
|
||||
_pfnSearchMissingCommand.swap(pfn);
|
||||
}
|
||||
|
||||
void Microsoft::Terminal::Core::Terminal::SetShowNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept
|
||||
{
|
||||
_pfnShowNotification.swap(pfn);
|
||||
}
|
||||
|
||||
void Microsoft::Terminal::Core::Terminal::SetClearQuickFixCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnClearQuickFix.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetPromptStartedCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnPromptStarted.swap(pfn);
|
||||
}
|
||||
|
||||
void Terminal::SetOutputStartedCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnOutputStarted.swap(pfn);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Stores the search highlighted regions in the terminal
|
||||
void Terminal::SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept
|
||||
|
||||
@@ -159,12 +159,14 @@ public:
|
||||
|
||||
bool IsVtInputEnabled() const noexcept override;
|
||||
void NotifyBufferRotation(const int delta) override;
|
||||
void NotifyShellIntegrationMark() override;
|
||||
void NotifyShellIntegrationMark(ShellIntegrationMark mark) override;
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
void SearchMissingCommand(const std::wstring_view command) override;
|
||||
|
||||
void ShowNotification(const std::wstring_view title, const std::wstring_view body) override;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
void ClearMark();
|
||||
@@ -233,8 +235,11 @@ public:
|
||||
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
|
||||
void CompletionsChangedCallback(std::function<void(std::wstring_view, unsigned int)> pfn) noexcept;
|
||||
void SetSearchMissingCommandCallback(std::function<void(std::wstring_view, const til::CoordType)> pfn) noexcept;
|
||||
void SetShowNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept;
|
||||
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
|
||||
void SetWindowSizeChangedCallback(std::function<void(int32_t, int32_t)> pfn) noexcept;
|
||||
void SetPromptStartedCallback(std::function<void()> pfn) noexcept;
|
||||
void SetOutputStartedCallback(std::function<void()> pfn) noexcept;
|
||||
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
|
||||
void SetSearchHighlightFocused(size_t focusedIdx) noexcept;
|
||||
void ScrollToSearchHighlight(til::CoordType searchScrollOffset);
|
||||
@@ -243,7 +248,7 @@ public:
|
||||
|
||||
const std::optional<til::color> GetTabColor() const;
|
||||
|
||||
const size_t GetTaskbarState() const noexcept;
|
||||
const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState GetTaskbarState() const noexcept;
|
||||
const size_t GetTaskbarProgress() const noexcept;
|
||||
|
||||
void ColorSelection(const TextAttribute& attr, winrt::Microsoft::Terminal::Core::MatchMode matchMode);
|
||||
@@ -341,8 +346,11 @@ private:
|
||||
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
|
||||
std::function<void(std::wstring_view, unsigned int)> _pfnCompletionsChanged;
|
||||
std::function<void(std::wstring_view, const til::CoordType)> _pfnSearchMissingCommand;
|
||||
std::function<void(std::wstring_view, std::wstring_view)> _pfnShowNotification;
|
||||
std::function<void()> _pfnClearQuickFix;
|
||||
std::function<void(int32_t, int32_t)> _pfnWindowSizeChanged;
|
||||
std::function<void()> _pfnPromptStarted;
|
||||
std::function<void()> _pfnOutputStarted;
|
||||
|
||||
RenderSettings _renderSettings;
|
||||
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
|
||||
@@ -363,6 +371,9 @@ private:
|
||||
|
||||
til::enumset<Mode> _systemMode{ Mode::AutoWrap };
|
||||
|
||||
::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState _taskbarState{ ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState::Clear };
|
||||
size_t _taskbarProgress = 0;
|
||||
|
||||
bool _focused = false;
|
||||
bool _snapOnInput = true;
|
||||
bool _altGrAliasing = true;
|
||||
@@ -371,9 +382,6 @@ private:
|
||||
bool _autoMarkPrompts = false;
|
||||
bool _rainbowSuggestions = false;
|
||||
|
||||
size_t _taskbarState = 0;
|
||||
size_t _taskbarProgress = 0;
|
||||
|
||||
size_t _hyperlinkPatternId = 0;
|
||||
|
||||
std::wstring _answerbackMessage;
|
||||
|
||||
@@ -173,7 +173,7 @@ void Terminal::SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::D
|
||||
{
|
||||
_assertLocked();
|
||||
|
||||
_taskbarState = static_cast<size_t>(state);
|
||||
_taskbarState = state;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
@@ -380,6 +380,14 @@ void Terminal::SearchMissingCommand(const std::wstring_view command)
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::ShowNotification(const std::wstring_view title, const std::wstring_view body)
|
||||
{
|
||||
if (_pfnShowNotification)
|
||||
{
|
||||
_pfnShowNotification(title, body);
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::NotifyBufferRotation(const int delta)
|
||||
{
|
||||
// Update our selection, so it doesn't move as the buffer is cycled
|
||||
@@ -416,8 +424,26 @@ void Terminal::NotifyBufferRotation(const int delta)
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::NotifyShellIntegrationMark()
|
||||
void Terminal::NotifyShellIntegrationMark(ShellIntegrationMark mark)
|
||||
{
|
||||
// Notify the scrollbar that marks have been added so it can refresh the mark indicators
|
||||
_NotifyScrollEvent();
|
||||
|
||||
switch (mark)
|
||||
{
|
||||
case ShellIntegrationMark::Prompt:
|
||||
if (_pfnPromptStarted)
|
||||
{
|
||||
_pfnPromptStarted();
|
||||
}
|
||||
break;
|
||||
case ShellIntegrationMark::Output:
|
||||
if (_pfnOutputStarted)
|
||||
{
|
||||
_pfnOutputStarted();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,8 +352,14 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
_AllowKittyKeyboardMode = profile.AllowKittyKeyboardMode();
|
||||
_AllowVtChecksumReport = profile.AllowVtChecksumReport();
|
||||
_AllowVtClipboardWrite = profile.AllowVtClipboardWrite();
|
||||
_AllowOscNotifications = profile.AllowOscNotifications();
|
||||
_PathTranslationStyle = profile.PathTranslationStyle();
|
||||
_DragDropDelimiter = profile.DragDropDelimiter();
|
||||
_NotifyOnActivity = profile.NotifyOnActivity();
|
||||
_NotifyOnNextPrompt = profile.NotifyOnNextPrompt();
|
||||
_NotifyOnActivityThreshold = profile.NotifyOnActivityThreshold();
|
||||
_NotifyOnNextPromptThreshold = profile.NotifyOnNextPromptThreshold();
|
||||
_AutoDetectRunningCommand = profile.AutoDetectRunningCommand();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
#include "LibraryResources.h"
|
||||
#include "../TerminalSettingsModel/AllShortcutActions.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
@@ -42,4 +44,65 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
// Builds the "view all" flyout lazily on the first click of a
|
||||
// row's "..." button, then caches it on the button so subsequent clicks
|
||||
// just re-show it.
|
||||
void Actions::ViewAllKeyChordsButton_Click(const IInspectable& sender, const RoutedEventArgs& /*e*/)
|
||||
{
|
||||
const auto button = sender.try_as<Button>();
|
||||
if (!button)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve cached flyout, if possible
|
||||
if (const auto existing = button.Flyout())
|
||||
{
|
||||
existing.ShowAt(button);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto cmdVM = button.DataContext().try_as<Editor::CommandViewModel>();
|
||||
if (!cmdVM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Flyout flyout;
|
||||
flyout.Placement(Primitives::FlyoutPlacementMode::Bottom);
|
||||
flyout.FlyoutPresenterStyle(Resources().Lookup(box_value(L"EdgeToEdgeFlyoutPresenterStyle")).as<winrt::Windows::UI::Xaml::Style>());
|
||||
|
||||
StackPanel content;
|
||||
content.Orientation(Orientation::Vertical);
|
||||
content.MinWidth(120.0);
|
||||
|
||||
if (cmdVM.HasNoKeyChords())
|
||||
{
|
||||
const auto emptyTemplate = Resources().Lookup(box_value(L"ViewAllKeyChordsFlyoutEmptyStateTemplate")).as<DataTemplate>();
|
||||
content.Children().Append(emptyTemplate.LoadContent().as<UIElement>());
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto separatorTemplate = Resources().Lookup(box_value(L"ViewAllKeyChordsFlyoutSeparatorTemplate")).as<DataTemplate>();
|
||||
const auto itemTemplate = Resources().Lookup(box_value(L"ViewAllKeyChordsFlyoutItemTemplate")).as<DataTemplate>();
|
||||
const auto chords = cmdVM.KeyChordList();
|
||||
const auto count = chords.Size();
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
content.Children().Append(separatorTemplate.LoadContent().as<UIElement>());
|
||||
}
|
||||
|
||||
auto chordVisual = itemTemplate.LoadContent().as<Editor::KeyChordVisual>();
|
||||
chordVisual.KeyChord(chords.GetAt(i).CurrentKeys());
|
||||
content.Children().Append(chordVisual);
|
||||
}
|
||||
}
|
||||
|
||||
flyout.Content(content);
|
||||
button.Flyout(flyout);
|
||||
flyout.ShowAt(button);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
||||
|
||||
void ViewAllKeyChordsButton_Click(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(Editor::ActionsViewModel, ViewModel, PropertyChanged.raise, nullptr);
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
@@ -17,182 +16,116 @@
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- Theme Dictionary -->
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlForeground"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#B5B5B5" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundPointerOver"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundFocused"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#636363" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#DADADA" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border" />
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<!-- Styles -->
|
||||
<Style x:Key="KeyBindingContainerStyle"
|
||||
<Style x:Key="ActionRowItemContainerStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="12,4,4,4" />
|
||||
<Setter Property="Padding" Value="{StaticResource SettingsCardPadding}" />
|
||||
<Setter Property="MinHeight" Value="{StaticResource SettingsCardMinHeight}" />
|
||||
<Setter Property="Margin" Value="{StaticResource SettingsCardItemMargin}" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="XYFocusKeyboardNavigation" Value="Enabled" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyBindingNameTextBlockStyle"
|
||||
|
||||
<Style x:Key="ActionRowNameTextStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="TextWrapping" Value="WrapWholeWords" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordEditorStyle"
|
||||
TargetType="local:KeyChordListener">
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
|
||||
<Style x:Key="ActionRowSubtleButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="MinWidth" Value="32" />
|
||||
<Setter Property="Width" Value="32" />
|
||||
<Setter Property="Height" Value="32" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
</Style>
|
||||
|
||||
<!-- Converters & Misc. -->
|
||||
<SolidColorBrush x:Key="ActionContainerBackgroundEditing"
|
||||
Color="{ThemeResource SystemListMediumColor}" />
|
||||
<SolidColorBrush x:Key="ActionContainerBackground"
|
||||
Color="Transparent" />
|
||||
<!--
|
||||
FlyoutPresenter style with no internal padding so a full-width Border
|
||||
separator inside the flyout can reach the flyout's left/right edges.
|
||||
-->
|
||||
<Style x:Key="EdgeToEdgeFlyoutPresenterStyle"
|
||||
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||
TargetType="FlyoutPresenter">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
|
||||
</Style>
|
||||
|
||||
<!-- Templates -->
|
||||
<DataTemplate x:Key="ViewAllKeyChordsFlyoutSeparatorTemplate">
|
||||
<Border Height="1"
|
||||
Margin="0,4,0,4"
|
||||
Background="{ThemeResource DividerStrokeColorDefaultBrush}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ViewAllKeyChordsFlyoutEmptyStateTemplate">
|
||||
<TextBlock x:Uid="Actions_NoKeyBindings"
|
||||
Margin="12,8,12,8"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SecondaryTextBlockStyle}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ViewAllKeyChordsFlyoutItemTemplate">
|
||||
<local:KeyChordVisual Margin="{ThemeResource MenuFlyoutItemThemePaddingNarrow}"
|
||||
HorizontalAlignment="Right" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="CommandTemplate"
|
||||
x:DataType="local:CommandViewModel">
|
||||
<ListViewItem AutomationProperties.Name="{x:Bind DisplayNameAndKeyChordAutomationPropName, Mode=OneWay}"
|
||||
Style="{StaticResource KeyBindingContainerStyle}">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- command name -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid AutomationProperties.Name="{x:Bind DisplayNameAndKeyChordAutomationPropName, Mode=OneWay}"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- command name -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- edit button -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- "..." button -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Command Name -->
|
||||
<TextBlock Grid.Column="0"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource KeyBindingNameTextBlockStyle}"
|
||||
Text="{x:Bind DisplayName, Mode=OneWay}" />
|
||||
<!-- Key Chord Text -->
|
||||
<Grid Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Column="0"
|
||||
Padding="8,4,8,4"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(FirstKeyChordText)}">
|
||||
<TextBlock FontSize="14"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind FirstKeyChordText, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Border>
|
||||
<Border Grid.Column="1"
|
||||
Padding="8,4,8,4"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
ToolTipService.ToolTip="{x:Bind AdditionalKeyChordTooltipText, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(AdditionalKeyChordCountText)}">
|
||||
<TextBlock FontSize="14"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind AdditionalKeyChordCountText, Mode=OneWay}" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
<!-- Command Name -->
|
||||
<TextBlock Grid.Column="0"
|
||||
Style="{StaticResource ActionRowNameTextStyle}"
|
||||
Text="{x:Bind DisplayName, Mode=OneWay}" />
|
||||
|
||||
<!-- Key Chord -->
|
||||
<local:KeyChordVisual Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
KeyChord="{x:Bind FirstKeyChord, Mode=OneWay}" />
|
||||
|
||||
<!-- Edit button -->
|
||||
<Button x:Uid="Actions_EditButton"
|
||||
Grid.Column="2"
|
||||
AutomationProperties.Name="{x:Bind DisplayName, Mode=OneWay}"
|
||||
Click="{x:Bind Edit_Click}"
|
||||
Style="{StaticResource ActionRowSubtleButtonStyle}">
|
||||
<FontIcon FontSize="14"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<!-- "..." button + flyout -->
|
||||
<Button x:Uid="Actions_ViewAllKeyChordsButton"
|
||||
Grid.Column="3"
|
||||
Click="ViewAllKeyChordsButton_Click"
|
||||
Style="{StaticResource ActionRowSubtleButtonStyle}">
|
||||
<FontIcon FontSize="14"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
@@ -208,7 +141,8 @@
|
||||
<!-- Add New Button -->
|
||||
<Button x:Name="AddNewButton"
|
||||
Margin="0,12,0,0"
|
||||
Click="{x:Bind ViewModel.AddNewCommand}">
|
||||
Click="{x:Bind ViewModel.AddNewCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
@@ -221,11 +155,42 @@
|
||||
|
||||
<!-- Commands -->
|
||||
<ListView x:Name="CommandsListView"
|
||||
Margin="-8,0,0,0"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="{x:Bind ViewModel.CmdListItemClicked}"
|
||||
ItemContainerStyle="{StaticResource ActionRowItemContainerStyle}"
|
||||
ItemTemplate="{StaticResource CommandTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.CommandList, Mode=OneWay}" />
|
||||
ItemsSource="{x:Bind ViewModel.CommandList, Mode=OneWay}"
|
||||
SelectionMode="None">
|
||||
<!--
|
||||
The framework ListViewItemPresenter reads its per-state backgrounds
|
||||
from these theme resources (not from ListViewItem.Background), so we
|
||||
override them here to match the card chrome on ActionRowItemContainerStyle.
|
||||
-->
|
||||
<ListView.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<StaticResource x:Key="ListViewItemBackground"
|
||||
ResourceKey="ExpanderHeaderBackground" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundPointerOver"
|
||||
ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundPressed"
|
||||
ResourceKey="ControlFillColorTertiaryBrush" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundSelected"
|
||||
ResourceKey="ExpanderHeaderBackground" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundSelectedPointerOver"
|
||||
ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundSelectedPressed"
|
||||
ResourceKey="ControlFillColorTertiaryBrush" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="ListViewItemBackground"
|
||||
ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</ListView.Resources>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Page>
|
||||
|
||||
@@ -57,13 +57,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return;
|
||||
}
|
||||
std::vector<Editor::KeyChordViewModel> keyChordVMs;
|
||||
int32_t idx = 1;
|
||||
for (const auto keys : _keyChordList)
|
||||
{
|
||||
auto kcVM{ make<KeyChordViewModel>(keys) };
|
||||
_RegisterKeyChordVMEvents(kcVM);
|
||||
keyChordVMs.push_back(kcVM);
|
||||
auto kcVM{ make_self<KeyChordViewModel>(keys) };
|
||||
kcVM->Index(idx++);
|
||||
_RegisterKeyChordVMEvents(*kcVM);
|
||||
keyChordVMs.push_back(*kcVM);
|
||||
}
|
||||
_KeyChordList = single_threaded_observable_vector(std::move(keyChordVMs));
|
||||
_KeyChordList.VectorChanged([weakThis{ get_weak() }](const auto& /*sender*/, const auto& /*args*/) {
|
||||
if (auto self{ weakThis.get() })
|
||||
{
|
||||
self->_ReindexKeyChordList();
|
||||
self->_NotifyChanges(L"FirstKeyChord", L"FirstKeyChordText", L"AdditionalKeyChordCountText", L"AdditionalKeyChordTooltipText", L"DisplayNameAndKeyChordAutomationPropName");
|
||||
}
|
||||
});
|
||||
|
||||
std::vector<hstring> shortcutActions;
|
||||
for (const auto [action, name] : _availableActionsAndNamesMap)
|
||||
@@ -119,7 +128,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return _cachedDisplayName;
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::Name()
|
||||
winrt::hstring CommandViewModel::Name() const noexcept
|
||||
{
|
||||
return _command.HasName() ? _command.Name() : L"";
|
||||
}
|
||||
@@ -145,7 +154,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return result;
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::FirstKeyChordText()
|
||||
winrt::hstring CommandViewModel::FirstKeyChordText() const
|
||||
{
|
||||
if (_KeyChordList.Size() != 0)
|
||||
{
|
||||
@@ -154,7 +163,21 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return L"";
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordCountText()
|
||||
Control::KeyChord CommandViewModel::FirstKeyChord() const noexcept
|
||||
{
|
||||
if (_KeyChordList.Size() != 0)
|
||||
{
|
||||
return _KeyChordList.GetAt(0).CurrentKeys();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CommandViewModel::HasNoKeyChords() const noexcept
|
||||
{
|
||||
return _KeyChordList.Size() == 0;
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordCountText() const
|
||||
{
|
||||
const auto size = _KeyChordList.Size();
|
||||
if (size > 1)
|
||||
@@ -164,7 +187,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return L"";
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordTooltipText()
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordTooltipText() const
|
||||
{
|
||||
const auto size = _KeyChordList.Size();
|
||||
if (size <= 1)
|
||||
@@ -183,12 +206,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return winrt::hstring{ result };
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ID()
|
||||
winrt::hstring CommandViewModel::ID() const noexcept
|
||||
{
|
||||
return _command.ID();
|
||||
}
|
||||
|
||||
bool CommandViewModel::IsUserAction()
|
||||
bool CommandViewModel::IsUserAction() const noexcept
|
||||
{
|
||||
return _command.Origin() == OriginTag::User;
|
||||
}
|
||||
@@ -206,23 +229,40 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void CommandViewModel::AddKeybinding_Click()
|
||||
{
|
||||
auto kbdVM{ make_self<KeyChordViewModel>(nullptr) };
|
||||
kbdVM->Index(gsl::narrow_cast<int32_t>(_KeyChordList.Size()) + 1);
|
||||
kbdVM->IsInEditMode(true);
|
||||
_RegisterKeyChordVMEvents(*kbdVM);
|
||||
KeyChordList().Append(*kbdVM);
|
||||
FocusContainer.raise(*this, *kbdVM);
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ActionNameTextBoxAutomationPropName()
|
||||
// Reassigns 1-based Index values for every KeyChordViewModel in the list. Called
|
||||
// whenever the list changes shape so the per-row "Key Binding #N" label stays in sync.
|
||||
void CommandViewModel::_ReindexKeyChordList()
|
||||
{
|
||||
const auto size = _KeyChordList.Size();
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto kcVM{ _KeyChordList.GetAt(i) };
|
||||
const auto newIdx = gsl::narrow_cast<int32_t>(i) + 1;
|
||||
if (kcVM.Index() != newIdx)
|
||||
{
|
||||
kcVM.Index(newIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ActionNameTextBoxAutomationPropName() const
|
||||
{
|
||||
return RS_(L"Actions_Name/Text");
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ShortcutActionComboBoxAutomationPropName()
|
||||
winrt::hstring CommandViewModel::ShortcutActionComboBoxAutomationPropName() const
|
||||
{
|
||||
return RS_(L"Actions_ShortcutAction/Text");
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalArgumentsControlAutomationPropName()
|
||||
winrt::hstring CommandViewModel::AdditionalArgumentsControlAutomationPropName() const
|
||||
{
|
||||
return RS_(L"Actions_Arguments/Text");
|
||||
}
|
||||
@@ -273,6 +313,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
self->FocusContainer.raise(*self, senderVM);
|
||||
}
|
||||
}
|
||||
else if (propertyName == L"KeyChordText")
|
||||
{
|
||||
// The first chord of the list is what the row visual on the Actions page binds to,
|
||||
// so propagate the change up so the row updates.
|
||||
if (self->_KeyChordList.Size() > 0 && self->_KeyChordList.GetAt(0) == senderVM)
|
||||
{
|
||||
self->_NotifyChanges(L"FirstKeyChord", L"FirstKeyChordText", L"DisplayNameAndKeyChordAutomationPropName");
|
||||
}
|
||||
else
|
||||
{
|
||||
self->_NotifyChanges(L"AdditionalKeyChordTooltipText");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1065,12 +1118,21 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
KeyChordViewModel::KeyChordViewModel(Control::KeyChord currentKeys)
|
||||
{
|
||||
CurrentKeys(currentKeys);
|
||||
|
||||
// DisplayLabel is derived from Index, so re-fire the change for it whenever Index changes.
|
||||
PropertyChanged([this](const auto& /*sender*/, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args) {
|
||||
if (args.PropertyName() == L"Index")
|
||||
{
|
||||
_NotifyChanges(L"DisplayLabel");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void KeyChordViewModel::CurrentKeys(const Control::KeyChord& newKeys)
|
||||
{
|
||||
_currentKeys = newKeys;
|
||||
KeyChordText(Model::KeyChordSerialization::ToString(_currentKeys));
|
||||
_NotifyChanges(L"CurrentKeys");
|
||||
}
|
||||
|
||||
Control::KeyChord KeyChordViewModel::CurrentKeys() const noexcept
|
||||
@@ -1126,6 +1188,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
hstring KeyChordViewModel::CancelButtonName() const noexcept { return RS_(L"Actions_CancelButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
hstring KeyChordViewModel::AcceptButtonName() const noexcept { return RS_(L"Actions_AcceptButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
hstring KeyChordViewModel::DeleteButtonName() const noexcept { return RS_(L"Actions_DeleteButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
hstring KeyChordViewModel::EditButtonName() const noexcept { return RS_(L"Actions_EditButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
|
||||
winrt::hstring KeyChordViewModel::DisplayLabel() const
|
||||
{
|
||||
return hstring{ RS_fmt(L"EditAction_KeyBindingNumberFormat", _Index) };
|
||||
}
|
||||
|
||||
ActionsViewModel::ActionsViewModel(Model::CascadiaSettings settings) :
|
||||
_Settings{ settings }
|
||||
|
||||
@@ -69,16 +69,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void Initialize();
|
||||
|
||||
winrt::hstring DisplayName();
|
||||
winrt::hstring Name();
|
||||
winrt::hstring Name() const noexcept;
|
||||
void Name(const winrt::hstring& newName);
|
||||
winrt::hstring DisplayNameAndKeyChordAutomationPropName();
|
||||
|
||||
winrt::hstring FirstKeyChordText();
|
||||
winrt::hstring AdditionalKeyChordCountText();
|
||||
winrt::hstring AdditionalKeyChordTooltipText();
|
||||
winrt::hstring FirstKeyChordText() const;
|
||||
Control::KeyChord FirstKeyChord() const noexcept;
|
||||
bool HasNoKeyChords() const noexcept;
|
||||
winrt::hstring AdditionalKeyChordCountText() const;
|
||||
winrt::hstring AdditionalKeyChordTooltipText() const;
|
||||
|
||||
winrt::hstring ID();
|
||||
bool IsUserAction();
|
||||
winrt::hstring ID() const noexcept;
|
||||
bool IsUserAction() const noexcept;
|
||||
|
||||
void Edit_Click();
|
||||
til::typed_event<Editor::CommandViewModel, IInspectable> EditRequested;
|
||||
@@ -89,9 +91,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void AddKeybinding_Click();
|
||||
|
||||
// UIA text
|
||||
winrt::hstring ActionNameTextBoxAutomationPropName();
|
||||
winrt::hstring ShortcutActionComboBoxAutomationPropName();
|
||||
winrt::hstring AdditionalArgumentsControlAutomationPropName();
|
||||
winrt::hstring ActionNameTextBoxAutomationPropName() const;
|
||||
winrt::hstring ShortcutActionComboBoxAutomationPropName() const;
|
||||
winrt::hstring AdditionalArgumentsControlAutomationPropName() const;
|
||||
|
||||
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeRequested;
|
||||
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeNamesRequested;
|
||||
@@ -115,6 +117,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void _RegisterActionArgsVMEvents(Editor::ActionArgsViewModel actionArgsVM);
|
||||
void _ReplaceCommandWithUserCopy(bool reinitialize);
|
||||
void _CreateAndInitializeActionArgsVMHelper();
|
||||
void _ReindexKeyChordList();
|
||||
};
|
||||
|
||||
struct ArgWrapper : ArgWrapperT<ArgWrapper>, ViewModelHelper<ArgWrapper>
|
||||
@@ -230,15 +233,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void CancelChanges();
|
||||
void DeleteKeyChord();
|
||||
|
||||
winrt::hstring DisplayLabel() const;
|
||||
|
||||
// UIA Text
|
||||
hstring CancelButtonName() const noexcept;
|
||||
hstring AcceptButtonName() const noexcept;
|
||||
hstring DeleteButtonName() const noexcept;
|
||||
hstring EditButtonName() const noexcept;
|
||||
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(bool, IsInEditMode, false);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(Control::KeyChord, ProposedKeys);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(winrt::hstring, KeyChordText);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::UI::Xaml::Controls::Flyout, AcceptChangesFlyout, nullptr);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(int32_t, Index, 0);
|
||||
|
||||
public:
|
||||
til::typed_event<Editor::KeyChordViewModel, Terminal::Control::KeyChord> AddKeyChordRequested;
|
||||
|
||||
@@ -55,6 +55,8 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
// View-model specific
|
||||
String DisplayName { get; };
|
||||
String FirstKeyChordText { get; };
|
||||
Microsoft.Terminal.Control.KeyChord FirstKeyChord { get; };
|
||||
Boolean HasNoKeyChords { get; };
|
||||
String AdditionalKeyChordCountText { get; };
|
||||
String AdditionalKeyChordTooltipText { get; };
|
||||
String DisplayNameAndKeyChordAutomationPropName { get; };
|
||||
@@ -138,9 +140,12 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
String KeyChordText { get; };
|
||||
|
||||
// UI side
|
||||
Microsoft.Terminal.Control.KeyChord CurrentKeys { get; };
|
||||
Microsoft.Terminal.Control.KeyChord ProposedKeys;
|
||||
Windows.UI.Xaml.Controls.Flyout AcceptChangesFlyout;
|
||||
Boolean IsInEditMode { get; };
|
||||
Int32 Index;
|
||||
String DisplayLabel { get; };
|
||||
void ToggleEditMode();
|
||||
void AcceptChanges();
|
||||
void CancelChanges();
|
||||
@@ -148,6 +153,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
String CancelButtonName { get; };
|
||||
String AcceptButtonName { get; };
|
||||
String DeleteButtonName { get; };
|
||||
String EditButtonName { get; };
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<KeyChordViewModel, Microsoft.Terminal.Control.KeyChord> AddKeyChordRequested;
|
||||
event Windows.Foundation.TypedEventHandler<KeyChordViewModel, ModifyKeyChordEventArgs> ModifyKeyChordRequested;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -64,6 +64,7 @@
|
||||
|
||||
<local:ColorToBrushConverter x:Key="ColorToBrushConverter" />
|
||||
<local:ColorToStringConverter x:Key="ColorToStringConverter" />
|
||||
<mtu:StringNotEmptyToVisibilityConverter x:Key="StringNotEmptyToVisibilityConverter" />
|
||||
|
||||
<Color x:Key="DeleteButtonColor">Firebrick</Color>
|
||||
|
||||
@@ -1228,13 +1229,19 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentPresenter x:Name="ContentPresenter"
|
||||
Grid.Column="0"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTransitions="{TemplateBinding ContentTransitions}" />
|
||||
<StackPanel Grid.Column="0"
|
||||
Padding="0,12,0,12"
|
||||
VerticalAlignment="Center">
|
||||
<ContentPresenter x:Name="ContentPresenter"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTransitions="{TemplateBinding ContentTransitions}" />
|
||||
<TextBlock Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{Binding Tag, RelativeSource={RelativeSource Mode=TemplatedParent}}"
|
||||
Visibility="{Binding Tag, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource StringNotEmptyToVisibilityConverter}}" />
|
||||
</StackPanel>
|
||||
<FontIcon Grid.Column="1"
|
||||
Margin="20,0,8,0"
|
||||
HorizontalAlignment="Right"
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(TextMeasurement, TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, L"Globals_TextMeasurement_", L"Text");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(AmbiguousWidth, AmbiguousWidth, winrt::Microsoft::Terminal::Control::AmbiguousWidth, L"Globals_AmbiguousWidth_", L"Text");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(GraphicsAPI, GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, L"Globals_GraphicsAPI_", L"Text");
|
||||
}
|
||||
|
||||
bool CompatibilityViewModel::DebugFeaturesAvailable() const noexcept
|
||||
|
||||
@@ -28,6 +28,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
GETSET_BINDABLE_ENUM_SETTING(TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, _settings.GlobalSettings().TextMeasurement);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AmbiguousWidth, winrt::Microsoft::Terminal::Control::AmbiguousWidth, _settings.GlobalSettings().AmbiguousWidth);
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, _settings.GlobalSettings().GraphicsAPI);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), SoftwareRendering);
|
||||
|
||||
private:
|
||||
Model::CascadiaSettings _settings;
|
||||
};
|
||||
|
||||
@@ -23,6 +23,11 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
|
||||
IInspectable CurrentAmbiguousWidth;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> AmbiguousWidthList { get; };
|
||||
|
||||
IInspectable CurrentGraphicsAPI;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> GraphicsAPIList { get; };
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, SoftwareRendering);
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass Compatibility : Windows.UI.Xaml.Controls.Page
|
||||
|
||||
@@ -25,83 +25,119 @@
|
||||
</Page.Resources>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Allow Headless -->
|
||||
<local:SettingContainer x:Name="AllowHeadless"
|
||||
x:Uid="Globals_AllowHeadless">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AllowHeadless, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
<!-- Section: Compatibility -->
|
||||
<local:SettingContainer x:Uid="Compatibility_Section_Compatibility"
|
||||
StartExpanded="True"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Allow Headless -->
|
||||
<local:SettingContainer x:Name="AllowHeadless"
|
||||
x:Uid="Globals_AllowHeadless">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AllowHeadless, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Text Measurement -->
|
||||
<local:SettingContainer x:Name="TextMeasurement"
|
||||
x:Uid="Globals_TextMeasurement">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TextMeasurementList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTextMeasurement, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Ambiguous Width -->
|
||||
<local:SettingContainer x:Name="AmbiguousWidth"
|
||||
x:Uid="Globals_AmbiguousWidth">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.AmbiguousWidthList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentAmbiguousWidth, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Debug Features -->
|
||||
<local:SettingContainer x:Name="DebugFeaturesEnabled"
|
||||
x:Uid="Globals_DebugFeaturesEnabled"
|
||||
Visibility="{x:Bind ViewModel.DebugFeaturesAvailable}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DebugFeaturesEnabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Reset Application State -->
|
||||
<local:SettingContainer x:Name="ResetApplicationState"
|
||||
x:Uid="Settings_ResetApplicationState">
|
||||
<Button x:Uid="Settings_ResetApplicationStateButton"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout x:Name="ResetCacheFlyout"
|
||||
FlyoutPresenterStyle="{StaticResource CustomFlyoutPresenterStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Settings_ResetApplicationStateConfirmationMessageHeader"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<TextBlock x:Uid="Settings_ResetApplicationStateConfirmationMessageBody"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Settings_ResetApplicationStateConfirmationButton"
|
||||
Click="ResetApplicationStateButton_Click" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Reset to Default Settings -->
|
||||
<local:SettingContainer x:Name="ResetToDefaultSettings"
|
||||
x:Uid="Settings_ResetToDefaultSettings">
|
||||
<Button x:Uid="Settings_ResetToDefaultSettingsButton"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout FlyoutPresenterStyle="{StaticResource CustomFlyoutPresenterStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Settings_ResetToDefaultSettingsConfirmationMessageHeader"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<TextBlock x:Uid="Settings_ResetToDefaultSettingsConfirmationMessageBody"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Settings_ResetToDefaultSettingsConfirmationButton"
|
||||
Click="{x:Bind ViewModel.ResetToDefaultSettings}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Text Measurement -->
|
||||
<local:SettingContainer x:Name="TextMeasurement"
|
||||
x:Uid="Globals_TextMeasurement">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TextMeasurementList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTextMeasurement, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Rendering -->
|
||||
<local:SettingContainer x:Uid="Compatibility_Section_Rendering"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Graphics API -->
|
||||
<local:SettingContainer x:Name="GraphicsAPI"
|
||||
x:Uid="Globals_GraphicsAPI">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.GraphicsAPIList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentGraphicsAPI, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Ambiguous Width -->
|
||||
<local:SettingContainer x:Name="AmbiguousWidth"
|
||||
x:Uid="Globals_AmbiguousWidth">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.AmbiguousWidthList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentAmbiguousWidth, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Disable Partial Invalidation -->
|
||||
<local:SettingContainer x:Name="DisablePartialInvalidation"
|
||||
x:Uid="Globals_DisablePartialInvalidation">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DisablePartialInvalidation, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Debug Features -->
|
||||
<local:SettingContainer x:Name="DebugFeaturesEnabled"
|
||||
x:Uid="Globals_DebugFeaturesEnabled"
|
||||
Visibility="{x:Bind ViewModel.DebugFeaturesAvailable}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DebugFeaturesEnabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
<!-- Software Rendering -->
|
||||
<local:SettingContainer x:Name="SoftwareRendering"
|
||||
x:Uid="Globals_SoftwareRendering">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SoftwareRendering, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Reset Application State -->
|
||||
<local:SettingContainer x:Name="ResetApplicationState"
|
||||
x:Uid="Settings_ResetApplicationState">
|
||||
<Button x:Uid="Settings_ResetApplicationStateButton"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout x:Name="ResetCacheFlyout"
|
||||
FlyoutPresenterStyle="{StaticResource CustomFlyoutPresenterStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Settings_ResetApplicationStateConfirmationMessageHeader"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<TextBlock x:Uid="Settings_ResetApplicationStateConfirmationMessageBody"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Settings_ResetApplicationStateConfirmationButton"
|
||||
Click="ResetApplicationStateButton_Click" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Reset to Default Settings -->
|
||||
<local:SettingContainer x:Name="ResetToDefaultSettings"
|
||||
x:Uid="Settings_ResetToDefaultSettings">
|
||||
<Button x:Uid="Settings_ResetToDefaultSettingsButton"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout FlyoutPresenterStyle="{StaticResource CustomFlyoutPresenterStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Settings_ResetToDefaultSettingsConfirmationMessageHeader"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<TextBlock x:Uid="Settings_ResetToDefaultSettingsConfirmationMessageBody"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Settings_ResetToDefaultSettingsConfirmationButton"
|
||||
Click="{x:Bind ViewModel.ResetToDefaultSettings}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
|
||||
</StackPanel>
|
||||
</Page>
|
||||
|
||||
@@ -17,130 +17,11 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<!-- Theme Dictionary -->
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Button">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
<!-- Override visual states -->
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Grid>
|
||||
<!-- Define the appearance of the button -->
|
||||
<Border x:Name="border"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="border"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SystemControlHighlightAccentRevealBackgroundBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed" />
|
||||
<VisualState x:Name="Disabled" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Button">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
<!-- Override visual states -->
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Grid>
|
||||
<!-- Define the appearance of the button -->
|
||||
<Border x:Name="border"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="border"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SystemControlHighlightAccentRevealBackgroundBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed" />
|
||||
<VisualState x:Name="Disabled" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Button" />
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<GridLength x:Key="ArgumentNameWidth">148</GridLength>
|
||||
|
||||
<!-- Styles -->
|
||||
<Style x:Key="KeyBindingContainerStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="4" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="XYFocusKeyboardNavigation" Value="Enabled" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordEditorStyle"
|
||||
TargetType="local:KeyChordListener">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
<x:Int32 x:Key="EditButtonSize">32</x:Int32>
|
||||
<x:Double x:Key="EditButtonIconSize">14</x:Double>
|
||||
|
||||
<Style x:Key="EditButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
@@ -149,6 +30,7 @@
|
||||
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
|
||||
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="AccentEditButtonStyle"
|
||||
BasedOn="{StaticResource AccentButtonStyle}"
|
||||
TargetType="Button">
|
||||
@@ -157,42 +39,63 @@
|
||||
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
|
||||
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
|
||||
</Style>
|
||||
<Style x:Key="TextBlockGroupingStyle"
|
||||
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
|
||||
<Setter Property="Margin" Value="0,0,0,4" />
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
|
||||
<Style x:Key="KeyChordEditorStyle"
|
||||
TargetType="local:KeyChordListener">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="MinWidth" Value="160" />
|
||||
</Style>
|
||||
|
||||
<!-- Templates -->
|
||||
<!--
|
||||
Item container for the per-chord ListView. We're hosting a SettingContainer
|
||||
inside each item, so strip the default ListViewItem visuals (padding, border,
|
||||
hover/selection background) so they don't double up.
|
||||
-->
|
||||
<Style x:Key="KeyChordListViewItemStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="MinHeight" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
</Style>
|
||||
|
||||
<!-- "Key Binding #N" template -->
|
||||
<DataTemplate x:Key="KeyChordTemplate"
|
||||
x:DataType="local:KeyChordViewModel">
|
||||
<ListViewItem IsTabStop="False"
|
||||
Style="{StaticResource KeyBindingContainerStyle}">
|
||||
<Grid Padding="-4,0,0,0"
|
||||
VerticalAlignment="Center">
|
||||
<local:SettingContainer Header="{x:Bind DisplayLabel, Mode=OneWay}">
|
||||
<Grid VerticalAlignment="Center"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<!-- Key visual / key chord listener -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Cancel button (visible only in edit mode) -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Accept button (visible only in edit mode) -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Edit (pencil) button (visible only NOT in edit mode) -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Delete button -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="0"
|
||||
Background="{ThemeResource AppBarItemBackgroundThemeBrush}"
|
||||
Click="{x:Bind ToggleEditMode}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
|
||||
<TextBlock FontSize="14"
|
||||
Text="{x:Bind KeyChordText, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Button>
|
||||
|
||||
<!-- Read-only key chord visual -->
|
||||
<local:KeyChordVisual Grid.Column="0"
|
||||
KeyChord="{x:Bind CurrentKeys, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}" />
|
||||
|
||||
<!-- Editable key chord listener -->
|
||||
<local:KeyChordListener Grid.Column="0"
|
||||
Keys="{x:Bind ProposedKeys, Mode=TwoWay}"
|
||||
Style="{StaticResource KeyChordEditorStyle}"
|
||||
Visibility="{x:Bind IsInEditMode, Mode=OneWay}" />
|
||||
|
||||
<!-- Cancel changes (edit mode only) -->
|
||||
<Button x:Uid="Actions_CancelButton"
|
||||
Grid.Column="1"
|
||||
Margin="8,0,0,0"
|
||||
AutomationProperties.Name="{x:Bind CancelButtonName}"
|
||||
Click="{x:Bind CancelChanges}"
|
||||
Style="{StaticResource EditButtonStyle}"
|
||||
@@ -201,9 +104,9 @@
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<!-- Accept changes (edit mode only) -->
|
||||
<Button x:Uid="Actions_AcceptButton"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,8,0"
|
||||
AutomationProperties.Name="{x:Bind AcceptButtonName}"
|
||||
Click="{x:Bind AcceptChanges}"
|
||||
Flyout="{x:Bind AcceptChangesFlyout, Mode=OneWay}"
|
||||
@@ -213,8 +116,19 @@
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<Button Grid.Column="3"
|
||||
HorizontalAlignment="Left"
|
||||
<!-- Edit button -->
|
||||
<Button x:Uid="Actions_EditButton"
|
||||
Grid.Column="3"
|
||||
AutomationProperties.Name="{x:Bind EditButtonName}"
|
||||
Click="{x:Bind ToggleEditMode}"
|
||||
Style="{StaticResource EditButtonStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
|
||||
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<!-- Delete button -->
|
||||
<Button Grid.Column="4"
|
||||
AutomationProperties.Name="{x:Bind DeleteButtonName}"
|
||||
Style="{StaticResource DeleteSmallButtonStyle}">
|
||||
<Button.Content>
|
||||
@@ -233,25 +147,23 @@
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!--
|
||||
BODGY: Each ArgWrapper DataTemplate below wraps its editor control
|
||||
in a <local:SettingContainer Header="{x:Bind Name}"> rather than sharing a
|
||||
single outer template. This is because a bug in WinUI 2 prevents a
|
||||
ContentPresenter + ContentTemplateSelector pattern from working correctly,
|
||||
resulting in "Microsoft.Terminal.Settings.Editor.ArgWrapper" being shown.
|
||||
-->
|
||||
|
||||
<!-- Example shortcut action to test this template: Adjust Opacity -->
|
||||
<!-- Currently that is the only Int32 arg, so just clamp the min/max values according to that -->
|
||||
<DataTemplate x:Key="Int32Template"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="100"
|
||||
@@ -259,24 +171,14 @@
|
||||
SmallChange="10"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxInt32(Value), Mode=TwoWay, BindBack=Int32BindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Switch To Tab -->
|
||||
<DataTemplate x:Key="UInt32Template"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -284,24 +186,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxUInt32(Value), Mode=TwoWay, BindBack=UInt32BindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Close Other Tabs -->
|
||||
<DataTemplate x:Key="UInt32OptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -309,24 +201,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxUInt32Optional(Value), Mode=TwoWay, BindBack=UInt32OptionalBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Split Pane -->
|
||||
<DataTemplate x:Key="Int32OptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -334,24 +216,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxInt32Optional(Value), Mode=TwoWay, BindBack=Int32OptionalBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Adjust Font Size -->
|
||||
<DataTemplate x:Key="FloatTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -359,24 +231,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxFloat(Value), Mode=TwoWay, BindBack=FloatBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Split Pane -->
|
||||
<DataTemplate x:Key="SplitSizeTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="0.2"
|
||||
Maximum="1"
|
||||
@@ -384,144 +246,95 @@
|
||||
SmallChange="0.1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxFloat(Value), Mode=TwoWay, BindBack=FloatBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Send Input -->
|
||||
<DataTemplate x:Key="StringTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBox Grid.Column="1"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<TextBox MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Set Color Scheme -->
|
||||
<DataTemplate x:Key="ColorSchemeTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ComboBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ComboBox MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind EnumList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind EnumValue, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Export Buffer -->
|
||||
<DataTemplate x:Key="FilePickerTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBox Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="2"
|
||||
Click="{x:Bind BrowseForFile_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<Grid ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="1"
|
||||
Click="{x:Bind BrowseForFile_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: New Tab -->
|
||||
<DataTemplate x:Key="FolderPickerTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBox Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="2"
|
||||
Click="{x:Bind BrowseForFolder_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<Grid ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="1"
|
||||
Click="{x:Bind BrowseForFolder_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Set Focus Mode -->
|
||||
<DataTemplate x:Key="BoolTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ToggleSwitch Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
IsOn="{x:Bind UnboxBool(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}" />
|
||||
</Grid>
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ToggleSwitch AutomationProperties.Name="{x:Bind Name}"
|
||||
IsOn="{x:Bind UnboxBool(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Split Pane -->
|
||||
<DataTemplate x:Key="BoolOptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<CheckBox Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<CheckBox AutomationProperties.Name="{x:Bind Name}"
|
||||
IsChecked="{x:Bind UnboxBoolOptional(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}"
|
||||
IsThreeState="True" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Resize Pane -->
|
||||
@@ -532,24 +345,14 @@
|
||||
|
||||
<DataTemplate x:Key="EnumTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ComboBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ComboBox MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind EnumList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind EnumValue, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Copy Text -->
|
||||
@@ -572,66 +375,35 @@
|
||||
|
||||
<DataTemplate x:Key="FlagTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ItemsControl Grid.Column="1"
|
||||
Margin="0"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ItemsControl AutomationProperties.Name="{x:Bind Name}"
|
||||
ItemTemplate="{StaticResource FlagItemTemplate}"
|
||||
ItemsSource="{x:Bind FlagList, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Add Mark -->
|
||||
<DataTemplate x:Key="TerminalCoreColorOptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<local:NullableColorPicker x:Uid="Actions_NullableColorPicker"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ColorSchemeVM="{x:Bind DefaultColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind UnboxTerminalCoreColorOptional(Value), Mode=TwoWay, BindBack=TerminalCoreColorBindBack}"
|
||||
NullColorPreview="{x:Bind DefaultColorScheme.ForegroundColor.Color, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Set Tab Color -->
|
||||
<DataTemplate x:Key="WindowsUIColorOptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<local:NullableColorPicker x:Uid="Actions_NullableColorPicker"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ColorSchemeVM="{x:Bind DefaultColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind UnboxWindowsUIColorOptional(Value), Mode=TwoWay, BindBack=WindowsUIColorBindBack}"
|
||||
NullColorPreview="{x:Bind DefaultColorScheme.ForegroundColor.Color, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<local:ArgsTemplateSelectors x:Key="ArgsTemplateSelector"
|
||||
@@ -655,122 +427,106 @@
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="{StaticResource SettingStackMargin}">
|
||||
<Grid Margin="{StaticResource SettingStackMargin}"
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Actions_CommandDetails"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource TextBlockGroupingStyle}" />
|
||||
<TextBlock x:Uid="Actions_Name"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="0,0,0,8"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBox x:Name="CommandNameTextBox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,8"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ActionNameTextBoxAutomationPropName}"
|
||||
PlaceholderText="{x:Bind ViewModel.DisplayName, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />
|
||||
<TextBlock x:Uid="Actions_ShortcutAction"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center" />
|
||||
<AutoSuggestBox x:Name="ShortcutActionBox"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ShortcutActionComboBoxAutomationPropName}"
|
||||
GotFocus="ShortcutActionBox_GotFocus"
|
||||
LostFocus="ShortcutActionBox_LostFocus"
|
||||
QuerySubmitted="ShortcutActionBox_QuerySubmitted"
|
||||
TextChanged="ShortcutActionBox_TextChanged" />
|
||||
<TextBlock x:Uid="Actions_Keybindings"
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource TextBlockGroupingStyle}" />
|
||||
<ListView x:Name="KeyChordListView"
|
||||
x:Uid="Actions_KeyBindingsListView"
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
ItemTemplate="{StaticResource KeyChordTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.KeyChordList, Mode=OneWay}"
|
||||
SelectionMode="None">
|
||||
<ListView.Footer>
|
||||
<Button Margin="0,4,0,0"
|
||||
Click="{x:Bind ViewModel.AddKeybinding_Click}">
|
||||
<TextBlock x:Uid="Actions_AddKeyChord" />
|
||||
</Button>
|
||||
</ListView.Footer>
|
||||
</ListView>
|
||||
<TextBlock x:Uid="Actions_Arguments"
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource TextBlockGroupingStyle}"
|
||||
Visibility="{x:Bind ViewModel.ActionArgsVM.HasArgs, Mode=OneWay}" />
|
||||
<ItemsControl Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.AdditionalArgumentsControlAutomationPropName}"
|
||||
IsTabStop="False"
|
||||
ItemTemplateSelector="{StaticResource ArgsTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.ActionArgsVM.ArgValues, Mode=OneWay}" />
|
||||
<Button Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
IsEnabled="{x:Bind ViewModel.IsUserAction, Mode=OneWay}"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Actions_DeleteButton2"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Actions_CommandDeleteConfirmationMessage"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Actions_CommandDeleteConfirmationButton"
|
||||
Click="{x:Bind ViewModel.Delete_Click}" />
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<StackPanel HorizontalAlignment="Stretch"
|
||||
Style="{StaticResource SettingsStackStyle}">
|
||||
|
||||
<!-- Action type (top-most setting on the page) -->
|
||||
<local:SettingContainer x:Name="ActionType"
|
||||
x:Uid="EditAction_ActionType">
|
||||
<AutoSuggestBox x:Name="ShortcutActionBox"
|
||||
MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ShortcutActionComboBoxAutomationPropName}"
|
||||
GotFocus="ShortcutActionBox_GotFocus"
|
||||
LostFocus="ShortcutActionBox_LostFocus"
|
||||
QuerySubmitted="ShortcutActionBox_QuerySubmitted"
|
||||
TextChanged="ShortcutActionBox_TextChanged" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Key bindings expander -->
|
||||
<local:SettingContainer x:Name="KeyBindingsContainer"
|
||||
x:Uid="EditAction_KeyBindings"
|
||||
StartExpanded="{x:Bind mtu:Converters.InvertBoolean(ViewModel.HasNoKeyChords), Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<!-- "New key binding" button -->
|
||||
<local:SettingContainer x:Name="NewKeyBinding"
|
||||
x:Uid="EditAction_NewKeyBinding">
|
||||
<Button x:Uid="EditAction_AddKeyBinding"
|
||||
Click="{x:Bind ViewModel.AddKeybinding_Click}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Existing key bindings, one container per chord -->
|
||||
<ListView x:Name="KeyChordListView"
|
||||
x:Uid="Actions_KeyBindingsListView"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsItemClickEnabled="False"
|
||||
ItemContainerStyle="{StaticResource KeyChordListViewItemStyle}"
|
||||
ItemTemplate="{StaticResource KeyChordTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.KeyChordList, Mode=OneWay}"
|
||||
SelectionMode="None" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Additional customizations expander -->
|
||||
<local:SettingContainer x:Name="AdditionalCustomizations"
|
||||
x:Uid="EditAction_AdditionalCustomizations"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<!-- Action name -->
|
||||
<local:SettingContainer x:Name="ActionName"
|
||||
x:Uid="EditAction_ActionName">
|
||||
<TextBox x:Name="CommandNameTextBox"
|
||||
MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ActionNameTextBoxAutomationPropName}"
|
||||
PlaceholderText="{x:Bind ViewModel.DisplayName, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Action argument controls -->
|
||||
<ItemsControl HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.AdditionalArgumentsControlAutomationPropName}"
|
||||
IsTabStop="False"
|
||||
ItemTemplateSelector="{StaticResource ArgsTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.ActionArgsVM.ArgValues, Mode=OneWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel HorizontalAlignment="Stretch" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Delete command button -->
|
||||
<local:SettingContainer x:Name="DeleteCommand"
|
||||
x:Uid="EditAction_DeleteCommand">
|
||||
<Button IsEnabled="{x:Bind ViewModel.IsUserAction, Mode=OneWay}"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Actions_DeleteButton2"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Actions_CommandDeleteConfirmationMessage"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Actions_CommandDeleteConfirmationButton"
|
||||
Click="{x:Bind ViewModel.Delete_Click}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Page>
|
||||
|
||||
@@ -27,126 +27,164 @@
|
||||
</Page.Resources>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Theme -->
|
||||
<local:SettingContainer x:Name="Theme"
|
||||
x:Uid="Globals_Theme">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemsSource="{x:Bind ViewModel.ThemeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTheme, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model:Theme">
|
||||
<TextBlock Text="{x:Bind local:GlobalAppearanceViewModel.ThemeNameConverter((model:Theme)), Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
<!-- Section: Visual style -->
|
||||
<local:SettingContainer x:Uid="Globals_Section_VisualStyle"
|
||||
StartExpanded="True"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Theme -->
|
||||
<local:SettingContainer x:Name="Theme"
|
||||
x:Uid="Globals_Theme">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemsSource="{x:Bind ViewModel.ThemeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTheme, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model:Theme">
|
||||
<TextBlock Text="{x:Bind local:GlobalAppearanceViewModel.ThemeNameConverter((model:Theme)), Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Acrylic in Tab Row -->
|
||||
<local:SettingContainer x:Name="AcrylicTabRow"
|
||||
x:Uid="Globals_AcrylicTabRow">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.UseAcrylicInTabRow, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Unfocused Acrylic -->
|
||||
<local:SettingContainer x:Name="EnableUnfocusedAcrylic"
|
||||
x:Uid="Globals_EnableUnfocusedAcrylic">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.EnableUnfocusedAcrylic, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Disable Animations -->
|
||||
<!-- NOTE: the UID is "DisablePaneAnimationsReversed" not "DisablePaneAnimations". See GH#9124 for more details. -->
|
||||
<local:SettingContainer x:Name="DisableAnimations"
|
||||
x:Uid="Globals_DisableAnimationsReversed">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.InvertedDisableAnimations, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show pane headers -->
|
||||
<local:SettingContainer x:Name="ShowPaneHeaders"
|
||||
x:Uid="Globals_ShowPaneHeaders">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowPaneHeaders, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Position of new tab -->
|
||||
<local:SettingContainer x:Name="NewTabPosition"
|
||||
x:Uid="Globals_NewTabPosition">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.NewTabPositionList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentNewTabPosition, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
<!-- Section: Tabs and layout -->
|
||||
<local:SettingContainer x:Uid="Globals_Section_TabsLayout"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Position of new tab -->
|
||||
<local:SettingContainer x:Name="NewTabPosition"
|
||||
x:Uid="Globals_NewTabPosition">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.NewTabPositionList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentNewTabPosition, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Always show tabs -->
|
||||
<local:SettingContainer x:Name="AlwaysShowTabs"
|
||||
x:Uid="Globals_AlwaysShowTabs">
|
||||
<ToggleSwitch IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.ShowTabsInTitlebar), Mode=OneWay}"
|
||||
IsOn="{x:Bind ViewModel.AlwaysShowTabs, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show tabs in full screen -->
|
||||
<local:SettingContainer x:Name="ShowTabsFullscreen"
|
||||
x:Uid="Globals_ShowTabsFullscreen">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTabsFullscreen, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Width Mode -->
|
||||
<local:SettingContainer x:Name="TabWidthMode"
|
||||
x:Uid="Globals_TabWidthMode">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TabWidthModeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTabWidthMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Titlebar -->
|
||||
<local:SettingContainer x:Name="ShowTitlebar"
|
||||
x:Uid="Globals_ShowTitlebar">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTabsInTitlebar, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}"
|
||||
Toggled="{x:Bind ViewModel.ShowTitlebarToggled}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Titlebar -->
|
||||
<local:SettingContainer x:Name="ShowTitlebar"
|
||||
x:Uid="Globals_ShowTitlebar">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTabsInTitlebar, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}"
|
||||
Toggled="{x:Bind ViewModel.ShowTitlebarToggled}" />
|
||||
<!-- Section: Window behavior -->
|
||||
<local:SettingContainer x:Uid="Globals_Section_WindowBehavior"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Always on Top -->
|
||||
<local:SettingContainer x:Name="AlwaysOnTop"
|
||||
x:Uid="Globals_AlwaysOnTop">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AlwaysOnTop, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Automatically hide window -->
|
||||
<local:SettingContainer x:Name="AutoHideWindow"
|
||||
x:Uid="Globals_AutoHideWindow">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AutoHideWindow, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Always show tabs -->
|
||||
<local:SettingContainer x:Name="AlwaysShowTabs"
|
||||
x:Uid="Globals_AlwaysShowTabs">
|
||||
<ToggleSwitch IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.ShowTabsInTitlebar), Mode=OneWay}"
|
||||
IsOn="{x:Bind ViewModel.AlwaysShowTabs, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
<!-- Section: Title bar & identity -->
|
||||
<local:SettingContainer x:Uid="Globals_Section_TitleBarIdentity"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Show Title in Titlebar (use active terminal title as application title) -->
|
||||
<local:SettingContainer x:Name="ShowTitleInTitlebar"
|
||||
x:Uid="Globals_ShowTitleInTitlebar">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTitleInTitlebar, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Admin Shield -->
|
||||
<local:SettingContainer x:Name="ShowAdminShield"
|
||||
x:Uid="Globals_ShowAdminShield">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowAdminShield, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show tabs in full screen -->
|
||||
<local:SettingContainer x:Name="ShowTabsFullscreen"
|
||||
x:Uid="Globals_ShowTabsFullscreen">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTabsFullscreen, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: System integration & notifications -->
|
||||
<local:SettingContainer x:Uid="Globals_Section_SystemIntegration"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Always Show Notification Icon -->
|
||||
<local:SettingContainer x:Name="AlwaysShowNotificationIcon"
|
||||
x:Uid="Globals_AlwaysShowNotificationIcon">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AlwaysShowNotificationIcon, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Acrylic in Tab Row -->
|
||||
<local:SettingContainer x:Name="AcrylicTabRow"
|
||||
x:Uid="Globals_AcrylicTabRow">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.UseAcrylicInTabRow, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Title in Titlebar -->
|
||||
<local:SettingContainer x:Name="ShowTitleInTitlebar"
|
||||
x:Uid="Globals_ShowTitleInTitlebar">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTitleInTitlebar, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Always on Top -->
|
||||
<local:SettingContainer x:Name="AlwaysOnTop"
|
||||
x:Uid="Globals_AlwaysOnTop">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AlwaysOnTop, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Width Mode -->
|
||||
<local:SettingContainer x:Name="TabWidthMode"
|
||||
x:Uid="Globals_TabWidthMode">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TabWidthModeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTabWidthMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Disable Animations -->
|
||||
<!-- NOTE: the UID is "DisablePaneAnimationsReversed" not "DisablePaneAnimations". See GH#9124 for more details. -->
|
||||
<local:SettingContainer x:Name="DisableAnimations"
|
||||
x:Uid="Globals_DisableAnimationsReversed">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.InvertedDisableAnimations, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Always Show Notification Icon -->
|
||||
<local:SettingContainer x:Name="AlwaysShowNotificationIcon"
|
||||
x:Uid="Globals_AlwaysShowNotificationIcon">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AlwaysShowNotificationIcon, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Minimize To Notification Area -->
|
||||
<local:SettingContainer x:Name="MinimizeToNotificationArea"
|
||||
x:Uid="Globals_MinimizeToNotificationArea">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.MinimizeToNotificationArea, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Automatically hide window -->
|
||||
<local:SettingContainer x:Name="AutoHideWindow"
|
||||
x:Uid="Globals_AutoHideWindow">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AutoHideWindow, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Admin Shield -->
|
||||
<local:SettingContainer x:Name="ShowAdminShield"
|
||||
x:Uid="Globals_ShowAdminShield">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowAdminShield, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Unfocused Acrylic -->
|
||||
<local:SettingContainer x:Name="EnableUnfocusedAcrylic"
|
||||
x:Uid="Globals_EnableUnfocusedAcrylic">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.EnableUnfocusedAcrylic, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
<!-- Minimize To Notification Area -->
|
||||
<local:SettingContainer x:Name="MinimizeToNotificationArea"
|
||||
x:Uid="Globals_MinimizeToNotificationArea">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.MinimizeToNotificationArea, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AlwaysShowTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsFullscreen);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowPaneHeaders);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, UseAcrylicInTabRow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTitleInTitlebar);
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, AlwaysShowTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowTabsFullscreen);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowPaneHeaders);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowTabsInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, UseAcrylicInTabRow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowTitleInTitlebar);
|
||||
|
||||
@@ -26,149 +26,179 @@
|
||||
|
||||
<StackPanel>
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Copy On Select -->
|
||||
<local:SettingContainer x:Name="CopyOnSelect"
|
||||
x:Uid="Globals_CopyOnSelect">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CopyOnSelect, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
<!-- Section: Clipboard and paste behavior -->
|
||||
<local:SettingContainer x:Uid="Interaction_Section_Clipboard"
|
||||
StartExpanded="True"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Copy On Select -->
|
||||
<local:SettingContainer x:Name="CopyOnSelect"
|
||||
x:Uid="Globals_CopyOnSelect">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CopyOnSelect, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Trim Paste -->
|
||||
<local:SettingContainer x:Name="TrimPaste"
|
||||
x:Uid="Globals_TrimPaste">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.TrimPaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Trim Block Selection -->
|
||||
<local:SettingContainer x:Name="TrimBlockSelection"
|
||||
x:Uid="Globals_TrimBlockSelection">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.TrimBlockSelection, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Copy Format -->
|
||||
<local:SettingContainer x:Name="CopyFormat"
|
||||
x:Uid="Globals_CopyFormat">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.CopyFormatList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentCopyFormat, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Copy Format -->
|
||||
<local:SettingContainer x:Name="CopyFormat"
|
||||
x:Uid="Globals_CopyFormat">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.CopyFormatList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentCopyFormat, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
<!-- Section: Text selection & editing -->
|
||||
<local:SettingContainer x:Uid="Interaction_Section_TextSelection"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Word Delimiters -->
|
||||
<local:SettingContainer x:Name="WordDelimiters"
|
||||
x:Uid="Globals_WordDelimiters"
|
||||
CurrentValue="{x:Bind ViewModel.WordDelimiters, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.WordDelimiters, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Color Selection -->
|
||||
<local:SettingContainer x:Name="EnableColorSelection"
|
||||
x:Uid="Globals_EnableColorSelection">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.EnableColorSelection, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Trim Block Selection -->
|
||||
<local:SettingContainer x:Name="TrimBlockSelection"
|
||||
x:Uid="Globals_TrimBlockSelection">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.TrimBlockSelection, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
<!-- Section: Window and layout behavior -->
|
||||
<local:SettingContainer x:Uid="Interaction_Section_WindowLayout"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Snap On Resize -->
|
||||
<local:SettingContainer x:Name="SnapToGridOnResize"
|
||||
x:Uid="Globals_SnapToGridOnResize">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SnapToGridOnResize, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Focus Follow Mouse Mode -->
|
||||
<local:SettingContainer x:Name="FocusFollowMouse"
|
||||
x:Uid="Globals_FocusFollowMouse">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.FocusFollowMouse, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Switcher Mode -->
|
||||
<local:SettingContainer x:Name="TabSwitcherMode"
|
||||
x:Uid="Globals_TabSwitcherMode">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TabSwitcherModeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTabSwitcherMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Trim Paste -->
|
||||
<local:SettingContainer x:Name="TrimPaste"
|
||||
x:Uid="Globals_TrimPaste">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.TrimPaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
<!-- Section: Mouse & scrolling -->
|
||||
<local:SettingContainer x:Uid="Interaction_Section_MouseScrolling"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Enable Font Size Changes with Scrolling -->
|
||||
<local:SettingContainer x:Name="ScrollToZoom"
|
||||
x:Uid="Globals_ScrollToZoom">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToZoom, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Window Opacity Changes with Scrolling -->
|
||||
<local:SettingContainer x:Name="ScrollToChangeOpacity"
|
||||
x:Uid="Globals_ScrollToChangeOpacity">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToChangeOpacity, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Word Delimiters -->
|
||||
<local:SettingContainer x:Name="WordDelimiters"
|
||||
x:Uid="Globals_WordDelimiters"
|
||||
CurrentValue="{x:Bind ViewModel.WordDelimiters, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.WordDelimiters, Mode=TwoWay}" />
|
||||
<!-- Section: URLs & external actions -->
|
||||
<local:SettingContainer x:Uid="Interaction_Section_UrlsExternal"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Detect URLs -->
|
||||
<local:SettingContainer x:Name="DetectURLs"
|
||||
x:Uid="Globals_DetectURLs">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DetectURLs, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Search Web Default Query URL -->
|
||||
<local:SettingContainer x:Name="SearchWebDefaultQueryUrl"
|
||||
x:Uid="Globals_SearchWebDefaultQueryUrl"
|
||||
CurrentValue="{x:Bind ViewModel.SearchWebDefaultQueryUrl, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.SearchWebDefaultQueryUrl, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Snap On Resize -->
|
||||
<local:SettingContainer x:Name="SnapToGridOnResize"
|
||||
x:Uid="Globals_SnapToGridOnResize">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SnapToGridOnResize, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
<!-- Section: Warnings -->
|
||||
<local:SettingContainer x:Uid="Interaction_Section_Warnings"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Confirm Close On -->
|
||||
<local:SettingContainer x:Name="ConfirmOnClose"
|
||||
x:Uid="Globals_ConfirmOnClose">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.ConfirmOnCloseList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentConfirmOnClose, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Input Service Warning -->
|
||||
<local:SettingContainer x:Name="InputServiceWarning"
|
||||
x:Uid="Globals_InputServiceWarning">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.InputServiceWarning, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Large Paste Warning -->
|
||||
<local:SettingContainer x:Name="WarnAboutLargePaste"
|
||||
x:Uid="Globals_WarnAboutLargePaste">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.WarnAboutLargePaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Multi Line Paste Warning -->
|
||||
<local:SettingContainer x:Name="WarnAboutMultiLinePaste"
|
||||
x:Uid="Globals_WarnAboutMultiLinePaste">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind WarnAboutMultiLinePasteList}"
|
||||
SelectedItem="{x:Bind CurrentWarnAboutMultiLinePaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Switcher Mode -->
|
||||
<local:SettingContainer x:Name="TabSwitcherMode"
|
||||
x:Uid="Globals_TabSwitcherMode">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TabSwitcherModeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTabSwitcherMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Focus Follow Mouse Mode -->
|
||||
<local:SettingContainer x:Name="FocusFollowMouse"
|
||||
x:Uid="Globals_FocusFollowMouse">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.FocusFollowMouse, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Font Size Changes with Scrolling -->
|
||||
<local:SettingContainer x:Name="ScrollToZoom"
|
||||
x:Uid="Globals_ScrollToZoom">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToZoom, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Window Opacity Changes with Scrolling -->
|
||||
<local:SettingContainer x:Name="ScrollToChangeOpacity"
|
||||
x:Uid="Globals_ScrollToChangeOpacity">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToChangeOpacity, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Detect URLs -->
|
||||
<local:SettingContainer x:Name="DetectURLs"
|
||||
x:Uid="Globals_DetectURLs">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DetectURLs, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Search Web Default Query URL -->
|
||||
<local:SettingContainer x:Name="SearchWebDefaultQueryUrl"
|
||||
x:Uid="Globals_SearchWebDefaultQueryUrl"
|
||||
CurrentValue="{x:Bind ViewModel.SearchWebDefaultQueryUrl, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.SearchWebDefaultQueryUrl, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Color Selection -->
|
||||
<local:SettingContainer x:Name="EnableColorSelection"
|
||||
x:Uid="Globals_EnableColorSelection">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.EnableColorSelection, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Grouping: Warnings -->
|
||||
<TextBlock x:Uid="Globals_WarningsHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Confirm Close On -->
|
||||
<local:SettingContainer x:Name="ConfirmOnClose"
|
||||
x:Uid="Globals_ConfirmOnClose">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.ConfirmOnCloseList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentConfirmOnClose, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Input Service Warning -->
|
||||
<local:SettingContainer x:Name="InputServiceWarning"
|
||||
x:Uid="Globals_InputServiceWarning">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.InputServiceWarning, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Large Paste Warning -->
|
||||
<local:SettingContainer x:Name="WarnAboutLargePaste"
|
||||
x:Uid="Globals_WarnAboutLargePaste">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.WarnAboutLargePaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Multi Line Paste Warning -->
|
||||
<local:SettingContainer x:Name="WarnAboutMultiLinePaste"
|
||||
x:Uid="Globals_WarnAboutMultiLinePaste">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind WarnAboutMultiLinePasteList}"
|
||||
SelectedItem="{x:Bind CurrentWarnAboutMultiLinePaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
|
||||
131
src/cascadia/TerminalSettingsEditor/KeyChordVisual.cpp
Normal file
131
src/cascadia/TerminalSettingsEditor/KeyChordVisual.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "KeyChordVisual.h"
|
||||
#include "KeyChordVisual.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DependencyProperty KeyChordVisual::_KeyChordProperty{ nullptr };
|
||||
|
||||
KeyChordVisual::KeyChordVisual()
|
||||
{
|
||||
InitializeComponent();
|
||||
_InitializeProperties();
|
||||
}
|
||||
|
||||
void KeyChordVisual::_InitializeProperties()
|
||||
{
|
||||
if (!_KeyChordProperty)
|
||||
{
|
||||
_KeyChordProperty =
|
||||
DependencyProperty::Register(
|
||||
L"KeyChord",
|
||||
xaml_typename<Control::KeyChord>(),
|
||||
xaml_typename<Editor::KeyChordVisual>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &KeyChordVisual::_OnKeyChordChanged } });
|
||||
}
|
||||
}
|
||||
|
||||
void KeyChordVisual::_OnKeyChordChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
if (const auto control{ d.try_as<Editor::KeyChordVisual>() })
|
||||
{
|
||||
const auto controlImpl{ get_self<KeyChordVisual>(control) };
|
||||
controlImpl->_UpdateKeyVisuals();
|
||||
}
|
||||
}
|
||||
|
||||
// Capitalizes the first character of the provided string.
|
||||
// Examples: "enter" -> "Enter", "f1" -> "F1", "v" -> "V"
|
||||
static winrt::hstring _formatMainKeyName(std::wstring_view part)
|
||||
{
|
||||
if (part.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::wstring buffer{ part };
|
||||
buffer[0] = til::toupper_ascii(buffer[0]);
|
||||
return winrt::hstring{ buffer };
|
||||
}
|
||||
|
||||
void KeyChordVisual::_UpdateKeyVisuals()
|
||||
{
|
||||
auto panel{ KeysPanel() };
|
||||
if (!panel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
panel.Children().Clear();
|
||||
|
||||
const auto kc{ KeyChord() };
|
||||
if (!kc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Reuse the canonical serialization so the key naming stays in sync with the
|
||||
// rest of the app. Then split on '+' (no key name in the table contains a literal
|
||||
// '+'; VK_OEM_PLUS serializes as "plus") and render each part as its own visual.
|
||||
const auto serialized{ Model::KeyChordSerialization::ToString(kc) };
|
||||
if (serialized.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::wstring_view full{ serialized };
|
||||
for (const auto part : til::split_iterator{ full, L'+' })
|
||||
{
|
||||
if (til::equals_insensitive_ascii(part, L"win"))
|
||||
{
|
||||
_AddGlyphKey();
|
||||
}
|
||||
else if (til::equals_insensitive_ascii(part, L"ctrl"))
|
||||
{
|
||||
_AddTextKey(L"Ctrl");
|
||||
}
|
||||
else if (til::equals_insensitive_ascii(part, L"alt"))
|
||||
{
|
||||
_AddTextKey(L"Alt");
|
||||
}
|
||||
else if (til::equals_insensitive_ascii(part, L"shift"))
|
||||
{
|
||||
_AddTextKey(L"Shift");
|
||||
}
|
||||
else
|
||||
{
|
||||
_AddTextKey(_formatMainKeyName(part));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyChordVisual::_AddTextKey(const winrt::hstring& text)
|
||||
{
|
||||
const auto tmpl{ Resources().Lookup(box_value(L"KeyChordVisualTextKeyTemplate")).as<DataTemplate>() };
|
||||
const auto border{ tmpl.LoadContent().as<Border>() };
|
||||
if (const auto tb{ border.Child().try_as<TextBlock>() })
|
||||
{
|
||||
tb.Text(text);
|
||||
}
|
||||
KeysPanel().Children().Append(border);
|
||||
}
|
||||
|
||||
void KeyChordVisual::_AddGlyphKey()
|
||||
{
|
||||
const auto tmpl{ Resources().Lookup(box_value(L"KeyChordVisualWindowsKeyTemplate")).as<DataTemplate>() };
|
||||
const auto border{ tmpl.LoadContent().as<Border>() };
|
||||
|
||||
// Provide an accessible name for the glyph since it has no text fallback.
|
||||
if (const auto path{ border.Child() })
|
||||
{
|
||||
Automation::AutomationProperties::SetName(path, L"Win");
|
||||
}
|
||||
KeysPanel().Children().Append(border);
|
||||
}
|
||||
}
|
||||
31
src/cascadia/TerminalSettingsEditor/KeyChordVisual.h
Normal file
31
src/cascadia/TerminalSettingsEditor/KeyChordVisual.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "KeyChordVisual.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct KeyChordVisual : KeyChordVisualT<KeyChordVisual>
|
||||
{
|
||||
public:
|
||||
KeyChordVisual();
|
||||
|
||||
DEPENDENCY_PROPERTY(Control::KeyChord, KeyChord);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnKeyChordChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
|
||||
void _UpdateKeyVisuals();
|
||||
void _AddTextKey(const winrt::hstring& text);
|
||||
void _AddGlyphKey();
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(KeyChordVisual);
|
||||
}
|
||||
13
src/cascadia/TerminalSettingsEditor/KeyChordVisual.idl
Normal file
13
src/cascadia/TerminalSettingsEditor/KeyChordVisual.idl
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass KeyChordVisual : Windows.UI.Xaml.Controls.UserControl
|
||||
{
|
||||
KeyChordVisual();
|
||||
|
||||
Microsoft.Terminal.Control.KeyChord KeyChord;
|
||||
static Windows.UI.Xaml.DependencyProperty KeyChordProperty { get; };
|
||||
}
|
||||
}
|
||||
82
src/cascadia/TerminalSettingsEditor/KeyChordVisual.xaml
Normal file
82
src/cascadia/TerminalSettingsEditor/KeyChordVisual.xaml
Normal file
@@ -0,0 +1,82 @@
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<UserControl x:Class="Microsoft.Terminal.Settings.Editor.KeyChordVisual"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsTabStop="False"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<StaticResource x:Key="KeyChordVisualKeyBackground"
|
||||
ResourceKey="AccentFillColorDefaultBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyForeground"
|
||||
ResourceKey="TextOnAccentFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyBorderBrush"
|
||||
ResourceKey="AccentControlElevationBorderBrush" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="KeyChordVisualKeyBackground"
|
||||
ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyForeground"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyBorderBrush"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<Style x:Key="KeyChordVisualKeyBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="MinWidth" Value="32" />
|
||||
<Setter Property="MinHeight" Value="28" />
|
||||
<Setter Property="Padding" Value="8,2,8,2" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Background" Value="{ThemeResource KeyChordVisualKeyBackground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource KeyChordVisualKeyBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordVisualKeyTextStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="TextAlignment" Value="Center" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource KeyChordVisualKeyForeground}" />
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="KeyChordVisualTextKeyTemplate">
|
||||
<Border Style="{StaticResource KeyChordVisualKeyBorderStyle}">
|
||||
<TextBlock Style="{StaticResource KeyChordVisualKeyTextStyle}" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="KeyChordVisualWindowsKeyTemplate">
|
||||
<Border Style="{StaticResource KeyChordVisualKeyBorderStyle}">
|
||||
<Path Width="11"
|
||||
Height="11"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Data="M9 20H0V11H9V20ZM20 20H11V11H20V20ZM9 9H0V0H9V9ZM20 9H11V0H20V9Z"
|
||||
Fill="{ThemeResource KeyChordVisualKeyForeground}"
|
||||
Stretch="Uniform" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel x:Name="KeysPanel"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
Spacing="2" />
|
||||
</UserControl>
|
||||
@@ -43,278 +43,291 @@
|
||||
|
||||
<StackPanel>
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Default Profile -->
|
||||
<local:SettingContainer x:Name="DefaultProfile"
|
||||
x:Uid="Globals_DefaultProfile">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.DefaultProfiles}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultProfile, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="SettingsModel:Profile">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
<!-- Section: Launch behavior -->
|
||||
<local:SettingContainer x:Uid="Launch_Section_LaunchBehavior"
|
||||
StartExpanded="True"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Default Profile -->
|
||||
<local:SettingContainer x:Name="DefaultProfile"
|
||||
x:Uid="Globals_DefaultProfile">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.DefaultProfiles}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultProfile, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="SettingsModel:Profile">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- profile name -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- profile name -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind Name}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind Name}" />
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Default Terminal -->
|
||||
<local:SettingContainer x:Name="DefaultTerminalDropdown"
|
||||
x:Uid="Globals_DefaultTerminal"
|
||||
x:Load="false">
|
||||
<ComboBox x:Name="DefaultTerminal"
|
||||
ItemsSource="{x:Bind ViewModel.DefaultTerminals}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultTerminal, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="SettingsModel:DefaultTerminal">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
<!-- First Window Behavior -->
|
||||
<local:SettingContainer x:Name="FirstWindowPreference"
|
||||
x:Uid="Globals_FirstWindowPreference">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.FirstWindowPreferenceList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentFirstWindowPreference, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
<!-- terminal name and author -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
<!-- version -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Windowing Behavior -->
|
||||
<local:SettingContainer x:Name="WindowingBehavior"
|
||||
x:Uid="Globals_WindowingBehavior">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.WindowingBehaviorList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentWindowingBehavior, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<!-- terminal name -->
|
||||
<RowDefinition Height="auto" />
|
||||
<!-- author and version -->
|
||||
<RowDefinition Height="auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<!-- Start on User Login -->
|
||||
<local:SettingContainer x:Name="StartOnUserLogin"
|
||||
x:Uid="Globals_StartOnUserLogin"
|
||||
HelpText="{x:Bind ViewModel.StartOnUserLoginStatefulHelpText, Mode=OneWay}"
|
||||
Visibility="{x:Bind ViewModel.StartOnUserLoginAvailable, Mode=OneTime}">
|
||||
<ToggleSwitch IsEnabled="{x:Bind ViewModel.StartOnUserLoginConfigurable, Mode=OneWay}"
|
||||
IsOn="{x:Bind ViewModel.StartOnUserLogin, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<IconSourceElement Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Width="24"
|
||||
Height="24"
|
||||
VerticalAlignment="Center"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Text="{x:Bind Name}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Author}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Author)}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Version}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Version)}" />
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Language -->
|
||||
<local:SettingContainer x:Name="Language"
|
||||
x:Uid="Globals_Language">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.LanguageList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentLanguage, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="x:String">
|
||||
<TextBlock Text="{x:Bind local:LaunchViewModel.LanguageDisplayConverter((x:String))}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Language -->
|
||||
<local:SettingContainer x:Name="DefaultInputScope"
|
||||
x:Uid="Globals_DefaultInputScope">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.DefaultInputScopeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultInputScope, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Start on User Login -->
|
||||
<local:SettingContainer x:Name="StartOnUserLogin"
|
||||
x:Uid="Globals_StartOnUserLogin"
|
||||
HelpText="{x:Bind ViewModel.StartOnUserLoginStatefulHelpText, Mode=OneWay}"
|
||||
Visibility="{x:Bind ViewModel.StartOnUserLoginAvailable, Mode=OneTime}">
|
||||
<ToggleSwitch IsEnabled="{x:Bind ViewModel.StartOnUserLoginConfigurable, Mode=OneWay}"
|
||||
IsOn="{x:Bind ViewModel.StartOnUserLogin, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- First Window Behavior -->
|
||||
<local:SettingContainer x:Name="FirstWindowPreference"
|
||||
x:Uid="Globals_FirstWindowPreference">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.FirstWindowPreferenceList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentFirstWindowPreference, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Windowing Behavior -->
|
||||
<local:SettingContainer x:Name="WindowingBehavior"
|
||||
x:Uid="Globals_WindowingBehavior">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.WindowingBehaviorList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentWindowingBehavior, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Launch Size -->
|
||||
<local:SettingContainer x:Name="LaunchSize"
|
||||
x:Uid="Globals_LaunchSize"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchSizeCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid ColumnSpacing="12"
|
||||
RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Globals_InitialCols"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}" />
|
||||
<muxc:NumberBox x:Uid="Globals_InitialColsBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialCols, Mode=TwoWay}" />
|
||||
<TextBlock x:Uid="Globals_InitialRows"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}" />
|
||||
<muxc:NumberBox x:Uid="Globals_InitialRowsBox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialRows, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Launch Parameters -->
|
||||
<local:SettingContainer x:Name="LaunchParameters"
|
||||
x:Uid="Globals_LaunchParameters"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchParametersCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Globals_LaunchModeSetting"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<ComboBox x:Name="LaunchModeComboBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
MinWidth="240"
|
||||
AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.LaunchModeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentLaunchMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
<TextBlock x:Uid="Globals_LaunchPosition"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<Grid Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
ColumnSpacing="4">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Match the width of these NumberBoxes to the Width of the LaunchModeComboBox above minus the Grid's ColumnSpacing -->
|
||||
<muxc:NumberBox x:Name="PosXBox"
|
||||
x:Uid="Globals_InitialPosXBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Width="118"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
|
||||
Style="{StaticResource LaunchPositionNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialPosX, Mode=TwoWay}" />
|
||||
<muxc:NumberBox x:Name="PosYBox"
|
||||
x:Uid="Globals_InitialPosYBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="118"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
|
||||
Style="{StaticResource LaunchPositionNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialPosY, Mode=TwoWay}" />
|
||||
<CheckBox x:Name="UseDefaultLaunchPositionCheckbox"
|
||||
x:Uid="Globals_DefaultLaunchPositionCheckbox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
IsChecked="{x:Bind ViewModel.UseDefaultLaunchPosition, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<TextBlock x:Uid="Globals_CenterOnLaunch"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<ToggleSwitch x:Name="CenterOnLaunchToggle"
|
||||
Grid.Row="2"
|
||||
<!-- Launch Parameters -->
|
||||
<local:SettingContainer x:Name="LaunchParameters"
|
||||
x:Uid="Globals_LaunchParameters"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchParametersCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Globals_LaunchModeSetting"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<ComboBox x:Name="LaunchModeComboBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
MinWidth="240"
|
||||
AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.LaunchModeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentLaunchMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
<TextBlock x:Uid="Globals_LaunchPosition"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<Grid Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
IsOn="{x:Bind ViewModel.CenterOnLaunch, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</Grid>
|
||||
ColumnSpacing="4">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Match the width of these NumberBoxes to the Width of the LaunchModeComboBox above minus the Grid's ColumnSpacing -->
|
||||
<muxc:NumberBox x:Name="PosXBox"
|
||||
x:Uid="Globals_InitialPosXBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Width="118"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
|
||||
Style="{StaticResource LaunchPositionNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialPosX, Mode=TwoWay}" />
|
||||
<muxc:NumberBox x:Name="PosYBox"
|
||||
x:Uid="Globals_InitialPosYBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="118"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
|
||||
Style="{StaticResource LaunchPositionNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialPosY, Mode=TwoWay}" />
|
||||
<CheckBox x:Name="UseDefaultLaunchPositionCheckbox"
|
||||
x:Uid="Globals_DefaultLaunchPositionCheckbox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
IsChecked="{x:Bind ViewModel.UseDefaultLaunchPosition, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<TextBlock x:Uid="Globals_CenterOnLaunch"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<ToggleSwitch x:Name="CenterOnLaunchToggle"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
IsOn="{x:Bind ViewModel.CenterOnLaunch, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Launch Size -->
|
||||
<local:SettingContainer x:Name="LaunchSize"
|
||||
x:Uid="Globals_LaunchSize"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchSizeCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid ColumnSpacing="12"
|
||||
RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Globals_InitialCols"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}" />
|
||||
<muxc:NumberBox x:Uid="Globals_InitialColsBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialCols, Mode=TwoWay}" />
|
||||
<TextBlock x:Uid="Globals_InitialRows"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}" />
|
||||
<muxc:NumberBox x:Uid="Globals_InitialRowsBox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialRows, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Section: System & input defaults -->
|
||||
<local:SettingContainer x:Uid="Launch_Section_SystemInputDefaults"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Default Terminal -->
|
||||
<local:SettingContainer x:Name="DefaultTerminalDropdown"
|
||||
x:Uid="Globals_DefaultTerminal"
|
||||
x:Load="false">
|
||||
<ComboBox x:Name="DefaultTerminal"
|
||||
ItemsSource="{x:Bind ViewModel.DefaultTerminals}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultTerminal, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="SettingsModel:DefaultTerminal">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
<!-- terminal name and author -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
<!-- version -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<!-- terminal name -->
|
||||
<RowDefinition Height="auto" />
|
||||
<!-- author and version -->
|
||||
<RowDefinition Height="auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Width="24"
|
||||
Height="24"
|
||||
VerticalAlignment="Center"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Text="{x:Bind Name}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Author}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Author)}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Version}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Version)}" />
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Language -->
|
||||
<local:SettingContainer x:Name="Language"
|
||||
x:Uid="Globals_Language">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.LanguageList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentLanguage, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="x:String">
|
||||
<TextBlock Text="{x:Bind local:LaunchViewModel.LanguageDisplayConverter((x:String))}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Default IME Input Mode -->
|
||||
<local:SettingContainer x:Name="DefaultInputScope"
|
||||
x:Uid="Globals_DefaultInputScope">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.DefaultInputScopeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultInputScope, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include "Launch.h"
|
||||
#include "Interaction.h"
|
||||
#include "Compatibility.h"
|
||||
#include "Rendering.h"
|
||||
#include "RenderingViewModel.h"
|
||||
#include "Extensions.h"
|
||||
#include "Actions.h"
|
||||
#include "ProfileViewModel.h"
|
||||
@@ -17,6 +15,7 @@
|
||||
#include "ColorSchemes.h"
|
||||
#include "EditColorScheme.h"
|
||||
#include "AddProfile.h"
|
||||
#include "Profiles.h"
|
||||
#include "InteractionViewModel.h"
|
||||
#include "LaunchViewModel.h"
|
||||
#include "NewTabMenuViewModel.h"
|
||||
@@ -102,7 +101,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
MainPage::MainPage(const CascadiaSettings& settings) :
|
||||
_settingsSource{ settings },
|
||||
_settingsClone{ settings.Copy() },
|
||||
_profileVMs{ single_threaded_observable_vector<Editor::ProfileViewModel>() }
|
||||
_profilesPageVM{ winrt::make<ProfilesPageViewModel>() }
|
||||
{
|
||||
InitializeComponent();
|
||||
_UpdateBackgroundForMica();
|
||||
@@ -156,8 +155,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
});
|
||||
|
||||
_SetupProfilesPageEventHandling();
|
||||
|
||||
// Make sure to initialize the profiles _after_ we have initialized the color schemes page VM, because we pass
|
||||
// that VM into the appearance VMs within the profiles
|
||||
// that VM into the appearance VMs within the profiles. The Profiles VM owns the per-profile list itself.
|
||||
_InitializeProfilesList();
|
||||
|
||||
// Apply icons and tooltips (GH#19688, long names may be truncated) to static nav items
|
||||
@@ -205,28 +206,24 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
_UpdateBackgroundForMica();
|
||||
|
||||
// Deduce information about the currently selected item
|
||||
IInspectable lastBreadcrumb;
|
||||
const auto size = _breadcrumbs.Size();
|
||||
if (size > 0)
|
||||
// Capture data about where we are right now, so we can re-navigate to the same
|
||||
// place after we rebuild all the settings.
|
||||
IInspectable destination{ nullptr };
|
||||
auto subPage = BreadcrumbSubPage::None;
|
||||
hstring parentNavTag{};
|
||||
if (const auto size = _breadcrumbs.Size(); size > 0)
|
||||
{
|
||||
lastBreadcrumb = _breadcrumbs.GetAt(size - 1);
|
||||
const auto& crumb = _breadcrumbs.GetAt(size - 1).as<Breadcrumb>();
|
||||
destination = crumb->Tag();
|
||||
subPage = crumb->SubPage();
|
||||
// If we were inside the Profiles section, remember that so we can restore
|
||||
// the "Profiles ›" prefix on the rebuilt navigation.
|
||||
if (_RootCrumbIsProfilesBreadcrumb())
|
||||
{
|
||||
parentNavTag = hstring{ profilesTag };
|
||||
}
|
||||
}
|
||||
|
||||
// Collect only the first items out of the menu item source, the static
|
||||
// ones that we don't want to regenerate.
|
||||
//
|
||||
// By manipulating a MenuItemsSource this way, rather than manipulating the
|
||||
// MenuItems directly, we avoid a crash in WinUI.
|
||||
//
|
||||
// By making the vector only _originalNumItems big to start, GetMany
|
||||
// will only fill that number of elements out of the current source.
|
||||
std::vector<IInspectable> menuItemsSTL(_originalNumItems, nullptr);
|
||||
_menuItemSource.GetMany(0, menuItemsSTL);
|
||||
// now, just stick them back in.
|
||||
_menuItemSource.ReplaceAll(menuItemsSTL);
|
||||
|
||||
// Repopulate profile-related menu items
|
||||
_InitializeProfilesList();
|
||||
|
||||
// Update the Nav State with the new version of the settings
|
||||
@@ -236,64 +233,43 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_extensionsVM.UpdateSettings(_settingsClone, _colorSchemesPageVM);
|
||||
_profileDefaultsVM = nullptr; // Lazy-loaded upon navigation
|
||||
|
||||
// Now that the menuItems are repopulated,
|
||||
// refresh the current page using the breadcrumb data we collected before the refresh
|
||||
if (const auto& crumb{ lastBreadcrumb.try_as<Breadcrumb>() }; crumb && crumb->Tag())
|
||||
if (const auto& profileTag{ destination.try_as<Editor::ProfileViewModel>() })
|
||||
{
|
||||
bool foundNavigationParams = false;
|
||||
auto destination = crumb->Tag();
|
||||
auto subPage = crumb->SubPage();
|
||||
for (const auto& item : _menuItemSource)
|
||||
// Find the new profile VM by guid
|
||||
if (const auto newProfileVM = _FindProfileViewModelByGuid(profileTag.OriginalProfileGuid()))
|
||||
{
|
||||
const auto menuItem = item.try_as<MUX::Controls::NavigationViewItem>();
|
||||
if (!menuItem)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& tag = menuItem.Tag();
|
||||
if (const auto& stringTag{ tag.try_as<hstring>() })
|
||||
{
|
||||
if (const auto& destString{ destination.try_as<hstring>() })
|
||||
{
|
||||
foundNavigationParams = (*stringTag == *destString);
|
||||
}
|
||||
else if (destination.try_as<Editor::FolderEntryViewModel>() && *stringTag == newTabMenuTag)
|
||||
{
|
||||
foundNavigationParams = true;
|
||||
subPage = BreadcrumbSubPage::NewTabMenu_Folder;
|
||||
}
|
||||
else if (destination.try_as<Editor::ExtensionPackageViewModel>() && *stringTag == extensionsTag)
|
||||
{
|
||||
foundNavigationParams = true;
|
||||
subPage = BreadcrumbSubPage::Extensions_Extension;
|
||||
}
|
||||
}
|
||||
else if (const auto& profileTag{ tag.try_as<ProfileViewModel>() })
|
||||
{
|
||||
const auto destProfile = destination.try_as<ProfileViewModel>();
|
||||
if (destProfile && profileTag->OriginalProfileGuid() == destProfile->OriginalProfileGuid())
|
||||
{
|
||||
// Use the new profile VM from the refreshed menu items
|
||||
destination = tag;
|
||||
foundNavigationParams = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundNavigationParams)
|
||||
{
|
||||
// found the one that was selected before the refresh
|
||||
_Navigate(destination, subPage);
|
||||
return;
|
||||
}
|
||||
destination = newProfileVM;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back to the Profiles landing page
|
||||
destination = box_value(profilesTag);
|
||||
subPage = BreadcrumbSubPage::None;
|
||||
parentNavTag = {};
|
||||
}
|
||||
}
|
||||
else if (destination.try_as<Editor::FolderEntryViewModel>())
|
||||
{
|
||||
destination = box_value(newTabMenuTag);
|
||||
subPage = BreadcrumbSubPage::NewTabMenu_Folder;
|
||||
}
|
||||
else if (destination.try_as<Editor::ExtensionPackageViewModel>())
|
||||
{
|
||||
destination = box_value(extensionsTag);
|
||||
subPage = BreadcrumbSubPage::Extensions_Extension;
|
||||
}
|
||||
else if (!destination.try_as<hstring>())
|
||||
{
|
||||
// Couldn't find a meaningful previous page. Fall back to the first menu item.
|
||||
if (_menuItemSource && _menuItemSource.Size() > 0)
|
||||
{
|
||||
destination = _menuItemSource.GetAt(0).as<MUX::Controls::NavigationViewItem>().Tag();
|
||||
subPage = BreadcrumbSubPage::None;
|
||||
parentNavTag = {};
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find the selected item, fall back to first menu item
|
||||
// This happens when the selected item was a profile which doesn't exist in the new configuration
|
||||
// We can use menuItemsSTL here because the only things they miss are profile entries.
|
||||
const auto& firstItem{ _menuItemSource.GetAt(0).as<MUX::Controls::NavigationViewItem>() };
|
||||
_Navigate(firstItem.Tag(), BreadcrumbSubPage::None);
|
||||
_Navigate(destination, subPage, {}, parentNavTag);
|
||||
|
||||
_UpdateSearchIndex();
|
||||
}
|
||||
@@ -325,12 +301,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// can be empty to indicate that we should create a fresh profile
|
||||
void MainPage::_AddProfileHandler(winrt::guid profileGuid)
|
||||
{
|
||||
uint32_t insertIndex;
|
||||
auto selectedItem{ SettingsNav().SelectedItem() };
|
||||
if (_menuItemSource)
|
||||
{
|
||||
_menuItemSource.IndexOf(selectedItem, insertIndex);
|
||||
}
|
||||
if (profileGuid != winrt::guid{})
|
||||
{
|
||||
// if we were given a non-empty guid, we want to duplicate the corresponding profile
|
||||
@@ -338,13 +308,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
if (profile)
|
||||
{
|
||||
const auto duplicated = _settingsClone.DuplicateProfile(profile);
|
||||
_CreateAndNavigateToNewProfile(insertIndex, duplicated);
|
||||
_CreateAndNavigateToNewProfile(duplicated);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we were given an empty guid, create a new profile
|
||||
_CreateAndNavigateToNewProfile(insertIndex, nullptr);
|
||||
_CreateAndNavigateToNewProfile(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,7 +421,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
else if (_colorSchemesPageVM.CurrentPage() == ColorSchemesSubPage::Base)
|
||||
{
|
||||
_Navigate(boxedTag, BreadcrumbSubPage::None);
|
||||
// Preserve the current root context so that "Profiles > Color schemes" still shows the Profiles prefix.
|
||||
const hstring inheritedParentNavTag = _RootCrumbIsProfilesBreadcrumb() ? hstring{ profilesTag } : hstring{};
|
||||
_Navigate(boxedTag, BreadcrumbSubPage::None, {}, inheritedParentNavTag);
|
||||
}
|
||||
}
|
||||
else if (settingName == L"CurrentSchemeName")
|
||||
@@ -521,6 +493,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
if (currentPage == ProfileSubPage::Base)
|
||||
{
|
||||
_breadcrumbs.Clear();
|
||||
_AppendProfilesRootCrumb();
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(breadcrumbTag, breadcrumbText, BreadcrumbSubPage::None));
|
||||
}
|
||||
_NavigateToProfileSubPage(profile, currentPage, breadcrumbTag, {});
|
||||
@@ -535,7 +508,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// a view model object (i.e. ProfileViewModel, ColorSchemeViewModel, etc.) for dynamic pages
|
||||
// - subPage: the sub page to navigate to, used for pages that have multiple sub pages (i.e. Profile > Appearance/Terminal/Advanced)
|
||||
// - elementToFocus: the name of the element to focus on the target page
|
||||
void MainPage::_Navigate(const IInspectable& vm, BreadcrumbSubPage subPage, hstring elementToFocus)
|
||||
// - parentNavTag: optional nav tag of the parent page when this navigation is invoked from inside another
|
||||
// landing page. Used by the Profiles landing page to keep itself selected and to prepend a
|
||||
// "Profiles" breadcrumb when entering Color schemes / a profile / Defaults / Add Profile from there.
|
||||
void MainPage::_Navigate(const IInspectable& vm, BreadcrumbSubPage subPage, hstring elementToFocus, const hstring& parentNavTag)
|
||||
{
|
||||
_PreNavigateHelper();
|
||||
|
||||
@@ -554,11 +530,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
contentFrame().Navigate(xaml_typename<Editor::Interaction>(), winrt::make<NavigateToPageArgs>(winrt::make<InteractionViewModel>(_settingsClone.GlobalSettings()), *this, elementToFocus));
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Interaction/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == renderingTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Rendering>(), winrt::make<NavigateToPageArgs>(winrt::make<RenderingViewModel>(_settingsClone), *this, elementToFocus));
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Rendering/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == compatibilityTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Compatibility>(), winrt::make<NavigateToPageArgs>(winrt::make<CompatibilityViewModel>(_settingsClone), *this, elementToFocus));
|
||||
@@ -616,8 +587,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Extensions/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
}
|
||||
else if (*clickedItemTag == profilesTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles>(), winrt::make<NavigateToPageArgs>(_profilesPageVM, *this, elementToFocus));
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Profiles/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == globalProfileTag)
|
||||
{
|
||||
_AppendProfilesRootCrumb();
|
||||
|
||||
// lazy load profile defaults VM
|
||||
if (!_profileDefaultsVM)
|
||||
{
|
||||
@@ -636,9 +614,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
// Register handler for future user-driven sub-page changes
|
||||
_SetupProfileEventHandling(_profileDefaultsVM);
|
||||
|
||||
// Keep the Profiles nav item selected.
|
||||
selectedNavTag = profilesTag;
|
||||
}
|
||||
else if (*clickedItemTag == colorSchemesTag)
|
||||
{
|
||||
// Color Schemes page is accessible from root level and within Profiles,
|
||||
// so we need to prepend the root crumb in the second case.
|
||||
if (parentNavTag == profilesTag)
|
||||
{
|
||||
_AppendProfilesRootCrumb();
|
||||
selectedNavTag = profilesTag;
|
||||
}
|
||||
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_ColorSchemes/Content"), BreadcrumbSubPage::None));
|
||||
contentFrame().Navigate(xaml_typename<Editor::ColorSchemes>(), winrt::make<NavigateToPageArgs>(_colorSchemesPageVM, *this, elementToFocus));
|
||||
|
||||
@@ -654,47 +643,62 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
else if (*clickedItemTag == addProfileTag)
|
||||
{
|
||||
_AppendProfilesRootCrumb();
|
||||
|
||||
auto addProfileState{ winrt::make<AddProfilePageNavigationState>(_settingsClone) };
|
||||
addProfileState.AddNew({ get_weak(), &MainPage::_AddProfileHandler });
|
||||
contentFrame().Navigate(xaml_typename<Editor::AddProfile>(), winrt::make<NavigateToPageArgs>(addProfileState, *this, elementToFocus));
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_AddNewProfile/Content"), BreadcrumbSubPage::None));
|
||||
|
||||
// Keep the Profiles nav item selected.
|
||||
selectedNavTag = profilesTag;
|
||||
}
|
||||
}
|
||||
else if (const auto& profile = vm.try_as<Editor::ProfileViewModel>())
|
||||
{
|
||||
_AppendProfilesRootCrumb();
|
||||
selectedNavTag = profilesTag;
|
||||
|
||||
if (profile.Orphaned())
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Base_Orphaned>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus));
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, profile.Name(), BreadcrumbSubPage::None));
|
||||
profile.CurrentPage(ProfileSubPage::Base);
|
||||
_SetupProfileEventHandling(profile);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set CurrentPage before registering the handler to avoid double-navigation
|
||||
const ProfileSubPage profileSubPage = ProfileSubPageFromBreadcrumb(subPage);
|
||||
profile.CurrentPage(profileSubPage);
|
||||
|
||||
// Navigate directly to the correct sub-page
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, profile.Name(), BreadcrumbSubPage::None));
|
||||
_NavigateToProfileSubPage(profile, profileSubPage, vm, elementToFocus);
|
||||
|
||||
if (const auto profileNavItem = _FindProfileNavItem(profile.OriginalProfileGuid()))
|
||||
else
|
||||
{
|
||||
SettingsNav().SelectedItem(profileNavItem);
|
||||
}
|
||||
// Set CurrentPage before registering the handler to avoid double-navigation
|
||||
const ProfileSubPage profileSubPage = ProfileSubPageFromBreadcrumb(subPage);
|
||||
profile.CurrentPage(profileSubPage);
|
||||
|
||||
// Register handler for future user-driven sub-page changes
|
||||
_SetupProfileEventHandling(profile);
|
||||
// Navigate directly to the correct sub-page
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, profile.Name(), BreadcrumbSubPage::None));
|
||||
_NavigateToProfileSubPage(profile, profileSubPage, vm, elementToFocus);
|
||||
|
||||
// Register handler for future user-driven sub-page changes
|
||||
_SetupProfileEventHandling(profile);
|
||||
}
|
||||
}
|
||||
else if (const auto& colorSchemeVM = vm.try_as<Editor::ColorSchemeViewModel>())
|
||||
{
|
||||
selectedNavTag = colorSchemesTag;
|
||||
const auto boxedColorSchemesTag = box_value(colorSchemesTag);
|
||||
|
||||
// Suppress the handler to avoid double-navigation
|
||||
_colorSchemesPageViewModelChangedRevoker.revoke();
|
||||
|
||||
// Color Schemes page is accessible from within Profiles and root level,
|
||||
// so we need to prepend the root crumb in the first case.
|
||||
if (parentNavTag == profilesTag)
|
||||
{
|
||||
_AppendProfilesRootCrumb();
|
||||
selectedNavTag = profilesTag;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedNavTag = colorSchemesTag;
|
||||
}
|
||||
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(boxedColorSchemesTag, RS_(L"Nav_ColorSchemes/Content"), BreadcrumbSubPage::None));
|
||||
|
||||
if (subPage == BreadcrumbSubPage::None)
|
||||
@@ -813,26 +817,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
|
||||
// Select the appropriate nav item
|
||||
// NOTE: profiles are special in that they have their own nav item, so those are handled in the profile branch above
|
||||
if (!selectedNavTag.empty())
|
||||
{
|
||||
for (auto&& menuItem : _menuItemSource)
|
||||
{
|
||||
if (const auto& navViewItem{ menuItem.try_as<MUX::Controls::NavigationViewItem>() })
|
||||
{
|
||||
if (const auto& tag{ navViewItem.Tag() })
|
||||
{
|
||||
if (const auto& stringTag{ tag.try_as<hstring>() })
|
||||
{
|
||||
if (*stringTag == selectedNavTag)
|
||||
{
|
||||
SettingsNav().SelectedItem(navViewItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_SelectNavItemByTag(selectedNavTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -855,7 +842,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
if (gsl::narrow_cast<uint32_t>(args.Index()) < (_breadcrumbs.Size() - 1))
|
||||
{
|
||||
const auto crumb = args.Item().as<Breadcrumb>();
|
||||
_Navigate(crumb->Tag(), crumb->SubPage());
|
||||
// If the breadcrumb chain is rooted at the Profiles landing page, preserve
|
||||
// that context so navigating to sub pages (i.e. Color schemes) via a back-breadcrumb
|
||||
// keeps the "Profiles ›" prefix.
|
||||
const hstring parentNavTag = _RootCrumbIsProfilesBreadcrumb() ? hstring{ profilesTag } : hstring{};
|
||||
_Navigate(crumb->Tag(), crumb->SubPage(), {}, parentNavTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -872,35 +863,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_MoveXamlParsedNavItemsIntoItemSource();
|
||||
}
|
||||
|
||||
// Manually create a NavigationViewItem and view model for each profile
|
||||
// and keep a reference to them in a map so that we
|
||||
// can easily modify the correct one when the associated
|
||||
// profile changes.
|
||||
_profileVMs.Clear();
|
||||
// Populate the per-profile view models on the Profiles VM. The Profiles landing
|
||||
// page (and the search index) read this same list back through the VM.
|
||||
const auto& profileVMs = _profilesPageVM.Profiles();
|
||||
profileVMs.Clear();
|
||||
for (const auto& profile : _settingsClone.AllProfiles())
|
||||
{
|
||||
if (!profile.Deleted())
|
||||
{
|
||||
auto profileVM = _viewModelForProfile(profile, _settingsClone, Dispatcher());
|
||||
profileVM.SetupAppearances(_colorSchemesPageVM.AllColorSchemes());
|
||||
auto navItem = _CreateProfileNavViewItem(profileVM);
|
||||
_menuItemSource.Append(navItem);
|
||||
profileVM.DeleteProfileRequested({ this, &MainPage::_DeleteProfile });
|
||||
profileVMs.Append(profileVM);
|
||||
}
|
||||
}
|
||||
|
||||
// Top off (the end of the nav view) with the Add Profile item
|
||||
MUX::Controls::NavigationViewItem addProfileItem;
|
||||
const auto addProfileText = RS_(L"Nav_AddNewProfile/Content");
|
||||
addProfileItem.Content(box_value(addProfileText));
|
||||
addProfileItem.Tag(box_value(addProfileTag));
|
||||
WUX::Controls::ToolTipService::SetToolTip(addProfileItem, box_value(addProfileText));
|
||||
|
||||
FontIcon icon;
|
||||
// This is the "Add" symbol
|
||||
icon.Glyph(NavTagIconMap[addProfileTag]);
|
||||
addProfileItem.Icon(icon);
|
||||
|
||||
_menuItemSource.Append(addProfileItem);
|
||||
}
|
||||
|
||||
// BODGY
|
||||
@@ -936,79 +912,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
SettingsNav().MenuItemsSource(_menuItemSource);
|
||||
}
|
||||
|
||||
void MainPage::_CreateAndNavigateToNewProfile(const uint32_t index, const Model::Profile& profile)
|
||||
void MainPage::_CreateAndNavigateToNewProfile(const Model::Profile& profile)
|
||||
{
|
||||
const auto newProfile{ profile ? profile : _settingsClone.CreateNewProfile() };
|
||||
const auto profileViewModel{ _viewModelForProfile(newProfile, _settingsClone, Dispatcher()) };
|
||||
profileViewModel.SetupAppearances(_colorSchemesPageVM.AllColorSchemes());
|
||||
const auto navItem{ _CreateProfileNavViewItem(profileViewModel) };
|
||||
profileViewModel.DeleteProfileRequested({ this, &MainPage::_DeleteProfile });
|
||||
|
||||
if (_menuItemSource)
|
||||
{
|
||||
_menuItemSource.InsertAt(index, navItem);
|
||||
}
|
||||
_profilesPageVM.Profiles().Append(profileViewModel);
|
||||
|
||||
// Select and navigate to the new profile
|
||||
_Navigate(profileViewModel, BreadcrumbSubPage::None);
|
||||
}
|
||||
|
||||
static MUX::Controls::InfoBadge _createGlyphIconBadge(wil::zwstring_view glyph)
|
||||
{
|
||||
MUX::Controls::InfoBadge badge;
|
||||
MUX::Controls::FontIconSource icon;
|
||||
icon.FontFamily(winrt::Windows::UI::Xaml::Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
icon.FontSize(12);
|
||||
icon.Glyph(glyph);
|
||||
badge.IconSource(icon);
|
||||
return badge;
|
||||
}
|
||||
|
||||
MUX::Controls::NavigationViewItem MainPage::_CreateProfileNavViewItem(const Editor::ProfileViewModel& profile)
|
||||
{
|
||||
MUX::Controls::NavigationViewItem profileNavItem;
|
||||
profileNavItem.Content(box_value(profile.Name()));
|
||||
profileNavItem.Tag(box_value<Editor::ProfileViewModel>(profile));
|
||||
profileNavItem.Icon(UI::IconPathConverter::IconWUX(profile.EvaluatedIcon()));
|
||||
WUX::Controls::ToolTipService::SetToolTip(profileNavItem, box_value(profile.Name()));
|
||||
|
||||
if (profile.Orphaned())
|
||||
{
|
||||
profileNavItem.InfoBadge(_createGlyphIconBadge(L"\xE7BA") /* Warning Triangle */);
|
||||
}
|
||||
else if (profile.Hidden())
|
||||
{
|
||||
profileNavItem.InfoBadge(_createGlyphIconBadge(L"\xED1A") /* Hide */);
|
||||
}
|
||||
|
||||
// Update the menu item when the icon/name changes
|
||||
auto weakMenuItem{ make_weak(profileNavItem) };
|
||||
profile.PropertyChanged([weakMenuItem](const auto&, const WUX::Data::PropertyChangedEventArgs& args) {
|
||||
if (auto menuItem{ weakMenuItem.get() })
|
||||
{
|
||||
const auto& tag{ menuItem.Tag().as<Editor::ProfileViewModel>() };
|
||||
if (args.PropertyName() == L"Icon")
|
||||
{
|
||||
menuItem.Icon(UI::IconPathConverter::IconWUX(tag.EvaluatedIcon()));
|
||||
}
|
||||
else if (args.PropertyName() == L"Name")
|
||||
{
|
||||
menuItem.Content(box_value(tag.Name()));
|
||||
WUX::Controls::ToolTipService::SetToolTip(menuItem, box_value(tag.Name()));
|
||||
}
|
||||
else if (args.PropertyName() == L"Hidden")
|
||||
{
|
||||
menuItem.InfoBadge(tag.Hidden() ? _createGlyphIconBadge(L"\xED1A") /* Hide */ : nullptr);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add an event handler for when the user wants to delete a profile.
|
||||
profile.DeleteProfileRequested({ this, &MainPage::_DeleteProfile });
|
||||
|
||||
// Register the VM so that it appears in the search index
|
||||
_profileVMs.Append(profile);
|
||||
|
||||
return profileNavItem;
|
||||
_Navigate(profileViewModel);
|
||||
}
|
||||
|
||||
void MainPage::_DeleteProfile(const IInspectable /*sender*/, const Editor::DeleteProfileEventArgs& args)
|
||||
@@ -1025,33 +939,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// remove selected item
|
||||
uint32_t index;
|
||||
auto selectedItem{ SettingsNav().SelectedItem() };
|
||||
if (_menuItemSource)
|
||||
// Remove the profile VM
|
||||
const auto& profileVMs = _profilesPageVM.Profiles();
|
||||
for (uint32_t i = 0; i < profileVMs.Size(); ++i)
|
||||
{
|
||||
_menuItemSource.IndexOf(selectedItem, index);
|
||||
_menuItemSource.RemoveAt(index);
|
||||
|
||||
// Remove it from the list of VMs
|
||||
auto profileVM = selectedItem.as<MUX::Controls::NavigationViewItem>().Tag().as<Editor::ProfileViewModel>();
|
||||
uint32_t vmIndex;
|
||||
if (_menuItemSource.IndexOf(profileVM, vmIndex))
|
||||
if (profileVMs.GetAt(i).OriginalProfileGuid() == guid)
|
||||
{
|
||||
_profileVMs.RemoveAt(vmIndex);
|
||||
profileVMs.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
|
||||
// navigate to the profile next to this one
|
||||
const auto newSelectedItem{ _menuItemSource.GetAt(index < _menuItemSource.Size() - 1 ? index : index - 1) };
|
||||
const auto newTag = newSelectedItem.as<MUX::Controls::NavigationViewItem>().Tag();
|
||||
if (const auto profileViewModel = newTag.try_as<ProfileViewModel>())
|
||||
{
|
||||
profileViewModel->FocusDeleteButton(true);
|
||||
}
|
||||
_Navigate(newTag, BreadcrumbSubPage::None);
|
||||
// Since we are navigating to a new profile after deletion, scroll up to the top
|
||||
SettingsMainPage_ScrollViewer().ChangeView(nullptr, 0.0, nullptr);
|
||||
}
|
||||
|
||||
// Go back to the Profiles landing page
|
||||
_Navigate(box_value(profilesTag));
|
||||
SettingsMainPage_ScrollViewer().ChangeView(nullptr, 0.0, nullptr);
|
||||
}
|
||||
|
||||
IObservableVector<IInspectable> MainPage::Breadcrumbs() noexcept
|
||||
@@ -1061,29 +962,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void MainPage::_NavigateToProfileHandler(const IInspectable& /*sender*/, winrt::guid profileGuid)
|
||||
{
|
||||
if (const auto profileNavItem = _FindProfileNavItem(profileGuid))
|
||||
if (const auto profileVM = _FindProfileViewModelByGuid(profileGuid))
|
||||
{
|
||||
_Navigate(profileNavItem.Tag(), BreadcrumbSubPage::None);
|
||||
_Navigate(profileVM);
|
||||
}
|
||||
// Silently fail if the profile wasn't found
|
||||
}
|
||||
|
||||
MUX::Controls::NavigationViewItem MainPage::_FindProfileNavItem(winrt::guid profileGuid) const
|
||||
Editor::ProfileViewModel MainPage::_FindProfileViewModelByGuid(winrt::guid profileGuid) const
|
||||
{
|
||||
for (auto&& menuItem : _menuItemSource)
|
||||
for (const auto& profileVM : _profilesPageVM.Profiles())
|
||||
{
|
||||
if (const auto& navViewItem{ menuItem.try_as<MUX::Controls::NavigationViewItem>() })
|
||||
if (profileVM.OriginalProfileGuid() == profileGuid)
|
||||
{
|
||||
if (const auto& tag{ navViewItem.Tag() })
|
||||
{
|
||||
if (const auto& profileTag{ tag.try_as<ProfileViewModel>() })
|
||||
{
|
||||
if (profileTag->OriginalProfileGuid() == profileGuid)
|
||||
{
|
||||
return navViewItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return profileVM;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -1094,6 +986,62 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_Navigate(box_value(hstring{ colorSchemesTag }), BreadcrumbSubPage::ColorSchemes_Edit);
|
||||
}
|
||||
|
||||
void MainPage::_AppendProfilesRootCrumb()
|
||||
{
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(box_value(profilesTag), RS_(L"Nav_Profiles/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
|
||||
bool MainPage::_RootCrumbIsProfilesBreadcrumb() const
|
||||
{
|
||||
if (_breadcrumbs.Size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const auto rootTag = _breadcrumbs.GetAt(0).as<Breadcrumb>()->Tag().try_as<hstring>();
|
||||
return rootTag && *rootTag == profilesTag;
|
||||
}
|
||||
|
||||
void MainPage::_SelectNavItemByTag(std::wstring_view tag)
|
||||
{
|
||||
if (!_menuItemSource)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (auto&& menuItem : _menuItemSource)
|
||||
{
|
||||
if (const auto& navViewItem{ menuItem.try_as<MUX::Controls::NavigationViewItem>() })
|
||||
{
|
||||
if (const auto& itemTag{ navViewItem.Tag() })
|
||||
{
|
||||
if (const auto& stringTag{ itemTag.try_as<hstring>() })
|
||||
{
|
||||
if (*stringTag == tag)
|
||||
{
|
||||
SettingsNav().SelectedItem(navViewItem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::_SetupProfilesPageEventHandling()
|
||||
{
|
||||
_profilesPageVM.OpenDefaultsRequested([this](const auto&, const auto&) {
|
||||
_Navigate(box_value(globalProfileTag));
|
||||
});
|
||||
_profilesPageVM.OpenColorSchemesRequested([this](const auto&, const auto&) {
|
||||
_Navigate(box_value(colorSchemesTag), {}, {}, hstring{ profilesTag });
|
||||
});
|
||||
_profilesPageVM.AddProfileRequested([this](const auto&, const auto&) {
|
||||
_Navigate(box_value(addProfileTag));
|
||||
});
|
||||
_profilesPageVM.OpenProfileRequested([this](const auto&, const Editor::ProfileViewModel& profile) {
|
||||
_Navigate(profile);
|
||||
});
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Xaml::Media::Brush MainPage::BackgroundBrush()
|
||||
{
|
||||
return SettingsNav().Background();
|
||||
@@ -1196,7 +1144,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
co_return;
|
||||
}
|
||||
_currentSearch = SearchIndex::Instance().SearchAsync(sanitizedQuery,
|
||||
_profileVMs.GetView(),
|
||||
_profilesPageVM.Profiles().GetView(),
|
||||
get_self<implementation::NewTabMenuViewModel>(_newTabMenuPageVM)->FolderTreeFlatList().GetView(),
|
||||
_colorSchemesPageVM.AllColorSchemes().GetView(),
|
||||
_extensionsVM.ExtensionPackages().GetView(),
|
||||
|
||||
@@ -84,21 +84,25 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
std::optional<HWND> _hostingHwnd;
|
||||
|
||||
void _InitializeProfilesList();
|
||||
void _CreateAndNavigateToNewProfile(const uint32_t index, const Model::Profile& profile);
|
||||
winrt::Microsoft::UI::Xaml::Controls::NavigationViewItem _CreateProfileNavViewItem(const Editor::ProfileViewModel& profile);
|
||||
void _CreateAndNavigateToNewProfile(const Model::Profile& profile);
|
||||
void _DeleteProfile(const Windows::Foundation::IInspectable sender, const Editor::DeleteProfileEventArgs& args);
|
||||
void _AddProfileHandler(const winrt::guid profileGuid);
|
||||
|
||||
void _SetupProfileEventHandling(const winrt::Microsoft::Terminal::Settings::Editor::ProfileViewModel profile);
|
||||
void _SetupColorSchemesEventHandling();
|
||||
void _SetupActionsEventHandling();
|
||||
void _SetupProfilesPageEventHandling();
|
||||
void _NavigateToProfileSubPage(const Editor::ProfileViewModel& profile, ProfileSubPage page, const IInspectable& breadcrumbTag, const hstring& elementToFocus);
|
||||
|
||||
void _PreNavigateHelper();
|
||||
void _Navigate(const IInspectable& vm, BreadcrumbSubPage subPage, hstring elementToFocus = {});
|
||||
void _Navigate(const IInspectable& vm, BreadcrumbSubPage subPage = BreadcrumbSubPage::None, hstring elementToFocus = {}, const hstring& parentNavTag = {});
|
||||
void _NavigateToProfileHandler(const IInspectable& sender, winrt::guid profileGuid);
|
||||
void _NavigateToColorSchemeHandler(const IInspectable& sender, const IInspectable& args);
|
||||
Microsoft::UI::Xaml::Controls::NavigationViewItem _FindProfileNavItem(winrt::guid profileGuid) const;
|
||||
Editor::ProfileViewModel _FindProfileViewModelByGuid(winrt::guid profileGuid) const;
|
||||
|
||||
void _AppendProfilesRootCrumb();
|
||||
bool _RootCrumbIsProfilesBreadcrumb() const;
|
||||
void _SelectNavItemByTag(std::wstring_view tag);
|
||||
|
||||
void _UpdateBackgroundForMica();
|
||||
void _MoveXamlParsedNavItemsIntoItemSource();
|
||||
@@ -106,11 +110,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
safe_void_coroutine _UpdateSearchIndex();
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ProfileViewModel _profileDefaultsVM{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<winrt::Microsoft::Terminal::Settings::Editor::ProfileViewModel> _profileVMs{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ColorSchemesPageViewModel _colorSchemesPageVM{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ActionsViewModel _actionsVM{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::NewTabMenuViewModel _newTabMenuPageVM{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ExtensionsViewModel _extensionsVM{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ProfilesPageViewModel _profilesPageVM{ nullptr };
|
||||
|
||||
Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IObservableVector<Windows::Foundation::IInspectable>> _currentSearch{ nullptr };
|
||||
|
||||
|
||||
@@ -167,10 +167,6 @@
|
||||
Tag="ColorSchemes_Nav" />
|
||||
|
||||
|
||||
<muxc:NavigationViewItem x:Name="RenderingNavItem"
|
||||
x:Uid="Nav_Rendering"
|
||||
Tag="Rendering_Nav" />
|
||||
|
||||
<muxc:NavigationViewItem x:Name="CompatibilityNavItem"
|
||||
x:Uid="Nav_Compatibility"
|
||||
Tag="Compatibility_Nav" />
|
||||
@@ -192,11 +188,9 @@
|
||||
x:Uid="Nav_Extensions"
|
||||
Tag="Extensions_Nav" />
|
||||
|
||||
<muxc:NavigationViewItemHeader x:Uid="Nav_Profiles" />
|
||||
|
||||
<muxc:NavigationViewItem x:Name="BaseLayerMenuItem"
|
||||
x:Uid="Nav_ProfileDefaults"
|
||||
Tag="GlobalProfile_Nav" />
|
||||
<muxc:NavigationViewItem x:Name="ProfilesNavItem"
|
||||
x:Uid="Nav_Profiles"
|
||||
Tag="Profiles_Nav" />
|
||||
</muxc:NavigationView.MenuItems>
|
||||
|
||||
<muxc:NavigationView.FooterMenuItems>
|
||||
|
||||
@@ -86,6 +86,9 @@
|
||||
<ClInclude Include="KeyChordListener.h">
|
||||
<DependentUpon>KeyChordListener.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KeyChordVisual.h">
|
||||
<DependentUpon>KeyChordVisual.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Launch.h">
|
||||
<DependentUpon>Launch.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
@@ -119,8 +122,8 @@
|
||||
<DependentUpon>ColorSchemesPageViewModel.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RenderingViewModel.h">
|
||||
<DependentUpon>RenderingViewModel.idl</DependentUpon>
|
||||
<ClInclude Include="Profiles.h">
|
||||
<DependentUpon>Profiles.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="InteractionViewModel.h">
|
||||
@@ -167,9 +170,6 @@
|
||||
<DependentUpon>Appearances.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Rendering.h">
|
||||
<DependentUpon>Rendering.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SettingContainer.h">
|
||||
<DependentUpon>SettingContainer.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
@@ -216,6 +216,9 @@
|
||||
<Page Include="KeyChordListener.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="KeyChordVisual.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Launch.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
@@ -231,6 +234,9 @@
|
||||
<Page Include="Profiles_Base.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Profiles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Profiles_Base_Orphaned.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
@@ -246,9 +252,6 @@
|
||||
<Page Include="Appearances.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Rendering.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="SettingContainerStyle.xaml">
|
||||
<Type>DefaultStyle</Type>
|
||||
</Page>
|
||||
@@ -297,6 +300,9 @@
|
||||
<ClCompile Include="KeyChordListener.cpp">
|
||||
<DependentUpon>KeyChordListener.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KeyChordVisual.cpp">
|
||||
<DependentUpon>KeyChordVisual.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Launch.cpp">
|
||||
<DependentUpon>Launch.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
@@ -331,8 +337,8 @@
|
||||
<DependentUpon>ColorSchemesPageViewModel.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RenderingViewModel.cpp">
|
||||
<DependentUpon>RenderingViewModel.idl</DependentUpon>
|
||||
<ClCompile Include="Profiles.cpp">
|
||||
<DependentUpon>Profiles.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="InteractionViewModel.cpp">
|
||||
@@ -379,9 +385,6 @@
|
||||
<DependentUpon>Appearances.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Rendering.cpp">
|
||||
<DependentUpon>Rendering.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SettingContainer.cpp">
|
||||
<DependentUpon>SettingContainer.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
@@ -427,6 +430,10 @@
|
||||
<DependentUpon>KeyChordListener.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="KeyChordVisual.idl">
|
||||
<DependentUpon>KeyChordVisual.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="Launch.idl">
|
||||
<DependentUpon>Launch.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@@ -443,10 +450,6 @@
|
||||
<DependentUpon>Compatibility.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="Rendering.idl">
|
||||
<DependentUpon>Rendering.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="SearchIndex.idl" />
|
||||
<Midl Include="MainPage.idl">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
@@ -456,7 +459,10 @@
|
||||
<Midl Include="TerminalColorConverters.idl" />
|
||||
<Midl Include="ColorSchemeViewModel.idl" />
|
||||
<Midl Include="ColorSchemesPageViewModel.idl" />
|
||||
<Midl Include="RenderingViewModel.idl" />
|
||||
<Midl Include="Profiles.idl">
|
||||
<DependentUpon>Profiles.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="InteractionViewModel.idl" />
|
||||
<Midl Include="GlobalAppearanceViewModel.idl" />
|
||||
<Midl Include="LaunchViewModel.idl" />
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
<Midl Include="ActionsViewModel.idl" />
|
||||
<Midl Include="ColorSchemeViewModel.idl" />
|
||||
<Midl Include="ColorSchemesPageViewModel.idl" />
|
||||
<Midl Include="RenderingViewModel.idl" />
|
||||
<Midl Include="InteractionViewModel.idl" />
|
||||
<Midl Include="GlobalAppearanceViewModel.idl" />
|
||||
<Midl Include="LaunchViewModel.idl" />
|
||||
@@ -48,14 +47,15 @@
|
||||
<Page Include="Profiles_Advanced.xaml" />
|
||||
<Page Include="Profiles_Appearance.xaml" />
|
||||
<Page Include="Appearances.xaml" />
|
||||
<Page Include="Rendering.xaml" />
|
||||
<Page Include="Actions.xaml" />
|
||||
<Page Include="EditAction.xaml" />
|
||||
<Page Include="SettingContainerStyle.xaml" />
|
||||
<Page Include="AddProfile.xaml" />
|
||||
<Page Include="KeyChordListener.xaml" />
|
||||
<Page Include="KeyChordVisual.xaml" />
|
||||
<Page Include="NullableColorPicker.xaml" />
|
||||
<Page Include="IconPicker.xaml" />
|
||||
<Page Include="NewTabMenu.xaml" />
|
||||
<Page Include="Profiles.xaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -12,11 +12,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
inline constexpr std::wstring_view openJsonTag{ L"OpenJson_Nav" };
|
||||
inline constexpr std::wstring_view launchTag{ L"Launch_Nav" };
|
||||
inline constexpr std::wstring_view interactionTag{ L"Interaction_Nav" };
|
||||
inline constexpr std::wstring_view renderingTag{ L"Rendering_Nav" };
|
||||
inline constexpr std::wstring_view compatibilityTag{ L"Compatibility_Nav" };
|
||||
inline constexpr std::wstring_view actionsTag{ L"Actions_Nav" };
|
||||
inline constexpr std::wstring_view newTabMenuTag{ L"NewTabMenu_Nav" };
|
||||
inline constexpr std::wstring_view extensionsTag{ L"Extensions_Nav" };
|
||||
inline constexpr std::wstring_view profilesTag{ L"Profiles_Nav" };
|
||||
inline constexpr std::wstring_view globalProfileTag{ L"GlobalProfile_Nav" };
|
||||
inline constexpr std::wstring_view addProfileTag{ L"AddProfile" };
|
||||
inline constexpr std::wstring_view colorSchemesTag{ L"ColorSchemes_Nav" };
|
||||
@@ -28,11 +28,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
std::pair{ interactionTag, L"\xE7C9" }, /* Touch Pointer */
|
||||
std::pair{ globalAppearanceTag, L"\xE771" }, /* Personalize */
|
||||
std::pair{ colorSchemesTag, L"\xE790" }, /* Color */
|
||||
std::pair{ renderingTag, L"\xE7F8" }, /* Device Laptop No Pic */
|
||||
std::pair{ compatibilityTag, L"\xEC7A" }, /* Developer Tools */
|
||||
std::pair{ actionsTag, L"\xE765" }, /* Keyboard Classic */
|
||||
std::pair{ newTabMenuTag, L"\xE71D" }, /* All Apps */
|
||||
std::pair{ extensionsTag, L"\xEA86" }, /* Puzzle */
|
||||
std::pair{ profilesTag, L"\xE7EE" }, /* Other User */
|
||||
std::pair{ globalProfileTag, L"\xE81E" }, /* Map Layers */
|
||||
std::pair{ addProfileTag, L"\xE710" }, /* Add */
|
||||
std::pair{ openJsonTag, L"\xE713" }, /* Settings */
|
||||
|
||||
@@ -227,11 +227,27 @@
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid RowSpacing="12">
|
||||
<Grid x:Name="RootGrid"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
ColumnSpacing="16"
|
||||
RowSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition x:Name="ControlsColumn"
|
||||
Width="*" />
|
||||
<ColumnDefinition x:Name="PreviewColumn"
|
||||
Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<!--
|
||||
In the wide/medium (2-column) states, both PreviewArea and ControlsArea span
|
||||
both rows so the row sizing here doesn't matter.
|
||||
In the narrow (stacked) state, PreviewArea moves to row 0 and ControlsArea
|
||||
moves to row 1, and the rows are resized via the visual state setters.
|
||||
-->
|
||||
<RowDefinition x:Name="PreviewRow"
|
||||
Height="0" />
|
||||
<RowDefinition x:Name="ControlsRow"
|
||||
Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Folder Picker Dialog: used to select a folder to move entries to -->
|
||||
@@ -267,253 +283,390 @@
|
||||
</muxc:TreeView>
|
||||
</ContentDialog>
|
||||
|
||||
<!-- New Tab Menu Content -->
|
||||
<StackPanel Grid.Row="0"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Spacing="8">
|
||||
<Border Height="300"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="0,12,0,0"
|
||||
<Grid x:Name="PreviewArea"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!--
|
||||
Invisible header placeholder so the preview's top edge aligns with the first
|
||||
SettingContainer in the controls column
|
||||
-->
|
||||
<TextBlock x:Name="PreviewHeaderPlaceholder"
|
||||
Grid.Row="0"
|
||||
Margin="0,4,0,4"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
IsHitTestVisible="False"
|
||||
Opacity="0"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}"
|
||||
Text="Preview" />
|
||||
|
||||
<!-- Preview Border: contains the ListView and the multi-select footer. -->
|
||||
<Border Grid.Row="1"
|
||||
MinHeight="300"
|
||||
Margin="0,4,0,0"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}">
|
||||
<ListView x:Name="NewTabMenuListView"
|
||||
AllowDrop="True"
|
||||
CanDragItems="True"
|
||||
CanReorderItems="True"
|
||||
ItemTemplateSelector="{StaticResource NewTabMenuEntryTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.CurrentView, Mode=OneWay}"
|
||||
SelectionMode="Multiple" />
|
||||
</Border>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- General Controls -->
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="10">
|
||||
<Button x:Name="MoveToFolderButton"
|
||||
Click="MoveMultiple_Click"
|
||||
IsEnabled="False">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_MoveToFolderTextBlock"
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button x:Name="DeleteMultipleButton"
|
||||
Click="DeleteMultiple_Click"
|
||||
IsEnabled="False"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_DeleteMultipleTextBlock"
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Folder View Controls -->
|
||||
<StackPanel Grid.Row="1"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Visibility="{x:Bind ViewModel.IsFolderView, Mode=OneWay}">
|
||||
<TextBlock x:Uid="NewTabMenu_CurrentFolderTextBlock"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Name -->
|
||||
<local:SettingContainer x:Name="CurrentFolderName"
|
||||
x:Uid="NewTabMenu_CurrentFolderName"
|
||||
CurrentValue="{x:Bind ViewModel.CurrentFolderName, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentFolderName, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Icon -->
|
||||
<local:SettingContainer x:Name="CurrentFolderIcon"
|
||||
x:Uid="NewTabMenu_CurrentFolderIcon"
|
||||
CurrentValueAccessibleName="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
Height="16"
|
||||
Content="{x:Bind ViewModel.CurrentFolderIconPreview, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.CurrentFolderUsingNoIcon), Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
|
||||
Visibility="{x:Bind ViewModel.CurrentFolderUsingNoIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<local:IconPicker CurrentIconPath="{x:Bind ViewModel.CurrentFolderIconPath, Mode=TwoWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Inlining -->
|
||||
<local:SettingContainer x:Name="CurrentFolderInlining"
|
||||
x:Uid="NewTabMenu_CurrentFolderInlining">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderInlining, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Allow Empty -->
|
||||
<local:SettingContainer x:Name="CurrentFolderAllowEmpty"
|
||||
x:Uid="NewTabMenu_CurrentFolderAllowEmpty">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderAllowEmpty, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Add Entries -->
|
||||
<StackPanel Grid.Row="2">
|
||||
<TextBlock x:Uid="NewTabMenu_AddEntriesTextBlock"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Add Profile -->
|
||||
<local:SettingContainer x:Name="AddProfile"
|
||||
x:Uid="NewTabMenu_AddProfile"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="4">
|
||||
<!-- Select profile to add -->
|
||||
<ComboBox x:Name="AddProfileComboBox"
|
||||
MinWidth="{StaticResource StandardBoxMinWidth}"
|
||||
ItemsSource="{x:Bind ViewModel.AvailableProfiles, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.SelectedProfile, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model:Profile">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
<ListView x:Name="NewTabMenuListView"
|
||||
Grid.Row="0"
|
||||
AllowDrop="True"
|
||||
CanDragItems="True"
|
||||
CanReorderItems="True"
|
||||
ItemTemplateSelector="{StaticResource NewTabMenuEntryTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.CurrentView, Mode=OneWay}"
|
||||
SelectionMode="Multiple" />
|
||||
|
||||
<!-- Preview Controls -->
|
||||
<Border Grid.Row="1"
|
||||
Padding="8"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
|
||||
BorderThickness="0,1,0,0">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button x:Name="MoveToFolderButton"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Click="MoveMultiple_Click"
|
||||
IsEnabled="False">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- profile name -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind Name}" />
|
||||
<FontIcon Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_MoveToFolderTextBlock"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</Button>
|
||||
<Button x:Name="DeleteMultipleButton"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Click="DeleteMultiple_Click"
|
||||
IsEnabled="False"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_DeleteMultipleTextBlock"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<Button x:Name="AddProfileButton"
|
||||
x:Uid="NewTabMenu_AddProfileButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddProfileButton_Clicked">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<ScrollViewer x:Name="ControlsArea"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="1"
|
||||
HorizontalScrollMode="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<!-- Folder View Controls -->
|
||||
<StackPanel Margin="0,0,0,24"
|
||||
Visibility="{x:Bind ViewModel.IsFolderView, Mode=OneWay}">
|
||||
<TextBlock x:Uid="NewTabMenu_CurrentFolderTextBlock"
|
||||
Margin="0,4,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Name -->
|
||||
<local:SettingContainer x:Name="CurrentFolderName"
|
||||
x:Uid="NewTabMenu_CurrentFolderName"
|
||||
CurrentValue="{x:Bind ViewModel.CurrentFolderName, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentFolderName, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Icon -->
|
||||
<local:SettingContainer x:Name="CurrentFolderIcon"
|
||||
x:Uid="NewTabMenu_CurrentFolderIcon"
|
||||
CurrentValueAccessibleName="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
Height="16"
|
||||
Content="{x:Bind ViewModel.CurrentFolderIconPreview, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.CurrentFolderUsingNoIcon), Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
|
||||
Visibility="{x:Bind ViewModel.CurrentFolderUsingNoIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<local:IconPicker CurrentIconPath="{x:Bind ViewModel.CurrentFolderIconPath, Mode=TwoWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Inlining -->
|
||||
<local:SettingContainer x:Name="CurrentFolderInlining"
|
||||
x:Uid="NewTabMenu_CurrentFolderInlining">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderInlining, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Allow Empty -->
|
||||
<local:SettingContainer x:Name="CurrentFolderAllowEmpty"
|
||||
x:Uid="NewTabMenu_CurrentFolderAllowEmpty">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderAllowEmpty, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Separator -->
|
||||
<local:SettingContainer x:Name="AddSeparator"
|
||||
x:Uid="NewTabMenu_AddSeparator"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddSeparatorButton"
|
||||
x:Uid="NewTabMenu_AddSeparatorButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddSeparatorButton_Clicked">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
<!-- Add Entries -->
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="NewTabMenu_AddEntriesTextBlock"
|
||||
Margin="0,4,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Add Folder -->
|
||||
<local:SettingContainer x:Name="AddFolder"
|
||||
x:Uid="NewTabMenu_AddFolder"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="5">
|
||||
<TextBox x:Name="FolderNameTextBox"
|
||||
x:Uid="NewTabMenu_AddFolder_FolderName"
|
||||
MinWidth="{StaticResource StandardBoxMinWidth}"
|
||||
KeyDown="AddFolderNameTextBox_KeyDown"
|
||||
Text="{x:Bind ViewModel.AddFolderName, Mode=TwoWay}"
|
||||
TextChanged="AddFolderNameTextBox_TextChanged" />
|
||||
<Button x:Name="AddFolderButton"
|
||||
x:Uid="NewTabMenu_AddFolderButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddFolderButton_Clicked"
|
||||
IsEnabled="False">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
<!-- Add Profile -->
|
||||
<local:SettingContainer x:Name="AddProfile"
|
||||
x:Uid="NewTabMenu_AddProfile"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
|
||||
<!-- Add Match Profiles -->
|
||||
<local:SettingContainer x:Name="AddMatchProfiles"
|
||||
x:Uid="NewTabMenu_AddMatchProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithIcon}">
|
||||
<StackPanel Spacing="8">
|
||||
<HyperlinkButton x:Uid="NewTabMenu_AddMatchProfiles_Help"
|
||||
NavigateUri="https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Name"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherName, Mode=TwoWay}" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Source"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherSource, Mode=TwoWay}" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Commandline"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherCommandline, Mode=TwoWay}" />
|
||||
<Button x:Name="AddMatchProfilesButton"
|
||||
Click="AddMatchProfilesButton_Clicked">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="4">
|
||||
<!-- Select profile to add -->
|
||||
<ComboBox x:Name="AddProfileComboBox"
|
||||
MinWidth="{StaticResource StandardBoxMinWidth}"
|
||||
ItemsSource="{x:Bind ViewModel.AvailableProfiles, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.SelectedProfile, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model:Profile">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- profile name -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind Name}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<Button x:Name="AddProfileButton"
|
||||
x:Uid="NewTabMenu_AddProfileButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddProfileButton_Clicked">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Separator -->
|
||||
<local:SettingContainer x:Name="AddSeparator"
|
||||
x:Uid="NewTabMenu_AddSeparator"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddSeparatorButton"
|
||||
x:Uid="NewTabMenu_AddSeparatorButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddSeparatorButton_Clicked">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_AddMatchProfilesTextBlock"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Remaining Profiles -->
|
||||
<local:SettingContainer x:Name="AddRemainingProfiles"
|
||||
x:Uid="NewTabMenu_AddRemainingProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddRemainingProfilesButton"
|
||||
x:Uid="NewTabMenu_AddRemainingProfilesButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddRemainingProfilesButton_Clicked"
|
||||
IsEnabled="{x:Bind ViewModel.IsRemainingProfilesEntryMissing, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
<!-- Add Folder -->
|
||||
<local:SettingContainer x:Name="AddFolder"
|
||||
x:Uid="NewTabMenu_AddFolder"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="5">
|
||||
<TextBox x:Name="FolderNameTextBox"
|
||||
x:Uid="NewTabMenu_AddFolder_FolderName"
|
||||
MinWidth="{StaticResource StandardBoxMinWidth}"
|
||||
KeyDown="AddFolderNameTextBox_KeyDown"
|
||||
Text="{x:Bind ViewModel.AddFolderName, Mode=TwoWay}"
|
||||
TextChanged="AddFolderNameTextBox_TextChanged" />
|
||||
<Button x:Name="AddFolderButton"
|
||||
x:Uid="NewTabMenu_AddFolderButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddFolderButton_Clicked"
|
||||
IsEnabled="False">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Match Profiles -->
|
||||
<local:SettingContainer x:Name="AddMatchProfiles"
|
||||
x:Uid="NewTabMenu_AddMatchProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithIcon}">
|
||||
<StackPanel Spacing="8">
|
||||
<HyperlinkButton x:Uid="NewTabMenu_AddMatchProfiles_Help"
|
||||
NavigateUri="https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Name"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherName, Mode=TwoWay}" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Source"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherSource, Mode=TwoWay}" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Commandline"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherCommandline, Mode=TwoWay}" />
|
||||
<Button x:Name="AddMatchProfilesButton"
|
||||
Click="AddMatchProfilesButton_Clicked">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_AddMatchProfilesTextBlock"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Remaining Profiles -->
|
||||
<local:SettingContainer x:Name="AddRemainingProfiles"
|
||||
x:Uid="NewTabMenu_AddRemainingProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddRemainingProfilesButton"
|
||||
x:Uid="NewTabMenu_AddRemainingProfilesButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddRemainingProfilesButton_Clicked"
|
||||
IsEnabled="{x:Bind ViewModel.IsRemainingProfilesEntryMissing, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup>
|
||||
<!-- Wide: 2 columns, controls on left with leading icons, preview on right. -->
|
||||
<VisualState x:Name="Wide">
|
||||
<VisualState.StateTriggers>
|
||||
<AdaptiveTrigger MinWindowWidth="1200" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="AddProfile.Style" Value="{StaticResource SettingContainerWithIcon}" />
|
||||
<Setter Target="AddSeparator.Style" Value="{StaticResource SettingContainerWithIcon}" />
|
||||
<Setter Target="AddFolder.Style" Value="{StaticResource SettingContainerWithIcon}" />
|
||||
<Setter Target="AddMatchProfiles.Style" Value="{StaticResource ExpanderSettingContainerStyleWithIcon}" />
|
||||
<Setter Target="AddRemainingProfiles.Style" Value="{StaticResource SettingContainerWithIcon}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<!-- Medium: 2 columns, controls on left WITHOUT leading icons, preview on right. -->
|
||||
<VisualState x:Name="Medium">
|
||||
<VisualState.StateTriggers>
|
||||
<AdaptiveTrigger MinWindowWidth="900" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="AddProfile.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddSeparator.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddFolder.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddMatchProfiles.Style" Value="{StaticResource ExpanderSettingContainerStyle}" />
|
||||
<Setter Target="AddRemainingProfiles.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<!-- Narrow: single column, preview stacked on top, controls below, no icons. -->
|
||||
<VisualState x:Name="Narrow">
|
||||
<VisualState.StateTriggers>
|
||||
<AdaptiveTrigger MinWindowWidth="0" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<!-- Collapse the preview column and give the preview row real height so the rows are used instead of the columns. -->
|
||||
<Setter Target="PreviewColumn.Width" Value="0" />
|
||||
<Setter Target="PreviewRow.Height" Value="Auto" />
|
||||
|
||||
<!-- Move PreviewArea to row 0, spanning both columns. -->
|
||||
<Setter Target="PreviewArea.(Grid.Row)" Value="0" />
|
||||
<Setter Target="PreviewArea.(Grid.RowSpan)" Value="1" />
|
||||
<Setter Target="PreviewArea.(Grid.Column)" Value="0" />
|
||||
<Setter Target="PreviewArea.(Grid.ColumnSpan)" Value="2" />
|
||||
|
||||
<!-- Move ControlsArea to row 1, spanning both columns. -->
|
||||
<Setter Target="ControlsArea.(Grid.Row)" Value="1" />
|
||||
<Setter Target="ControlsArea.(Grid.RowSpan)" Value="1" />
|
||||
<Setter Target="ControlsArea.(Grid.Column)" Value="0" />
|
||||
<Setter Target="ControlsArea.(Grid.ColumnSpan)" Value="2" />
|
||||
|
||||
<!-- No icons in the narrow state either (progressive simplification). -->
|
||||
<Setter Target="AddProfile.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddSeparator.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddFolder.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddMatchProfiles.Style" Value="{StaticResource ExpanderSettingContainerStyle}" />
|
||||
<Setter Target="AddRemainingProfiles.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
|
||||
<!-- Hide the preview header placeholder in stacked mode (no controls beside the preview to align with). -->
|
||||
<Setter Target="PreviewHeaderPlaceholder.Visibility" Value="Collapsed" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</Page>
|
||||
|
||||
@@ -106,6 +106,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
_NotifyChanges(L"CurrentPathTranslationStyle");
|
||||
}
|
||||
else if (viewModelProperty == L"NotifyOnActivity")
|
||||
{
|
||||
_NotifyChanges(L"IsNotifyOnActivityFlagSet", L"NotifyOnActivityPreview");
|
||||
}
|
||||
else if (viewModelProperty == L"NotifyOnNextPrompt")
|
||||
{
|
||||
_NotifyChanges(L"IsNotifyOnNextPromptFlagSet", L"NotifyOnNextPromptPreview");
|
||||
}
|
||||
else if (viewModelProperty == L"Padding")
|
||||
{
|
||||
_parsedPadding = StringToXamlThickness(_profile.Padding());
|
||||
@@ -127,6 +135,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
_NotifyChanges(L"TabColorPreview");
|
||||
}
|
||||
else if (viewModelProperty == L"Name" || viewModelProperty == L"IsBaseLayer")
|
||||
{
|
||||
_NotifyChanges(L"SectionHeaderText");
|
||||
}
|
||||
});
|
||||
|
||||
_defaultAppearanceViewModel.PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
|
||||
@@ -357,6 +369,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return RS_(L"Profile_TabTitleNone");
|
||||
}
|
||||
|
||||
hstring ProfileViewModel::SectionHeaderText() const
|
||||
{
|
||||
if (IsBaseLayer())
|
||||
{
|
||||
return RS_(L"Profile_DefaultsSectionHeader");
|
||||
}
|
||||
return hstring{ RS_fmt(L"Profile_NameSectionHeaderFormat", Name()) };
|
||||
}
|
||||
|
||||
hstring ProfileViewModel::AnswerbackMessagePreview() const
|
||||
{
|
||||
if (const auto answerbackMessage{ AnswerbackMessage() }; !answerbackMessage.empty())
|
||||
@@ -571,6 +592,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return iconPath.empty() || iconPath == IconPicker::HideIconValue;
|
||||
}
|
||||
|
||||
#pragma region BellStyle
|
||||
hstring ProfileViewModel::BellStylePreview() const
|
||||
{
|
||||
const auto bellStyle = BellStyle();
|
||||
@@ -650,6 +672,147 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
WI_UpdateFlag(currentStyle, Model::BellStyle::Notification, winrt::unbox_value<bool>(on));
|
||||
BellStyle(currentStyle);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region NotifyOnActivity
|
||||
hstring ProfileViewModel::NotifyOnActivityPreview() const
|
||||
{
|
||||
using Ons = Control::OutputNotificationStyle;
|
||||
const auto style = NotifyOnActivity();
|
||||
if (WI_AreAllFlagsSet(style, Ons::Taskbar | Ons::Audible | Ons::Tab | Ons::Notification))
|
||||
{
|
||||
return RS_(L"Profile_OutputNotificationStyleAll/Content");
|
||||
}
|
||||
else if (style == Ons::None)
|
||||
{
|
||||
return RS_(L"Profile_OutputNotificationStyleNone/Content");
|
||||
}
|
||||
|
||||
std::wstring result;
|
||||
const auto appendIfFlagSet = [&](Ons flag, std::wstring_view resource) {
|
||||
// WI_IsFlagSet requires a compile-time constant flag; `flag` is a runtime parameter here.
|
||||
if ((WI_EnumValue(style) & WI_EnumValue(flag)) != 0)
|
||||
{
|
||||
if (!result.empty())
|
||||
{
|
||||
result.append(L", ");
|
||||
}
|
||||
result.append(resource);
|
||||
}
|
||||
};
|
||||
|
||||
appendIfFlagSet(Ons::Taskbar, RS_(L"Profile_OutputNotificationStyleTaskbar/Content"));
|
||||
appendIfFlagSet(Ons::Audible, RS_(L"Profile_OutputNotificationStyleAudible/Content"));
|
||||
appendIfFlagSet(Ons::Tab, RS_(L"Profile_OutputNotificationStyleTab/Content"));
|
||||
appendIfFlagSet(Ons::Notification, RS_(L"Profile_OutputNotificationStyleNotification/Content"));
|
||||
|
||||
return hstring{ result };
|
||||
}
|
||||
|
||||
bool ProfileViewModel::IsNotifyOnActivityFlagSet(const uint32_t flag)
|
||||
{
|
||||
return (WI_EnumValue(NotifyOnActivity()) & flag) == flag;
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnActivityTaskbar(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnActivity();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Taskbar, winrt::unbox_value<bool>(on));
|
||||
NotifyOnActivity(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnActivityAudible(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnActivity();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Audible, winrt::unbox_value<bool>(on));
|
||||
NotifyOnActivity(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnActivityTab(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnActivity();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Tab, winrt::unbox_value<bool>(on));
|
||||
NotifyOnActivity(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnActivityNotification(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnActivity();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Notification, winrt::unbox_value<bool>(on));
|
||||
NotifyOnActivity(currentStyle);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region NotifyOnNextPrompt
|
||||
hstring ProfileViewModel::NotifyOnNextPromptPreview() const
|
||||
{
|
||||
using Ons = Control::OutputNotificationStyle;
|
||||
const auto style = NotifyOnNextPrompt();
|
||||
if (WI_AreAllFlagsSet(style, Ons::Taskbar | Ons::Audible | Ons::Tab | Ons::Notification))
|
||||
{
|
||||
return RS_(L"Profile_OutputNotificationStyleAll/Content");
|
||||
}
|
||||
else if (style == Ons::None)
|
||||
{
|
||||
return RS_(L"Profile_OutputNotificationStyleNone/Content");
|
||||
}
|
||||
|
||||
std::wstring result;
|
||||
const auto appendIfFlagSet = [&](Ons flag, std::wstring_view resource) {
|
||||
// WI_IsFlagSet requires a compile-time constant flag; `flag` is a runtime parameter here.
|
||||
if ((WI_EnumValue(style) & WI_EnumValue(flag)) != 0)
|
||||
{
|
||||
if (!result.empty())
|
||||
{
|
||||
result.append(L", ");
|
||||
}
|
||||
result.append(resource);
|
||||
}
|
||||
};
|
||||
|
||||
appendIfFlagSet(Ons::Taskbar, RS_(L"Profile_OutputNotificationStyleTaskbar/Content"));
|
||||
appendIfFlagSet(Ons::Audible, RS_(L"Profile_OutputNotificationStyleAudible/Content"));
|
||||
appendIfFlagSet(Ons::Tab, RS_(L"Profile_OutputNotificationStyleTab/Content"));
|
||||
appendIfFlagSet(Ons::Notification, RS_(L"Profile_OutputNotificationStyleNotification/Content"));
|
||||
|
||||
return hstring{ result };
|
||||
}
|
||||
|
||||
bool ProfileViewModel::IsNotifyOnNextPromptFlagSet(const uint32_t flag)
|
||||
{
|
||||
return (WI_EnumValue(NotifyOnNextPrompt()) & flag) == flag;
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnNextPromptTaskbar(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnNextPrompt();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Taskbar, winrt::unbox_value<bool>(on));
|
||||
NotifyOnNextPrompt(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnNextPromptAudible(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnNextPrompt();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Audible, winrt::unbox_value<bool>(on));
|
||||
NotifyOnNextPrompt(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnNextPromptTab(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnNextPrompt();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Tab, winrt::unbox_value<bool>(on));
|
||||
NotifyOnNextPrompt(currentStyle);
|
||||
}
|
||||
|
||||
void ProfileViewModel::SetNotifyOnNextPromptNotification(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto currentStyle = NotifyOnNextPrompt();
|
||||
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Notification, winrt::unbox_value<bool>(on));
|
||||
NotifyOnNextPrompt(currentStyle);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region BellSound
|
||||
|
||||
// Method Description:
|
||||
// - Construct _CurrentBellSounds by importing the _inherited_ value from the model
|
||||
@@ -788,6 +951,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_NotifyChanges(L"CurrentBellSounds");
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
void ProfileViewModel::DeleteProfile()
|
||||
{
|
||||
|
||||
@@ -48,6 +48,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void SetBellStyleTaskbar(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetBellStyleNotification(winrt::Windows::Foundation::IReference<bool> on);
|
||||
|
||||
// notify on activity bits
|
||||
hstring NotifyOnActivityPreview() const;
|
||||
bool IsNotifyOnActivityFlagSet(const uint32_t flag);
|
||||
void SetNotifyOnActivityTaskbar(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnActivityAudible(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnActivityTab(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnActivityNotification(winrt::Windows::Foundation::IReference<bool> on);
|
||||
|
||||
// notify on next prompt bits
|
||||
hstring NotifyOnNextPromptPreview() const;
|
||||
bool IsNotifyOnNextPromptFlagSet(const uint32_t flag);
|
||||
void SetNotifyOnNextPromptTaskbar(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnNextPromptAudible(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnNextPromptTab(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetNotifyOnNextPromptNotification(winrt::Windows::Foundation::IReference<bool> on);
|
||||
|
||||
hstring BellSoundPreview();
|
||||
void RequestAddBellSound(hstring path);
|
||||
void RequestDeleteBellSound(const Editor::BellSoundViewModel& vm);
|
||||
@@ -100,6 +116,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
bool AutoMarkPromptsAvailable() const noexcept;
|
||||
bool RepositionCursorWithMouseAvailable() const noexcept;
|
||||
|
||||
hstring SectionHeaderText() const;
|
||||
bool Orphaned() const;
|
||||
hstring TabTitlePreview() const;
|
||||
hstring AnswerbackMessagePreview() const;
|
||||
@@ -143,10 +160,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AllowKittyKeyboardMode);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtChecksumReport);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtClipboardWrite);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AllowOscNotifications);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AnswerbackMessage);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, RainbowSuggestions);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, PathTranslationStyle);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, DragDropDelimiter);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, NotifyOnActivity);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, NotifyOnNextPrompt);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, NotifyOnActivityThreshold);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, NotifyOnNextPromptThreshold);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AutoDetectRunningCommand);
|
||||
|
||||
WINRT_PROPERTY(bool, IsBaseLayer, false);
|
||||
WINRT_PROPERTY(bool, FocusDeleteButton, false);
|
||||
|
||||
@@ -51,6 +51,20 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
void SetBellStyleTaskbar(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetBellStyleNotification(Windows.Foundation.IReference<Boolean> on);
|
||||
|
||||
String NotifyOnActivityPreview { get; };
|
||||
Boolean IsNotifyOnActivityFlagSet(UInt32 flag);
|
||||
void SetNotifyOnActivityTaskbar(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnActivityAudible(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnActivityTab(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnActivityNotification(Windows.Foundation.IReference<Boolean> on);
|
||||
|
||||
String NotifyOnNextPromptPreview { get; };
|
||||
Boolean IsNotifyOnNextPromptFlagSet(UInt32 flag);
|
||||
void SetNotifyOnNextPromptTaskbar(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnNextPromptAudible(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnNextPromptTab(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetNotifyOnNextPromptNotification(Windows.Foundation.IReference<Boolean> on);
|
||||
|
||||
String BellSoundPreview { get; };
|
||||
Windows.Foundation.Collections.IObservableVector<BellSoundViewModel> CurrentBellSounds { get; };
|
||||
void RequestAddBellSound(String path);
|
||||
@@ -105,6 +119,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
void CreateUnfocusedAppearance();
|
||||
void DeleteUnfocusedAppearance();
|
||||
|
||||
String SectionHeaderText { get; };
|
||||
Boolean Orphaned { get; };
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Name);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Guid, Guid);
|
||||
@@ -142,5 +157,11 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, DragDropDelimiter);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowOscNotifications);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.OutputNotificationStyle, NotifyOnActivity);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.OutputNotificationStyle, NotifyOnNextPrompt);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Int32, NotifyOnActivityThreshold);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Int32, NotifyOnNextPromptThreshold);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AutoDetectRunningCommand);
|
||||
}
|
||||
}
|
||||
|
||||
94
src/cascadia/TerminalSettingsEditor/Profiles.cpp
Normal file
94
src/cascadia/TerminalSettingsEditor/Profiles.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "Profiles.h"
|
||||
#include "Profiles.g.cpp"
|
||||
#include "ProfilesPageViewModel.g.cpp"
|
||||
#include "ProfileViewModel.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
Profiles::Profiles()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Automation::AutomationProperties::SetName(DefaultsNavigator(), RS_(L"Profiles_DefaultsNavigator_Title/Text"));
|
||||
Automation::AutomationProperties::SetName(ColorSchemesNavigator(), RS_(L"Profiles_ColorSchemesNavigator_Title/Text"));
|
||||
Automation::AutomationProperties::SetName(AddProfileButton(), RS_(L"Profiles_AddProfileButton/Text"));
|
||||
}
|
||||
|
||||
void Profiles::OnNavigatedTo(const NavigationEventArgs& e)
|
||||
{
|
||||
const auto args = e.Parameter().as<Editor::NavigateToPageArgs>();
|
||||
_ViewModel = args.ViewModel().as<Editor::ProfilesPageViewModel>();
|
||||
BringIntoViewWhenLoaded(args.ElementToFocus());
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalSettingsEditorProvider,
|
||||
"NavigatedToPage",
|
||||
TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
|
||||
TraceLoggingValue("profilesLanding", "PageId", "The identifier of the page that was navigated to"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
void Profiles::Defaults_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
_ViewModel.RequestOpenDefaults();
|
||||
}
|
||||
|
||||
void Profiles::ColorSchemes_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
_ViewModel.RequestOpenColorSchemes();
|
||||
}
|
||||
|
||||
void Profiles::AddProfile_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
_ViewModel.RequestAddProfile();
|
||||
}
|
||||
|
||||
void Profiles::Profile_Click(const IInspectable& sender, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
// Profile navigators are buttons whose DataContext is the bound ProfileViewModel.
|
||||
if (const auto element = sender.try_as<FrameworkElement>())
|
||||
{
|
||||
if (const auto profile = element.DataContext().try_as<Editor::ProfileViewModel>())
|
||||
{
|
||||
_ViewModel.RequestOpenProfile(profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProfilesPageViewModel::ProfilesPageViewModel()
|
||||
{
|
||||
_setProfiles(single_threaded_observable_vector<Editor::ProfileViewModel>());
|
||||
}
|
||||
|
||||
void ProfilesPageViewModel::RequestOpenDefaults()
|
||||
{
|
||||
OpenDefaultsRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ProfilesPageViewModel::RequestOpenColorSchemes()
|
||||
{
|
||||
OpenColorSchemesRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ProfilesPageViewModel::RequestAddProfile()
|
||||
{
|
||||
AddProfileRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ProfilesPageViewModel::RequestOpenProfile(const Editor::ProfileViewModel& profile)
|
||||
{
|
||||
OpenProfileRequested.raise(*this, profile);
|
||||
}
|
||||
|
||||
}
|
||||
67
src/cascadia/TerminalSettingsEditor/Profiles.h
Normal file
67
src/cascadia/TerminalSettingsEditor/Profiles.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- Profiles.h
|
||||
|
||||
Abstract:
|
||||
- The Profiles landing page in the Settings UI. The page hosts entry points to
|
||||
the list of individual profiles among other profile-related settings.
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Profiles.g.h"
|
||||
#include "ProfilesPageViewModel.g.h"
|
||||
#include "ProfileViewModel.h"
|
||||
#include "Utils.h"
|
||||
#include "ViewModelHelpers.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct ProfilesPageViewModel : ProfilesPageViewModelT<ProfilesPageViewModel>, ViewModelHelper<ProfilesPageViewModel>
|
||||
{
|
||||
public:
|
||||
ProfilesPageViewModel();
|
||||
|
||||
void RequestOpenDefaults();
|
||||
void RequestOpenColorSchemes();
|
||||
void RequestAddProfile();
|
||||
void RequestOpenProfile(const Editor::ProfileViewModel& profile);
|
||||
|
||||
// DON'T YOU DARE ADD A `WINRT_CALLBACK(PropertyChanged` TO A CLASS DERIVED FROM ViewModelHelper. Do this instead:
|
||||
using ViewModelHelper<ProfilesPageViewModel>::PropertyChanged;
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::ProfileViewModel>, Profiles, _propertyChangedHandlers, nullptr);
|
||||
|
||||
public:
|
||||
til::typed_event<Windows::Foundation::IInspectable, Windows::Foundation::IInspectable> OpenDefaultsRequested;
|
||||
til::typed_event<Windows::Foundation::IInspectable, Windows::Foundation::IInspectable> OpenColorSchemesRequested;
|
||||
til::typed_event<Windows::Foundation::IInspectable, Windows::Foundation::IInspectable> AddProfileRequested;
|
||||
til::typed_event<Windows::Foundation::IInspectable, Editor::ProfileViewModel> OpenProfileRequested;
|
||||
};
|
||||
|
||||
struct Profiles : public HasScrollViewer<Profiles>, ProfilesT<Profiles>
|
||||
{
|
||||
public:
|
||||
Profiles();
|
||||
|
||||
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
||||
|
||||
void Defaults_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
void ColorSchemes_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
void AddProfile_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
void Profile_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_PROPERTY(Editor::ProfilesPageViewModel, ViewModel, nullptr);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Profiles);
|
||||
BASIC_FACTORY(ProfilesPageViewModel);
|
||||
}
|
||||
31
src/cascadia/TerminalSettingsEditor/Profiles.idl
Normal file
31
src/cascadia/TerminalSettingsEditor/Profiles.idl
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "ProfileViewModel.idl";
|
||||
import "ColorSchemeViewModel.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass ProfilesPageViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
ProfilesPageViewModel();
|
||||
|
||||
Windows.Foundation.Collections.IObservableVector<ProfileViewModel> Profiles { get; };
|
||||
|
||||
void RequestOpenDefaults();
|
||||
void RequestOpenColorSchemes();
|
||||
void RequestAddProfile();
|
||||
void RequestOpenProfile(ProfileViewModel profile);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, IInspectable> OpenDefaultsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, IInspectable> OpenColorSchemesRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, IInspectable> AddProfileRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ProfileViewModel> OpenProfileRequested;
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass Profiles : Windows.UI.Xaml.Controls.Page
|
||||
{
|
||||
Profiles();
|
||||
ProfilesPageViewModel ViewModel { get; };
|
||||
}
|
||||
}
|
||||
136
src/cascadia/TerminalSettingsEditor/Profiles.xaml
Normal file
136
src/cascadia/TerminalSettingsEditor/Profiles.xaml
Normal file
@@ -0,0 +1,136 @@
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<Page x:Class="Microsoft.Terminal.Settings.Editor.Profiles"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:model="using:Microsoft.Terminal.Settings.Model"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<DataTemplate x:Key="ProfileNavigatorTemplate"
|
||||
x:DataType="local:ProfileViewModel">
|
||||
<Button HorizontalAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind Name, Mode=OneWay}"
|
||||
Click="Profile_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}">
|
||||
<Grid ColumnSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentControl Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
VerticalAlignment="Center"
|
||||
Content="{x:Bind IconPreview, Mode=OneWay}"
|
||||
IsTabStop="False" />
|
||||
<TextBlock Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}"
|
||||
Text="{x:Bind Name, Mode=OneWay}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<muxc:InfoBadge Grid.Column="2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{x:Bind Hidden, Mode=OneWay}">
|
||||
<muxc:InfoBadge.IconSource>
|
||||
<muxc:FontIconSource FontFamily="Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph="" />
|
||||
</muxc:InfoBadge.IconSource>
|
||||
</muxc:InfoBadge>
|
||||
<muxc:InfoBadge Grid.Column="2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{x:Bind Orphaned, Mode=OneWay}">
|
||||
<muxc:InfoBadge.IconSource>
|
||||
<muxc:FontIconSource FontFamily="Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph="" />
|
||||
</muxc:InfoBadge.IconSource>
|
||||
</muxc:InfoBadge>
|
||||
</Grid>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
|
||||
<!-- General Profile Settings -->
|
||||
<TextBlock x:Uid="Profiles_GeneralSettingsHeader"
|
||||
Margin="0,0,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Defaults navigator -->
|
||||
<Button x:Name="DefaultsNavigator"
|
||||
Click="Defaults_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock x:Uid="Profiles_DefaultsNavigator_Title"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||
<TextBlock x:Uid="Profiles_DefaultsNavigator_Description"
|
||||
Margin="0,2,0,0"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<!-- Color schemes navigator -->
|
||||
<Button x:Name="ColorSchemesNavigator"
|
||||
Click="ColorSchemes_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock x:Uid="Profiles_ColorSchemesNavigator_Title"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}" />
|
||||
<TextBlock x:Uid="Profiles_ColorSchemesNavigator_Description"
|
||||
Margin="0,2,0,0"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<!-- Terminal profiles section -->
|
||||
<TextBlock x:Uid="Profiles_TerminalProfilesHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Add Profile accent button -->
|
||||
<Button x:Name="AddProfileButton"
|
||||
Margin="0,4,0,0"
|
||||
Click="AddProfile_Click"
|
||||
Style="{StaticResource AccentButtonStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Profiles_AddProfileButton"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<!-- List of profiles. Each is a NavigatorButtonStyle button rendered by ProfileNavigatorTemplate. -->
|
||||
<ItemsControl Margin="0,0,0,16"
|
||||
ItemTemplate="{StaticResource ProfileNavigatorTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.Profiles, Mode=OneWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Vertical" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
@@ -198,6 +198,84 @@
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Notify On Activity -->
|
||||
<local:SettingContainer x:Name="NotifyOnActivity"
|
||||
x:Uid="Profile_NotifyOnActivity"
|
||||
ClearSettingValue="{x:Bind Profile.ClearNotifyOnActivity}"
|
||||
CurrentValue="{x:Bind Profile.NotifyOnActivityPreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasNotifyOnActivity, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.NotifyOnActivityOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleTaskbar"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnActivityFlagSet(1), BindBack=Profile.SetNotifyOnActivityTaskbar, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleAudible"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnActivityFlagSet(2), BindBack=Profile.SetNotifyOnActivityAudible, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleTab"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnActivityFlagSet(4), BindBack=Profile.SetNotifyOnActivityTab, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleNotification"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnActivityFlagSet(8), BindBack=Profile.SetNotifyOnActivityNotification, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Notify On Activity Minimum Duration -->
|
||||
<local:SettingContainer x:Name="NotifyOnActivityThreshold"
|
||||
x:Uid="Profile_NotifyOnActivityThreshold"
|
||||
ClearSettingValue="{x:Bind Profile.ClearNotifyOnActivityThreshold}"
|
||||
HasSettingValue="{x:Bind Profile.HasNotifyOnActivityThreshold, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.NotifyOnActivityThresholdOverrideSource, Mode=OneWay}">
|
||||
<muxc:NumberBox AutomationProperties.Name="{Binding ElementName=NotifyOnActivityThreshold, Path=Header}"
|
||||
LargeChange="10"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind Profile.NotifyOnActivityThreshold, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Notify On Next Prompt -->
|
||||
<local:SettingContainer x:Name="NotifyOnNextPrompt"
|
||||
x:Uid="Profile_NotifyOnNextPrompt"
|
||||
ClearSettingValue="{x:Bind Profile.ClearNotifyOnNextPrompt}"
|
||||
CurrentValue="{x:Bind Profile.NotifyOnNextPromptPreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasNotifyOnNextPrompt, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.NotifyOnNextPromptOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleTaskbar"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(1), BindBack=Profile.SetNotifyOnNextPromptTaskbar, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleAudible"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(2), BindBack=Profile.SetNotifyOnNextPromptAudible, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleTab"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(4), BindBack=Profile.SetNotifyOnNextPromptTab, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Profile_OutputNotificationStyleNotification"
|
||||
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(8), BindBack=Profile.SetNotifyOnNextPromptNotification, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Notify On Next Prompt Minimum Duration -->
|
||||
<local:SettingContainer x:Name="NotifyOnNextPromptThreshold"
|
||||
x:Uid="Profile_NotifyOnNextPromptThreshold"
|
||||
ClearSettingValue="{x:Bind Profile.ClearNotifyOnNextPromptThreshold}"
|
||||
HasSettingValue="{x:Bind Profile.HasNotifyOnNextPromptThreshold, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.NotifyOnNextPromptThresholdOverrideSource, Mode=OneWay}">
|
||||
<muxc:NumberBox AutomationProperties.Name="{Binding ElementName=NotifyOnNextPromptThreshold, Path=Header}"
|
||||
LargeChange="10"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind Profile.NotifyOnNextPromptThreshold, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Auto Detect Running Command -->
|
||||
<local:SettingContainer x:Name="AutoDetectRunningCommand"
|
||||
x:Uid="Profile_AutoDetectRunningCommand"
|
||||
ClearSettingValue="{x:Bind Profile.ClearAutoDetectRunningCommand}"
|
||||
HasSettingValue="{x:Bind Profile.HasAutoDetectRunningCommand, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.AutoDetectRunningCommandOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.AutoDetectRunningCommand, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- RightClickContextMenu -->
|
||||
<local:SettingContainer x:Name="RightClickContextMenu"
|
||||
x:Uid="Profile_RightClickContextMenu"
|
||||
|
||||
@@ -80,131 +80,124 @@
|
||||
SourceProfile="{x:Bind Profile, Mode=OneWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneTime}" />
|
||||
|
||||
<!-- Grouping: Transparency -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_TransparencyHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Section: Window settings -->
|
||||
<local:SettingContainer x:Uid="Profile_Section_Window"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Opacity -->
|
||||
<local:SettingContainer x:Name="Opacity"
|
||||
x:Uid="Profile_Opacity"
|
||||
ClearSettingValue="{x:Bind Profile.ClearOpacity}"
|
||||
HasSettingValue="{x:Bind Profile.HasOpacity, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.OpacityOverrideSource, Mode=OneWay}">
|
||||
<StackPanel>
|
||||
<Grid Style="{StaticResource CustomSliderControlGridStyle}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Slider x:Uid="Profile_OpacitySlider"
|
||||
Grid.Column="0"
|
||||
Value="{x:Bind mtu:Converters.PercentageToPercentageValue(Profile.Opacity), BindBack=Profile.SetAcrylicOpacityPercentageValue, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Style="{StaticResource SliderValueLabelStyle}"
|
||||
Text="{x:Bind mtu:Converters.PercentageToPercentageString(Profile.Opacity), Mode=OneWay}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Opacity -->
|
||||
<local:SettingContainer x:Name="Opacity"
|
||||
x:Uid="Profile_Opacity"
|
||||
ClearSettingValue="{x:Bind Profile.ClearOpacity}"
|
||||
HasSettingValue="{x:Bind Profile.HasOpacity, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.OpacityOverrideSource, Mode=OneWay}">
|
||||
<StackPanel>
|
||||
<Grid Style="{StaticResource CustomSliderControlGridStyle}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Slider x:Uid="Profile_OpacitySlider"
|
||||
Grid.Column="0"
|
||||
Value="{x:Bind mtu:Converters.PercentageToPercentageValue(Profile.Opacity), BindBack=Profile.SetAcrylicOpacityPercentageValue, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Style="{StaticResource SliderValueLabelStyle}"
|
||||
Text="{x:Bind mtu:Converters.PercentageToPercentageString(Profile.Opacity), Mode=OneWay}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
<!-- Use Acrylic -->
|
||||
<local:SettingContainer x:Name="UseAcrylic"
|
||||
x:Uid="Profile_UseAcrylic"
|
||||
ClearSettingValue="{x:Bind Profile.ClearUseAcrylic}"
|
||||
HasSettingValue="{x:Bind Profile.HasUseAcrylic, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.UseAcrylicOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.UseAcrylic, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Use Acrylic -->
|
||||
<local:SettingContainer x:Name="UseAcrylic"
|
||||
x:Uid="Profile_UseAcrylic"
|
||||
ClearSettingValue="{x:Bind Profile.ClearUseAcrylic}"
|
||||
HasSettingValue="{x:Bind Profile.HasUseAcrylic, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.UseAcrylicOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.UseAcrylic, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Padding -->
|
||||
<local:SettingContainer x:Name="Padding"
|
||||
x:Uid="Profile_Padding"
|
||||
ClearSettingValue="{x:Bind Profile.ClearPadding}"
|
||||
CurrentValue="{x:Bind Profile.Padding, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasPadding, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.PaddingOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Border Margin="0,12,0,12"
|
||||
Padding="2,0,2,0"
|
||||
HorizontalAlignment="Left"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultSolidBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{StaticResource OverlayCornerRadius}">
|
||||
<Grid>
|
||||
|
||||
</StackPanel>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="48" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Grouping: Window -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_WindowHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="72" />
|
||||
<ColumnDefinition Width="72" />
|
||||
<ColumnDefinition Width="72" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Padding -->
|
||||
<local:SettingContainer x:Name="Padding"
|
||||
x:Uid="Profile_Padding"
|
||||
ClearSettingValue="{x:Bind Profile.ClearPadding}"
|
||||
CurrentValue="{x:Bind Profile.Padding, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasPadding, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.PaddingOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Border Margin="0,12,0,12"
|
||||
Padding="2,0,2,0"
|
||||
HorizontalAlignment="Left"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultSolidBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{StaticResource OverlayCornerRadius}">
|
||||
<Grid>
|
||||
<muxc:NumberBox Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
LargeChange="10"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource PaddingNumberBoxStyle}"
|
||||
Value="{x:Bind Profile.LeftPadding, Mode=TwoWay}" />
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="48" />
|
||||
</Grid.RowDefinitions>
|
||||
<muxc:NumberBox Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
LargeChange="10"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource PaddingNumberBoxStyle}"
|
||||
Value="{x:Bind Profile.TopPadding, Mode=TwoWay}" />
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="72" />
|
||||
<ColumnDefinition Width="72" />
|
||||
<ColumnDefinition Width="72" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<muxc:NumberBox Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
LargeChange="10"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource PaddingNumberBoxStyle}"
|
||||
Value="{x:Bind Profile.RightPadding, Mode=TwoWay}" />
|
||||
|
||||
<muxc:NumberBox Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
LargeChange="10"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource PaddingNumberBoxStyle}"
|
||||
Value="{x:Bind Profile.LeftPadding, Mode=TwoWay}" />
|
||||
<muxc:NumberBox Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
LargeChange="10"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource PaddingNumberBoxStyle}"
|
||||
Value="{x:Bind Profile.BottomPadding, Mode=TwoWay}" />
|
||||
|
||||
<muxc:NumberBox Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
LargeChange="10"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource PaddingNumberBoxStyle}"
|
||||
Value="{x:Bind Profile.TopPadding, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</local:SettingContainer>
|
||||
|
||||
<muxc:NumberBox Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
LargeChange="10"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource PaddingNumberBoxStyle}"
|
||||
Value="{x:Bind Profile.RightPadding, Mode=TwoWay}" />
|
||||
|
||||
<muxc:NumberBox Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
LargeChange="10"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource PaddingNumberBoxStyle}"
|
||||
Value="{x:Bind Profile.BottomPadding, Mode=TwoWay}" />
|
||||
|
||||
</Grid>
|
||||
</Border>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Scrollbar Visibility -->
|
||||
<local:SettingContainer x:Name="ScrollbarVisibility"
|
||||
x:Uid="Profile_ScrollbarVisibility"
|
||||
ClearSettingValue="{x:Bind Profile.ClearScrollState}"
|
||||
HasSettingValue="{x:Bind Profile.HasScrollState, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.ScrollStateOverrideSource, Mode=OneWay}">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind Profile.ScrollStateList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind Profile.CurrentScrollState, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
<!-- Scrollbar Visibility -->
|
||||
<local:SettingContainer x:Name="ScrollbarVisibility"
|
||||
x:Uid="Profile_ScrollbarVisibility"
|
||||
ClearSettingValue="{x:Bind Profile.ClearScrollState}"
|
||||
HasSettingValue="{x:Bind Profile.HasScrollState, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.ScrollStateOverrideSource, Mode=OneWay}">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind Profile.ScrollStateList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind Profile.CurrentScrollState, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
<StackPanel MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Visibility="{x:Bind Profile.EditableUnfocusedAppearance, Mode=OneWay}">
|
||||
|
||||
@@ -23,7 +23,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
Automation::AutomationProperties::SetName(DeleteButton(), RS_(L"Profile_DeleteButton/Text"));
|
||||
AppearanceNavigator().Content(box_value(RS_(L"Profile_Appearance/Header")));
|
||||
AppearanceNavigator().Tag(box_value(RS_(L"Profile_AppearanceNavigator/HelpText")));
|
||||
TerminalNavigator().Content(box_value(RS_(L"Profile_Terminal/Header")));
|
||||
TerminalNavigator().Tag(box_value(RS_(L"Profile_TerminalNavigator/HelpText")));
|
||||
AdvancedNavigator().Content(box_value(RS_(L"Profile_Advanced/Header")));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,147 +34,161 @@
|
||||
<StackPanel Grid.Row="1"
|
||||
Style="{StaticResource SettingsStackStyle}">
|
||||
|
||||
<!-- Name -->
|
||||
<!--
|
||||
NOTE: Has/Clear is not bound because we don't want the reset button & override text to appear.
|
||||
Additionally, the JSON stubs generated by auto-generated profiles come with a name,
|
||||
so the name will always be overridden.
|
||||
-->
|
||||
<local:SettingContainer x:Name="Name"
|
||||
x:Uid="Profile_Name"
|
||||
CurrentValue="{x:Bind Profile.Name, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Name, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Commandline -->
|
||||
<local:SettingContainer x:Name="Commandline"
|
||||
x:Uid="Profile_Commandline"
|
||||
ClearSettingValue="{x:Bind Profile.ClearCommandline}"
|
||||
CurrentValue="{x:Bind Profile.Commandline, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasCommandline, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.CommandlineOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<!-- Section: {Profile.Name} profile (or "Profile defaults") -->
|
||||
<local:SettingContainer x:Uid="Profile_Section_HeaderPlaceholder"
|
||||
Header="{x:Bind Profile.SectionHeaderText, Mode=OneWay}"
|
||||
StartExpanded="True"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<TextBox x:Uid="Profile_CommandlineBox"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Commandline, Mode=TwoWay}" />
|
||||
<Button x:Uid="Profile_CommandlineBrowse"
|
||||
Margin="0,8,0,0"
|
||||
Click="Commandline_Click"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
<!-- Name -->
|
||||
<!--
|
||||
NOTE: Has/Clear is not bound because we don't want the reset button & override text to appear.
|
||||
Additionally, the JSON stubs generated by auto-generated profiles come with a name,
|
||||
so the name will always be overridden.
|
||||
-->
|
||||
<local:SettingContainer x:Name="Name"
|
||||
x:Uid="Profile_Name"
|
||||
CurrentValue="{x:Bind Profile.Name, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Name, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Commandline -->
|
||||
<local:SettingContainer x:Name="Commandline"
|
||||
x:Uid="Profile_Commandline"
|
||||
ClearSettingValue="{x:Bind Profile.ClearCommandline}"
|
||||
CurrentValue="{x:Bind Profile.Commandline, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasCommandline, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.CommandlineOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<StackPanel>
|
||||
<TextBox x:Uid="Profile_CommandlineBox"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Commandline, Mode=TwoWay}" />
|
||||
<Button x:Uid="Profile_CommandlineBrowse"
|
||||
Margin="0,8,0,0"
|
||||
Click="Commandline_Click"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Starting Directory -->
|
||||
<local:SettingContainer x:Name="StartingDirectory"
|
||||
x:Uid="Profile_StartingDirectory"
|
||||
ClearSettingValue="{x:Bind Profile.ClearStartingDirectory}"
|
||||
CurrentValue="{x:Bind Profile.CurrentStartingDirectoryPreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasStartingDirectory, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.StartingDirectoryOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBox x:Uid="Profile_StartingDirectoryBox"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.UseParentProcessDirectory), Mode=OneWay}"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.StartingDirectory, Mode=TwoWay}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Name="StartingDirectoryBrowse"
|
||||
x:Uid="Profile_StartingDirectoryBrowse"
|
||||
Margin="0,12,12,0"
|
||||
Click="StartingDirectory_Click"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.UseParentProcessDirectory), Mode=OneWay}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
<CheckBox x:Name="StartingDirectoryUseParentCheckbox"
|
||||
x:Uid="Profile_StartingDirectoryUseParentCheckbox"
|
||||
Margin="0,4,0,0"
|
||||
IsChecked="{x:Bind Profile.UseParentProcessDirectory, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Elevate -->
|
||||
<local:SettingContainer x:Name="Elevate"
|
||||
x:Uid="Profile_Elevate"
|
||||
ClearSettingValue="{x:Bind Profile.ClearElevate}"
|
||||
HasSettingValue="{x:Bind Profile.HasElevate, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.ElevateOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.Elevate, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Starting Directory -->
|
||||
<local:SettingContainer x:Name="StartingDirectory"
|
||||
x:Uid="Profile_StartingDirectory"
|
||||
ClearSettingValue="{x:Bind Profile.ClearStartingDirectory}"
|
||||
CurrentValue="{x:Bind Profile.CurrentStartingDirectoryPreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasStartingDirectory, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.StartingDirectoryOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBox x:Uid="Profile_StartingDirectoryBox"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.UseParentProcessDirectory), Mode=OneWay}"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.StartingDirectory, Mode=TwoWay}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Name="StartingDirectoryBrowse"
|
||||
x:Uid="Profile_StartingDirectoryBrowse"
|
||||
Margin="0,12,12,0"
|
||||
Click="StartingDirectory_Click"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.UseParentProcessDirectory), Mode=OneWay}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
<CheckBox x:Name="StartingDirectoryUseParentCheckbox"
|
||||
x:Uid="Profile_StartingDirectoryUseParentCheckbox"
|
||||
Margin="0,4,0,0"
|
||||
IsChecked="{x:Bind Profile.UseParentProcessDirectory, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
<!-- Section: Visual/UI Affordance -->
|
||||
<local:SettingContainer x:Uid="Profile_Section_VisualUI"
|
||||
Style="{StaticResource SectionExpanderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Tab Title -->
|
||||
<local:SettingContainer x:Name="TabTitle"
|
||||
x:Uid="Profile_TabTitle"
|
||||
ClearSettingValue="{x:Bind Profile.ClearTabTitle}"
|
||||
CurrentValue="{x:Bind Profile.TabTitlePreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasTabTitle, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.TabTitleOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.TabTitle, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Color -->
|
||||
<local:SettingContainer x:Name="TabColor"
|
||||
x:Uid="Profile_TabColor"
|
||||
ClearSettingValue="{x:Bind Profile.ClearTabColor}"
|
||||
CurrentValue="{x:Bind Profile.TabColorPreview, Mode=OneWay}"
|
||||
CurrentValueAccessibleName="{x:Bind Profile.TabColorPreview, Converter={StaticResource ColorToStringConverter}, Mode=OneWay}"
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Profile.HasTabColor, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.TabColorOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:NullableColorPicker x:Uid="Profile_TabColor_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Profile.DefaultAppearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Profile.TabColor, Mode=TwoWay}"
|
||||
NullColorPreview="{x:Bind Profile.TabThemeColorPreview, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Icon -->
|
||||
<local:SettingContainer x:Name="Icon"
|
||||
x:Uid="Profile_Icon"
|
||||
ClearSettingValue="{x:Bind Profile.ClearIcon}"
|
||||
CurrentValueAccessibleName="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasIcon, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.IconOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
Height="16"
|
||||
Content="{x:Bind Profile.IconPreview, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.UsingNoIcon), Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
Visibility="{x:Bind Profile.UsingNoIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<local:IconPicker CurrentIconPath="{x:Bind Profile.IconPath, Mode=TwoWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Hidden -->
|
||||
<local:SettingContainer x:Name="Hidden"
|
||||
x:Uid="Profile_Hidden"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.Hidden, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Icon -->
|
||||
<local:SettingContainer x:Name="Icon"
|
||||
x:Uid="Profile_Icon"
|
||||
ClearSettingValue="{x:Bind Profile.ClearIcon}"
|
||||
CurrentValueAccessibleName="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasIcon, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.IconOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
Height="16"
|
||||
Content="{x:Bind Profile.IconPreview, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.UsingNoIcon), Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
Visibility="{x:Bind Profile.UsingNoIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<local:IconPicker CurrentIconPath="{x:Bind Profile.IconPath, Mode=TwoWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Title -->
|
||||
<local:SettingContainer x:Name="TabTitle"
|
||||
x:Uid="Profile_TabTitle"
|
||||
ClearSettingValue="{x:Bind Profile.ClearTabTitle}"
|
||||
CurrentValue="{x:Bind Profile.TabTitlePreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasTabTitle, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.TabTitleOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.TabTitle, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Color -->
|
||||
<local:SettingContainer x:Name="TabColor"
|
||||
x:Uid="Profile_TabColor"
|
||||
ClearSettingValue="{x:Bind Profile.ClearTabColor}"
|
||||
CurrentValue="{x:Bind Profile.TabColorPreview, Mode=OneWay}"
|
||||
CurrentValueAccessibleName="{x:Bind Profile.TabColorPreview, Converter={StaticResource ColorToStringConverter}, Mode=OneWay}"
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Profile.HasTabColor, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.TabColorOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:NullableColorPicker x:Uid="Profile_TabColor_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Profile.DefaultAppearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Profile.TabColor, Mode=TwoWay}"
|
||||
NullColorPreview="{x:Bind Profile.TabThemeColorPreview, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Elevate -->
|
||||
<local:SettingContainer x:Name="Elevate"
|
||||
x:Uid="Profile_Elevate"
|
||||
ClearSettingValue="{x:Bind Profile.ClearElevate}"
|
||||
HasSettingValue="{x:Bind Profile.HasElevate, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.ElevateOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.Elevate, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Hidden -->
|
||||
<local:SettingContainer x:Name="Hidden"
|
||||
x:Uid="Profile_Hidden"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.Hidden, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<TextBlock x:Uid="Profile_AdditionalSettingsHeader"
|
||||
Margin="0,32,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
@@ -81,6 +81,16 @@
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Allow OSC 777 Desktop Notifications -->
|
||||
<local:SettingContainer x:Name="AllowOscNotifications"
|
||||
x:Uid="Profile_AllowOscNotifications"
|
||||
ClearSettingValue="{x:Bind Profile.ClearAllowOscNotifications}"
|
||||
HasSettingValue="{x:Bind Profile.HasAllowOscNotifications, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.AllowOscNotificationsOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.AllowOscNotifications, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Answerback Message -->
|
||||
<local:SettingContainer x:Name="AnswerbackMessage"
|
||||
x:Uid="Profile_AnswerbackMessage"
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "Rendering.h"
|
||||
#include "Rendering.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
Rendering::Rendering()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
void Rendering::OnNavigatedTo(const NavigationEventArgs& e)
|
||||
{
|
||||
const auto args = e.Parameter().as<Editor::NavigateToPageArgs>();
|
||||
_ViewModel = args.ViewModel().as<Editor::RenderingViewModel>();
|
||||
BringIntoViewWhenLoaded(args.ElementToFocus());
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalSettingsEditorProvider,
|
||||
"NavigatedToPage",
|
||||
TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
|
||||
TraceLoggingValue("rendering", "PageId", "The identifier of the page that was navigated to"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Rendering.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct Rendering : public HasScrollViewer<Rendering>, RenderingT<Rendering>
|
||||
{
|
||||
Rendering();
|
||||
|
||||
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(Editor::RenderingViewModel, ViewModel, PropertyChanged.raise, nullptr);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Rendering);
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "RenderingViewModel.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass Rendering : Windows.UI.Xaml.Controls.Page
|
||||
{
|
||||
Rendering();
|
||||
RenderingViewModel ViewModel { get; };
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<Page x:Class="Microsoft.Terminal.Settings.Editor.Rendering"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<DataTemplate x:Key="EnumComboBoxTemplate"
|
||||
x:DataType="local:EnumEntry">
|
||||
<TextBlock Text="{x:Bind EnumName}" />
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<local:SettingContainer x:Name="GraphicsAPI"
|
||||
x:Uid="Globals_GraphicsAPI">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.GraphicsAPIList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentGraphicsAPI, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<local:SettingContainer x:Name="DisablePartialInvalidation"
|
||||
x:Uid="Globals_DisablePartialInvalidation">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DisablePartialInvalidation, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<local:SettingContainer x:Name="SoftwareRendering"
|
||||
x:Uid="Globals_SoftwareRendering">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SoftwareRendering, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "RenderingViewModel.h"
|
||||
|
||||
#include "EnumEntry.h"
|
||||
|
||||
#include "RenderingViewModel.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
RenderingViewModel::RenderingViewModel(CascadiaSettings settings) noexcept :
|
||||
_settings{ std::move(settings) }
|
||||
{
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(GraphicsAPI, GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, L"Globals_GraphicsAPI_", L"Text");
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RenderingViewModel.g.h"
|
||||
#include "Utils.h"
|
||||
#include "ViewModelHelpers.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct RenderingViewModel : RenderingViewModelT<RenderingViewModel>, ViewModelHelper<RenderingViewModel>
|
||||
{
|
||||
explicit RenderingViewModel(Model::CascadiaSettings settings) noexcept;
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, _settings.GlobalSettings().GraphicsAPI);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), SoftwareRendering);
|
||||
|
||||
private:
|
||||
Model::CascadiaSettings _settings{ nullptr };
|
||||
};
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(RenderingViewModel);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user