Implement InitialPosition and CenterOnLaunch in the SUI (#13605)

## Summary of the Pull Request
`InitialPosition` and `CenterOnLaunch` can now be edited in the SUI

## PR Checklist
* [x] Closes #9075 
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

## Detailed Description of the Pull Request / Additional comments
`InitialPosition` follows the same style as `LaunchSize`, with a number box for the x coordinate and a number box for the y coordinate. When there is no value for either of these coordinates, the respective number box is empty (and displays the text `Undefined`). 

## Validation Steps Performed
They work
This commit is contained in:
PankajBhojwani 2022-10-05 12:37:16 -07:00 committed by GitHub
parent 00cdacc96b
commit 40bc3d7fbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 295 additions and 12 deletions

View File

@ -97,5 +97,7 @@ versioned
vsdevcmd
We'd
wildcards
XBox
YBox
yeru
zhe

View File

@ -6,6 +6,9 @@
#include "Launch.g.cpp"
#include "EnumEntry.h"
#include <LibraryResources.h>
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Terminal::Settings::Model;
@ -24,6 +27,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
FindName(L"DefaultTerminalDropdown");
}
Automation::AutomationProperties::SetName(LaunchModeComboBox(), RS_(L"Globals_LaunchModeSetting/Text"));
Automation::AutomationProperties::SetHelpText(LaunchModeComboBox(), RS_(L"Globals_LaunchModeSetting/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"));
Automation::AutomationProperties::SetHelpText(PosXBox(), RS_(L"Globals_InitialPosXBox/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"));
Automation::AutomationProperties::SetHelpText(PosYBox(), RS_(L"Globals_InitialPosYBox/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"));
Automation::AutomationProperties::SetHelpText(UseDefaultLaunchPositionCheckbox(), RS_(L"Globals_DefaultLaunchPositionCheckbox/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"));
Automation::AutomationProperties::SetName(CenterOnLaunchToggle(), RS_(L"Globals_CenterOnLaunch/Text"));
Automation::AutomationProperties::SetHelpText(CenterOnLaunchToggle(), RS_(L"Globals_CenterOnLaunch/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"));
}
void Launch::OnNavigatedTo(const NavigationEventArgs& e)

View File

@ -150,17 +150,6 @@
Style="{StaticResource ComboBoxSettingStyle}" />
</local:SettingContainer>
<!-- Launch Mode -->
<local:SettingContainer x:Name="Globals_LaunchMode"
x:Uid="Globals_LaunchMode">
<ComboBox AutomationProperties.AccessibilityView="Content"
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind ViewModel.LaunchModeList}"
SelectedItem="{x:Bind ViewModel.CurrentLaunchMode, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}" />
</local:SettingContainer>
<!-- Windowing Behavior -->
<local:SettingContainer x:Uid="Globals_WindowingBehavior">
<ComboBox AutomationProperties.AccessibilityView="Content"
@ -206,6 +195,68 @@
Value="{x:Bind ViewModel.InitialRows, Mode=TwoWay}" />
</Grid>
</local:SettingContainer>
<!-- Launch Parameters -->
<local:SettingContainer x:Uid="Globals_LaunchParameters"
CurrentValue="{x:Bind ViewModel.LaunchParametersCurrentValue, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
<Grid RowSpacing="10">
<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" />
<StackPanel Grid.Row="1"
Grid.Column="1">
<StackPanel Orientation="Horizontal"
Spacing="4">
<muxc:NumberBox x:Name="PosXBox"
x:Uid="Globals_InitialPosXBox"
IsEnabled="{x:Bind local:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
Style="{StaticResource LaunchSizeNumberBoxStyle}"
Value="{x:Bind ViewModel.InitialPosX, Mode=TwoWay}" />
<muxc:NumberBox x:Name="PosYBox"
x:Uid="Globals_InitialPosYBox"
IsEnabled="{x:Bind local:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
Style="{StaticResource LaunchSizeNumberBoxStyle}"
Value="{x:Bind ViewModel.InitialPosY, Mode=TwoWay}" />
</StackPanel>
<CheckBox x:Name="UseDefaultLaunchPositionCheckbox"
x:Uid="Globals_DefaultLaunchPositionCheckbox"
IsChecked="{x:Bind ViewModel.UseDefaultLaunchPosition, Mode=TwoWay}" />
</StackPanel>
<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>
</StackPanel>
</StackPanel>
</ScrollViewer>

View File

