Add Close... option to Tab context menu (#7728)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add a "Close..." option to the tab context menu, with nested entries to close tabs to the right and close other tabs (actions already available) ![immagine](https://user-images.githubusercontent.com/1140981/94178005-c7e03600-fe9a-11ea-9f87-c6f4895d4cf3.png) <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #1912 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #5524 * [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. * [ ] 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 <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments First contribution 🙂 Tried to follow some suggestions from https://github.com/microsoft/terminal/issues/1912#issuecomment-667079311 <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
This commit is contained in:
parent
f78687453c
commit
004da88bba
|
@ -177,8 +177,17 @@
|
|||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Do you want to close all tabs?</value>
|
||||
</data>
|
||||
<data name="TabCloseSubMenu" xml:space="preserve">
|
||||
<value>Close...</value>
|
||||
</data>
|
||||
<data name="TabCloseAfter" xml:space="preserve">
|
||||
<value>Close Tabs to the Right</value>
|
||||
</data>
|
||||
<data name="TabCloseOther" xml:space="preserve">
|
||||
<value>Close Other Tabs</value>
|
||||
</data>
|
||||
<data name="TabClose" xml:space="preserve">
|
||||
<value>Close</value>
|
||||
<value>Close Tab</value>
|
||||
</data>
|
||||
<data name="TabColorChoose" xml:space="preserve">
|
||||
<value>Color...</value>
|
||||
|
|
|
@ -593,10 +593,61 @@ namespace winrt::TerminalApp::implementation
|
|||
newTabFlyout.Items().Append(chooseColorMenuItem);
|
||||
newTabFlyout.Items().Append(renameTabMenuItem);
|
||||
newTabFlyout.Items().Append(menuSeparator);
|
||||
newTabFlyout.Items().Append(_CreateCloseSubMenu());
|
||||
newTabFlyout.Items().Append(closeTabMenuItem);
|
||||
_tabViewItem.ContextFlyout(newTabFlyout);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates a sub-menu containing menu items to close multiple tabs
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - the created MenuFlyoutSubItem
|
||||
Controls::MenuFlyoutSubItem Tab::_CreateCloseSubMenu()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Close tabs after
|
||||
_closeTabsAfterMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_CloseTabsAfter();
|
||||
}
|
||||
});
|
||||
_closeTabsAfterMenuItem.Text(RS_(L"TabCloseAfter"));
|
||||
|
||||
// Close other tabs
|
||||
_closeOtherTabsMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_CloseOtherTabs();
|
||||
}
|
||||
});
|
||||
_closeOtherTabsMenuItem.Text(RS_(L"TabCloseOther"));
|
||||
|
||||
Controls::MenuFlyoutSubItem closeSubMenu;
|
||||
closeSubMenu.Text(RS_(L"TabCloseSubMenu"));
|
||||
closeSubMenu.Items().Append(_closeTabsAfterMenuItem);
|
||||
closeSubMenu.Items().Append(_closeOtherTabsMenuItem);
|
||||
|
||||
return closeSubMenu;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Enable the Close menu items based on tab index and total number of tabs
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Tab::_EnableCloseMenuItems()
|
||||
{
|
||||
// close other tabs is enabled only if there are other tabs
|
||||
_closeOtherTabsMenuItem.IsEnabled(TabViewNumTabs() > 1);
|
||||
// close tabs after is enabled only if there are other tabs on the right
|
||||
_closeTabsAfterMenuItem.IsEnabled(TabViewIndex() < TabViewNumTabs() - 1);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This will update the contents of our TabViewItem for our current state.
|
||||
// - If we're not in a rename, we'll set the Header of the TabViewItem to
|
||||
|
@ -1053,12 +1104,35 @@ namespace winrt::TerminalApp::implementation
|
|||
SwitchToTabCommand(command);
|
||||
}
|
||||
|
||||
void Tab::UpdateTabViewIndex(const uint32_t idx)
|
||||
void Tab::_CloseTabsAfter()
|
||||
{
|
||||
CloseTabsAfterArgs args{ _TabViewIndex };
|
||||
ActionAndArgs closeTabsAfter{ ShortcutAction::CloseTabsAfter, args };
|
||||
|
||||
_dispatch.DoAction(closeTabsAfter);
|
||||
}
|
||||
|
||||
void Tab::_CloseOtherTabs()
|
||||
{
|
||||
CloseOtherTabsArgs args{ _TabViewIndex };
|
||||
ActionAndArgs closeOtherTabs{ ShortcutAction::CloseOtherTabs, args };
|
||||
|
||||
_dispatch.DoAction(closeOtherTabs);
|
||||
}
|
||||
|
||||
void Tab::UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs)
|
||||
{
|
||||
TabViewIndex(idx);
|
||||
TabViewNumTabs(numTabs);
|
||||
_EnableCloseMenuItems();
|
||||
SwitchToTabCommand().Action().Args().as<SwitchToTabArgs>().TabIndex(idx);
|
||||
}
|
||||
|
||||
void Tab::SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch)
|
||||
{
|
||||
_dispatch = dispatch;
|
||||
}
|
||||
|
||||
DEFINE_EVENT(Tab, ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
|
||||
DEFINE_EVENT(Tab, ColorSelected, _colorSelected, winrt::delegate<winrt::Windows::UI::Color>);
|
||||
DEFINE_EVENT(Tab, ColorCleared, _colorCleared, winrt::delegate<>);
|
||||
|
|
|
@ -68,7 +68,9 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
int GetLeafPaneCount() const noexcept;
|
||||
|
||||
void UpdateTabViewIndex(const uint32_t idx);
|
||||
void UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs);
|
||||
|
||||
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
|
||||
|
||||
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
|
@ -83,6 +85,8 @@ namespace winrt::TerminalApp::implementation
|
|||
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||
// This is needed since Tab is going to be managing its own SwitchToTab command.
|
||||
OBSERVABLE_GETSET_PROPERTY(uint32_t, TabViewIndex, _PropertyChangedHandlers, 0);
|
||||
// The TabViewNumTabs is the number of Tab objects in TerminalPage's _tabs vector.
|
||||
OBSERVABLE_GETSET_PROPERTY(uint32_t, TabViewNumTabs, _PropertyChangedHandlers, 0);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Pane> _rootPane{ nullptr };
|
||||
|
@ -92,6 +96,8 @@ namespace winrt::TerminalApp::implementation
|
|||
winrt::TerminalApp::ColorPickupFlyout _tabColorPickup{};
|
||||
std::optional<winrt::Windows::UI::Color> _themeTabColor{};
|
||||
std::optional<winrt::Windows::UI::Color> _runtimeTabColor{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeOtherTabsMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
|
||||
|
||||
bool _focused{ false };
|
||||
winrt::Microsoft::UI::Xaml::Controls::TabViewItem _tabViewItem{ nullptr };
|
||||
|
@ -100,10 +106,15 @@ namespace winrt::TerminalApp::implementation
|
|||
bool _inRename{ false };
|
||||
winrt::Windows::UI::Xaml::Controls::TextBox::LayoutUpdated_revoker _tabRenameBoxLayoutUpdatedRevoker;
|
||||
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
|
||||
|
||||
void _MakeTabViewItem();
|
||||
void _Focus();
|
||||
|
||||
void _CreateContextMenu();
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutSubItem _CreateCloseSubMenu();
|
||||
void _EnableCloseMenuItems();
|
||||
|
||||
void _RefreshVisualState();
|
||||
|
||||
void _BindEventHandlers(const winrt::Microsoft::Terminal::TerminalControl::TermControl& control) noexcept;
|
||||
|
@ -123,6 +134,9 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
void _MakeSwitchToTabCommand();
|
||||
|
||||
void _CloseTabsAfter();
|
||||
void _CloseOtherTabs();
|
||||
|
||||
friend class ::TerminalAppLocalTests::TabTests;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
import "ShortcutActionDispatch.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
|
@ -9,5 +10,7 @@ namespace TerminalApp
|
|||
Windows.UI.Xaml.Controls.IconSource IconSource { get; };
|
||||
Microsoft.Terminal.Settings.Model.Command SwitchToTabCommand { get; };
|
||||
UInt32 TabViewIndex { get; };
|
||||
|
||||
void SetDispatch(ShortcutActionDispatch dispatch);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -673,8 +673,10 @@ namespace winrt::TerminalApp::implementation
|
|||
auto newTabImpl = winrt::make_self<Tab>(profileGuid, term);
|
||||
_tabs.Append(*newTabImpl);
|
||||
|
||||
newTabImpl->SetDispatch(*_actionDispatch);
|
||||
|
||||
// Give the tab its index in the _tabs vector so it can manage its own SwitchToTab command.
|
||||
newTabImpl->UpdateTabViewIndex(_tabs.Size() - 1);
|
||||
_UpdateTabIndices();
|
||||
|
||||
// Hookup our event handlers to the new terminal
|
||||
_RegisterTerminalEvents(term, *newTabImpl);
|
||||
|
@ -2542,9 +2544,10 @@ namespace winrt::TerminalApp::implementation
|
|||
// - <none>
|
||||
void TerminalPage::_UpdateTabIndices()
|
||||
{
|
||||
for (uint32_t i = 0; i < _tabs.Size(); ++i)
|
||||
const uint32_t size = _tabs.Size();
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
_GetStrongTabImpl(i)->UpdateTabViewIndex(i);
|
||||
_GetStrongTabImpl(i)->UpdateTabViewIndex(i, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "SetTabColorArgs.g.cpp"
|
||||
#include "RenameTabArgs.g.cpp"
|
||||
#include "ExecuteCommandlineArgs.g.cpp"
|
||||
#include "CloseOtherTabsArgs.g.cpp"
|
||||
#include "CloseTabsAfterArgs.g.cpp"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
|
|
|
@ -505,6 +505,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
struct CloseOtherTabsArgs : public CloseOtherTabsArgsT<CloseOtherTabsArgs>
|
||||
{
|
||||
CloseOtherTabsArgs() = default;
|
||||
CloseOtherTabsArgs(uint32_t& tabIndex) :
|
||||
_Index{ tabIndex } {};
|
||||
GETSET_PROPERTY(Windows::Foundation::IReference<uint32_t>, Index, nullptr);
|
||||
|
||||
static constexpr std::string_view IndexKey{ "index" };
|
||||
|
@ -533,6 +535,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
struct CloseTabsAfterArgs : public CloseTabsAfterArgsT<CloseTabsAfterArgs>
|
||||
{
|
||||
CloseTabsAfterArgs() = default;
|
||||
CloseTabsAfterArgs(uint32_t& tabIndex) :
|
||||
_Index{ tabIndex } {};
|
||||
GETSET_PROPERTY(Windows::Foundation::IReference<uint32_t>, Index, nullptr);
|
||||
|
||||
static constexpr std::string_view IndexKey{ "index" };
|
||||
|
@ -567,4 +571,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
|||
BASIC_FACTORY(NewTabArgs);
|
||||
BASIC_FACTORY(SplitPaneArgs);
|
||||
BASIC_FACTORY(ExecuteCommandlineArgs);
|
||||
BASIC_FACTORY(CloseOtherTabsArgs);
|
||||
BASIC_FACTORY(CloseTabsAfterArgs);
|
||||
}
|
||||
|
|
|
@ -141,11 +141,13 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
|
||||
[default_interface] runtimeclass CloseOtherTabsArgs : IActionArgs
|
||||
{
|
||||
CloseOtherTabsArgs(UInt32 tabIndex);
|
||||
Windows.Foundation.IReference<UInt32> Index { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass CloseTabsAfterArgs : IActionArgs
|
||||
{
|
||||
CloseTabsAfterArgs(UInt32 tabIndex);
|
||||
Windows.Foundation.IReference<UInt32> Index { get; };
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue