feat(ui): ghost-window drag infrastructure for task rows
Add the borderless, transparent, topmost, click-through DragGhostWindow that hosts a tilted (~-6deg) translucent snapshot of the dragged row, a TaskDragController that owns its lifecycle (snapshot -> show -> follow -> close), and a pure DPI-aware DragHitTest helper (unit-tested) for the cross-window screen hit test. Adds the TaskRowViewModel.IsDragging flag and the 'grabbed' Border.task-row.dragging style (lift + scale + lower opacity + shadow). Not yet wired into the drag source.
This commit is contained in:
29
src/ClaudeDo.Ui/Views/Controls/DragGhostWindow.axaml.cs
Normal file
29
src/ClaudeDo.Ui/Views/Controls/DragGhostWindow.axaml.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace ClaudeDo.Ui.Views.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Borderless, transparent, topmost, click-through window that hosts the translucent drag
|
||||
/// "ghost" — a snapshot of the row being dragged. It never activates (so the source window
|
||||
/// keeps pointer capture) and is repositioned to the screen cursor on every captured move.
|
||||
/// </summary>
|
||||
public partial class DragGhostWindow : Window
|
||||
{
|
||||
public DragGhostWindow() => InitializeComponent();
|
||||
|
||||
/// <summary>
|
||||
/// Show <paramref name="image"/> at <paramref name="logicalWidth"/>×<paramref name="logicalHeight"/>
|
||||
/// with <paramref name="pad"/> of slack around it so the tilt isn't clipped by the window bounds.
|
||||
/// </summary>
|
||||
public void SetImage(IImage image, double logicalWidth, double logicalHeight, double pad)
|
||||
{
|
||||
GhostImage.Source = image;
|
||||
GhostImage.Width = logicalWidth;
|
||||
GhostImage.Height = logicalHeight;
|
||||
GhostImage.Margin = new Thickness(pad);
|
||||
Width = logicalWidth + pad * 2;
|
||||
Height = logicalHeight + pad * 2;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user