@ -5,16 +5,20 @@
#include "LaunchViewModel.h"
#include "LaunchViewModel.g.cpp"
#include "EnumEntry.h"
#include <LibraryResources.h>
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Windows::UI::Xaml::Data;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
LaunchViewModel::LaunchViewModel(Model::CascadiaSettings settings) :
_Settings{ settings }
{
_useDefaultLaunchPosition = isnan(InitialPosX()) && isnan(InitialPosY());
INITIALIZE_BINDABLE_ENUM_SETTING(FirstWindowPreference, FirstWindowPreference, FirstWindowPreference, L"Globals_FirstWindowPreference", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(LaunchMode, LaunchMode, LaunchMode, L"Globals_LaunchMode", L"Content");
// More options were added to the JSON mapper when the enum was made into [Flags]
@ -23,6 +27,118 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_LaunchModeList.RemoveAt(6); // fullscreenFocus
_LaunchModeList.RemoveAt(3); // maximizedFullscreen
INITIALIZE_BINDABLE_ENUM_SETTING(WindowingBehavior, WindowingMode, WindowingMode, L"Globals_WindowingBehavior", L"Content");
// Add a property changed handler to our own property changed event.
// This propagates changes from the settings model to anybody listening to our
// unique view model members.
PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
const auto viewModelProperty{ args.PropertyName() };
if (viewModelProperty == L"CenterOnLaunch")
{
_NotifyChanges(L"LaunchParametersCurrentValue");
}
});
}
winrt::hstring LaunchViewModel::LaunchParametersCurrentValue()
{
const auto launchModeString = CurrentLaunchMode().as<EnumEntry>()->EnumName();
const auto centerOnLaunchString = CenterOnLaunch() ? RS_(L"Globals_CenterOnLaunchOn") : RS_(L"Globals_CenterOnLaunchOff");
winrt::hstring result;
if (UseDefaultLaunchPosition())
{
result = fmt::format(L"{}, {}, {}", launchModeString, RS_(L"Globals_LaunchModeDefault/Content"), centerOnLaunchString);
}
else
{
const std::wstring xPosString = isnan(InitialPosX()) ? RS_(L"Globals_LaunchModeDefault/Content").c_str() : std::to_wstring(gsl::narrow_cast<int>(InitialPosX()));
const std::wstring yPosString = isnan(InitialPosY()) ? RS_(L"Globals_LaunchModeDefault/Content").c_str() : std::to_wstring(gsl::narrow_cast<int>(InitialPosY()));
result = fmt::format(L"{}, ({},{}), {}", launchModeString, xPosString, yPosString, centerOnLaunchString);
}
return result;
}
double LaunchViewModel::InitialPosX()
{
const auto x = _Settings.GlobalSettings().InitialPosition().X;
// If there's no value here, return NAN - XAML will ignore it and
// put the placeholder text in the box instead
const auto xCoord = x.try_as<int64_t>();
return xCoord.has_value() ? gsl::narrow_cast<double>(xCoord.value()) : NAN;
}
double LaunchViewModel::InitialPosY()
{
const auto y = _Settings.GlobalSettings().InitialPosition().Y;
// If there's no value here, return NAN - XAML will ignore it and
// put the placeholder text in the box instead
const auto yCoord = y.try_as<int64_t>();
return yCoord.has_value() ? gsl::narrow_cast<double>(yCoord.value()) : NAN;
}
void LaunchViewModel::InitialPosX(double xCoord)
{
winrt::Windows::Foundation::IReference<int64_t> xCoordRef;
// If the value was cleared, xCoord will be NAN, so check for that
if (!isnan(xCoord))
{
xCoordRef = gsl::narrow_cast<int64_t>(xCoord);
}
const LaunchPosition newPos{ xCoordRef, _Settings.GlobalSettings().InitialPosition().Y };
_Settings.GlobalSettings().InitialPosition(newPos);
_NotifyChanges(L"LaunchParametersCurrentValue");
}
void LaunchViewModel::InitialPosY(double yCoord)
{
winrt::Windows::Foundation::IReference<int64_t> yCoordRef;
// If the value was cleared, yCoord will be NAN, so check for that
if (!isnan(yCoord))
{
yCoordRef = gsl::narrow_cast<int64_t>(yCoord);
}
const LaunchPosition newPos{ _Settings.GlobalSettings().InitialPosition().X, yCoordRef };
_Settings.GlobalSettings().InitialPosition(newPos);
_NotifyChanges(L"LaunchParametersCurrentValue");
}
void LaunchViewModel::UseDefaultLaunchPosition(bool useDefaultPosition)
{
_useDefaultLaunchPosition = useDefaultPosition;
if (useDefaultPosition)
{
InitialPosX(NAN);
InitialPosY(NAN);
_NotifyChanges(L"InitialPosX", L"InitialPosY");
}
_NotifyChanges(L"UseDefaultLaunchPosition", L"LaunchParametersCurrentValue");
}
bool LaunchViewModel::UseDefaultLaunchPosition()
{
return _useDefaultLaunchPosition;
}
winrt::Windows::Foundation::IInspectable LaunchViewModel::CurrentLaunchMode()
{
return winrt::box_value<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(_LaunchModeMap.Lookup(_Settings.GlobalSettings().LaunchMode()));
}
void LaunchViewModel::CurrentLaunchMode(const winrt::Windows::Foundation::IInspectable& enumEntry)
{
if (const auto ee = enumEntry.try_as<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>())
{
const auto setting = winrt::unbox_value<LaunchMode>(ee.EnumValue());
_Settings.GlobalSettings().LaunchMode(setting);
_NotifyChanges(L"LaunchParametersCurrentValue");
}
}
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> LaunchViewModel::LaunchModeList()
{
return _LaunchModeList;
}
winrt::Windows::Foundation::IInspectable LaunchViewModel::CurrentDefaultProfile()

