Skip to content

Commit

Permalink
store block comment position in block data
Browse files Browse the repository at this point in the history
  • Loading branch information
riknoll committed Sep 9, 2024
1 parent 124290f commit 3cca149
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
40 changes: 40 additions & 0 deletions pxtblocks/plugins/comments/blockComment.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as Blockly from "blockly";

import { TextInputBubble } from "./textinput_bubble";
import { getBlockDataForField, setBlockDataForField } from "../../fields";

const eventUtils = Blockly.Events;

Expand All @@ -13,6 +14,12 @@ const DEFAULT_BUBBLE_WIDTH = 160;
/** The default height in workspace-scale units of the text input bubble. */
const DEFAULT_BUBBLE_HEIGHT = 80;

// makecode fields generated from functions always use valid JavaScript
// identifiers for their names. starting the name with a ~ prevents us
// from colliding with those fields
const COMMENT_OFFSET_X_FIELD_NAME = "~commentOffsetX";
const COMMENT_OFFSET_Y_FIELD_NAME = "~commentOffsetY";

/**
* An icon which allows the user to add comment text to a block.
*/
Expand Down Expand Up @@ -246,6 +253,15 @@ export class CommentIcon extends Blockly.icons.Icon {
}
}

onPositionChange(): void {
if (this.textInputBubble) {
const coord = this.textInputBubble.getPositionRelativeToAnchor();

setBlockDataForField(this.sourceBlock, COMMENT_OFFSET_X_FIELD_NAME, coord.x + "");
setBlockDataForField(this.sourceBlock, COMMENT_OFFSET_Y_FIELD_NAME, coord.y + "");
}
}

bubbleIsVisible(): boolean {
return this.bubbleVisiblity;
}
Expand Down Expand Up @@ -291,6 +307,7 @@ export class CommentIcon extends Blockly.icons.Icon {
* to update the state of this icon in response to changes in the bubble.
*/
private showEditableBubble() {
const savedPosition = this.getSavedOffsetData();
this.textInputBubble = new TextInputBubble(
this.sourceBlock.workspace as Blockly.WorkspaceSvg,
this.getAnchorLocation(),
Expand All @@ -300,17 +317,23 @@ export class CommentIcon extends Blockly.icons.Icon {
this.textInputBubble.setSize(this.bubbleSize, true);
this.textInputBubble.addTextChangeListener(() => this.onTextChange());
this.textInputBubble.addSizeChangeListener(() => this.onSizeChange());
this.textInputBubble.addPositionChangeListener(() => this.onPositionChange());
this.textInputBubble.setDeleteHandler(() => {
this.setBubbleVisible(false);
this.sourceBlock.setCommentText(null);
});
this.textInputBubble.setCollapseHandler(() => {
this.setBubbleVisible(false);
});

if (savedPosition) {
this.textInputBubble.setPositionRelativeToAnchor(savedPosition.x, savedPosition.y);
}
}

/** Shows the non editable text bubble for this comment. */
private showNonEditableBubble() {
const savedPosition = this.getSavedOffsetData();
this.textInputBubble = new TextInputBubble(
this.sourceBlock.workspace as Blockly.WorkspaceSvg,
this.getAnchorLocation(),
Expand All @@ -322,6 +345,9 @@ export class CommentIcon extends Blockly.icons.Icon {
this.textInputBubble.setCollapseHandler(() => {
this.setBubbleVisible(false);
});
if (savedPosition) {
this.textInputBubble.setPositionRelativeToAnchor(savedPosition.x, savedPosition.y);
}
}

/** Hides any open bubbles owned by this comment. */
Expand Down Expand Up @@ -350,6 +376,20 @@ export class CommentIcon extends Blockly.icons.Icon {
const bbox = (this.sourceBlock as Blockly.BlockSvg).getSvgRoot().getBBox();
return new Blockly.utils.Rect(bbox.y, bbox.y + bbox.height, bbox.x, bbox.x + bbox.width);
}

private getSavedOffsetData(): Blockly.utils.Coordinate | undefined {
const offsetX = getBlockDataForField(this.sourceBlock, COMMENT_OFFSET_X_FIELD_NAME);
const offsetY = getBlockDataForField(this.sourceBlock, COMMENT_OFFSET_Y_FIELD_NAME);

if (offsetX && offsetY) {
return new Blockly.utils.Coordinate(
parseFloat(offsetX),
parseFloat(offsetY)
);
}

return undefined;
}
}

/** The save state format for a comment icon. */
Expand Down
4 changes: 4 additions & 0 deletions pxtblocks/plugins/comments/bubble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ export abstract class Bubble implements Blockly.IDeletable {
this.renderTail();
}

getPositionRelativeToAnchor() {
return new Blockly.utils.Coordinate(this.relativeLeft, this.relativeTop);
}

/** @returns the size of this bubble. */
protected getSize() {
return this.size;
Expand Down
19 changes: 19 additions & 0 deletions pxtblocks/plugins/comments/textinput_bubble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ export class TextInputBubble extends Bubble {
/** Functions listening for changes to the size of this bubble. */
private sizeChangeListeners: (() => void)[] = [];

/** Functions listening for changes to the position of this bubble. */
private positionChangeListeners: (() => void)[] = []

/** The text of this bubble. */
private text = '';

Expand Down Expand Up @@ -83,6 +86,11 @@ export class TextInputBubble extends Bubble {
return this.text;
}

override moveTo(x: number, y: number) {
super.moveTo(x, y);
this.onPositionChange();
}

/** Sets the text of this bubble. Calls change listeners. */
setText(text: string) {
this.text = text;
Expand All @@ -100,6 +108,10 @@ export class TextInputBubble extends Bubble {
this.sizeChangeListeners.push(listener);
}

addPositionChangeListener(listener: () => void) {
this.positionChangeListeners.push(listener);
}

/** Creates the editor UI for this bubble. */
private createEditor(container: SVGGElement): {
inputRoot: SVGForeignObjectElement;
Expand Down Expand Up @@ -316,6 +328,13 @@ export class TextInputBubble extends Bubble {
listener();
}
}

/** Handles a position change event for the text area. Calls event listeners. */
private onPositionChange() {
for (const listener of this.positionChangeListeners) {
listener();
}
}
}

Blockly.Css.register(`
Expand Down

0 comments on commit 3cca149

Please sign in to comment.