mirror of
https://github.com/google/blockly.git
synced 2025-12-16 06:10:12 +01:00
* feat: change gestures to look at selected when dragging * chore: fix tests * chore: format * chore: PR comments
197 lines
5.6 KiB
TypeScript
197 lines
5.6 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import {WorkspaceComment} from './workspace_comment.js';
|
|
import {WorkspaceSvg} from '../workspace_svg.js';
|
|
import {CommentView} from './comment_view.js';
|
|
import {Coordinate} from '../utils/coordinate.js';
|
|
import {Rect} from '../utils/rect.js';
|
|
import {Size} from '../utils/size.js';
|
|
import {IBoundedElement} from '../interfaces/i_bounded_element.js';
|
|
import {IRenderedElement} from '../interfaces/i_rendered_element.js';
|
|
import * as dom from '../utils/dom.js';
|
|
import {IDraggable} from '../interfaces/i_draggable.js';
|
|
import {CommentDragStrategy} from '../dragging/comment_drag_strategy.js';
|
|
import * as browserEvents from '../browser_events.js';
|
|
import * as common from '../common.js';
|
|
import {ISelectable} from '../interfaces/i_selectable.js';
|
|
|
|
export class RenderedWorkspaceComment
|
|
extends WorkspaceComment
|
|
implements IBoundedElement, IRenderedElement, IDraggable, ISelectable
|
|
{
|
|
/** The class encompassing the svg elements making up the workspace comment. */
|
|
private view: CommentView;
|
|
|
|
public readonly workspace: WorkspaceSvg;
|
|
|
|
private dragStrategy = new CommentDragStrategy(this);
|
|
|
|
/** Constructs the workspace comment, including the view. */
|
|
constructor(workspace: WorkspaceSvg, id?: string) {
|
|
super(workspace, id);
|
|
|
|
this.workspace = workspace;
|
|
|
|
this.view = new CommentView(workspace);
|
|
// Set the size to the default size as defined in the superclass.
|
|
this.view.setSize(this.getSize());
|
|
this.view.setEditable(this.isEditable());
|
|
|
|
this.addModelUpdateBindings();
|
|
|
|
browserEvents.conditionalBind(
|
|
this.view.getSvgRoot(),
|
|
'pointerdown',
|
|
this,
|
|
this.startGesture,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Adds listeners to the view that updates the model (i.e. the superclass)
|
|
* when changes are made to the view.
|
|
*/
|
|
private addModelUpdateBindings() {
|
|
this.view.addTextChangeListener(
|
|
(_, newText: string) => void super.setText(newText),
|
|
);
|
|
this.view.addSizeChangeListener(
|
|
(_, newSize: Size) => void super.setSize(newSize),
|
|
);
|
|
this.view.addOnCollapseListener(
|
|
() => void super.setCollapsed(this.view.isCollapsed()),
|
|
);
|
|
this.view.addDisposeListener(() => {
|
|
if (!this.isDeadOrDying()) this.dispose();
|
|
});
|
|
}
|
|
|
|
/** Sets the text of the comment. */
|
|
override setText(text: string): void {
|
|
// setText will trigger the change listener that updates
|
|
// the model aka superclass.
|
|
this.view.setText(text);
|
|
}
|
|
|
|
/** Sets the size of the comment. */
|
|
override setSize(size: Size) {
|
|
// setSize will trigger the change listener that updates
|
|
// the model aka superclass.
|
|
this.view.setSize(size);
|
|
}
|
|
|
|
/** Sets whether the comment is collapsed or not. */
|
|
override setCollapsed(collapsed: boolean) {
|
|
// setCollapsed will trigger the change listener that updates
|
|
// the model aka superclass.
|
|
this.view.setCollapsed(collapsed);
|
|
}
|
|
|
|
/** Sets whether the comment is editable or not. */
|
|
override setEditable(editable: boolean): void {
|
|
super.setEditable(editable);
|
|
// Use isEditable rather than isOwnEditable to account for workspace state.
|
|
this.view.setEditable(this.isEditable());
|
|
}
|
|
|
|
/** Returns the root SVG element of this comment. */
|
|
getSvgRoot(): SVGElement {
|
|
return this.view.getSvgRoot();
|
|
}
|
|
|
|
/** Returns the bounding rectangle of this comment in workspace coordinates. */
|
|
getBoundingRectangle(): Rect {
|
|
const loc = this.getRelativeToSurfaceXY();
|
|
const size = this.getSize();
|
|
return new Rect(loc.y, loc.y + size.height, loc.x, loc.x + size.width);
|
|
}
|
|
|
|
/** Move the comment by the given amounts in workspace coordinates. */
|
|
moveBy(dx: number, dy: number, reason?: string[] | undefined): void {
|
|
const loc = this.getRelativeToSurfaceXY();
|
|
const newLoc = new Coordinate(loc.x + dx, loc.y + dy);
|
|
this.moveTo(newLoc, reason);
|
|
}
|
|
|
|
/** Moves the comment to the given location in workspace coordinates. */
|
|
override moveTo(location: Coordinate, reason?: string[] | undefined): void {
|
|
super.moveTo(location, reason);
|
|
this.view.moveTo(location);
|
|
}
|
|
|
|
/**
|
|
* Moves the comment during a drag. Doesn't fire move events.
|
|
*
|
|
* @internal
|
|
*/
|
|
moveDuringDrag(location: Coordinate): void {
|
|
this.location = location;
|
|
this.view.moveTo(location);
|
|
}
|
|
|
|
/**
|
|
* Adds the dragging CSS class to this comment.
|
|
*
|
|
* @internal
|
|
*/
|
|
setDragging(dragging: boolean): void {
|
|
if (dragging) {
|
|
dom.addClass(this.getSvgRoot(), 'blocklyDragging');
|
|
} else {
|
|
dom.removeClass(this.getSvgRoot(), 'blocklyDragging');
|
|
}
|
|
}
|
|
|
|
/** Disposes of the view. */
|
|
override dispose() {
|
|
this.disposing = true;
|
|
if (!this.view.isDeadOrDying()) this.view.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
/**
|
|
* Starts a gesture because we detected a pointer down on the comment
|
|
* (that wasn't otherwise gobbled up, e.g. by resizing).
|
|
*/
|
|
private startGesture(e: PointerEvent) {
|
|
const gesture = this.workspace.getGesture(e);
|
|
if (gesture) {
|
|
gesture.handleCommentStart(e, this);
|
|
common.setSelected(this);
|
|
}
|
|
}
|
|
|
|
/** Returns whether this comment is movable or not. */
|
|
isMovable(): boolean {
|
|
return this.dragStrategy.isMovable();
|
|
}
|
|
|
|
/** Starts a drag on the comment. */
|
|
startDrag(): void {
|
|
this.dragStrategy.startDrag();
|
|
}
|
|
|
|
/** Drags the comment to the given location. */
|
|
drag(newLoc: Coordinate): void {
|
|
this.dragStrategy.drag(newLoc);
|
|
}
|
|
|
|
/** Ends the drag on the comment. */
|
|
endDrag(): void {
|
|
this.dragStrategy.endDrag();
|
|
}
|
|
|
|
/** Moves the comment back to where it was at the start of a drag. */
|
|
revertDrag(): void {
|
|
this.dragStrategy.revertDrag();
|
|
}
|
|
|
|
select(): void {}
|
|
|
|
unselect(): void {}
|
|
}
|