@@ -83,6 +83,20 @@ public void AddItem(DockItem item, ElementPane? pane, DockDirection? direction)
83
83
84
84
return Walk ( _rootPane ) ;
85
85
}
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
86
100
}
87
101
public partial class DockControl // handlers, forwarded handlers
88
102
{
@@ -108,6 +122,16 @@ internal void OnPaneCloseRequested(ElementPane pane, RoutedEventArgs e)
108
122
TryCloseEmptyPane ( pane ) ;
109
123
}
110
124
}
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
+ }
111
135
internal void OnPaneDropEnter ( ElementPane pane , DragEventArgs e )
112
136
{
113
137
Debug . WriteLine ( $ "@xy DockControl::OnPaneDropEnter") ;
@@ -120,7 +144,7 @@ internal void OnPaneDropEnter(ElementPane pane, DragEventArgs e)
120
144
if ( pane . CanAcceptDrop ( item ) )
121
145
{
122
146
e . AcceptedOperation = DataPackageOperation . Move ;
123
- _dockingDiamond ? . ShowAt ( pane ) ;
147
+ _dockingDiamond ? . ShowAt ( pane , item ) ;
124
148
}
125
149
else
126
150
{
@@ -133,7 +157,7 @@ internal void OnPaneDropEnter(ElementPane pane, DragEventArgs e)
133
157
if ( container != pane )
134
158
{
135
159
e . AcceptedOperation = DataPackageOperation . Move ;
136
- _dockingDiamond ? . ShowAt ( pane ) ;
160
+ _dockingDiamond ? . ShowAt ( pane , null ) ;
137
161
}
138
162
else
139
163
{
@@ -142,10 +166,6 @@ internal void OnPaneDropEnter(ElementPane pane, DragEventArgs e)
142
166
}
143
167
}
144
168
}
145
- //internal void OnPaneDropOver(ElementPane pane, DragEventArgs e)
146
- //{
147
- // //Debug.WriteLine($"@xy DockControl::OnPaneDropOver");
148
- //}
149
169
internal void OnPaneDropLeave ( ElementPane pane , DragEventArgs e )
150
170
{
151
171
Debug . WriteLine ( $ "@xy DockControl::OnPaneDropLeave") ;
@@ -170,6 +190,7 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
170
190
if ( ! pane . CanAcceptDrop ( item ) ) return ;
171
191
172
192
var direction = _dockingDiamond ? . Direction ?? DockDirection . None ;
193
+ var dirInfo = direction . Explode ( ) ;
173
194
if ( direction is DockDirection . None )
174
195
{
175
196
if ( container == pane ) return ;
@@ -182,28 +203,79 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
182
203
TryCloseEmptyPane ( container ) ;
183
204
}
184
205
}
206
+ else if ( dirInfo . IsEdge )
207
+ {
208
+ throw new NotImplementedException ( direction . ToString ( ) ) ;
209
+ }
185
210
else if ( pane is DocumentPane { ParentPane : EditorPane editorPane } )
186
211
{
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 )
193
213
{
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
+ }
196
223
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 )
199
237
{
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 ;
201
241
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 ( ) ;
203
248
204
- newPane . Add ( item ) ;
249
+ parentPane . NestedPanes . Insert ( index + direction is DockDirection . Left or DockDirection . Top ? 0 : 1 , newPane ) ;
205
250
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
+ }
207
279
}
208
280
else
209
281
{
@@ -213,6 +285,8 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
213
285
}
214
286
else if ( item is ToolItem )
215
287
{
288
+ if ( ! dirInfo . IsInner && ! dirInfo . IsEdge ) throw new ArgumentOutOfRangeException ( direction . ToString ( ) ) ;
289
+
216
290
if ( pane . ParentPane is not { } parentPane ) return ;
217
291
if ( ! ( parentPane . NestedPanes . IndexOf ( pane ) is var index && index != - 1 ) ) return ;
218
292
@@ -232,11 +306,11 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
232
306
// add the target pane and the new pane.
233
307
else
234
308
{
235
- var newLayoutPane = new LayoutPane { Orientation = pane . ParentPane . Orientation . Opposite ( ) } ;
309
+ var newLayoutPane = new LayoutPane { Orientation = pane . ParentPane . Orientation . ToOpposite ( ) } ;
236
310
var newPane = new ToolPane ( ) ;
237
311
238
312
parentPane . NestedPanes . Remove ( pane ) ;
239
- if ( direction is DockDirection . Left or DockDirection . Top )
313
+ if ( direction . IsLeading ( ) )
240
314
{
241
315
newLayoutPane . NestedPanes . Add ( newPane ) ;
242
316
newLayoutPane . NestedPanes . Add ( pane ) ;
@@ -335,7 +409,7 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
335
409
// add the target pane and the new pane.
336
410
else
337
411
{
338
- var newLayoutPane = new LayoutPane { Orientation = pane . ParentPane . Orientation . Opposite ( ) } ;
412
+ var newLayoutPane = new LayoutPane { Orientation = pane . ParentPane . Orientation . ToOpposite ( ) } ;
339
413
var newPane = new ToolPane ( ) ;
340
414
341
415
parentPane . NestedPanes . Remove ( pane ) ;
@@ -352,7 +426,7 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
352
426
parentPane . NestedPanes . Insert ( index , newLayoutPane ) ;
353
427
354
428
pane . RepairTabView ( ) ;
355
-
429
+
356
430
newPane . AddRange ( items ) ;
357
431
}
358
432
@@ -365,17 +439,6 @@ internal void OnPaneDrop(ElementPane pane, DragEventArgs e)
365
439
}
366
440
}
367
441
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
-
379
442
internal void OnItemCloseRequested ( ElementPane pane , TabViewTabCloseRequestedEventArgs e )
380
443
{
381
444
Debug . WriteLine ( $ "@xy DockControl::OnItemCloseRequested") ;
@@ -437,6 +500,7 @@ private void ReduceEmptyPaneRecursively(LayoutPane? pane)
437
500
ReduceEmptyPaneRecursively ( pane ) ;
438
501
}
439
502
}
503
+
440
504
private ( ElementPane ? Container , DockItem ? Item ) ExtractDragInfo ( DataPackageView view )
441
505
{
442
506
if ( ExtractValue < ElementPane > ( view . Properties , PropertyKeys . Container , out var container ) )
0 commit comments