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 Close... option to Tab context menu #7728

Merged
merged 4 commits into from
Oct 15, 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
13 changes: 11 additions & 2 deletions src/cascadia/TerminalApp/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -454,4 +463,4 @@
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
<value>Cancel</value>
</data>
</root>
</root>
76 changes: 75 additions & 1 deletion src/cascadia/TerminalApp/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<>);
Expand Down
16 changes: 15 additions & 1 deletion src/cascadia/TerminalApp/Tab.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 };
Expand All @@ -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 };
Expand All @@ -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;
Expand All @@ -123,6 +134,9 @@ namespace winrt::TerminalApp::implementation

void _MakeSwitchToTabCommand();

void _CloseTabsAfter();
void _CloseOtherTabs();

friend class ::TerminalAppLocalTests::TabTests;
};
}
3 changes: 3 additions & 0 deletions src/cascadia/TerminalApp/Tab.idl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "ShortcutActionDispatch.idl";

namespace TerminalApp
{
Expand All @@ -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);
}
}
9 changes: 6 additions & 3 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,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);
Expand Down Expand Up @@ -2523,9 +2525,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);
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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" };
Expand Down Expand Up @@ -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" };
Expand Down Expand Up @@ -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);
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -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; };
};
}