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:
James Clarke 2019-11-08 12:27:20 -05:00 committed by Michael Niksa
parent 3e8a1a78bc
commit bd1604a0b5
3 changed files with 67 additions and 24 deletions

View file

@ -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

View file

@ -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();
}
}

View file

@ -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();