From d42ca12192905aa2d1ad35123294a44b8e827394 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Fri, 5 Apr 2024 20:39:20 +0000 Subject: [PATCH] feat: visual comment selection (#7996) * feat: add visually highlighting selected comment * chore: TSDoc --- core/comments/comment_view.ts | 29 +++++++++++++++++++++ core/comments/rendered_workspace_comment.ts | 10 +++++-- core/gesture.ts | 6 +++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/core/comments/comment_view.ts b/core/comments/comment_view.ts index 88ec05381b8..06a6433ec66 100644 --- a/core/comments/comment_view.ts +++ b/core/comments/comment_view.ts @@ -19,6 +19,11 @@ export class CommentView implements IRenderedElement { /** The root group element of the comment view. */ private svgRoot: SVGGElement; + /** + * The svg rect element that we use to create a hightlight around the comment. + */ + private highlightRect: SVGRectElement; + /** The group containing all of the top bar elements. */ private topBarGroup: SVGGElement; @@ -99,6 +104,8 @@ export class CommentView implements IRenderedElement { 'class': 'blocklyComment blocklyEditable', }); + this.highlightRect = this.createHighlightRect(this.svgRoot); + ({ topBarGroup: this.topBarGroup, topBarBackground: this.topBarBackground, @@ -124,6 +131,17 @@ export class CommentView implements IRenderedElement { this.moveTo(new Coordinate(0, 0)); } + /** + * Creates the rect we use for highlighting the comment when it's selected. + */ + private createHighlightRect(svgRoot: SVGGElement): SVGRectElement { + return dom.createSvgElement( + Svg.RECT, + {'class': 'blocklyCommentHighlight'}, + svgRoot, + ); + } + /** * Creates the top bar and the elements visually within it. * Registers event listeners. @@ -293,6 +311,8 @@ export class CommentView implements IRenderedElement { this.svgRoot.setAttribute('height', `${size.height}`); this.svgRoot.setAttribute('width', `${size.width}`); + this.highlightRect.setAttribute('height', `${size.height}`); + this.highlightRect.setAttribute('width', `${size.width}`); this.updateTopBarSize(size); this.updateTextAreaSize(size, topBarSize); @@ -816,4 +836,13 @@ css.register(` transform: scale(-1, 1); cursor: sw-resize; } + +.blocklyCommentHighlight { + fill: none; +} + +.blocklySelected .blocklyCommentHighlight { + stroke: #fc3; + stroke-width: 3px; +} `); diff --git a/core/comments/rendered_workspace_comment.ts b/core/comments/rendered_workspace_comment.ts index f6d86f2033c..dc7111a6f5b 100644 --- a/core/comments/rendered_workspace_comment.ts +++ b/core/comments/rendered_workspace_comment.ts @@ -190,7 +190,13 @@ export class RenderedWorkspaceComment this.dragStrategy.revertDrag(); } - select(): void {} + /** Visually highlights the comment. */ + select(): void { + dom.addClass(this.getSvgRoot(), 'blocklySelected'); + } - unselect(): void {} + /** Visually unhighlights the comment. */ + unselect(): void { + dom.removeClass(this.getSvgRoot(), 'blocklySelected'); + } } diff --git a/core/gesture.ts b/core/gesture.ts index 5b45c5ea737..927f6431866 100644 --- a/core/gesture.ts +++ b/core/gesture.ts @@ -544,6 +544,8 @@ export class Gesture { this.workspaceDragger.endDrag(this.currentDragDeltaXY); } else if (this.isBubbleClick()) { // Do nothing, bubbles don't currently respond to clicks. + } else if (this.isCommentClick()) { + // Do nothing, comments don't currently respond to clicks. } else if (this.isFieldClick()) { this.doFieldClick(); } else if (this.isIconClick()) { @@ -1075,6 +1077,10 @@ export class Gesture { return hasStartBubble && !this.hasExceededDragRadius; } + private isCommentClick(): boolean { + return !!this.startComment && !this.hasExceededDragRadius; + } + /** * Whether this gesture is a click on a block. This should only be called * when ending a gesture (pointerup).