fix(dock): decouple DockLayout from window creation and remove redundant state
This commit is contained in:
@@ -297,18 +297,17 @@ public sealed partial class DockLayout : Control
|
||||
return tabView;
|
||||
}
|
||||
|
||||
private object? _draggedItem;
|
||||
private DockPosition _currentDropPosition = DockPosition.None;
|
||||
|
||||
private record DockDragPayload(object Item, DockPanelNode SourceNode);
|
||||
|
||||
public event EventHandler<TabTornOffEventArgs>? TabTornOff;
|
||||
|
||||
private void TabView_TabDragStarting(Microsoft.UI.Xaml.Controls.TabView sender, Microsoft.UI.Xaml.Controls.TabViewTabDragStartingEventArgs args)
|
||||
{
|
||||
_draggedItem = args.Item;
|
||||
|
||||
if (_draggedItem != null && sender.Tag is DockPanelNode sourceNode)
|
||||
if (args.Item != null && sender.Tag is DockPanelNode sourceNode)
|
||||
{
|
||||
var payload = new DockDragPayload(_draggedItem, sourceNode);
|
||||
var payload = new DockDragPayload(args.Item, sourceNode);
|
||||
args.Data.Properties.Add(DRAG_PROPERTY_DOCK_TAB, payload); // Identify our drag
|
||||
}
|
||||
}
|
||||
@@ -316,7 +315,7 @@ public sealed partial class DockLayout : Control
|
||||
private void TabView_DragOver(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.DataView.Properties.TryGetValue(DRAG_PROPERTY_DOCK_TAB, out var payloadObj) &&
|
||||
payloadObj is DockDragPayload payload &&
|
||||
payloadObj is DockDragPayload &&
|
||||
sender is FrameworkElement targetElement)
|
||||
{
|
||||
e.AcceptedOperation = global::Windows.ApplicationModel.DataTransfer.DataPackageOperation.Move;
|
||||
@@ -349,7 +348,6 @@ public sealed partial class DockLayout : Control
|
||||
private void ClearDragOperationState()
|
||||
{
|
||||
ClearOverlayState();
|
||||
_draggedItem = null;
|
||||
}
|
||||
|
||||
private void UpdateDropOverlay(FrameworkElement targetElement, DockPosition position)
|
||||
@@ -441,6 +439,9 @@ public sealed partial class DockLayout : Control
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
// Raise event to let the host handle window creation
|
||||
TabTornOff?.Invoke(this, new TabTornOffEventArgs(args.Item, sourceNode));
|
||||
|
||||
DockMutationEngine.CleanupEmptyNodes(sourceNode);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -10,8 +10,14 @@ public sealed class TabTornOffEventArgs : EventArgs
|
||||
/// </summary>
|
||||
public object TabContent { get; }
|
||||
|
||||
public TabTornOffEventArgs(object tabContent)
|
||||
/// <summary>
|
||||
/// Gets the source node the tab is being torn off from.
|
||||
/// </summary>
|
||||
public object SourceNode { get; }
|
||||
|
||||
public TabTornOffEventArgs(object tabContent, object sourceNode)
|
||||
{
|
||||
TabContent = tabContent;
|
||||
SourceNode = sourceNode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,5 +17,13 @@ internal sealed partial class DockWindow : WindowEx
|
||||
rootGroup.AddChild(panel);
|
||||
|
||||
PART_DockLayout.Root = rootGroup;
|
||||
PART_DockLayout.TabTornOff += OnTabTornOff;
|
||||
}
|
||||
|
||||
private void OnTabTornOff(object? sender, TabTornOffEventArgs e)
|
||||
{
|
||||
App.CreateAndShowDockWindow(e.TabContent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,11 @@ internal sealed partial class EngineEditorWindow : WindowEx
|
||||
{
|
||||
var result = TabTearOffService.TryTearOffTab(list, args.Item, sender);
|
||||
|
||||
if (!result.IsSuccess)
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
App.CreateAndShowDockWindow(args.Item);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning($"Tab tear-off failed: {result.Message}");
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ internal static class TabTearOffService
|
||||
|
||||
try
|
||||
{
|
||||
App.CreateAndShowDockWindow(tabItem);
|
||||
// We no longer create the window here to decouple the service from the app shell.
|
||||
// The caller is responsible for window creation (e.g. via an event handler).
|
||||
return Result.Success();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -49,10 +50,10 @@ internal static class TabTearOffService
|
||||
catch (Exception rollbackEx)
|
||||
{
|
||||
Logger.LogError(rollbackEx);
|
||||
return Result.Failure($"Failed to create tear-off window and rollback failed: {ex.Message}. Rollback error: {rollbackEx.Message}");
|
||||
return Result.Failure($"Failed to tear off tab and rollback failed: {ex.Message}. Rollback error: {rollbackEx.Message}");
|
||||
}
|
||||
|
||||
return Result.Failure($"Failed to create tear-off window: {ex.Message}");
|
||||
return Result.Failure($"Failed to tear off tab: {ex.Message}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Reference in New Issue
Block a user