feat(ui): drag-reorder Mission Control panes by their header

This commit is contained in:
Mika Kuns
2026-06-26 16:11:51 +02:00
parent f63be285a2
commit f6ecfc995f
3 changed files with 60 additions and 2 deletions
@@ -1,8 +1,46 @@
using System.Linq;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.VisualTree;
using ClaudeDo.Ui.ViewModels;
using ClaudeDo.Ui.ViewModels.Islands;
namespace ClaudeDo.Ui.Views.MissionControl;
public partial class MissionControlView : UserControl
{
public MissionControlView() => InitializeComponent();
// Shared with MonitorPaneView (the drag source).
public static readonly DataFormat<string> PaneFormat =
DataFormat.CreateStringApplicationFormat("claudedo-monitor-pane");
public MissionControlView()
{
InitializeComponent();
AddHandler(DragDrop.DragOverEvent, OnPaneDragOver);
AddHandler(DragDrop.DropEvent, OnPaneDrop);
}
private void OnPaneDragOver(object? sender, DragEventArgs e)
{
e.DragEffects = (e.DataTransfer?.Contains(PaneFormat) ?? false)
? DragDropEffects.Move
: DragDropEffects.None;
}
private void OnPaneDrop(object? sender, DragEventArgs e)
{
if (DataContext is not MissionControlViewModel vm) return;
var draggedId = e.DataTransfer?.TryGetValue(PaneFormat);
if (string.IsNullOrEmpty(draggedId)) return;
if (e.Source is not Avalonia.Visual src) return;
var targetPane = src.FindAncestorOfType<MonitorPaneView>();
if (targetPane?.DataContext is not TaskMonitorViewModel target) return;
var dragged = vm.Monitors.FirstOrDefault(m => m.SubscribedTaskId == draggedId);
if (dragged is null) return;
vm.MoveMonitor(dragged, target);
}
}