Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiaoy312 committed Feb 21, 2025
1 parent 836e7ed commit 6582046
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 185 deletions.
174 changes: 103 additions & 71 deletions src/Uno.Toolkit.UI/Controls/DockControl/DockControl.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel.DataTransfer;

#if IS_WINUI
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Uno.Extensions;
using Uno.Extensions.Specialized;
using Uno.UI.Extensions;

#else
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
#endif

using MUXC = Microsoft.UI.Xaml.Controls;

namespace Uno.Toolkit.UI;

Expand Down Expand Up @@ -62,40 +54,22 @@ public void AddItem(DockItem item, ElementPane? pane, DockDirection? direction)

internal IEnumerable<string> GetDebugDescriptions() => [];
#endif

private class DockControlElementFactory : MUXC.IElementFactoryShim
{
public UIElement GetElement(MUXC.ElementFactoryGetArgs args)
{
if (args.Data is DockPane pane)
{
return pane;
}

return new DockPane()
{
DataContext = args.Data,
};
}

public void RecycleElement(MUXC.ElementFactoryRecycleArgs args)
{
}
}
}
public partial class DockControl : Control // drag-and-drop
public partial class DockControl : Control // forwarded handlers
{
internal void OnPaneDropEnter(ElementPane pane, DragEventArgs e)
{
Debug.WriteLine($"@xy DockControl::OnPaneDropEnter");

var item = e.DataView.Properties[PropertyKeys.Item];
if (pane.CanAcceptDrop(item))
{
e.AcceptedOperation = DataPackageOperation.Move;
_dockingDiamond?.ShowAt(pane);
}
else
{
e.AcceptedOperation = DataPackageOperation.None;
_dockingDiamond?.Hide();
}
}
Expand All @@ -107,80 +81,138 @@ internal void OnPaneDropLeave(ElementPane pane, DragEventArgs e)
{
Debug.WriteLine($"@xy DockControl::OnPaneDropLeave");

e.AcceptedOperation = DataPackageOperation.None;
_dockingDiamond?.Hide();
}
internal void OnPaneDrop(ElementPane targetPane, DragEventArgs e)
internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
{
Debug.WriteLine($"@xy DockControl::OnPaneDrop: {_dockingDiamond?.Direction}");
Debug.WriteLine($"@xy DockControl::OnPaneDrop: {pane.GetType().Name}, {_dockingDiamond?.Direction}, {e.AcceptedOperation}");

_dockingDiamond?.Hide();

if (e.AcceptedOperation is DataPackageOperation.None) return;
if (e.DataView.Properties[PropertyKeys.Container] is not ElementPane originPane) return;
if (e.DataView.Properties[PropertyKeys.Item] is not DockItem item) return;
if (!pane.CanAcceptDrop(item)) return;

var direction = _dockingDiamond?.Direction ?? DockDirection.None;
if (direction is DockDirection.None)
{
if (originPane == targetPane) return;
if (originPane == pane) return;

if (targetPane.CanAcceptDrop(item) && originPane.Remove(item))
if (originPane.Remove(item))
{
targetPane.Add(item);
pane.Add(item);
TryCloseEmptyPane(originPane);
}
}
else if (item is DocumentItem & pane is DocumentPane)
{
// For document pane, if we previously had splited, then only allow split in the same orientation (horizontally/vertically).
// If not, any direction is okay. If the document panes were to be reduced to a single pane again, remove the orientation restriction.
throw new NotImplementedException();
}
else if (item is ToolItem)
{
if (targetPane.FindFirstAncestor<LayoutPane>() is not { } parentLayoutPane) return;
if (!(parentLayoutPane.NestedPanes.IndexOf(targetPane) is var index && index != -1)) return;
if (pane.ParentPane is not { } parentPane) return;
if (!(parentPane.NestedPanes.IndexOf(pane) is var index && index != -1)) return;

if (originPane.Remove(item))
{
ElementPane GetDestinationPane()
// if the direction is parallel to the parent layout, just insert the new pane before/after the target pane
if (parentPane.Orientation == direction.ToOrientation())
{
// if the direction is parallel to the parent layout, just insert the new pane before/after the target pane
if (parentLayoutPane.Orientation == direction.ToOrientation())
{
var newPane = new ToolPane();

parentLayoutPane.NestedPanes.Insert(index + direction is DockDirection.Right or DockDirection.Bottom ? 1 : 0, newPane);
var newPane = new ToolPane();

return newPane;
parentPane.NestedPanes.Insert(index + direction is DockDirection.Right or DockDirection.Bottom ? 1 : 0, newPane);

newPane.Add(item);
}
// if the direction is perpendicular to the parent layout,
// remove the target pane from its parent, insert a new layout pane at its place,
// add the target pane and the new pane.
else
{
var newLayoutPane = new LayoutPane { Orientation = pane.ParentPane.Orientation.Opposite() };
var newPane = new ToolPane();

parentPane.NestedPanes.Remove(pane);
if (direction is DockDirection.Left or DockDirection.Top)
{
newLayoutPane.NestedPanes.Add(newPane);
newLayoutPane.NestedPanes.Add(pane);
}
// if the direction is perpendicular to the parent layout,
// remove the target pane from its parent, insert a new layout pane at its place,
// add the target pane and the new pane.
else
{
var newLayoutPane = new LayoutPane { Orientation = parentLayoutPane.Orientation.Opposite() };
var newPane = new ToolPane();

if (direction is DockDirection.Left or DockDirection.Top)
{
newLayoutPane.NestedPanes.Add(newPane);
newLayoutPane.NestedPanes.Add(targetPane);
}
else
{
newLayoutPane.NestedPanes.Add(targetPane);
newLayoutPane.NestedPanes.Add(newPane);
}
parentLayoutPane.NestedPanes.Remove(targetPane);
parentLayoutPane.NestedPanes.Insert(index, newLayoutPane);

return newPane;
newLayoutPane.NestedPanes.Add(pane);
newLayoutPane.NestedPanes.Add(newPane);
}
parentPane.NestedPanes.Insert(index, newLayoutPane);

pane.RepairTabView();

newPane.Add(item);
}
var destinationPane = GetDestinationPane();
destinationPane.Add(item);

TryCloseEmptyPane(originPane);
}
}

// throw new NotImplementedException($"DockControl::OnItemDropCompleted: {direction}");
else
{
throw new NotImplementedException($"DockControl::OnItemDropCompleted: {direction}");
}
}

//internal void OnItemAdded(ElementPane pane, DockItem item) { }
//internal void OnItemRemoved(ElementPane pane, DockItem item) { }
internal void OnItemCloseRequested(ElementPane pane, TabViewTabCloseRequestedEventArgs e)
{
Debug.WriteLine($"@xy DockControl::OnItemCloseRequested");

if (e.Item is DockItem item)
{
pane.Remove(item);
TryCloseEmptyPane(pane);
}
}
internal void OnItemDragStarting(ElementPane pane, TabViewTabDragStartingEventArgs e)
{
Debug.WriteLine($"@xy DockControl::OnItemDragStarting");

e.Data.Properties[PropertyKeys.Container] = pane;
e.Data.Properties[PropertyKeys.Item] = e.Item;
}
internal void OnItemDropCompleted(ElementPane pane, TabViewTabDragCompletedEventArgs e)
{
Debug.WriteLine($"@xy DockControl::OnItemDropCompleted");

_dockingDiamond?.Hide();
}
}
internal void OnItemDroppedOutside(ElementPane pane, TabViewTabDroppedOutsideEventArgs e)
{
Debug.WriteLine($"@xy DockControl::OnItemDroppedOutside");
}
}
public partial class DockControl : Control
{
private void TryCloseEmptyPane(ElementPane pane)
{
if (pane is { ParentPane: { } parent, ElementCount: 0 })
{
if (parent.NestedPanes.Remove(pane))
{
ReduceEmptyPaneRecursively(parent);
}
}
}
private void ReduceEmptyPaneRecursively(LayoutPane? pane)
{
if (pane?.NestedPanes.Count == 0 &&
pane.ParentPane?.NestedPanes is { } parentNestedPanes &&
parentNestedPanes.Remove(pane) &&
parentNestedPanes.Count == 0)
{
ReduceEmptyPaneRecursively(pane);
}
}
}
35 changes: 9 additions & 26 deletions src/Uno.Toolkit.UI/Controls/DockControl/DockControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,32 +128,11 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="utu:DocumentPane">
<void:Grid Background="LimeGreen">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<utu:DockTabListView x:Name="ElementsTabStrip"
Grid.Row="0"
SelectionMode="Single"
Background="SkyBlue">
<utu:DockTabListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</utu:DockTabListView.ItemsPanel>
</utu:DockTabListView>

