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
294 changes: 135 additions & 159 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
"webpack-dev-server": "^4.11.1"
},
"dependencies": {
"@blockly/continuous-toolbox": "^5.0.15",
"@blockly/continuous-toolbox": "^7.0.0-beta.1",
"@blockly/field-colour": "^4.0.2",
"blockly": "^11.0.0"
"blockly": "^12.0.0-beta.1"
}
}
138 changes: 0 additions & 138 deletions src/checkable_continuous_flyout.js

This file was deleted.

112 changes: 112 additions & 0 deletions src/checkable_continuous_flyout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* @license
* Copyright 2024 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import * as Blockly from "blockly/core";
import { ContinuousFlyout } from "@blockly/continuous-toolbox";
import { CheckboxBubble } from "./checkbox_bubble";
import { StatusIndicatorLabel } from "./status_indicator_label";
import { STATUS_INDICATOR_LABEL_TYPE } from "./status_indicator_label_flyout_inflater";

export class CheckableContinuousFlyout extends ContinuousFlyout {
/**
* Creates a new CheckableContinuousFlyout.
*
* @param workspaceOptions Configuration options for the flyout workspace.
*/
constructor(workspaceOptions: Blockly.Options) {
workspaceOptions.modalInputs = false;
super(workspaceOptions);
this.tabWidth_ = 0;
this.MARGIN = 12;
this.GAP_Y = 12;
}

/**
* Serializes a block to JSON in order to copy it to the main workspace.
*
* @param block The block to serialize.
* @returns A JSON representation of the block.
*/
protected serializeBlock(block: Blockly.BlockSvg) {
const json = super.serializeBlock(block);
// Delete the serialized block's ID so that a new one is generated when it is
// placed on the workspace. Otherwise, the block on the workspace may be
// indistinguishable from the one in the flyout, which can cause reporter blocks
// to have their value dropdown shown in the wrong place.
delete json.id;
return json;
}

/**
* Set the state of a checkbox by block ID.
*
* @param blockId ID of the block whose checkbox should be set
* @param value Value to set the checkbox to.
*/
setCheckboxState(blockId: string, value: boolean) {
this.getWorkspace()
.getBlockById(blockId)
?.getIcon("checkbox")
?.setChecked(value);
}

getFlyoutScale() {
return 0.675;
}

getWidth() {
return 250;
}

protected reflowInternal_() {
super.reflowInternal_();

if (this.RTL) {
// The parent implementation assumes that the flyout grows to fit its
// contents, and adjusts blocks in RTL mode accordingly. In Scratch, the
// flyout width is fixed (and blocks may exceed it), so re-adjust blocks
// accordingly based on the actual fixed width.
for (const item of this.getContents()) {
const oldX = item.getElement().getBoundingRectangle().left;
let newX =
this.getWidth() / this.workspace_.scale -
item.getElement().getBoundingRectangle().getWidth() -
this.MARGIN;
if (
"checkboxInFlyout" in item.getElement() &&
item.getElement().checkboxInFlyout
) {
newX -= CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN;
}
item.getElement().moveBy(newX - oldX, 0);
}
}
}

/**
* Validates that the given toolbox item represents a label.
*
* @param item The toolbox item to check.
* @returns True if the item represents a label in the flyout.
*/
protected toolboxItemIsLabel(item: Blockly.FlyoutItem) {
return (
item.getType() === STATUS_INDICATOR_LABEL_TYPE ||
super.toolboxItemIsLabel(item)
);
}

/**
* Updates the state of status indicators for hardware-based extensions.
*/
refreshStatusButtons() {
for (const item of this.contents) {
if (item.element instanceof StatusIndicatorLabel) {
item.element.refreshStatus();
}
}
}
}
9 changes: 4 additions & 5 deletions src/checkbox_bubble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,14 @@ export class CheckboxBubble
* Recalculates this bubble's location, keeping it adjacent to its block.
*/
updateLocation() {
const blockLocation = this.sourceBlock.getRelativeToSurfaceXY();
const blockBounds = this.sourceBlock.getHeightWidth();
const bounds = this.sourceBlock.getBoundingRectangle();
const x = this.sourceBlock.workspace.RTL
? blockLocation.x + blockBounds.width + CheckboxBubble.CHECKBOX_MARGIN
: blockLocation.x -
? bounds.right + CheckboxBubble.CHECKBOX_MARGIN
: bounds.left -
CheckboxBubble.CHECKBOX_MARGIN -
CheckboxBubble.CHECKBOX_SIZE;
const y =
blockLocation.y + (blockBounds.height - CheckboxBubble.CHECKBOX_SIZE) / 2;
bounds.top + (bounds.getHeight() - CheckboxBubble.CHECKBOX_SIZE) / 2;
this.moveTo(x, y);
}

