Skip to content

Commit 3acc2f4

Browse files
committed
chore: fix DocumentPane outer insert
1 parent 7e837ad commit 3acc2f4

File tree

10 files changed

+435
-95
lines changed

10 files changed

+435
-95
lines changed

samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/NestedSamples/DockControl_NestedPage.xaml

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="50" Background="Pink">
1616
<Button Content="AddDocument" Click="AddDocument" />
1717
<Button Content="AddTool" Click="AddTool" />
18+
<Button Content="RefreshTV" Click="RefreshTV" Background="Green" />
19+
<Button Content="ResetPanes" Click="ResetPanes" Background="Red" />
1820
</StackPanel>
1921
</Grid>
2022
</Page>

samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Content/NestedSamples/DockControl_NestedPage.xaml.cs

+10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using System.Linq;
55
using Uno.Toolkit.Samples.Entities;
66
using Uno.Toolkit.UI;
7+
using Uno.Extensions;
8+
79

810
#if IS_WINUI
911
using Microsoft.UI;
@@ -58,4 +60,12 @@ private void AddTool(object sender, RoutedEventArgs e)
5860
Content = $"content: Tool {_itemCounter}",
5961
});
6062
}
63+
private void RefreshTV(object sender, RoutedEventArgs e)
64+
{
65+
SUT.RefreshTabViews();
66+
}
67+
private void ResetPanes(object sender, RoutedEventArgs e)
68+
{
69+
SUT.ResetPanes();
70+
}
6171
}

src/Uno.Toolkit.UI/Controls/DockControl/DockControl.Enums.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
public enum DockDirection
44
{
55
None,
6-
Left, Top, Right, Bottom,
7-
//LeftMost, TopMost, RightMost, BottomMost, // maybe use the pane argument to specify "-most" or not
6+
Left, Top, Right, Bottom, // to split relative to the target pane
7+
OuterLeft, OuterTop, OuterRight, OuterBottom, // to split relative to a Editor/DocumentPane, as a ToolPane instead of a split DocumentPane
8+
EdgeLeft, EdgeTop, EdgeRight, EdgeBottom,
89
}
910

1011
public enum DockPaneClosingBehavior

src/Uno.Toolkit.UI/Controls/DockControl/DockControl.cs

+99-35
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ public void AddItem(DockItem item, ElementPane? pane, DockDirection? direction)
8383