<Border Grid.Row="1" Background="Orange">
<ContentControl x:Name="ActiveElementHost" />
</Border>

</void:Grid>
<Grid Background="Transparent">
<TabView x:Name="TabView"
IsAddTabButtonVisible="False"
CanReorderTabs="True"
void:TabWidthMode="SizeToContent"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<TabView.Resources>
Expand Down Expand Up @@ -201,15 +180,19 @@
</Grid.RowDefinitions>

<Grid Grid.Row="0">
<ContentControl Content="{Binding ElementName=TabView, Path=SelectedItem}" />
<ContentControl Content="{Binding ElementName=TabView, Path=SelectedItem}">
<ContentControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Grid>
<void:ContentControl Grid.Row="1" />
<void:ListView Grid.Row="2" />

<TabView x:Name="TabView"
Grid.Row="1"
IsAddTabButtonVisible="False"
CanReorderTabs="True"
void:TabWidthMode="SizeToContent"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<TabView.Resources>
Expand Down
8 changes: 1 addition & 7 deletions src/Uno.Toolkit.UI/Controls/DockControl/DockDirection.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Uno.Toolkit.UI;
namespace Uno.Toolkit.UI;

public enum DockDirection
{
Expand Down
8 changes: 2 additions & 6 deletions src/Uno.Toolkit.UI/Controls/DockControl/DockGridPanel.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Uno.UI.Extensions;

#if IS_WINUI
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Uno.UI.Extensions;
#else
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
Expand Down Expand Up @@ -81,4 +77,4 @@ public DockPaneItemsGrid()
{
Loaded += (s, e) => this.FindFirstAncestor<LayoutPane>()?.OnItemsPanelPrepared(this);
}
}
}
18 changes: 1 addition & 17 deletions src/Uno.Toolkit.UI/Controls/DockControl/DockItem.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

#if IS_WINUI
#if IS_WINUI
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
#else
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
#endif

namespace Uno.Toolkit.UI;
Expand Down Expand Up @@ -69,11 +61,3 @@ public DockItem()

public partial class DocumentItem : DockItem{ }
public partial class ToolItem : DockItem { }


public class DockItemHeaderTemplate : DataTemplate
{
public DockItemHeaderTemplate()
{
}
}
Loading

0 comments on commit 6582046

Please sign in to comment.