Expand Down
20 changes: 13 additions & 7 deletions src/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -751,8 +751,9 @@ const styles = `
}

/* Category tree in Toolbox. */
.blocklyToolboxDiv {
.blocklyToolbox {
background-color: var(--colour-toolbox);
border-right: 1px solid #ddd;
color: var(--colour-toolboxText);
overflow-x: visible;
overflow-y: auto;
Expand All @@ -763,6 +764,11 @@ const styles = `
padding: 0;
}

.blocklyToolbox[dir="RTL"] {
border-right: none;
border-left: 1px solid #ddd;
}

.blocklyTreeRoot {
padding: 4px 0;
}
Expand All @@ -771,7 +777,7 @@ const styles = `
outline: none;
}

.blocklyToolboxDiv .blocklyTreeRow {
.blocklyToolbox .blocklyToolboxCategory {
line-height: 22px;
margin: 0;
padding: 0.375rem 0px;
Expand All @@ -789,11 +795,11 @@ const styles = `
margin: 1px 0 8px 5px;
}

.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {
margin-left: 8px;
.blocklyToolbox[dir="RTL"] .blocklyToolboxCategory {
margin-left: 0px;
}

.blocklyTreeRow:hover {
.blocklyToolboxCategory:hover {
color: var(--colour-toolboxHover);
}

Expand Down Expand Up @@ -844,7 +850,7 @@ const styles = `
background-position: -48px -1px;
}

.blocklyTreeLabel {
.blocklyToolboxCategoryLabel {
cursor: default;
font-family: "Helvetica Neue", Helvetica, sans-serif;
font-size: .65rem;
Expand All @@ -855,7 +861,7 @@ const styles = `
text-wrap: wrap;
}

.blocklyTreeSelected .blocklyTreeLabel {
.blocklyToolboxSelected .blocklyToolboxCategoryLabel {
color: inherit;
}

Expand Down
6 changes: 3 additions & 3 deletions src/fields/field_matrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class FieldMatrix extends Blockly.Field<string> {
* Touch event wrapper.
* Runs when the field is selected.
*/
private mouseDownWrapper: Blockly.browserEvents.Data | null = null;
private mouseDownWrapper_: Blockly.browserEvents.Data | null = null;

/**
* Touch event wrapper.
Expand Down Expand Up @@ -558,8 +558,8 @@ class FieldMatrix extends Blockly.Field<string> {
dispose() {
super.dispose();
this.matrixStage_ = null;
if (this.mouseDownWrapper) {
Blockly.browserEvents.unbind(this.mouseDownWrapper);
if (this.mouseDownWrapper_) {
Blockly.browserEvents.unbind(this.mouseDownWrapper_);
}
if (this.matrixTouchWrapper_) {
Blockly.browserEvents.unbind(this.matrixTouchWrapper_);
Expand Down
8 changes: 4 additions & 4 deletions src/fields/scratch_field_angle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class ScratchFieldAngle extends Blockly.FieldNumber {
/**
* Opaque identifier used to unbind event listener in dispose().
*/
private mouseDownWrapper: Blockly.browserEvents.Data;
private mouseDownWrapper_: Blockly.browserEvents.Data;

/**
* Opaque identifier used to unbind event listener in dispose().
Expand Down Expand Up @@ -142,8 +142,8 @@ class ScratchFieldAngle extends Blockly.FieldNumber {
dispose() {
super.dispose();
this.gauge = null;
if (this.mouseDownWrapper) {
Blockly.browserEvents.unbind(this.mouseDownWrapper);
if (this.mouseDownWrapper_) {
Blockly.browserEvents.unbind(this.mouseDownWrapper_);
}
if (this.mouseUpWrapper) {
Blockly.browserEvents.unbind(this.mouseUpWrapper);
Expand Down Expand Up @@ -286,7 +286,7 @@ class ScratchFieldAngle extends Blockly.FieldNumber {
this.getSourceBlock() as Blockly.BlockSvg
);

this.mouseDownWrapper = Blockly.browserEvents.bind(
this.mouseDownWrapper_ = Blockly.browserEvents.bind(
this.handle,
"mousedown",
this,
Expand Down
Loading