mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
Add 'Move Tab' submenu to tab context menu (#18107)
## Summary of the Pull Request Adds a "Move tab" submenu to the tab's context menu. This submenu includes "move tab to new window", "move left", and "move right". The new "move left/right" items are disabled if the tab can't be moved in a certain direction.' Closes #17900
This commit is contained in:
parent
d04381ec05
commit
d8089e903e
@ -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>
|
||||
@ -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>
|
||||
</data>
|
||||
<data name="TabMoveRight" xml:space="preserve">
|
||||
<value>Move right</value>
|
||||
</data>
|
||||
</root>
|
||||
@ -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;
|
||||
@ -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:
|
||||
@ -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"));
|
||||
@ -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"));
|
||||
@ -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)
|
||||
@ -164,7 +225,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
TabViewIndex(idx);
|
||||
TabViewNumTabs(numTabs);
|
||||
_EnableCloseMenuItems();
|
||||
_EnableMenuItems();
|
||||
_UpdateSwitchToTabKeyChord();
|
||||
}
|
||||
|
||||
|
||||
@ -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{};
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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;
|
||||
@ -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"
|
||||
@ -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&&) {
|
||||
@ -1560,8 +1545,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
});
|
||||
auto closeSubMenu = _AppendCloseMenuItems(contextMenuFlyout);
|
||||
closeSubMenu.Items().Append(closePaneMenuItem);
|
||||
|
||||
TabViewItem().ContextFlyout(contextMenuFlyout);
|
||||
}
|
||||
@ -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 */)
|
||||
{
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user