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 'Move Tab' submenu to tab context menu #18107

Merged
merged 1 commit into from
Oct 31, 2024
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
11 changes: 10 additions & 1 deletion src/cascadia/TerminalApp/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@
<data name="TabCloseSubMenu" xml:space="preserve">
<value>Close</value>
</data>
<data name="TabMoveSubMenu" xml:space="preserve">
<value>Move tab</value>
</data>
<data name="TabCloseAfter" xml:space="preserve">
<value>Close tabs to the right</value>
</data>
Expand Down Expand Up @@ -941,4 +944,10 @@
<data name="CloseSnippetsPaneButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Close pane</value>
</data>
</root>
<data name="TabMoveLeft" xml:space="preserve">
<value>Move left</value>
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer "Move tab left" and "Move tab right" personally, but in the absence of other opinions i can stand down

</data>
<data name="TabMoveRight" xml:space="preserve">
<value>Move right</value>
</data>
</root>
103 changes: 82 additions & 21 deletions src/cascadia/TerminalApp/TabBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "TabBase.g.cpp"
#include "Utils.h"
#include "ColorHelper.h"
#include "../inc/WindowingBehavior.h"

using namespace winrt;
using namespace winrt::Windows::UI::Xaml;
Expand Down Expand Up @@ -56,10 +57,72 @@ namespace winrt::TerminalApp::implementation
tab->RequestFocusActiveControl.raise();
}
});
_AppendMoveMenuItems(contextMenuFlyout);
_AppendCloseMenuItems(contextMenuFlyout);
TabViewItem().ContextFlyout(contextMenuFlyout);
}

void TabBase::_AppendMoveMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout)
{
auto weakThis{ get_weak() };

// Move to new window
{
Controls::FontIcon moveTabToNewWindowTabSymbol;
moveTabToNewWindowTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
moveTabToNewWindowTabSymbol.Glyph(L"\xE8A7");

_moveToNewWindowMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
MoveTabArgs args{ winrt::to_hstring(NewWindow), MoveTabDirection::Forward };
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
tab->_dispatch.DoAction(*tab, actionAndArgs);
}
});
_moveToNewWindowMenuItem.Text(RS_(L"MoveTabToNewWindowText"));
_moveToNewWindowMenuItem.Icon(moveTabToNewWindowTabSymbol);

const auto moveTabToNewWindowToolTip = RS_(L"MoveTabToNewWindowToolTip");
WUX::Controls::ToolTipService::SetToolTip(_moveToNewWindowMenuItem, box_value(moveTabToNewWindowToolTip));
Automation::AutomationProperties::SetHelpText(_moveToNewWindowMenuItem, moveTabToNewWindowToolTip);
}

// Move left
{
_moveLeftMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
MoveTabArgs args{ hstring{}, MoveTabDirection::Backward };
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
tab->_dispatch.DoAction(*tab, actionAndArgs);
}
});
_moveLeftMenuItem.Text(RS_(L"TabMoveLeft"));
}

// Move right
{
_moveRightMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
MoveTabArgs args{ hstring{}, MoveTabDirection::Forward };
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
tab->_dispatch.DoAction(*tab, actionAndArgs);
}
});
_moveRightMenuItem.Text(RS_(L"TabMoveRight"));
}

// Create a sub-menu for our extended move tab items.
Controls::MenuFlyoutSubItem moveSubMenu;
moveSubMenu.Text(RS_(L"TabMoveSubMenu"));
moveSubMenu.Items().Append(_moveToNewWindowMenuItem);
moveSubMenu.Items().Append(_moveRightMenuItem);
moveSubMenu.Items().Append(_moveLeftMenuItem);
flyout.Items().Append(moveSubMenu);
}

