Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some polish to nested commands in the command palette #7299

Merged
1 commit merged into from
Aug 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/Command.idl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace TerminalApp

Windows.UI.Xaml.Controls.IconSource IconSource;

Boolean HasNestedCommands();
Boolean HasNestedCommands { get; };
Windows.Foundation.Collections.IMapView<String, Command> NestedCommands { get; };
}
}
3 changes: 3 additions & 0 deletions src/cascadia/TerminalApp/CommandPalette.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ namespace winrt::TerminalApp::implementation
// action. Instead, display a new list of commands for the user
// to pick from.
_nestedActionStack.Append(command);
ParentCommandName(command.Name());
_currentNestedCommands.Clear();
for (const auto& nameAndCommand : command.NestedCommands())
{
Expand Down Expand Up @@ -764,6 +765,8 @@ namespace winrt::TerminalApp::implementation
_searchBox().Text(L"");

_nestedActionStack.Clear();

ParentCommandName(L"");
_currentNestedCommands.Clear();
}

Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/CommandPalette.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ namespace winrt::TerminalApp::implementation
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, SearchBoxText, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, ControlName, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, ParentCommandName, _PropertyChangedHandlers);

private:
friend struct CommandPaletteT<CommandPalette>; // for Xaml to bind events
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/CommandPalette.idl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace TerminalApp
String NoMatchesText { get; };
String SearchBoxText { get; };
String ControlName { get; };
String ParentCommandName { get; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

future: we may want to display the icon if it has one, too.


Windows.Foundation.Collections.IObservableVector<Command> FilteredActions { get; };

Expand Down
46 changes: 37 additions & 9 deletions src/cascadia/TerminalApp/CommandPalette.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ the MIT License. See LICENSE in the project root for license information. -->
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Windows10version1903="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 8)"
TabNavigation="Cycle"
IsTabStop="True"
TabNavigation="Cycle"
IsTabStop="True"
AllowFocusOnInteraction="True"
PointerPressed="_rootPointerPressed"
PreviewKeyDown="_previewKeyDownHandler"
Expand All @@ -27,7 +27,9 @@ the MIT License. See LICENSE in the project root for license information. -->
<Windows10version1903:ThemeShadow x:Name="CommandPaletteShadow" />

<!-- This creates an instance of our CommandKeyChordVisibilityConverter we can reference below -->
<local:CommandKeyChordVisibilityConverter x:Key="CommandKeyChordVisibilityConverter"/>
<local:EmptyStringVisibilityConverter x:Key="CommandKeyChordVisibilityConverter"/>
<local:EmptyStringVisibilityConverter x:Key="ParentCommandVisibilityConverter"/>
<local:HasNestedCommandsVisibilityConverter x:Key="HasNestedCommandsVisibilityConverter"/>

<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
Expand Down Expand Up @@ -170,12 +172,23 @@ the MIT License. See LICENSE in the project root for license information. -->
</TextBox>

<TextBlock
Padding="16"
x:Name="_noMatchesText"
FontStyle="Italic"
Visibility="Collapsed"
Grid.Row="1"
Text="{x:Bind NoMatchesText, Mode=OneWay}">
Padding="16, 0, 16, 4"
x:Name="_parentCommandText"
FontStyle="Italic"
Visibility="{x:Bind ParentCommandName,
Mode=OneWay,
Converter={StaticResource ParentCommandVisibilityConverter}}"
Grid.Row="1"
Text="{x:Bind ParentCommandName, Mode=OneWay}">
</TextBlock>

<TextBlock
Padding="16"
x:Name="_noMatchesText"
FontStyle="Italic"
Visibility="Collapsed"
Grid.Row="1"
Text="{x:Bind NoMatchesText, Mode=OneWay}">
</TextBlock>

<ListView
Expand Down Expand Up @@ -236,6 +249,21 @@ the MIT License. See LICENSE in the project root for license information. -->
Text="{x:Bind KeyChordText, Mode=OneWay}" />
</Border>

<!-- xE70E is ChevronUp. Rotated 90 degrees, it's _ChevronRight_ -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HA, clever

