Add Split Tab option to tab context menu (#10832)
<!-- 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 Adds the Split Tab option to the tab context menu. Clicking this option will `auto` split the active pane of the tab into a duplicate pane. Clicking on an unfocused tab and splitting it will bring that tab into focus and split its active pane. We could make this a flyout from the context menu to let people choose horizontal/vertical split in the future if it's requested. I'm also wondering if this should be called Split Pane instead of Split Tab? <!-- 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 #5025 * [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 https://user-images.githubusercontent.com/48369326/127691919-aae4683a-212a-4525-a0eb-a61c877461ed.mp4 <!-- 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
2bd4670100
commit
0b4839d94d
|
@ -662,10 +662,13 @@
|
|||
<data name="DropPathTabRun.Text" xml:space="preserve">
|
||||
<value>Open a new tab in given starting directory</value>
|
||||
</data>
|
||||
<data name="SplitTabText" xml:space="preserve">
|
||||
<value>Split Tab</value>
|
||||
</data>
|
||||
<data name="DropPathTabNewWindow.Text" xml:space="preserve">
|
||||
<value>Open a new window with given starting directory</value>
|
||||
</data>
|
||||
<data name="DropPathTabSplit.Text" xml:space="preserve">
|
||||
<value>Split the window and start in given directory</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
|
|
@ -192,6 +192,16 @@ namespace winrt::TerminalApp::implementation
|
|||
}
|
||||
});
|
||||
|
||||
newTabImpl->SplitTabRequested([weakTab, weakThis{ get_weak() }]() {
|
||||
auto page{ weakThis.get() };
|
||||
auto tab{ weakTab.get() };
|
||||
|
||||
if (page && tab)
|
||||
{
|
||||
page->_SplitTab(*tab);
|
||||
}
|
||||
});
|
||||
|
||||
auto tabViewItem = newTabImpl->TabViewItem();
|
||||
_tabView.TabItems().Append(tabViewItem);
|
||||
|
||||
|
@ -357,6 +367,20 @@ namespace winrt::TerminalApp::implementation
|
|||
CATCH_LOG();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets the specified tab as the focused tab and splits its active pane
|
||||
// Arguments:
|
||||
// - tab: tab to split
|
||||
void TerminalPage::_SplitTab(TerminalTab& tab)
|
||||
{
|
||||
try
|
||||
{
|
||||
_SetFocusedTab(tab);
|
||||
_SplitPane(tab, SplitState::Automatic, SplitType::Duplicate);
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Removes the tab (both TerminalControl and XAML) after prompting for approval
|
||||
// Arguments:
|
||||
|
|
|
@ -1238,6 +1238,33 @@ namespace winrt::TerminalApp::implementation
|
|||
return;
|
||||
}
|
||||
|
||||
_SplitPane(*focusedTab, splitType, splitMode, splitSize, newTerminalArgs);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Split the focused pane of the given tab, either horizontally or vertically, and place the
|
||||
// given TermControl into the newly created pane.
|
||||
// - If splitType == SplitState::None, this method does nothing.
|
||||
// Arguments:
|
||||
// - tab: The tab that is going to be split.
|
||||
// - splitType: one value from the TerminalApp::SplitState enum, indicating how the
|
||||
// new pane should be split from its parent.
|
||||
// - splitMode: value from TerminalApp::SplitType enum, indicating the profile to be used in the newly split pane.
|
||||
// - newTerminalArgs: An object that may contain a blob of parameters to
|
||||
// control which profile is created and with possible other
|
||||
// configurations. See CascadiaSettings::BuildSettings for more details.
|
||||
void TerminalPage::_SplitPane(TerminalTab& tab,
|
||||
const SplitState splitType,
|
||||
const SplitType splitMode,
|
||||
const float splitSize,
|
||||
const NewTerminalArgs& newTerminalArgs)
|
||||
{
|
||||
// Do nothing if we're requesting no split.
|
||||
if (splitType == SplitState::None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TerminalSettingsCreateResult controlSettings{ nullptr };
|
||||
|
@ -1246,12 +1273,12 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
if (splitMode == SplitType::Duplicate)
|
||||
{
|
||||
std::optional<GUID> current_guid = focusedTab->GetFocusedProfile();
|
||||
std::optional<GUID> current_guid = tab.GetFocusedProfile();
|
||||
if (current_guid)
|
||||
{
|
||||
profileFound = true;
|
||||
controlSettings = TerminalSettings::CreateWithProfileByID(_settings, current_guid.value(), *_bindings);
|
||||
const auto workingDirectory = focusedTab->GetActiveTerminalControl().WorkingDirectory();
|
||||
const auto workingDirectory = tab.GetActiveTerminalControl().WorkingDirectory();
|
||||
const auto validWorkingDirectory = !workingDirectory.empty();
|
||||
if (validWorkingDirectory)
|
||||
{
|
||||
|
@ -1287,10 +1314,10 @@ namespace winrt::TerminalApp::implementation
|
|||
auto realSplitType = splitType;
|
||||
if (realSplitType == SplitState::Automatic)
|
||||
{
|
||||
realSplitType = focusedTab->PreCalculateAutoSplit(availableSpace);
|
||||
realSplitType = tab.PreCalculateAutoSplit(availableSpace);
|
||||
}
|
||||
|
||||
const auto canSplit = focusedTab->PreCalculateCanSplit(realSplitType, splitSize, availableSpace);
|
||||
const auto canSplit = tab.PreCalculateCanSplit(realSplitType, splitSize, availableSpace);
|
||||
if (!canSplit)
|
||||
{
|
||||
return;
|
||||
|
@ -1299,11 +1326,11 @@ namespace winrt::TerminalApp::implementation
|
|||
auto newControl = _InitControl(controlSettings, controlConnection);
|
||||
|
||||
// Hookup our event handlers to the new terminal
|
||||
_RegisterTerminalEvents(newControl, *focusedTab);
|
||||
_RegisterTerminalEvents(newControl, tab);
|
||||
|
||||
_UnZoomIfNeeded();
|
||||
|
||||
focusedTab->SplitPane(realSplitType, splitSize, realGuid, newControl);
|
||||
tab.SplitPane(realSplitType, splitSize, realGuid, newControl);
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
|
|
@ -219,6 +219,8 @@ namespace winrt::TerminalApp::implementation
|
|||
void _DuplicateFocusedTab();
|
||||
void _DuplicateTab(const TerminalTab& tab);
|
||||
|
||||
void _SplitTab(TerminalTab& tab);
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction _HandleCloseTabRequested(winrt::TerminalApp::TabBase tab);
|
||||
void _CloseTabAtIndex(uint32_t index);
|
||||
void _RemoveTab(const winrt::TerminalApp::TabBase& tab);
|
||||
|
@ -254,6 +256,11 @@ namespace winrt::TerminalApp::implementation
|
|||
const Microsoft::Terminal::Settings::Model::SplitType splitMode = Microsoft::Terminal::Settings::Model::SplitType::Manual,
|
||||
const float splitSize = 0.5f,
|
||||
const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr);
|
||||
void _SplitPane(TerminalTab& tab,
|
||||
const Microsoft::Terminal::Settings::Model::SplitState splitType,
|
||||
const Microsoft::Terminal::Settings::Model::SplitType splitMode = Microsoft::Terminal::Settings::Model::SplitType::Manual,
|
||||
const float splitSize = 0.5f,
|
||||
const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr);
|
||||
void _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
|
||||
void _ToggleSplitOrientation();
|
||||
|
||||
|
|
|
@ -936,12 +936,30 @@ namespace winrt::TerminalApp::implementation
|
|||
duplicateTabMenuItem.Icon(duplicateTabSymbol);
|
||||
}
|
||||
|
||||
Controls::MenuFlyoutItem splitTabMenuItem;
|
||||
{
|
||||
// "Split Tab"
|
||||
Controls::FontIcon splitTabSymbol;
|
||||
splitTabSymbol.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" });
|
||||
splitTabSymbol.Glyph(L"\xF246"); // ViewDashboard
|
||||
|
||||
splitTabMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->_SplitTabRequestedHandlers();
|
||||
}
|
||||
});
|
||||
splitTabMenuItem.Text(RS_(L"SplitTabText"));
|
||||
splitTabMenuItem.Icon(splitTabSymbol);
|
||||
}
|
||||
|
||||
// Build the menu
|
||||
Controls::MenuFlyout contextMenuFlyout;
|
||||
Controls::MenuFlyoutSeparator menuSeparator;
|
||||
contextMenuFlyout.Items().Append(chooseColorMenuItem);
|
||||
contextMenuFlyout.Items().Append(renameTabMenuItem);
|
||||
contextMenuFlyout.Items().Append(duplicateTabMenuItem);
|
||||
contextMenuFlyout.Items().Append(splitTabMenuItem);
|
||||
contextMenuFlyout.Items().Append(menuSeparator);
|
||||
|
||||
// GH#5750 - When the context menu is dismissed with ESC, toss the focus
|
||||
|
@ -1315,4 +1333,5 @@ namespace winrt::TerminalApp::implementation
|
|||
DEFINE_EVENT(TerminalTab, ColorCleared, _colorCleared, winrt::delegate<>);
|
||||
DEFINE_EVENT(TerminalTab, TabRaiseVisualBell, _TabRaiseVisualBellHandlers, winrt::delegate<>);
|
||||
DEFINE_EVENT(TerminalTab, DuplicateRequested, _DuplicateRequestedHandlers, winrt::delegate<>);
|
||||
DEFINE_EVENT(TerminalTab, SplitTabRequested, _SplitTabRequestedHandlers, winrt::delegate<>);
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ namespace winrt::TerminalApp::implementation
|
|||
DECLARE_EVENT(ColorCleared, _colorCleared, winrt::delegate<>);
|
||||
DECLARE_EVENT(TabRaiseVisualBell, _TabRaiseVisualBellHandlers, winrt::delegate<>);
|
||||
DECLARE_EVENT(DuplicateRequested, _DuplicateRequestedHandlers, winrt::delegate<>);
|
||||
DECLARE_EVENT(SplitTabRequested, _SplitTabRequestedHandlers, winrt::delegate<>);
|
||||
TYPED_EVENT(TaskbarProgressChanged, IInspectable, IInspectable);
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in a new issue