// Method Description:
// - Append the close menu items to the context menu flyout
// Arguments:
Expand All @@ -75,7 +138,9 @@ namespace winrt::TerminalApp::implementation
_closeTabsAfterMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
tab->_CloseTabsAfter();
CloseTabsAfterArgs args{ tab->_TabViewIndex };
ActionAndArgs closeTabsAfter{ ShortcutAction::CloseTabsAfter, args };
tab->_dispatch.DoAction(*tab, closeTabsAfter);
}
});
_closeTabsAfterMenuItem.Text(RS_(L"TabCloseAfter"));
Expand All @@ -88,7 +153,9 @@ namespace winrt::TerminalApp::implementation
_closeOtherTabsMenuItem.Click([weakThis](auto&&, auto&&) {
if (auto tab{ weakThis.get() })
{
tab->_CloseOtherTabs();
CloseOtherTabsArgs args{ tab->_TabViewIndex };
ActionAndArgs closeOtherTabs{ ShortcutAction::CloseOtherTabs, args };
tab->_dispatch.DoAction(*tab, closeOtherTabs);
}
});
_closeOtherTabsMenuItem.Text(RS_(L"TabCloseOther"));
Expand Down Expand Up @@ -129,33 +196,27 @@ namespace winrt::TerminalApp::implementation
}

// Method Description:
// - Enable the Close menu items based on tab index and total number of tabs
// - Enable menu items based on tab index and total number of tabs
// Arguments:
// - <none>
// Return Value:
// - <none>
void TabBase::_EnableCloseMenuItems()
void TabBase::_EnableMenuItems()
{
// 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);
}
const auto tabIndex = TabViewIndex();
const auto numOfTabs = TabViewNumTabs();

void TabBase::_CloseTabsAfter()
{
CloseTabsAfterArgs args{ _TabViewIndex };
ActionAndArgs closeTabsAfter{ ShortcutAction::CloseTabsAfter, args };
// enabled if there are other tabs
_closeOtherTabsMenuItem.IsEnabled(numOfTabs > 1);

_dispatch.DoAction(closeTabsAfter);
}
// enabled if there are other tabs on the right
_closeTabsAfterMenuItem.IsEnabled(tabIndex < numOfTabs - 1);

void TabBase::_CloseOtherTabs()
{
CloseOtherTabsArgs args{ _TabViewIndex };
ActionAndArgs closeOtherTabs{ ShortcutAction::CloseOtherTabs, args };
// enabled if not left-most tab
_moveLeftMenuItem.IsEnabled(tabIndex > 0);

_dispatch.DoAction(closeOtherTabs);
// enabled if not last tab
_moveRightMenuItem.IsEnabled(tabIndex < numOfTabs - 1);
}

void TabBase::UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs)
Expand All @@ -164,7 +225,7 @@ namespace winrt::TerminalApp::implementation

TabViewIndex(idx);
TabViewNumTabs(numTabs);
_EnableCloseMenuItems();
_EnableMenuItems();
_UpdateSwitchToTabKeyChord();
}

Expand Down
8 changes: 5 additions & 3 deletions src/cascadia/TerminalApp/TabBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ namespace winrt::TerminalApp::implementation
winrt::Windows::UI::Xaml::FocusState _focusState{ winrt::Windows::UI::Xaml::FocusState::Unfocused };
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeOtherTabsMenuItem{};
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveToNewWindowMenuItem{};
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveRightMenuItem{};
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveLeftMenuItem{};
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
Microsoft::Terminal::Settings::Model::IActionMapView _actionMap{ nullptr };
winrt::hstring _keyChord{};
Expand All @@ -69,10 +72,9 @@ namespace winrt::TerminalApp::implementation

virtual void _MakeTabViewItem();

void _AppendMoveMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
winrt::Windows::UI::Xaml::Controls::MenuFlyoutSubItem _AppendCloseMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
void _EnableCloseMenuItems();
void _CloseTabsAfter();
void _CloseOtherTabs();
void _EnableMenuItems();
void _UpdateSwitchToTabKeyChord();
void _UpdateToolTip();

Expand Down
32 changes: 4 additions & 28 deletions src/cascadia/TerminalApp/TerminalTab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "Utils.h"
#include "ColorHelper.h"
#include "AppLogic.h"
#include "../inc/WindowingBehavior.h"