View File

@ -14,6 +14,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
public:
LaunchViewModel(Model::CascadiaSettings settings);
winrt::hstring LaunchParametersCurrentValue();
double InitialPosX();
double InitialPosY();
void InitialPosX(double xCoord);
void InitialPosY(double yCoord);
void UseDefaultLaunchPosition(bool useDefaultPosition);
bool UseDefaultLaunchPosition();
IInspectable CurrentDefaultProfile();
void CurrentDefaultProfile(const IInspectable& value);
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> DefaultProfiles() const;
@ -22,16 +30,25 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void CurrentDefaultTerminal(const IInspectable& value);
winrt::Windows::Foundation::Collections::IObservableVector<Model::DefaultTerminal> DefaultTerminals() const;
// We cannot use the macro for LaunchMode because we want to insert an event into the setter
winrt::Windows::Foundation::IInspectable CurrentLaunchMode();
void CurrentLaunchMode(const winrt::Windows::Foundation::IInspectable& enumEntry);
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> LaunchModeList();
GETSET_BINDABLE_ENUM_SETTING(FirstWindowPreference, Model::FirstWindowPreference, _Settings.GlobalSettings().FirstWindowPreference);
GETSET_BINDABLE_ENUM_SETTING(LaunchMode, Model::LaunchMode, _Settings.GlobalSettings().LaunchMode);
GETSET_BINDABLE_ENUM_SETTING(WindowingBehavior, Model::WindowingMode, _Settings.GlobalSettings().WindowingBehavior);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), CenterOnLaunch);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), StartOnUserLogin);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), InitialRows);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), InitialCols);
private:
Model::CascadiaSettings _Settings;
bool _useDefaultLaunchPosition;
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> _LaunchModeList;
winrt::Windows::Foundation::Collections::IMap<Model::LaunchMode, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> _LaunchModeMap;
};
};

View File

@ -11,6 +11,11 @@ namespace Microsoft.Terminal.Settings.Editor
{
LaunchViewModel(Microsoft.Terminal.Settings.Model.CascadiaSettings settings);
String LaunchParametersCurrentValue { get; };
Double InitialPosX;
Double InitialPosY;
Boolean UseDefaultLaunchPosition;
IInspectable CurrentDefaultProfile;
IObservableVector<Microsoft.Terminal.Settings.Model.Profile> DefaultProfiles { get; };
@ -26,6 +31,7 @@ namespace Microsoft.Terminal.Settings.Editor
IInspectable CurrentWindowingBehavior;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> WindowingBehaviorList { get; };
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, CenterOnLaunch);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, StartOnUserLogin);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Int32, InitialRows);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Int32, InitialCols);

View File

