fix: Normalize Zelos connection indicators

This commit is contained in:
Aaron Dodson
2026-01-12 15:12:26 -08:00
parent ba329e40e7
commit 7f4ec3a9ea
9 changed files with 40 additions and 166 deletions

View File

@@ -781,6 +781,13 @@ export class BlockSvg
}
}
/**
* Returns whether or not this block is currently being dragged.
*/
isDragging() {
return this.dragging;
}
/**
* Set whether this block is movable or not.
*
@@ -1728,24 +1735,11 @@ export class BlockSvg
* @internal
*/
fadeForReplacement(add: boolean) {
// TODO (7204): Remove these internal methods.
(this.pathObject as AnyDuringMigration).updateReplacementFade(add);
}
/**
* Visual effect to show that if the dragging block is dropped it will connect
* to this input.
*
* @param conn The connection on the input to highlight.
* @param add True if highlighting should be added.
* @internal
*/
highlightShapeForInput(conn: RenderedConnection, add: boolean) {
// TODO (7204): Remove these internal methods.
(this.pathObject as AnyDuringMigration).updateShapeForInputHighlight(
conn,
add,
);
if (add) {
this.addClass('blocklyReplaceable');
} else {
this.removeClass('blocklyReplaceable');
}
}
/**

View File

@@ -92,6 +92,10 @@ export class InsertionMarkerPreviewer implements IConnectionPreviewer {
staticConn.highlight();
}
if (this.workspace.getRenderer().shouldHighlightConnection(draggedConn)) {
draggedConn.highlight();
}
this.draggedConn = draggedConn;
this.staticConn = staticConn;
} finally {
@@ -224,6 +228,10 @@ export class InsertionMarkerPreviewer implements IConnectionPreviewer {
this.staticConn.unhighlight();
this.staticConn = null;
}
if (this.draggedConn) {
this.draggedConn.unhighlight();
this.draggedConn = null;
}
if (this.fadedBlock) {
this.fadedBlock.fadeForReplacement(false);
this.fadedBlock = null;

View File

@@ -332,6 +332,7 @@ export class RenderedConnection
const highlightSvg = this.findHighlightSvg();
if (highlightSvg) {
highlightSvg.style.display = '';
highlightSvg.parentElement?.appendChild(highlightSvg);
}
}

View File

@@ -7,7 +7,6 @@
// Former goog.module ID: Blockly.blockRendering.PathObject
import type {BlockSvg} from '../../block_svg.js';
import type {Connection} from '../../connection.js';
import {RenderedConnection} from '../../rendered_connection.js';
import type {BlockStyle} from '../../theme.js';
import {Coordinate} from '../../utils/coordinate.js';
@@ -192,28 +191,6 @@ export class PathObject implements IPathObject {
this.setClass_('blocklyDraggable', enable);
}
/**
* Add or remove styling that shows that if the dragging block is dropped,
* this block will be replaced. If a shadow block, it will disappear.
* Otherwise it will bump.
*
* @param enable True if styling should be added.
*/
updateReplacementFade(enable: boolean) {
this.setClass_('blocklyReplaceable', enable);
}
/**
* Add or remove styling that shows that if the dragging block is dropped,
* this block will be connected to the input.
*
* @param _conn The connection on the input to highlight.
* @param _enable True if styling should be added.
*/
updateShapeForInputHighlight(_conn: Connection, _enable: boolean) {
// NOOP
}
/** Adds the given path as a connection highlight for the given connection. */
addConnectionHighlight(
connection: RenderedConnection,

View File

@@ -11,6 +11,7 @@ import type {BlockSvg} from '../../block_svg.js';
import {Connection} from '../../connection.js';
import {ConnectionType} from '../../connection_type.js';
import type {IRegistrable} from '../../interfaces/i_registrable.js';
import type {RenderedConnection} from '../../rendered_connection.js';
import type {BlockStyle, Theme} from '../../theme.js';
import {ConstantProvider} from './constants.js';
import {Drawer} from './drawer.js';
@@ -188,11 +189,11 @@ export class Renderer implements IRegistrable {
/**
* Determine whether or not to highlight a connection.
*
* @param _conn The connection to determine whether or not to highlight.
* @param connection The connection to determine whether or not to highlight.
* @returns True if we should highlight the connection.
*/
shouldHighlightConnection(_conn: Connection): boolean {
return true;
shouldHighlightConnection(connection: RenderedConnection): boolean {
return !connection.getSourceBlock().isDragging();
}
/**

View File

@@ -105,12 +105,6 @@ export class ConstantProvider extends BaseConstantProvider {
/** The size of the selected glow. */
SELECTED_GLOW_SIZE = 0.5;
/** The replacement glow colour. */
REPLACEMENT_GLOW_COLOUR = '#fff200';
/** The size of the selected glow. */
REPLACEMENT_GLOW_SIZE = 2;
/**
* The ID of the selected glow filter, or the empty string if no filter is
* set.
@@ -122,17 +116,6 @@ export class ConstantProvider extends BaseConstantProvider {
*/
private selectedGlowFilter: SVGElement | null = null;
/**
* The ID of the replacement glow filter, or the empty string if no filter
* is set.
*/
replacementGlowFilterId = '';
/**
* The <filter> element to use for a replacement glow, or null if not set.
*/
private replacementGlowFilter: SVGElement | null = null;
/**
* The object containing information about the hexagon used for a boolean
* reporter block. Null before init is called.
@@ -269,16 +252,6 @@ export class ConstantProvider extends BaseConstantProvider {
selectedGlowSize && !isNaN(selectedGlowSize)
? selectedGlowSize
: this.SELECTED_GLOW_SIZE;
this.REPLACEMENT_GLOW_COLOUR =
theme.getComponentStyle('replacementGlowColour') ||
this.REPLACEMENT_GLOW_COLOUR;
const replacementGlowSize = Number(
theme.getComponentStyle('replacementGlowSize'),
);
this.REPLACEMENT_GLOW_SIZE =
replacementGlowSize && !isNaN(replacementGlowSize)
? replacementGlowSize
: this.REPLACEMENT_GLOW_SIZE;
}
override dispose() {
@@ -286,9 +259,6 @@ export class ConstantProvider extends BaseConstantProvider {
if (this.selectedGlowFilter) {
dom.removeNode(this.selectedGlowFilter);
}
if (this.replacementGlowFilter) {
dom.removeNode(this.replacementGlowFilter);
}
}
override makeStartHat() {
@@ -740,67 +710,6 @@ export class ConstantProvider extends BaseConstantProvider {
this.selectedGlowFilterId = selectedGlowFilter.id;
this.selectedGlowFilter = selectedGlowFilter;
// Using a dilate distorts the block shape.
// Instead use a gaussian blur, and then set all alpha to 1 with a transfer.
const replacementGlowFilter = dom.createSvgElement(
Svg.FILTER,
{
'id': 'blocklyReplacementGlowFilter' + this.randomIdentifier,
'height': '160%',
'width': '180%',
'y': '-30%',
'x': '-40%',
},
defs,
);
dom.createSvgElement(
Svg.FEGAUSSIANBLUR,
{'in': 'SourceGraphic', 'stdDeviation': this.REPLACEMENT_GLOW_SIZE},
replacementGlowFilter,
);
// Set all gaussian blur pixels to 1 opacity before applying flood
const replacementComponentTransfer = dom.createSvgElement(
Svg.FECOMPONENTTRANSFER,
{'result': 'outBlur'},
replacementGlowFilter,
);
dom.createSvgElement(
Svg.FEFUNCA,
{'type': 'table', 'tableValues': '0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'},
replacementComponentTransfer,
);
// Color the highlight
dom.createSvgElement(
Svg.FEFLOOD,
{
'flood-color': this.REPLACEMENT_GLOW_COLOUR,
'flood-opacity': 1,
'result': 'outColor',
},
replacementGlowFilter,
);
dom.createSvgElement(
Svg.FECOMPOSITE,
{
'in': 'outColor',
'in2': 'outBlur',
'operator': 'in',
'result': 'outGlow',
},
replacementGlowFilter,
);
dom.createSvgElement(
Svg.FECOMPOSITE,
{
'in': 'SourceGraphic',
'in2': 'outGlow',
'operator': 'over',
},
replacementGlowFilter,
);
this.replacementGlowFilterId = replacementGlowFilter.id;
this.replacementGlowFilter = replacementGlowFilter;
if (injectionDivIfIsParent) {
// If this renderer is for the parent workspace, add CSS variables scoped
// to the injection div referencing the created patterns so that CSS can
@@ -809,10 +718,6 @@ export class ConstantProvider extends BaseConstantProvider {
'--blocklySelectedGlowFilter',
`url(#${this.selectedGlowFilterId})`,
);
injectionDivIfIsParent.style.setProperty(
'--blocklyReplacementGlowFilter',
`url(#${this.replacementGlowFilterId})`,
);
}
}
@@ -904,10 +809,6 @@ export class ConstantProvider extends BaseConstantProvider {
`fill: none;`,
`filter: var(--blocklySelectedGlowFilter);`,
`}`,
`${selector} .blocklyReplaceable>.blocklyPath {`,
`filter: var(--blocklyReplacementGlowFilter);`,
`}`,
];
}
}

View File

@@ -7,7 +7,6 @@
// Former goog.module ID: Blockly.zelos.PathObject
import type {BlockSvg} from '../../block_svg.js';
import type {Connection} from '../../connection.js';
import {FocusManager} from '../../focus_manager.js';
import type {BlockStyle} from '../../theme.js';
import * as dom from '../../utils/dom.js';
@@ -113,26 +112,6 @@ export class PathObject extends BasePathObject {
}
}
override updateReplacementFade(enable: boolean) {
this.setClass_('blocklyReplaceable', enable);
}
override updateShapeForInputHighlight(conn: Connection, enable: boolean) {
const name = conn.getParentInput()!.name;
const outlinePath = this.getOutlinePath(name);
if (!outlinePath) {
return;
}
if (enable) {
outlinePath.setAttribute(
'filter',
'url(#' + this.constants.replacementGlowFilterId + ')',
);
} else {
outlinePath.removeAttribute('filter');
}
}
/**
* Method that's called when the drawer is about to draw the block.
*/

View File

@@ -7,6 +7,8 @@
// Former goog.module ID: Blockly.zelos.Renderer
import type {BlockSvg} from '../../block_svg.js';
import {ConnectionType} from '../../connection_type.js';
import type {RenderedConnection} from '../../rendered_connection.js';
import type {BlockStyle} from '../../theme.js';
import * as blockRendering from '../common/block_rendering.js';
import type {RenderInfo as BaseRenderInfo} from '../common/info.js';
@@ -86,6 +88,19 @@ export class Renderer extends BaseRenderer {
override getConstants(): ConstantProvider {
return this.constants_;
}
/**
* Determine whether or not to highlight a connection.
*
* @param connection The connection to determine whether or not to highlight.
* @returns True if we should highlight the connection.
*/
override shouldHighlightConnection(connection: RenderedConnection): boolean {
return (
super.shouldHighlightConnection(connection) ||
connection.type === ConnectionType.INPUT_VALUE
);
}
}
blockRendering.register('zelos', Renderer);

View File

@@ -215,8 +215,6 @@ export namespace Theme {
cursorColour?: string;
selectedGlowColour?: string;
selectedGlowOpacity?: number;
replacementGlowColour?: string;
replacementGlowOpacity?: number;
}
export interface FontStyle {