-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PRE-MERGE #17330 Add a snippets pane
- Loading branch information
Showing
18 changed files
with
602 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1521,4 +1521,5 @@ namespace winrt::TerminalApp::implementation | |
_ShowAboutDialog(); | ||
args.Handled(true); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
#include "pch.h" | ||
#include "SnippetsPaneContent.h" | ||
#include "SnippetsPaneContent.g.cpp" | ||
#include "FilteredTask.g.cpp" | ||
|
||
using namespace winrt::Windows::Foundation; | ||
using namespace winrt::Microsoft::Terminal::Settings; | ||
using namespace winrt::Microsoft::Terminal::Settings::Model; | ||
|
||
namespace winrt | ||
{ | ||
namespace WUX = Windows::UI::Xaml; | ||
namespace MUX = Microsoft::UI::Xaml; | ||
using IInspectable = Windows::Foundation::IInspectable; | ||
} | ||
|
||
namespace winrt::TerminalApp::implementation | ||
{ | ||
SnippetsPaneContent::SnippetsPaneContent() | ||
{ | ||
InitializeComponent(); | ||
|
||
// auto res = Windows::UI::Xaml::Application::Current().Resources(); | ||
auto bg = Resources().Lookup(winrt::box_value(L"PageBackground")); | ||
Background(bg.try_as<WUX::Media::Brush>()); | ||
} | ||
|
||
void SnippetsPaneContent::_updateFilteredCommands() | ||
{ | ||
const auto& queryString = _filterBox().Text(); | ||
|
||
// DON'T replace the itemSource here. If you do, it'll un-expand all the | ||
// nested items the user has expanded. Instead, just update the filter. | ||
// That'll also trigger a PropertyChanged for the Visibility property. | ||
for (const auto& t : _allTasks) | ||
{ | ||
t.UpdateFilter(queryString); | ||
} | ||
} | ||
|
||
void SnippetsPaneContent::UpdateSettings(const CascadiaSettings& settings) | ||
{ | ||
_settings = settings; | ||
|
||
// You'd think that `FilterToSendInput(queryString)` would work. It | ||
// doesn't! That uses the queryString as the current command the user | ||
// has typed, then relies on the suggestions UI to _also_ filter with that | ||
// string. | ||
|
||
const auto tasks = _settings.GlobalSettings().ActionMap().FilterToSendInput(L""); // IVector<Model::Command> | ||
_allTasks = winrt::single_threaded_observable_vector<TerminalApp::FilteredTask>(); | ||
for (const auto& t : tasks) | ||
{ | ||
const auto& filtered{ winrt::make<FilteredTask>(t) }; | ||
_allTasks.Append(filtered); | ||
} | ||
_treeView().ItemsSource(_allTasks); | ||
|
||
_updateFilteredCommands(); | ||
} | ||
|
||
void SnippetsPaneContent::_filterTextChanged(const IInspectable& /*sender*/, | ||
const Windows::UI::Xaml::RoutedEventArgs& /*args*/) | ||
{ | ||
_updateFilteredCommands(); | ||
} | ||
|
||
winrt::Windows::UI::Xaml::FrameworkElement SnippetsPaneContent::GetRoot() | ||
{ | ||
return *this; | ||
} | ||
winrt::Windows::Foundation::Size SnippetsPaneContent::MinimumSize() | ||
{ | ||
return { 1, 1 }; | ||
} | ||
void SnippetsPaneContent::Focus(winrt::Windows::UI::Xaml::FocusState reason) | ||
{ | ||
reason; | ||
// _box.Focus(reason); | ||
} | ||
void SnippetsPaneContent::Close() | ||
{ | ||
CloseRequested.raise(*this, nullptr); | ||
} | ||
|
||
INewContentArgs SnippetsPaneContent::GetNewTerminalArgs(BuildStartupKind /*kind*/) const | ||
{ | ||
return BaseContentArgs(L"snippets"); | ||
} | ||
|
||
winrt::hstring SnippetsPaneContent::Icon() const | ||
{ | ||
static constexpr std::wstring_view glyph{ L"\xe70b" }; // QuickNote | ||
return winrt::hstring{ glyph }; | ||
} | ||
|
||
winrt::Windows::UI::Xaml::Media::Brush SnippetsPaneContent::BackgroundBrush() | ||
{ | ||
return Background(); | ||
} | ||
|
||
void SnippetsPaneContent::SetLastActiveControl(const Microsoft::Terminal::Control::TermControl& control) | ||
{ | ||
_control = control; | ||
} | ||
|
||
void SnippetsPaneContent::_runCommandButtonClicked(const Windows::Foundation::IInspectable& sender, | ||
const Windows::UI::Xaml::RoutedEventArgs&) | ||
{ | ||
if (const auto& taskVM{ sender.try_as<WUX::Controls::Button>().DataContext().try_as<FilteredTask>() }) | ||
{ | ||
if (const auto& strongControl{ _control.get() }) | ||
{ | ||
// By using the last active control as the sender here, the | ||
// action dispatch will send this to the active control, | ||
// thinking that it is the control that requested this event. | ||
DispatchCommandRequested.raise(strongControl, taskVM->Command()); | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
#pragma once | ||
#include "SnippetsPaneContent.g.h" | ||
#include "FilteredTask.g.h" | ||
#include "FilteredCommand.h" | ||
#include "ActionPaletteItem.h" | ||
#include <LibraryResources.h> | ||
|
||
namespace winrt::TerminalApp::implementation | ||
{ | ||
struct SnippetsPaneContent : SnippetsPaneContentT<SnippetsPaneContent> | ||
{ | ||
SnippetsPaneContent(); | ||
|
||
winrt::Windows::UI::Xaml::FrameworkElement GetRoot(); | ||
|
||
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings); | ||
|
||
winrt::Windows::Foundation::Size MinimumSize(); | ||
void Focus(winrt::Windows::UI::Xaml::FocusState reason = winrt::Windows::UI::Xaml::FocusState::Programmatic); | ||
void Close(); | ||
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(BuildStartupKind kind) const; | ||
|
||
winrt::hstring Title() { return RS_(L"SnippetPaneTitle/Text"); } | ||
uint64_t TaskbarState() { return 0; } | ||
uint64_t TaskbarProgress() { return 0; } | ||
bool ReadOnly() { return false; } | ||
winrt::hstring Icon() const; | ||
Windows::Foundation::IReference<winrt::Windows::UI::Color> TabColor() const noexcept { return nullptr; } | ||
winrt::Windows::UI::Xaml::Media::Brush BackgroundBrush(); | ||
|
||
void SetLastActiveControl(const Microsoft::Terminal::Control::TermControl& control); | ||
|
||
til::typed_event<> ConnectionStateChanged; | ||
til::typed_event<IPaneContent> CloseRequested; | ||
til::typed_event<IPaneContent, winrt::TerminalApp::BellEventArgs> BellRequested; | ||
til::typed_event<IPaneContent> TitleChanged; | ||
til::typed_event<IPaneContent> TabColorChanged; | ||
til::typed_event<IPaneContent> TaskbarProgressChanged; | ||
til::typed_event<IPaneContent> ReadOnlyChanged; | ||
til::typed_event<IPaneContent> FocusRequested; | ||
|
||
til::typed_event<winrt::Windows::Foundation::IInspectable, Microsoft::Terminal::Settings::Model::Command> DispatchCommandRequested; | ||
|
||
private: | ||
friend struct SnippetsPaneContentT<SnippetsPaneContent>; // for Xaml to bind events | ||
|
||
winrt::weak_ref<Microsoft::Terminal::Control::TermControl> _control{ nullptr }; | ||
winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr }; | ||
winrt::Windows::Foundation::Collections::IObservableVector<TerminalApp::FilteredTask> _allTasks{ nullptr }; | ||
|
||
void _runCommandButtonClicked(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs&); | ||
void _filterTextChanged(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args); | ||
|
||
void _updateFilteredCommands(); | ||
}; | ||
|
||
struct FilteredTask : FilteredTaskT<FilteredTask, TerminalApp::implementation::FilteredCommand> | ||
{ | ||
FilteredTask() = default; | ||
|
||
FilteredTask(const winrt::Microsoft::Terminal::Settings::Model::Command& command) | ||
{ | ||
_constructFilteredCommand(winrt::make<winrt::TerminalApp::implementation::ActionPaletteItem>(command, L"")); | ||
_command = command; | ||
|
||
// The Children() method must always return a non-null vector | ||
_children = winrt::single_threaded_observable_vector<TerminalApp::FilteredTask>(); | ||
if (_command.HasNestedCommands()) | ||
{ | ||
for (const auto& [_, child] : _command.NestedCommands()) | ||
{ | ||
auto vm{ winrt::make<FilteredTask>(child) }; | ||
_children.Append(vm); | ||
} | ||
} | ||
} | ||
|
||
void UpdateFilter(const winrt::hstring& filter) override | ||
{ | ||
TerminalApp::implementation::FilteredCommand::UpdateFilter(filter); | ||
for (const auto& c : _children) | ||
{ | ||
c.UpdateFilter(filter); | ||
} | ||
|
||
PropertyChanged.raise(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Visibility" }); | ||
} | ||
|
||
winrt::hstring Input() | ||
{ | ||
if (const auto& actionItem{ _Item.try_as<winrt::TerminalApp::ActionPaletteItem>() }) | ||
{ | ||
if (const auto& command{ actionItem.Command() }) | ||
{ | ||
if (const auto& sendInput{ command.ActionAndArgs().Args().try_as<winrt::Microsoft::Terminal::Settings::Model::SendInputArgs>() }) | ||
{ | ||
return sendInput.Input(); | ||
} | ||
} | ||
} | ||
return L""; | ||
}; | ||
|
||
winrt::Windows::Foundation::Collections::IObservableVector<TerminalApp::FilteredTask> Children() { return _children; } | ||
bool HasChildren() { return _children.Size() > 0; } | ||
winrt::Microsoft::Terminal::Settings::Model::Command Command() { return _command; } | ||
|
||
// Used to control if this item is visible in the TreeView. Turns out, | ||
// TreeView is in fact sane enough to remove items entirely if they're | ||
// Collapsed. | ||
winrt::Windows::UI::Xaml::Visibility Visibility() | ||
{ | ||
// Is there no filter, or do we match it? | ||
if (_Filter.empty() || _Weight > 0) | ||
{ | ||
return winrt::Windows::UI::Xaml::Visibility::Visible; | ||
} | ||
// If we don't match, maybe one of our children does | ||
auto totalWeight = _Weight; | ||
for (const auto& c : _children) | ||
{ | ||
totalWeight += c.Weight(); | ||
} | ||
|
||
return totalWeight > 0 ? winrt::Windows::UI::Xaml::Visibility::Visible : winrt::Windows::UI::Xaml::Visibility::Collapsed; | ||
}; | ||
|
||
private: | ||
winrt::Microsoft::Terminal::Settings::Model::Command _command{ nullptr }; | ||
winrt::Windows::Foundation::Collections::IObservableVector<TerminalApp::FilteredTask> _children{ nullptr }; | ||
}; | ||
} | ||
|
||
namespace winrt::TerminalApp::factory_implementation | ||
{ | ||
BASIC_FACTORY(SnippetsPaneContent); | ||
} |
Oops, something went wrong.