<FontIcon
FontFamily="Segoe MDL2 Assets"
Glyph="&#xE70E;"
HorizontalAlignment="Right"
Visibility="{x:Bind HasNestedCommands,
Mode=OneWay,
Converter={StaticResource HasNestedCommandsVisibilityConverter}}"
Grid.Column="2">

<FontIcon.RenderTransform>
<RotateTransform CenterX="0.5" CenterY="0.5" Angle="90"/>
</FontIcon.RenderTransform>
</FontIcon>

</Grid>
</ListViewItem>
</DataTemplate>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "pch.h"
#include "CommandKeyChordVisibilityConverter.h"
#include "CommandKeyChordVisibilityConverter.g.cpp"
#include "EmptyStringVisibilityConverter.h"
#include "EmptyStringVisibilityConverter.g.cpp"

using namespace winrt::Windows;
using namespace winrt::Windows::UI::Xaml;
Expand All @@ -9,7 +9,7 @@ namespace winrt::TerminalApp::implementation
{
// Method Description:
// - Attempt to convert something into another type. For the
// CommandKeyChordVisibilityConverter, we're gonna check if `value` is a
// EmptyStringVisibilityConverter, we're gonna check if `value` is a
// string, and try and convert it into a Visibility value. If the input
// param wasn't a string, or was the empty string, we'll return
// Visibility::Collapsed. Otherwise, we'll return Visible.
Expand All @@ -18,20 +18,20 @@ namespace winrt::TerminalApp::implementation
// - value: the input object to attempt to convert into a Visibility.
// Return Value:
// - Visible if the object was a string and wasn't the empty string.
Foundation::IInspectable CommandKeyChordVisibilityConverter::Convert(Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
Foundation::IInspectable EmptyStringVisibilityConverter::Convert(Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
{
const auto& name = winrt::unbox_value_or<hstring>(value, L"");
return winrt::box_value(name.empty() ? Visibility::Collapsed : Visibility::Visible);
}

// unused for one-way bindings
Foundation::IInspectable CommandKeyChordVisibilityConverter::ConvertBack(Foundation::IInspectable const& /* value */,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
Foundation::IInspectable EmptyStringVisibilityConverter::ConvertBack(Foundation::IInspectable const& /* value */,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
{
throw hresult_not_implemented();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#pragma once

#include "CommandKeyChordVisibilityConverter.g.h"
#include "EmptyStringVisibilityConverter.g.h"
#include "..\inc\cppwinrt_utils.h"

namespace winrt::TerminalApp::implementation
{
struct CommandKeyChordVisibilityConverter : CommandKeyChordVisibilityConverterT<CommandKeyChordVisibilityConverter>
struct EmptyStringVisibilityConverter : EmptyStringVisibilityConverterT<EmptyStringVisibilityConverter>
{
CommandKeyChordVisibilityConverter() = default;
EmptyStringVisibilityConverter() = default;

Windows::Foundation::IInspectable Convert(Windows::Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& targetType,
Expand All @@ -23,5 +23,5 @@ namespace winrt::TerminalApp::implementation

namespace winrt::TerminalApp::factory_implementation
{
BASIC_FACTORY(CommandKeyChordVisibilityConverter);
BASIC_FACTORY(EmptyStringVisibilityConverter);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ namespace TerminalApp
// See https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart

// We use the default attribute to declare IValueConverter as the default
// interface. In the listing, CommandKeyChordVisibilityConverter has only a
// interface. In the listing, EmptyStringVisibilityConverter has only a
// constructor, and no methods, so no default interface is generated for it.
// The default attribute is optimal if you won't be adding instance members
// to CommandKeyChordVisibilityConverter, because no QueryInterface will be
// to EmptyStringVisibilityConverter, because no QueryInterface will be
// required to call the IValueConverter methods
runtimeclass CommandKeyChordVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter
runtimeclass EmptyStringVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter
{
CommandKeyChordVisibilityConverter();
EmptyStringVisibilityConverter();
};

}
38 changes: 38 additions & 0 deletions src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "pch.h"
#include "HasNestedCommandsVisibilityConverter.h"
#include "HasNestedCommandsVisibilityConverter.g.cpp"

using namespace winrt::Windows;
using namespace winrt::Windows::UI::Xaml;

namespace winrt::TerminalApp::implementation
{
// Method Description:
// - Attempt to convert something into another type. For the
// HasNestedCommandsVisibilityConverter, we're gonna check if `value` is a
// string, and try and convert it into a Visibility value. If the input
// param wasn't a string, or was the empty string, we'll return
// Visibility::Collapsed. Otherwise, we'll return Visible.

// Arguments:
// - value: the input object to attempt to convert into a Visibility.
// Return Value:
// - Visible if the object was a string and wasn't the empty string.
Foundation::IInspectable HasNestedCommandsVisibilityConverter::Convert(Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
{
const auto& hasNestedCommands = winrt::unbox_value_or<bool>(value, false);
return winrt::box_value(hasNestedCommands ? Visibility::Visible : Visibility::Collapsed);
}

// unused for one-way bindings
Foundation::IInspectable HasNestedCommandsVisibilityConverter::ConvertBack(Foundation::IInspectable const& /* value */,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
{
throw hresult_not_implemented();
}
}
27 changes: 27 additions & 0 deletions src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include "HasNestedCommandsVisibilityConverter.g.h"
#include "..\inc\cppwinrt_utils.h"

namespace winrt::TerminalApp::implementation
{
struct HasNestedCommandsVisibilityConverter : HasNestedCommandsVisibilityConverterT<HasNestedCommandsVisibilityConverter>
{
HasNestedCommandsVisibilityConverter() = default;

Windows::Foundation::IInspectable Convert(Windows::Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& targetType,
Windows::Foundation::IInspectable const& parameter,
hstring const& language);

Windows::Foundation::IInspectable ConvertBack(Windows::Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& targetType,
Windows::Foundation::IInspectable const& parameter,
hstring const& language);
};
}

namespace winrt::TerminalApp::factory_implementation
{
BASIC_FACTORY(HasNestedCommandsVisibilityConverter);
}
19 changes: 19 additions & 0 deletions src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

namespace TerminalApp
{
// See https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart

// We use the default attribute to declare IValueConverter as the default
// interface. In the listing, HasNestedCommandsVisibilityConverter has only a
// constructor, and no methods, so no default interface is generated for it.
// The default attribute is optimal if you won't be adding instance members
// to HasNestedCommandsVisibilityConverter, because no QueryInterface will be
// required to call the IValueConverter methods
runtimeclass HasNestedCommandsVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter
{
HasNestedCommandsVisibilityConverter();
};

}
17 changes: 12 additions & 5 deletions src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,11 @@
<ClInclude Include="../Command.h">
<DependentUpon>../Command.idl</DependentUpon>
</ClInclude>
<ClInclude Include="../CommandKeyChordVisibilityConverter.h">
<DependentUpon>../CommandKeyChordVisibilityConverter.idl</DependentUpon>
<ClInclude Include="../EmptyStringVisibilityConverter.h">
<DependentUpon>../EmptyStringVisibilityConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="../HasNestedCommandsVisibilityConverter.h">
<DependentUpon>../HasNestedCommandsVisibilityConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="../Tab.h">
<DependentUpon>../Tab.idl</DependentUpon>
Expand Down Expand Up @@ -168,8 +171,11 @@
<ClCompile Include="../Command.cpp">
<DependentUpon>../Command.idl</DependentUpon>
</ClCompile>
<ClCompile Include="../CommandKeyChordVisibilityConverter.cpp">
<DependentUpon>../CommandKeyChordVisibilityConverter.idl</DependentUpon>
<ClCompile Include="../EmptyStringVisibilityConverter.cpp">
<DependentUpon>../EmptyStringVisibilityConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="../HasNestedCommandsVisibilityConverter.cpp">
<DependentUpon>../HasNestedCommandsVisibilityConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="../Tab.cpp">
<DependentUpon>../Tab.idl</DependentUpon>
Expand Down Expand Up @@ -261,7 +267,8 @@
<SubType>Code</SubType>
</Midl>
<Midl Include="../Command.idl" />
<Midl Include="../CommandKeyChordVisibilityConverter.idl" />
<Midl Include="../EmptyStringVisibilityConverter.idl" />
<Midl Include="../HasNestedCommandsVisibilityConverter.idl" />
<Midl Include="../Tab.idl" />
<Midl Include="../TerminalSettings.idl" />
</ItemGroup>
Expand Down