using namespace winrt;
using namespace winrt::Windows::UI::Xaml;
Expand Down Expand Up @@ -1443,23 +1442,6 @@ namespace winrt::TerminalApp::implementation
Automation::AutomationProperties::SetHelpText(splitTabMenuItem, splitTabToolTip);
}

Controls::MenuFlyoutItem moveTabToNewWindowMenuItem;
{
// "Move tab to new window"
Controls::FontIcon moveTabToNewWindowTabSymbol;
moveTabToNewWindowTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
moveTabToNewWindowTabSymbol.Glyph(L"\xE8A7");

moveTabToNewWindowMenuItem.Click({ get_weak(), &TerminalTab::_moveTabToNewWindowClicked });
moveTabToNewWindowMenuItem.Text(RS_(L"MoveTabToNewWindowText"));
moveTabToNewWindowMenuItem.Icon(moveTabToNewWindowTabSymbol);

const auto moveTabToNewWindowToolTip = RS_(L"MoveTabToNewWindowToolTip");

WUX::Controls::ToolTipService::SetToolTip(moveTabToNewWindowMenuItem, box_value(moveTabToNewWindowToolTip));
Automation::AutomationProperties::SetHelpText(moveTabToNewWindowMenuItem, moveTabToNewWindowToolTip);
}

Controls::MenuFlyoutItem closePaneMenuItem = _closePaneMenuItem;
{
// "Close pane"
Expand Down Expand Up @@ -1535,12 +1517,15 @@ namespace winrt::TerminalApp::implementation
contextMenuFlyout.Items().Append(renameTabMenuItem);
contextMenuFlyout.Items().Append(duplicateTabMenuItem);
contextMenuFlyout.Items().Append(splitTabMenuItem);
contextMenuFlyout.Items().Append(moveTabToNewWindowMenuItem);
_AppendMoveMenuItems(contextMenuFlyout);
contextMenuFlyout.Items().Append(exportTabMenuItem);
contextMenuFlyout.Items().Append(findMenuItem);
contextMenuFlyout.Items().Append(restartConnectionMenuItem);
contextMenuFlyout.Items().Append(menuSeparator);

auto closeSubMenu = _AppendCloseMenuItems(contextMenuFlyout);
closeSubMenu.Items().Append(closePaneMenuItem);

// GH#5750 - When the context menu is dismissed with ESC, toss the focus
// back to our control.
contextMenuFlyout.Closed([weakThis](auto&&, auto&&) {
Expand All @@ -1560,8 +1545,6 @@ namespace winrt::TerminalApp::implementation
}
}
});
auto closeSubMenu = _AppendCloseMenuItems(contextMenuFlyout);
closeSubMenu.Items().Append(closePaneMenuItem);

TabViewItem().ContextFlyout(contextMenuFlyout);
}
Expand Down Expand Up @@ -2001,13 +1984,6 @@ namespace winrt::TerminalApp::implementation
actionAndArgs.Action(ShortcutAction::ExportBuffer);
_dispatch.DoAction(*this, actionAndArgs);
}
void TerminalTab::_moveTabToNewWindowClicked(const winrt::Windows::Foundation::IInspectable& /* sender */,
const winrt::Windows::UI::Xaml::RoutedEventArgs& /* args */)
{
MoveTabArgs args{ winrt::to_hstring(NewWindow), MoveTabDirection::Forward };
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
_dispatch.DoAction(*this, actionAndArgs);
}
void TerminalTab::_findClicked(const winrt::Windows::Foundation::IInspectable& /* sender */,
const winrt::Windows::UI::Xaml::RoutedEventArgs& /* args */)
{
Expand Down
1 change: 0 additions & 1 deletion src/cascadia/TerminalApp/TerminalTab.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ namespace winrt::TerminalApp::implementation
void _splitTabClicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
void _closePaneClicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
void _exportTextClicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
void _moveTabToNewWindowClicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
void _findClicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);

void _bubbleRestartTerminalRequested(TerminalApp::TerminalPaneContent sender, const winrt::Windows::Foundation::IInspectable& args);
Expand Down
Loading