8484
return Walk(_rootPane);
8585
}
86+
87+
#if DEBUG
88+
internal void RefreshTabViews()
89+
{
90+
foreach (var pane in Hierarchy.Walk<DockPane>(_rootPane, x => (x as LayoutPane)?.NestedPanes).OfType<ElementPane>())
91+
{
92+
pane.RepairTabView();
93+
}
94+
}
95+
internal void ResetPanes()
96+
{
97+
_rootPane?.PopulateNestedPanes();
98+
}
99+
#endif
86100
}
87101
public partial class DockControl // handlers, forwarded handlers
88102
{
@@ -108,6 +122,16 @@ internal void OnPaneCloseRequested(ElementPane pane, RoutedEventArgs e)
108122
TryCloseEmptyPane(pane);
109123
}
110124
}
125+
internal void OnPaneDragStarting(ElementPane pane, DragStartingEventArgs e)
126+
{
127+
Debug.WriteLine($"@xy DockPanel::OnPaneDragStarting");
128+
129+
e.Data.Properties[PropertyKeys.Container] = pane;
130+
}
131+
internal void OnPaneDropCompleted(ElementPane pane, DropCompletedEventArgs e)
132+
{
133+
Debug.WriteLine($"@xy DockPanel::OnPaneDragStarting");
134+
}
111135
internal void OnPaneDropEnter(ElementPane pane, DragEventArgs e)
112136
{
113137
Debug.WriteLine($"@xy DockControl::OnPaneDropEnter");
@@ -120,7 +144,7 @@ internal void OnPaneDropEnter(ElementPane pane, DragEventArgs e)
120144
if (pane.CanAcceptDrop(item))
121145
{
122146
e.AcceptedOperation = DataPackageOperation.Move;
123-
_dockingDiamond?.ShowAt(pane);
147+
_dockingDiamond?.ShowAt(pane, item);
124148
}
125149
else
126150
{
@@ -133,7 +157,7 @@ internal void OnPaneDropEnter(ElementPane pane, DragEventArgs e)
133157
if (container != pane)
134158
{
135159
e.AcceptedOperation = DataPackageOperation.Move;
136-
_dockingDiamond?.ShowAt(pane);
160+
_dockingDiamond?.ShowAt(pane, null);
137161
}
138162
else
139163
{
@@ -142,10 +166,6 @@ internal void OnPaneDropEnter(ElementPane pane, DragEventArgs e)
142166
}
143167
}
144168
}
145-
//internal void OnPaneDropOver(ElementPane pane, DragEventArgs e)
146-
//{
147-
// //Debug.WriteLine($"@xy DockControl::OnPaneDropOver");
148-
//}
149169
internal void OnPaneDropLeave(ElementPane pane, DragEventArgs e)
150170
{
151171
Debug.WriteLine($"@xy DockControl::OnPaneDropLeave");
@@ -170,6 +190,7 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
170190
if (!pane.CanAcceptDrop(item)) return;
171191

172192
var direction = _dockingDiamond?.Direction ?? DockDirection.None;
193+
var dirInfo = direction.Explode();
173194
if (direction is DockDirection.None)
174195
{
175196
if (container == pane) return;
@@ -182,28 +203,79 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
182203
TryCloseEmptyPane(container);
183204
}
184205
}
206+
else if (dirInfo.IsEdge)
207+
{
208+
throw new NotImplementedException(direction.ToString());
209+
}
185210
else if (pane is DocumentPane { ParentPane: EditorPane editorPane })
186211
{
187-
if (pane.ParentPane is not { } parentPane) return;
188-
if (!(parentPane.NestedPanes.IndexOf(pane) is var index && index != -1)) return;
189-
190-
// For document pane, if we previously had splited, then only allow split in the same orientation (horizontally/vertically).
191-
// If not, any direction is okay. If the document panes were to be reduced back to a single one again, remove the orientation restriction.
192-
if (!editorPane.IsOrientationLocked && direction.ToOrientation() is { } orientation)
212+
if (dirInfo.IsInner)
193213
{
194-
editorPane.Orientation = orientation;
195-
}
214+
if (pane.ParentPane is not { } parentPane) return;
215+
if (!(parentPane.NestedPanes.IndexOf(pane) is var index && index != -1)) return;
216+
217+
// For document pane, if we previously had splited, then only allow split in the same orientation (horizontally/vertically).
218+
// If not, any direction is okay. If the document panes were to be reduced back to a single one again, remove the orientation restriction.
219+
if (!editorPane.IsOrientationLocked && direction.ToOrientation() is { } orientation)
220+
{
221+
editorPane.Orientation = orientation;
222+
}
196223

197-
if (editorPane.Orientation == direction.ToOrientation() &&
198-
container.Remove(item))
224+
if (editorPane.Orientation == direction.ToOrientation() &&
225+
container.Remove(item))
226+
{
227+
var newPane = new DocumentPane();
228+
229+
parentPane.NestedPanes.Insert(index + (direction.IsLeading() ? 0 : 1), newPane);
230+
231+
newPane.Add(item);
232+
233+
TryCloseEmptyPane(container);
234+
}
235+
}
236+
else if (dirInfo.IsOuter && item is ToolItem)
199237
{
200-
var newPane = new DocumentPane();
238+
// refactor@xy: this block is mostly the same as `else if (item is ToolItem)` extract the logics into: TryInsertParallelPane(refPane, item, orientation)
239+
if (editorPane.ParentPane is not { } parentPane) return;
240+
if (!(parentPane.NestedPanes.IndexOf(editorPane) is var index && index != -1)) return;
201241

202-
parentPane.NestedPanes.Insert(index + direction is DockDirection.Left or DockDirection.Top ? 0 : 1, newPane);
242+
if (container.Remove(item))
243+
{
244+
// if the direction is parallel to the parent layout, just insert the new pane before/after the target pane
245+
if (parentPane.Orientation == direction.ToOrientation())
246+
{
247+
var newPane = new ToolPane();
203248

204-
newPane.Add(item);
249+
parentPane.NestedPanes.Insert(index + direction is DockDirection.Left or DockDirection.Top ? 0 : 1, newPane);
205250

206-
TryCloseEmptyPane(container);
251+
newPane.Add(item);
252+
}
253+
// if the direction is perpendicular to the parent layout,
254+
// remove the target pane from its parent, insert a new layout pane at its place,
255+
// add the target pane and the new pane.
256+
else
257+
{
258+
var newLayoutPane = new LayoutPane { Orientation = parentPane.Orientation.ToOpposite() };
259+
var newPane = new ToolPane();
260+
261+
parentPane.NestedPanes.Remove(editorPane);
262+
if (direction.IsLeading())
263+
{
264+
newLayoutPane.NestedPanes.Add(newPane);
265+
newLayoutPane.NestedPanes.Add(editorPane);
266+
}
267+
else
268+
{
269+
newLayoutPane.NestedPanes.Add(editorPane);
270+
newLayoutPane.NestedPanes.Add(newPane);
271+
}
272+
parentPane.NestedPanes.Insert(index, newLayoutPane);
273+
274+
newPane.Add(item);
275+
}
276+
277+
TryCloseEmptyPane(container);
278+
}
207279
}
208280
else
209281
{
@@ -213,6 +285,8 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
213285
}
214286
else if (item is ToolItem)
215287
{
288+
if (!dirInfo.IsInner && !dirInfo.IsEdge) throw new ArgumentOutOfRangeException(direction.ToString());
289+
216290
if (pane.ParentPane is not { } parentPane) return;
217291
if (!(parentPane.NestedPanes.IndexOf(pane) is var index && index != -1)) return;
218292

@@ -232,11 +306,11 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
232306
// add the target pane and the new pane.
233307
else
234308
{
235-
var newLayoutPane = new LayoutPane { Orientation = pane.ParentPane.Orientation.Opposite() };
309+
var newLayoutPane = new LayoutPane { Orientation = pane.ParentPane.Orientation.ToOpposite() };
236310
var newPane = new ToolPane();
237311

238312
parentPane.NestedPanes.Remove(pane);
239-
if (direction is DockDirection.Left or DockDirection.Top)
313+
if (direction.IsLeading())
240314
{
241315
newLayoutPane.NestedPanes.Add(newPane);
242316
newLayoutPane.NestedPanes.Add(pane);
@@ -335,7 +409,7 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
335409
// add the target pane and the new pane.
336410
else
337411
{
338-
var newLayoutPane = new LayoutPane { Orientation = pane.ParentPane.Orientation.Opposite() };
412+
var newLayoutPane = new LayoutPane { Orientation = pane.ParentPane.Orientation.ToOpposite() };
339413
var newPane = new ToolPane();
340414

341415
parentPane.NestedPanes.Remove(pane);
@@ -352,7 +426,7 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
352426
parentPane.NestedPanes.Insert(index, newLayoutPane);
353427

354428
pane.RepairTabView();
355-
429+
356430
newPane.AddRange(items);
357431
}
358432

@@ -365,17 +439,6 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
365439
}
366440
}
367441

368-
internal void OnPaneDragStarting(ElementPane pane, DragStartingEventArgs e)
369-
{
370-
Debug.WriteLine($"@xy DockPanel::OnPaneDragStarting");
371-
372-
e.Data.Properties[PropertyKeys.Container] = pane;
373-
}
374-
internal void OnPaneDropCompleted(ElementPane pane, DropCompletedEventArgs e)
375-
{
376-
Debug.WriteLine($"@xy DockPanel::OnPaneDragStarting");
377-
}
378-
379442
internal void OnItemCloseRequested(ElementPane pane, TabViewTabCloseRequestedEventArgs e)
380443
{
381444
Debug.WriteLine($"@xy DockControl::OnItemCloseRequested");
@@ -437,6 +500,7 @@ private void ReduceEmptyPaneRecursively(LayoutPane? pane)
437500
ReduceEmptyPaneRecursively(pane);
438501
}
439502
}
503+
440504
private (ElementPane? Container, DockItem? Item) ExtractDragInfo(DataPackageView view)
441505
{
442506
if (ExtractValue<ElementPane>(view.Properties, PropertyKeys.Container, out var container))

0 commit comments

Comments
 (0)