@ -315,6 +315,46 @@
<value>Initial Rows</value>
<comment>Name for a control to choose the number of rows in the terminal's text grid.</comment>
</data>
<data name="Globals_InitialPosX.Text" xml:space="preserve">
<value>X position</value>
<comment>Header for a control to choose the X coordinate of the terminal's starting position.</comment>
</data>
<data name="Globals_InitialPosY.Text" xml:space="preserve">
<value>Y position</value>
<comment>Header for a control to choose the Y coordinate of the terminal's starting position.</comment>
</data>
<data name="Globals_InitialPosXBox.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>X position</value>
<comment>Name for a control to choose the X coordinate of the terminal's starting position.</comment>
</data>
<data name="Globals_InitialPosXBox.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Enter the value for the x-coordinate.</value>
<comment>Tooltip for the control that allows the user to choose the X coordinate of the terminal's starting position.</comment>
</data>
<data name="Globals_InitialPosXBox.PlaceholderText" xml:space="preserve">
<value>X</value>
<comment>The string to be displayed when there is no current value in the x-coordinate number box.</comment>
</data>
<data name="Globals_InitialPosYBox.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Y position</value>
<comment>Name for a control to choose the Y coordinate of the terminal's starting position.</comment>
</data>
<data name="Globals_InitialPosYBox.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Enter the value for the y-coordinate.</value>
<comment>Tooltip for the control that allows the user to choose the Y coordinate of the terminal's starting position.</comment>
</data>
<data name="Globals_InitialPosYBox.PlaceholderText" xml:space="preserve">
<value>Y</value>
<comment>The string to be displayed when there is no current value in the y-coordinate number box.</comment>
</data>
<data name="Globals_DefaultLaunchPositionCheckbox.Content" xml:space="preserve">
<value>Use system default</value>
<comment>A checkbox for the "launch position" setting. Toggling this control sets the launch position to the system default.</comment>
</data>
<data name="Globals_DefaultLaunchPositionCheckbox.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>If enabled, use the system default launch position.</value>
<comment>A description for what the "default launch position" checkbox does. Presented near "Globals_DefaultLaunchPositionCheckbox".</comment>
</data>
<data name="Globals_FirstWindowPreference.Header" xml:space="preserve">
<value>When Terminal starts</value>
<comment>Header for a control to select how the terminal should load its first window.</comment>
@ -338,6 +378,22 @@
<value>How the terminal will appear on launch. Focus will hide the tabs and title bar.</value>
<comment>'Focus' must match &lt;Globals_LaunchModeFocus.Content&gt;.</comment>
</data>
<data name="Globals_LaunchParameters.Header" xml:space="preserve">
<value>Launch parameters</value>
<comment>Header for a set of settings that determine how terminal launches. These settings include the launch mode, launch position and whether the teminal should center itself on launch.</comment>
</data>
<data name="Globals_LaunchParameters.HelpText" xml:space="preserve">
<value>Settings that control how the terminal launches</value>
<comment>A description for what the "launch parameters" expander contains. Presented near "Globals_LaunchParameters.Header".</comment>
</data>
<data name="Globals_LaunchModeSetting.Text" xml:space="preserve">
<value>Launch mode</value>
<comment>Header for a control to select what mode to launch the terminal in.</comment>
</data>
<data name="Globals_LaunchModeSetting.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>How the terminal will appear on launch. Focus will hide the tabs and title bar.</value>
<comment>'Focus' must match &lt;Globals_LaunchModeFocus.Content&gt;.</comment>
</data>
<data name="Globals_LaunchModeDefault.Content" xml:space="preserve">
<value>Default</value>
<comment>An option to choose from for the "launch mode" setting. Default option.</comment>
@ -422,6 +478,22 @@
<value>When enabled, this enables the launch of Terminal at machine startup.</value>
<comment>A description for what the "start on user login" setting does. Presented near "Globals_StartOnUserLogin.Header".</comment>
</data>
<data name="Globals_CenterOnLaunchOn" xml:space="preserve">
<value>On</value>
<comment>The "On" value for the center on launch setting.</comment>
</data>
<data name="Globals_CenterOnLaunchOff" xml:space="preserve">
<value>Off</value>
<comment>The "Off" value for the center on launch setting.</comment>
</data>
<data name="Globals_CenterOnLaunch.Text" xml:space="preserve">
<value>Center on launch</value>
<comment>Header for a control to toggle whether the app should launch in the center of the screen, or not.</comment>
</data>
<data name="Globals_CenterOnLaunch.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When enabled, the window will be placed in the center of the screen when launched.</value>
<comment>A description for what the "center on launch" setting does. Presented near "Globals_CenterOnLaunch.Header".</comment>
</data>
<data name="Globals_AlwaysOnTop.Header" xml:space="preserve">
<value>Always on top</value>
<comment>Header for a control to toggle if the app will always be presented on top of other windows, or is treated normally (when disabled).</comment>
@ -1154,6 +1226,14 @@
<value>The number of rows and columns displayed in the window upon first load. Measured in characters.</value>
<comment>A description for what the "rows" and "columns" settings do. Presented near "Globals_LaunchSize.Header".</comment>
</data>
<data name="Globals_LaunchPosition.Text" xml:space="preserve">
<value>Launch position</value>
<comment>Header for a group of settings that control the launch position of the app. Presented near "Globals_InitialPosX" and "Globals_InitialPosY".</comment>
</data>
<data name="Globals_LaunchPosition.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>The initial position of the terminal window upon startup. When launching as maximized, full screen, or with "Center on launch" enabled, this is used to target the monitor of interest.</value>
<comment>A description for what the "X position" and "Y position" settings do. Presented near "Globals_LaunchPosition.Header".</comment>
</data>
<data name="Profile_BellStyleAll.Content" xml:space="preserve">
<value>All</value>
<comment>An option to choose from for the "bell style" setting. When selected, a combination of the other bell styles is used to notify the user.</comment>