Add support for tab drag and drop (#3478)
* Add support for tag drag and drop Co-authored-by: James Clarke (WDG) <jeclarke@ntdev.microsoft.com>
This commit is contained in:
parent
3e8a1a78bc
commit
bd1604a0b5
|
@ -15,9 +15,9 @@ the MIT License. See LICENSE in the project root for license information. -->
|
|||
HorizontalContentAlignment="Stretch"
|
||||
IsAddTabButtonVisible="false"
|
||||
TabWidthMode="SizeToContent"
|
||||
CanReorderTabs="False"
|
||||
CanDragTabs="False"
|
||||
AllowDropTabs="False">
|
||||
CanReorderTabs="True"
|
||||
CanDragTabs="True"
|
||||
AllowDropTabs="True">
|
||||
|
||||
<mux:TabView.TabStripFooter>
|
||||
<mux:SplitButton
|
||||
|
|
|
@ -57,6 +57,26 @@ namespace winrt::TerminalApp::implementation
|
|||
_tabContent = this->TabContent();
|
||||
_tabRow = this->TabRow();
|
||||
_tabView = _tabRow.TabView();
|
||||
_rearranging = false;
|
||||
|
||||
_tabView.TabDragStarting([this](auto&& /*o*/, auto&& /*a*/) {
|
||||
_rearranging = true;
|
||||
_rearrangeFrom = std::nullopt;
|
||||
_rearrangeTo = std::nullopt;
|
||||
});
|
||||
|
||||
_tabView.TabDragCompleted([this](auto&& /*o*/, auto&& /*a*/) {
|
||||
if (_rearrangeFrom.has_value() && _rearrangeTo.has_value() && _rearrangeTo != _rearrangeFrom)
|
||||
{
|
||||
auto tab = _tabs.at(_rearrangeFrom.value());
|
||||
_tabs.erase(_tabs.begin() + _rearrangeFrom.value());
|
||||
_tabs.insert(_tabs.begin() + _rearrangeTo.value(), tab);
|
||||
}
|
||||
|
||||
_rearranging = false;
|
||||
_rearrangeFrom = std::nullopt;
|
||||
_rearrangeTo = std::nullopt;
|
||||
});
|
||||
|
||||
auto tabRowImpl = winrt::get_self<implementation::TabRowControl>(_tabRow);
|
||||
_newTabButton = tabRowImpl->NewTabButton();
|
||||
|
@ -1171,12 +1191,27 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
// Method Description:
|
||||
// - Responds to changes in the TabView's item list by changing the tabview's
|
||||
// visibility.
|
||||
// visibility. This method is also invoked when tabs are dragged / dropped as part of tab reordering
|
||||
// and this method hands that case as well in concert with TabDragStarting and TabDragCompleted handlers
|
||||
// that are set up in TerminalPage::Create()
|
||||
// Arguments:
|
||||
// - sender: the control that originated this event
|
||||
// - eventArgs: the event's constituent arguments
|
||||
void TerminalPage::_OnTabItemsChanged(const IInspectable& /*sender*/, const Windows::Foundation::Collections::IVectorChangedEventArgs& /*eventArgs*/)
|
||||
void TerminalPage::_OnTabItemsChanged(const IInspectable& /*sender*/, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs)
|
||||
{
|
||||
if (_rearranging)
|
||||
{
|
||||
if (eventArgs.CollectionChange() == Windows::Foundation::Collections::CollectionChange::ItemRemoved)
|
||||
{
|
||||
_rearrangeFrom = eventArgs.Index();
|
||||
}
|
||||
|
||||
if (eventArgs.CollectionChange() == Windows::Foundation::Collections::CollectionChange::ItemInserted)
|
||||
{
|
||||
_rearrangeTo = eventArgs.Index();
|
||||
}
|
||||
}
|
||||
|
||||
_UpdateTabView();
|
||||
}
|
||||
|
||||
|
@ -1196,34 +1231,37 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
// Method Description:
|
||||
// - Responds to the TabView control's Selection Changed event (to move a
|
||||
// new terminal control into focus.)
|
||||
// new terminal control into focus) when not in in the middle of a tab rearrangement.
|
||||
// Arguments:
|
||||
// - sender: the control that originated this event
|
||||
// - eventArgs: the event's constituent arguments
|
||||
void TerminalPage::_OnTabSelectionChanged(const IInspectable& sender, const WUX::Controls::SelectionChangedEventArgs& /*eventArgs*/)
|
||||
{
|
||||
auto tabView = sender.as<MUX::Controls::TabView>();
|
||||
auto selectedIndex = tabView.SelectedIndex();
|
||||
|
||||
// Unfocus all the tabs.
|
||||
for (auto tab : _tabs)
|
||||
if (!_rearranging)
|
||||
{
|
||||
tab->SetFocused(false);
|
||||
}
|
||||
auto tabView = sender.as<MUX::Controls::TabView>();
|
||||
auto selectedIndex = tabView.SelectedIndex();
|
||||
|
||||
if (selectedIndex >= 0)
|
||||
{
|
||||
try
|
||||
// Unfocus all the tabs.
|
||||
for (auto tab : _tabs)
|
||||
{
|
||||
auto tab = _tabs.at(selectedIndex);
|
||||
|
||||
_tabContent.Children().Clear();
|
||||
_tabContent.Children().Append(tab->GetRootElement());
|
||||
|
||||
tab->SetFocused(true);
|
||||
_titleChangeHandlers(*this, Title());
|
||||
tab->SetFocused(false);
|
||||
}
|
||||
|
||||
if (selectedIndex >= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto tab = _tabs.at(selectedIndex);
|
||||
|
||||
_tabContent.Children().Clear();
|
||||
_tabContent.Children().Append(tab->GetRootElement());
|
||||
|
||||
tab->SetFocused(true);
|
||||
_titleChangeHandlers(*this, Title());
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "CascadiaSettings.h"
|
||||
#include "Profile.h"
|
||||
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Microsoft.Terminal.TerminalControl.h>
|
||||
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
|
||||
|
@ -60,6 +61,10 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
bool _isFullscreen{ false };
|
||||
|
||||
bool _rearranging;
|
||||
std::optional<int> _rearrangeFrom;
|
||||
std::optional<int> _rearrangeTo;
|
||||
|
||||
void _ShowAboutDialog();
|
||||
void _ShowCloseWarningDialog();
|
||||
|
||||
|
|
Loading…
Reference in a new issue