Skip to content

Commit

Permalink
Convert the About and Close All Tabs dialogs to xaml (#5140)
Browse files Browse the repository at this point in the history
## Summary of the Pull Request

This pull request replaces about a hundred lines of manual xaml DOM code with a few lines of actual xaml, and wires up bound properties and event handlers in the good and correct way.

As part of this change, I've replaced the giant TextBlock in the about dialog with StackPanels, and replaced the Hyperlinks with HyperlinkButtons. This is in line with other platform applications.

URLs are _not_ localizable resources, so I moved them into the about dialog's xaml. Per #5138, we'll likely change them so that they get localization for "free" (dispatching based on the browser's language, without having to localize the URL in the application).
  • Loading branch information
DHowett authored Mar 27, 2020
1 parent 5e9adad commit d7123d5
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 159 deletions.
88 changes: 44 additions & 44 deletions src/cascadia/TerminalApp/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -162,40 +162,6 @@ Temporarily using the Windows Terminal default settings.
<data name="ReloadJsonParseErrorTitle" xml:space="preserve">
<value>Failed to reload settings</value>
</data>
<data name="AboutTitleText" xml:space="preserve">
<value>About</value>
</data>
<data name="VersionLabelText" xml:space="preserve">
<value>Version:</value>
</data>
<data name="DocumentationLabelText" xml:space="preserve">
<value>Documentation
</value>
</data>
<data name="GettingStartedLabelText" xml:space="preserve">
<value>Getting Started
</value>
</data>
<data name="ReleaseNotesLabelText" xml:space="preserve">
<value>Release Notes
</value>
</data>
<data name="PrivacyPolicyLabelText" xml:space="preserve">
<value>Privacy Policy
</value>
</data>
<data name="DocumentationUriValue" xml:space="preserve">
<value>https://aka.ms/terminal-documentation</value>
</data>
<data name="GettingStartedUriValue" xml:space="preserve">
<value>https://aka.ms/terminal-getting-started</value>
</data>
<data name="ReleaseNotesUriValue" xml:space="preserve">
<value>https://aka.ms/terminal-release-notes</value>
</data>
<data name="PrivacyPolicyUriValue" xml:space="preserve">
<value>https://aka.ms/terminal-privacy-policy</value>
</data>
<data name="FeedbackUriValue" xml:space="preserve">
<value>https://aka.ms/terminal-feedback</value>
</data>
Expand All @@ -208,15 +174,6 @@ Temporarily using the Windows Terminal default settings.
<data name="SettingsMenuItem" xml:space="preserve">
<value>Settings</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="CloseAll" xml:space="preserve">
<value>Close all</value>
</data>
<data name="CloseWindowWarningTitle" xml:space="preserve">
<value>Do you want to close all tabs?</value>
</data>
<data name="InvalidBackgroundImage" xml:space="preserve">
<value>Found a profile with an invalid "backgroundImage". Defaulting that profile to have no background image. Make sure that when setting a "backgroundImage", the value is a valid file path to an image.</value>
</data>
Expand Down Expand Up @@ -283,4 +240,47 @@ Temporarily using the Windows Terminal default settings.
<data name="WindowMinimizeButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Minimize</value>
</data>
</root>
<data name="AboutDialog.Title" xml:space="preserve">
<value>About</value>
</data>
<data name="AboutDialog.CloseButtonText" xml:space="preserve">
<value>OK</value>
</data>
<data name="AboutDialog_VersionLabel.Text" xml:space="preserve">
<value>Version:</value>
<comment>This is the heading for a version number label</comment>
</data>
<data name="AboutDialog_GettingStartedLink.Content" xml:space="preserve">
<value>Getting Started</value>
<comment>A hyperlink name for a guide on how to get started using Terminal</comment>
</data>
<data name="AboutDialog_DocumentationLink.Content" xml:space="preserve">
<value>Documentation</value>
<comment>A hyperlink name for user documentation</comment>
</data>
<data name="AboutDialog_ReleaseNotesLink.Content" xml:space="preserve">
<value>Release Notes</value>
<comment>A hyperlink name for the Terminal's release notes</comment>
</data>
<data name="AboutDialog_PrivacyPolicyLink.Content" xml:space="preserve">
<value>Privacy Policy</value>
<comment>A hyperlink name for the Terminal's privacy policy</comment>
</data>
<data name="AboutDialog_DisplayNameUnpackaged" xml:space="preserve">
<value>Windows Terminal (Unpackaged)</value>
<comment>This display name is used when the application's name cannot be determined</comment>
</data>
<data name="AboutDialog_VersionUnknown" xml:space="preserve">
<value>Unknown</value>
<comment>This is displayed when the version of the application cannot be determined</comment>
</data>
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Close all</value>
</data>
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Do you want to close all tabs?</value>
</data>
</root>
140 changes: 27 additions & 113 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,112 +224,38 @@ namespace winrt::TerminalApp::implementation
}

// Method Description:
// - Show a ContentDialog with a single "Ok" button to dismiss. Looks up the
// the title and text from our Resources using the provided keys.
// - Only one dialog can be visible at a time. If another dialog is visible
// when this is called, nothing happens. See _ShowDialog for details
// Arguments:
// - titleKey: The key to use to lookup the title text from our resources.
// - contentKey: The key to use to lookup the content text from our resources.
void TerminalPage::ShowOkDialog(const winrt::hstring& titleKey,
const winrt::hstring& contentKey)
// - Show a dialog with "About" information. Displays the app's Display
// Name, version, getting started link, documentation link, release
// Notes link, and privacy policy link.
void TerminalPage::_ShowAboutDialog()
{
auto title = GetLibraryResourceString(titleKey);
auto message = GetLibraryResourceString(contentKey);
auto buttonText = RS_(L"Ok");
_showDialogHandlers(*this, FindName(L"AboutDialog").try_as<WUX::Controls::ContentDialog>());
}

WUX::Controls::ContentDialog dialog;
dialog.Title(winrt::box_value(title));
dialog.Content(winrt::box_value(message));
dialog.CloseButtonText(buttonText);
dialog.DefaultButton(WUX::Controls::ContentDialogButton::Close);
winrt::hstring TerminalPage::ApplicationDisplayName()
{
try
{
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
return package.DisplayName();
}
CATCH_LOG();

_showDialogHandlers(*this, dialog);
return RS_(L"AboutDialog_DisplayNameUnpackaged");
}

// Method Description:
// - Show a dialog with "About" information. Displays the app's Display
// Name, version, getting started link, documentation link, release
// Notes link, and privacy policy link.
void TerminalPage::_ShowAboutDialog()
winrt::hstring TerminalPage::ApplicationVersion()
{
const auto title = RS_(L"AboutTitleText");
const auto versionLabel = RS_(L"VersionLabelText");
const auto gettingStartedLabel = RS_(L"GettingStartedLabelText");
const auto documentationLabel = RS_(L"DocumentationLabelText");
const auto releaseNotesLabel = RS_(L"ReleaseNotesLabelText");
const auto privacyPolicyLabel = RS_(L"PrivacyPolicyLabelText");
const auto gettingStartedUriValue = RS_(L"GettingStartedUriValue");
const auto documentationUriValue = RS_(L"DocumentationUriValue");
const auto releaseNotesUriValue = RS_(L"ReleaseNotesUriValue");
const auto privacyPolicyUriValue = RS_(L"PrivacyPolicyUriValue");
const auto package = winrt::Windows::ApplicationModel::Package::Current();
const auto packageName = package.DisplayName();
const auto version = package.Id().Version();
winrt::Windows::UI::Xaml::Documents::Run about;
winrt::Windows::UI::Xaml::Documents::Run gettingStarted;
winrt::Windows::UI::Xaml::Documents::Run documentation;
winrt::Windows::UI::Xaml::Documents::Run releaseNotes;
winrt::Windows::UI::Xaml::Documents::Run privacyPolicy;
winrt::Windows::UI::Xaml::Documents::Hyperlink gettingStartedLink;
winrt::Windows::UI::Xaml::Documents::Hyperlink documentationLink;
winrt::Windows::UI::Xaml::Documents::Hyperlink releaseNotesLink;
winrt::Windows::UI::Xaml::Documents::Hyperlink privacyPolicyLink;
std::wstringstream aboutTextStream;

gettingStarted.Text(gettingStartedLabel);
documentation.Text(documentationLabel);
releaseNotes.Text(releaseNotesLabel);
privacyPolicy.Text(privacyPolicyLabel);

winrt::Windows::Foundation::Uri gettingStartedUri{ gettingStartedUriValue };
winrt::Windows::Foundation::Uri documentationUri{ documentationUriValue };
winrt::Windows::Foundation::Uri releaseNotesUri{ releaseNotesUriValue };
winrt::Windows::Foundation::Uri privacyPolicyUri{ privacyPolicyUriValue };

gettingStartedLink.NavigateUri(gettingStartedUri);
documentationLink.NavigateUri(documentationUri);
releaseNotesLink.NavigateUri(releaseNotesUri);
privacyPolicyLink.NavigateUri(privacyPolicyUri);

gettingStartedLink.Inlines().Append(gettingStarted);
documentationLink.Inlines().Append(documentation);
releaseNotesLink.Inlines().Append(releaseNotes);
privacyPolicyLink.Inlines().Append(privacyPolicy);

// Format our about text. It will look like the following:
// <Display Name>
// Version: <Major>.<Minor>.<Build>.<Revision>
// Getting Started
// Documentation
// Release Notes
// Privacy Policy

aboutTextStream << packageName.c_str() << L"\n";

aboutTextStream << versionLabel.c_str() << L" ";
aboutTextStream << version.Major << L"." << version.Minor << L"." << version.Build << L"." << version.Revision << L"\n";

winrt::hstring aboutText{ aboutTextStream.str() };
about.Text(aboutText);

const auto buttonText = RS_(L"Ok");

WUX::Controls::TextBlock aboutTextBlock;
aboutTextBlock.Inlines().Append(about);
aboutTextBlock.Inlines().Append(gettingStartedLink);
aboutTextBlock.Inlines().Append(documentationLink);
aboutTextBlock.Inlines().Append(releaseNotesLink);
aboutTextBlock.Inlines().Append(privacyPolicyLink);
aboutTextBlock.IsTextSelectionEnabled(true);

WUX::Controls::ContentDialog dialog;
dialog.Title(winrt::box_value(title));
dialog.Content(aboutTextBlock);
dialog.CloseButtonText(buttonText);
dialog.DefaultButton(WUX::Controls::ContentDialogButton::Close);

_showDialogHandlers(*this, dialog);
try
{
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
const auto version{ package.Id().Version() };
winrt::hstring formatted{ wil::str_printf<std::wstring>(L"%u.%u.%u.%u", version.Major, version.Minor, version.Build, version.Revision) };
return formatted;
}
CATCH_LOG();

return RS_(L"AboutDialog_VersionUnknown");
}

// Method Description:
Expand All @@ -341,19 +267,7 @@ namespace winrt::TerminalApp::implementation
// when this is called, nothing happens. See _ShowDialog for details
void TerminalPage::_ShowCloseWarningDialog()
{
auto title = RS_(L"CloseWindowWarningTitle");
auto primaryButtonText = RS_(L"CloseAll");
auto closeButtonText = RS_(L"Cancel");

WUX::Controls::ContentDialog dialog;
dialog.Title(winrt::box_value(title));

dialog.CloseButtonText(closeButtonText);
dialog.PrimaryButtonText(primaryButtonText);
dialog.DefaultButton(WUX::Controls::ContentDialogButton::Primary);
auto token = dialog.PrimaryButtonClick({ this, &TerminalPage::_CloseWarningPrimaryButtonOnClick });

_showDialogHandlers(*this, dialog);
_showDialogHandlers(*this, FindName(L"CloseAllDialog").try_as<WUX::Controls::ContentDialog>());
}

// Method Description:
Expand Down
7 changes: 5 additions & 2 deletions src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ namespace winrt::TerminalApp::implementation

hstring Title();

void ShowOkDialog(const winrt::hstring& titleKey, const winrt::hstring& contentKey);

void TitlebarClicked();

float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;

winrt::hstring ApplicationDisplayName();
winrt::hstring ApplicationVersion();

void CloseWindow();

int32_t SetStartupCommandline(winrt::array_view<const hstring> args);
Expand All @@ -58,6 +59,8 @@ namespace winrt::TerminalApp::implementation
TYPED_EVENT(Initialized, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::RoutedEventArgs);

private:
friend struct TerminalPageT<TerminalPage>; // for Xaml to bind events

// If you add controls here, but forget to null them either here or in
// the ctor, you're going to have a bad time. It'll mysteriously fail to
// activate the app.
Expand Down
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.idl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ namespace TerminalApp
Int32 SetStartupCommandline(String[] commands);
String EarlyExitMessage { get; };

// XAML bound properties
String ApplicationDisplayName { get; };
String ApplicationVersion { get; };

event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
Expand Down
34 changes: 34 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,39 @@ the MIT License. See LICENSE in the project root for license information. -->
<local:TabRowControl x:Name="TabRow" Grid.Row="0" />

<Grid x:Name="TabContent" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />

<ContentDialog
x:Load="False"
x:Name="AboutDialog"
x:Uid="AboutDialog"
DefaultButton="Close">
<StackPanel Orientation="Vertical">
<TextBlock IsTextSelectionEnabled="True">
<Run Text="{x:Bind ApplicationDisplayName}" /> <LineBreak />
<Run x:Uid="AboutDialog_VersionLabel" />
<Run Text="{x:Bind ApplicationVersion}" />
</TextBlock>
<HyperlinkButton
x:Uid="AboutDialog_GettingStartedLink"
NavigateUri="https://aka.ms/terminal-getting-started" />
<HyperlinkButton
x:Uid="AboutDialog_DocumentationLink"
NavigateUri="https://aka.ms/terminal-documentation" />
<HyperlinkButton
x:Uid="AboutDialog_ReleaseNotesLink"
NavigateUri="https://aka.ms/terminal-release-notes" />
<HyperlinkButton
x:Uid="AboutDialog_PrivacyPolicyLink"
NavigateUri="https://aka.ms/terminal-privacy-policy" />
</StackPanel>
</ContentDialog>

<ContentDialog
x:Load="False"
x:Name="CloseAllDialog"
x:Uid="CloseAllDialog"
DefaultButton="Primary"
PrimaryButtonClick="_CloseWarningPrimaryButtonOnClick">
</ContentDialog>
</Grid>
</Page>

0 comments on commit d7123d5

Please sign in to comment.