@@ -238,6 +238,23 @@ protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
238238 e . Handled = true ;
239239 return ;
240240 }
241+ // If the pointer is over a comment block, scroll its comment body text.
242+ if ( _vm is not null )
243+ {
244+ var mpos = ToCanvasPos ( e . GetPosition ( this ) ) ;
245+ var commentHit = HitTest ( mpos , testComments : true ) as CommentBlockViewModel ;
246+ if ( commentHit is not null )
247+ {
248+ const double scrollStep = 24.0 ;
249+ double newOffset = commentHit . CommentScrollOffset - e . Delta . Y * scrollStep ;
250+ // Clamp to [0, maxScroll] using the last-rendered max (0 if not yet rendered).
251+ _commentMaxScrollOffsets . TryGetValue ( commentHit , out double maxScroll ) ;
252+ commentHit . CommentScrollOffset = Math . Min ( Math . Max ( 0.0 , newOffset ) , maxScroll ) ;
253+ InvalidateVisual ( ) ;
254+ e . Handled = true ;
255+ return ;
256+ }
257+ }
241258 base . OnPointerWheelChanged ( e ) ;
242259 }
243260
@@ -266,12 +283,14 @@ private void OnPointerPressedTunnel(object? sender, PointerPressedEventArgs e)
266283 bool isResizingEditedElement =
267284 ReferenceEquals ( resizeHit , _editingParamNode ) ||
268285 ReferenceEquals ( resizeHit , _editingNameElement ) ||
269- ReferenceEquals ( resizeHit , _editingCommentBlock ) ;
286+ ReferenceEquals ( resizeHit , _editingCommentBlock ) ||
287+ ReferenceEquals ( resizeHit , _editingCommentHeaderBlock ) ;
270288
271289 if ( ! isResizingEditedElement )
272290 {
273291 if ( _editingParamNode is not null ) CommitParamEdit ( ) ;
274292 if ( _editingCommentBlock is not null ) CommitCommentEdit ( ) ;
293+ if ( _editingCommentHeaderBlock is not null ) CommitCommentHeaderEdit ( ) ;
275294 if ( _editingNameElement is not null ) CommitNameEdit ( ) ;
276295 }
277296
@@ -320,12 +339,14 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
320339 bool isResizingEditedElement =
321340 ReferenceEquals ( resizeHit , _editingParamNode ) ||
322341 ReferenceEquals ( resizeHit , _editingNameElement ) ||
323- ReferenceEquals ( resizeHit , _editingCommentBlock ) ;
342+ ReferenceEquals ( resizeHit , _editingCommentBlock ) ||
343+ ReferenceEquals ( resizeHit , _editingCommentHeaderBlock ) ;
324344
325345 if ( ! isResizingEditedElement )
326346 {
327347 if ( _editingParamNode is not null ) CommitParamEdit ( ) ;
328348 if ( _editingCommentBlock is not null ) CommitCommentEdit ( ) ;
349+ if ( _editingCommentHeaderBlock is not null ) CommitCommentHeaderEdit ( ) ;
329350 if ( _editingNameElement is not null ) CommitNameEdit ( ) ;
330351 }
331352 ClearMultiSelection ( ) ;
@@ -349,6 +370,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
349370 {
350371 if ( _editingParamNode is not null ) CommitParamEdit ( ) ;
351372 if ( _editingCommentBlock is not null ) CommitCommentEdit ( ) ;
373+ if ( _editingCommentHeaderBlock is not null ) CommitCommentHeaderEdit ( ) ;
352374 if ( _editingNameElement is not null ) CommitNameEdit ( ) ;
353375 minimizeHit . InlineBasicParameter ( ) ;
354376 InvalidateAndMeasure ( ) ;
@@ -391,6 +413,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
391413 ReferenceEquals ( clickedElement , _editingParamNode ) ||
392414 ReferenceEquals ( clickedElement , _editingNameElement ) ||
393415 ReferenceEquals ( clickedElement , _editingCommentBlock ) ||
416+ ReferenceEquals ( clickedElement , _editingCommentHeaderBlock ) ||
394417 ( clickedElement is not null && _multiSelection . Contains ( clickedElement ) &&
395418 ( ( _editingParamNode is not null && _multiSelection . Contains ( _editingParamNode ) ) ||
396419 ( _editingNameElement is not null && _multiSelection . Contains ( _editingNameElement ) ) ||
@@ -401,6 +424,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
401424 {
402425 if ( _editingParamNode is not null ) CommitParamEdit ( ) ;
403426 if ( _editingCommentBlock is not null ) CommitCommentEdit ( ) ;
427+ if ( _editingCommentHeaderBlock is not null ) CommitCommentHeaderEdit ( ) ;
404428 if ( _editingNameElement is not null ) CommitNameEdit ( ) ;
405429 }
406430 }
@@ -466,12 +490,16 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
466490 return ;
467491 }
468492
469- // ── Double-click on a comment block: open the inline comment editor ──
493+ // ── Double-click on a comment block: open the inline comment or header editor ──
470494 var commentHit = HitTest ( mpos , testComments : true ) as CommentBlockViewModel ;
471495 if ( commentHit is not null )
472496 {
473497 _vm . SelectElementCommand . Execute ( commentHit ) ;
474- BeginCommentEdit ( commentHit ) ;
498+ // Open the header editor when the click lands in the header band; otherwise the comment editor.
499+ if ( mpos . Y < commentHit . Y + CommentHeaderHeight )
500+ BeginCommentHeaderEdit ( commentHit ) ;
501+ else
502+ BeginCommentEdit ( commentHit ) ;
475503 e . Handled = true ;
476504 return ;
477505 }
@@ -554,6 +582,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
554582 // Always commit any open inline edit first.
555583 if ( _editingParamNode is not null ) CommitParamEdit ( ) ;
556584 if ( _editingCommentBlock is not null ) CommitCommentEdit ( ) ;
585+ if ( _editingCommentHeaderBlock is not null ) CommitCommentHeaderEdit ( ) ;
557586 if ( _editingNameElement is not null ) CommitNameEdit ( ) ;
558587
559588 if ( hit is not null )
@@ -672,7 +701,8 @@ protected override void OnPointerMoved(PointerEventArgs e)
672701 // Only sync inline editor if it's the element being resized
673702 if ( ReferenceEquals ( _resizing , _editingParamNode ) ||
674703 ReferenceEquals ( _resizing , _editingNameElement ) ||
675- ReferenceEquals ( _resizing , _editingCommentBlock ) )
704+ ReferenceEquals ( _resizing , _editingCommentBlock ) ||
705+ ReferenceEquals ( _resizing , _editingCommentHeaderBlock ) )
676706 {
677707 SyncEditingElementPositions ( ) ;
678708 }
@@ -743,14 +773,16 @@ protected override void OnPointerMoved(PointerEventArgs e)
743773 {
744774 if ( ( _editingParamNode is not null && _multiSelection . Contains ( _editingParamNode ) ) ||
745775 ( _editingNameElement is not null && _multiSelection . Contains ( _editingNameElement ) ) ||
746- ( _editingCommentBlock is not null && _multiSelection . Contains ( _editingCommentBlock ) ) )
776+ ( _editingCommentBlock is not null && _multiSelection . Contains ( _editingCommentBlock ) ) ||
777+ ( _editingCommentHeaderBlock is not null && _multiSelection . Contains ( _editingCommentHeaderBlock ) ) )
747778 {
748779 SyncEditingElementPositions ( ) ;
749780 }
750781 }
751782 else if ( ReferenceEquals ( _dragging , _editingParamNode ) ||
752783 ReferenceEquals ( _dragging , _editingNameElement ) ||
753- ReferenceEquals ( _dragging , _editingCommentBlock ) )
784+ ReferenceEquals ( _dragging , _editingCommentBlock ) ||
785+ ReferenceEquals ( _dragging , _editingCommentHeaderBlock ) )
754786 {
755787 SyncEditingElementPositions ( ) ;
756788 }
0 commit comments