Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 0 additions & 169 deletions COMPILATION_FIXES.md

This file was deleted.

2 changes: 2 additions & 0 deletions src/XTMF2.GUI/Controls/ModelSystemCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,8 @@ public ModelSystemCanvas()
// ── Resize drag state ─────────────────────────────────────────────────
/// <summary>The canvas element being resized, or <c>null</c> when not resizing.</summary>
private ICanvasElement? _resizing;
/// <summary><c>true</c> while a drag or resize operation is in progress (used to prevent inline editor close on focus loss).</summary>
private bool _inDragOrResize;
/// <summary>Pointer position at the start of the resize drag.</summary>
private Point _resizeStartPos;
/// <summary>Node rendered width at the start of the resize drag.</summary>
Expand Down
83 changes: 72 additions & 11 deletions src/XTMF2.GUI/Controls/ModelSystemCanvas/ModelSystemCanvas.Input.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,20 @@ private void OnPointerPressedTunnel(object? sender, PointerPressedEventArgs e)
var resizeHit = HitTestResizeHandle(mpos);
if (resizeHit is null) return;

// Commit any open editor so its LostFocus handler doesn't fire after
// we capture the pointer, which would interfere with the resize drag.
if (_editingParamNode is not null) CommitParamEdit();
if (_editingCommentBlock is not null) CommitCommentEdit();
if (_editingNameElement is not null) CommitNameEdit();
// Don't commit open editors if we're resizing the element being edited.
// The _inDragOrResize flag will prevent LostFocus handlers from closing them,
// and SyncEditingElementPositions() will keep them synchronized during the resize.
bool isResizingEditedElement =
ReferenceEquals(resizeHit, _editingParamNode) ||
ReferenceEquals(resizeHit, _editingNameElement) ||
ReferenceEquals(resizeHit, _editingCommentBlock);

if (!isResizingEditedElement)
{
if (_editingParamNode is not null) CommitParamEdit();
if (_editingCommentBlock is not null) CommitCommentEdit();
if (_editingNameElement is not null) CommitNameEdit();
}

ClearMultiSelection();
_resizing = resizeHit;
Expand Down Expand Up @@ -307,9 +316,18 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
var resizeHit = HitTestResizeHandle(mpos);
if (resizeHit is not null)
{
if (_editingParamNode is not null) CommitParamEdit();
if (_editingCommentBlock is not null) CommitCommentEdit();
if (_editingNameElement is not null) CommitNameEdit();
// Don't commit editors if we're resizing the element being edited.
bool isResizingEditedElement =
ReferenceEquals(resizeHit, _editingParamNode) ||
ReferenceEquals(resizeHit, _editingNameElement) ||
ReferenceEquals(resizeHit, _editingCommentBlock);

if (!isResizingEditedElement)
{
if (_editingParamNode is not null) CommitParamEdit();
if (_editingCommentBlock is not null) CommitCommentEdit();
if (_editingNameElement is not null) CommitNameEdit();
}
ClearMultiSelection();
_resizing = resizeHit;
_resizeStartPos = mpos;
Expand Down Expand Up @@ -365,11 +383,26 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
// Clicking elsewhere commits any open edit.
// Guard: if the click was already handled by a child (e.g. the variable
// autocomplete dropdown's TextBlock items), do not commit the edit.
// Also: if we're about to drag one of the edited elements, keep the editor open.
if (!e.Handled)
{
if (_editingParamNode is not null) CommitParamEdit();
if (_editingCommentBlock is not null) CommitCommentEdit();
if (_editingNameElement is not null) CommitNameEdit();
var clickedElement = HitTest(mpos, testComments: false);
bool isDraggingEditedElement =
ReferenceEquals(clickedElement, _editingParamNode) ||
ReferenceEquals(clickedElement, _editingNameElement) ||
ReferenceEquals(clickedElement, _editingCommentBlock) ||
(clickedElement is not null && _multiSelection.Contains(clickedElement) &&
((_editingParamNode is not null && _multiSelection.Contains(_editingParamNode)) ||
(_editingNameElement is not null && _multiSelection.Contains(_editingNameElement)) ||
(_editingCommentBlock is not null && _multiSelection.Contains(_editingCommentBlock))));

// Only commit if we're not about to drag one of the edited elements.
if (!isDraggingEditedElement)
{
if (_editingParamNode is not null) CommitParamEdit();
if (_editingCommentBlock is not null) CommitCommentEdit();
if (_editingNameElement is not null) CommitNameEdit();
}
}
}

Expand Down Expand Up @@ -632,9 +665,17 @@ protected override void OnPointerMoved(PointerEventArgs e)
// ── Resize drag ───────────────────────────────────────────────────
if (_resizing is not null)
{
_inDragOrResize = true;
var dw = mpos.X - _resizeStartPos.X;
var dh = mpos.Y - _resizeStartPos.Y;
_resizing.ResizeToPreview(_resizeStartW + dw, _resizeStartH + dh);
// Only sync inline editor if it's the element being resized
if (ReferenceEquals(_resizing, _editingParamNode) ||
ReferenceEquals(_resizing, _editingNameElement) ||
ReferenceEquals(_resizing, _editingCommentBlock))
{
SyncEditingElementPositions();
}
InvalidateAndMeasure();
e.Handled = true;
return;
Expand Down Expand Up @@ -675,6 +716,7 @@ protected override void OnPointerMoved(PointerEventArgs e)
if (_dragging is null) return;

// ── Element drag (single or group) ────────────────────────────────
_inDragOrResize = true;
if (_multiSelection.Count > 1 && _multiSelection.Contains(_dragging))
{
// Group drag: preview every element in the multi-selection by the per-frame delta.
Expand All @@ -696,6 +738,22 @@ protected override void OnPointerMoved(PointerEventArgs e)
_dragging.MoveToPreview(newX, newY);
}

// Only sync inline editor if it's being dragged as part of the current drag operation
if (_multiSelection.Count > 1)
{
if ((_editingParamNode is not null && _multiSelection.Contains(_editingParamNode)) ||
(_editingNameElement is not null && _multiSelection.Contains(_editingNameElement)) ||
(_editingCommentBlock is not null && _multiSelection.Contains(_editingCommentBlock)))
{
SyncEditingElementPositions();
}
}
else if (ReferenceEquals(_dragging, _editingParamNode) ||
ReferenceEquals(_dragging, _editingNameElement) ||
ReferenceEquals(_dragging, _editingCommentBlock))
{
SyncEditingElementPositions();
}
InvalidateAndMeasure();
TryAutoScrollForDrag(svPos);
e.Handled = true;
Expand Down Expand Up @@ -733,6 +791,9 @@ protected override void OnPointerReleased(PointerReleasedEventArgs e)
}
}

// ── Drag/resize release ──────────────────────────────────────────────
_inDragOrResize = false;

// ── Right-drag release: complete link creation ────────────────────
if (_linkOrigin is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ private void OnNameEditorKeyDown(object? sender, KeyEventArgs e)

private void OnNameEditorLostFocus(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
// Don't commit if we're in the middle of a drag/resize operation.
if (_inDragOrResize) return;

if (_editingNameElement is not null)
{
CommitNameEdit();
Expand Down Expand Up @@ -240,6 +243,9 @@ private void OnCommentEditorKeyDown(object? sender, KeyEventArgs e)

private void OnCommentEditorLostFocus(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
// Don't commit if we're in the middle of a drag/resize operation.
if (_inDragOrResize) return;

if (_editingCommentBlock is not null)
{
CommitCommentEdit();
Expand Down
Loading
Loading