Skip to content

Commit 589e05d

Browse files
authored
fix!: Normalize Zelos connection indicators (#9565)
* fix: Normalize Zelos connection indicators * feat: Add `IPathObject.updateReplacing()`
1 parent 1cbf1b3 commit 589e05d

10 files changed

Lines changed: 51 additions & 161 deletions

File tree

packages/blockly/core/block_svg.ts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,13 @@ export class BlockSvg
791791
}
792792
}
793793

794+
/**
795+
* Returns whether or not this block is currently being dragged.
796+
*/
797+
isDragging() {
798+
return this.dragging;
799+
}
800+
794801
/**
795802
* Set whether this block is movable or not.
796803
*
@@ -1738,24 +1745,7 @@ export class BlockSvg
17381745
* @internal
17391746
*/
17401747
fadeForReplacement(add: boolean) {
1741-
// TODO (7204): Remove these internal methods.
1742-
(this.pathObject as AnyDuringMigration).updateReplacementFade(add);
1743-
}
1744-
1745-
/**
1746-
* Visual effect to show that if the dragging block is dropped it will connect
1747-
* to this input.
1748-
*
1749-
* @param conn The connection on the input to highlight.
1750-
* @param add True if highlighting should be added.
1751-
* @internal
1752-
*/
1753-
highlightShapeForInput(conn: RenderedConnection, add: boolean) {
1754-
// TODO (7204): Remove these internal methods.
1755-
(this.pathObject as AnyDuringMigration).updateShapeForInputHighlight(
1756-
conn,
1757-
add,
1758-
);
1748+
this.pathObject.updateReplacing?.(add);
17591749
}
17601750

17611751
/**

packages/blockly/core/insertion_marker_previewer.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ export class InsertionMarkerPreviewer implements IConnectionPreviewer {
9292
staticConn.highlight();
9393
}
9494

95+
if (this.workspace.getRenderer().shouldHighlightConnection(draggedConn)) {
96+
draggedConn.highlight();
97+
}
98+
9599
this.draggedConn = draggedConn;
96100
this.staticConn = staticConn;
97101
} finally {
@@ -224,6 +228,10 @@ export class InsertionMarkerPreviewer implements IConnectionPreviewer {
224228
this.staticConn.unhighlight();
225229
this.staticConn = null;
226230
}
231+
if (this.draggedConn) {
232+
this.draggedConn.unhighlight();
233+
this.draggedConn = null;
234+
}
227235
if (this.fadedBlock) {
228236
this.fadedBlock.fadeForReplacement(false);
229237
this.fadedBlock = null;

packages/blockly/core/rendered_connection.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ export class RenderedConnection
331331
const highlightSvg = this.findHighlightSvg();
332332
if (highlightSvg) {
333333
highlightSvg.style.display = '';
334+
highlightSvg.parentElement?.appendChild(highlightSvg);
334335
}
335336
}
336337

packages/blockly/core/renderers/common/i_path_object.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,13 @@ export interface IPathObject {
106106
* @param blockStyle The block style to use.
107107
*/
108108
setStyle?(blockStyle: BlockStyle): void;
109+
110+
/**
111+
* Add or remove styling indicating that a block will be bumped out and
112+
* replaced by another block that is mid-move.
113+
*
114+
* @param replacing True if the block is at risk of being replaced, false
115+
* otherwise.
116+
*/
117+
updateReplacing?(replacing: boolean): void;
109118
}

packages/blockly/core/renderers/common/path_object.ts

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
// Former goog.module ID: Blockly.blockRendering.PathObject
88

99
import type {BlockSvg} from '../../block_svg.js';
10-
import type {Connection} from '../../connection.js';
1110
import {RenderedConnection} from '../../rendered_connection.js';
1211
import type {BlockStyle} from '../../theme.js';
1312
import {Coordinate} from '../../utils/coordinate.js';
@@ -193,25 +192,14 @@ export class PathObject implements IPathObject {
193192
}
194193

195194
/**
196-
* Add or remove styling that shows that if the dragging block is dropped,
197-
* this block will be replaced. If a shadow block, it will disappear.
198-
* Otherwise it will bump.
195+
* Add or remove styling indicating that a block will be bumped out and
196+
* replaced by another block that is mid-move.
199197
*
200-
* @param enable True if styling should be added.
201-
*/
202-
updateReplacementFade(enable: boolean) {
203-
this.setClass_('blocklyReplaceable', enable);
204-
}
205-
206-
/**
207-
* Add or remove styling that shows that if the dragging block is dropped,
208-
* this block will be connected to the input.
209-
*
210-
* @param _conn The connection on the input to highlight.
211-
* @param _enable True if styling should be added.
198+
* @param replacing True if the block is at risk of being replaced, false
199+
* otherwise.
212200
*/
213-
updateShapeForInputHighlight(_conn: Connection, _enable: boolean) {
214-
// NOOP
201+
updateReplacing(replacing: boolean) {
202+
this.setClass_('blocklyReplaceable', replacing);
215203
}
216204

217205
/** Adds the given path as a connection highlight for the given connection. */

packages/blockly/core/renderers/common/renderer.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {BlockSvg} from '../../block_svg.js';
1111
import {Connection} from '../../connection.js';
1212
import {ConnectionType} from '../../connection_type.js';
1313
import type {IRegistrable} from '../../interfaces/i_registrable.js';
14+
import type {RenderedConnection} from '../../rendered_connection.js';
1415
import type {BlockStyle, Theme} from '../../theme.js';
1516
import {ConstantProvider} from './constants.js';
1617
import {Drawer} from './drawer.js';
@@ -188,11 +189,11 @@ export class Renderer implements IRegistrable {
188189
/**
189190
* Determine whether or not to highlight a connection.
190191
*
191-
* @param _conn The connection to determine whether or not to highlight.
192+
* @param connection The connection to determine whether or not to highlight.
192193
* @returns True if we should highlight the connection.
193194
*/
194-
shouldHighlightConnection(_conn: Connection): boolean {
195-
return true;
195+
shouldHighlightConnection(connection: RenderedConnection): boolean {
196+
return !connection.getSourceBlock().isDragging();
196197
}
197198

198199
/**

packages/blockly/core/renderers/zelos/constants.ts

Lines changed: 0 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,6 @@ export class ConstantProvider extends BaseConstantProvider {
105105
/** The size of the selected glow. */
106106
SELECTED_GLOW_SIZE = 0.5;
107107

108-
/** The replacement glow colour. */
109-
REPLACEMENT_GLOW_COLOUR = '#fff200';
110-
111-
/** The size of the selected glow. */
112-
REPLACEMENT_GLOW_SIZE = 2;
113-
114108
/**
115109
* The ID of the selected glow filter, or the empty string if no filter is
116110
* set.
@@ -122,17 +116,6 @@ export class ConstantProvider extends BaseConstantProvider {
122116
*/
123117
private selectedGlowFilter: SVGElement | null = null;
124118

125-
/**
126-
* The ID of the replacement glow filter, or the empty string if no filter
127-
* is set.
128-
*/
129-
replacementGlowFilterId = '';
130-
131-
/**
132-
* The <filter> element to use for a replacement glow, or null if not set.
133-
*/
134-
private replacementGlowFilter: SVGElement | null = null;
135-
136119
/**
137120
* The object containing information about the hexagon used for a boolean
138121
* reporter block. Null before init is called.
@@ -269,26 +252,13 @@ export class ConstantProvider extends BaseConstantProvider {
269252
selectedGlowSize && !isNaN(selectedGlowSize)
270253
? selectedGlowSize
271254
: this.SELECTED_GLOW_SIZE;
272-
this.REPLACEMENT_GLOW_COLOUR =
273-
theme.getComponentStyle('replacementGlowColour') ||
274-
this.REPLACEMENT_GLOW_COLOUR;
275-
const replacementGlowSize = Number(
276-
theme.getComponentStyle('replacementGlowSize'),
277-
);
278-
this.REPLACEMENT_GLOW_SIZE =
279-
replacementGlowSize && !isNaN(replacementGlowSize)
280-
? replacementGlowSize
281-
: this.REPLACEMENT_GLOW_SIZE;
282255
}
283256

284257
override dispose() {
285258
super.dispose();
286259
if (this.selectedGlowFilter) {
287260
dom.removeNode(this.selectedGlowFilter);
288261
}
289-
if (this.replacementGlowFilter) {
290-
dom.removeNode(this.replacementGlowFilter);
291-
}
292262
}
293263

294264
override makeStartHat() {
@@ -740,67 +710,6 @@ export class ConstantProvider extends BaseConstantProvider {
740710
this.selectedGlowFilterId = selectedGlowFilter.id;
741711
this.selectedGlowFilter = selectedGlowFilter;
742712

743-
// Using a dilate distorts the block shape.
744-
// Instead use a gaussian blur, and then set all alpha to 1 with a transfer.
745-
const replacementGlowFilter = dom.createSvgElement(
746-
Svg.FILTER,
747-
{
748-
'id': 'blocklyReplacementGlowFilter' + this.randomIdentifier,
749-
'height': '160%',
750-
'width': '180%',
751-
'y': '-30%',
752-
'x': '-40%',
753-
},
754-
defs,
755-
);
756-
dom.createSvgElement(
757-
Svg.FEGAUSSIANBLUR,
758-
{'in': 'SourceGraphic', 'stdDeviation': this.REPLACEMENT_GLOW_SIZE},
759-
replacementGlowFilter,
760-
);
761-
// Set all gaussian blur pixels to 1 opacity before applying flood
762-
const replacementComponentTransfer = dom.createSvgElement(
763-
Svg.FECOMPONENTTRANSFER,
764-
{'result': 'outBlur'},
765-
replacementGlowFilter,
766-
);
767-
dom.createSvgElement(
768-
Svg.FEFUNCA,
769-
{'type': 'table', 'tableValues': '0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'},
770-
replacementComponentTransfer,
771-
);
772-
// Color the highlight
773-
dom.createSvgElement(
774-
Svg.FEFLOOD,
775-
{
776-
'flood-color': this.REPLACEMENT_GLOW_COLOUR,
777-
'flood-opacity': 1,
778-
'result': 'outColor',
779-
},
780-
replacementGlowFilter,
781-
);
782-
dom.createSvgElement(
783-
Svg.FECOMPOSITE,
784-
{
785-
'in': 'outColor',
786-
'in2': 'outBlur',
787-
'operator': 'in',
788-
'result': 'outGlow',
789-
},
790-
replacementGlowFilter,
791-
);
792-
dom.createSvgElement(
793-
Svg.FECOMPOSITE,
794-
{
795-
'in': 'SourceGraphic',
796-
'in2': 'outGlow',
797-
'operator': 'over',
798-
},
799-
replacementGlowFilter,
800-
);
801-
this.replacementGlowFilterId = replacementGlowFilter.id;
802-
this.replacementGlowFilter = replacementGlowFilter;
803-
804713
if (injectionDivIfIsParent) {
805714
// If this renderer is for the parent workspace, add CSS variables scoped
806715
// to the injection div referencing the created patterns so that CSS can
@@ -809,10 +718,6 @@ export class ConstantProvider extends BaseConstantProvider {
809718
'--blocklySelectedGlowFilter',
810719
`url(#${this.selectedGlowFilterId})`,
811720
);
812-
injectionDivIfIsParent.style.setProperty(
813-
'--blocklyReplacementGlowFilter',
814-
`url(#${this.replacementGlowFilterId})`,
815-
);
816721
}
817722
}
818723

@@ -904,10 +809,6 @@ export class ConstantProvider extends BaseConstantProvider {
904809
`fill: none;`,
905810
`filter: var(--blocklySelectedGlowFilter);`,
906811
`}`,
907-
908-
`${selector} .blocklyReplaceable>.blocklyPath {`,
909-
`filter: var(--blocklyReplacementGlowFilter);`,
910-
`}`,
911812
];
912813
}
913814
}

packages/blockly/core/renderers/zelos/path_object.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
// Former goog.module ID: Blockly.zelos.PathObject
88

99
import type {BlockSvg} from '../../block_svg.js';
10-
import type {Connection} from '../../connection.js';
1110
import {FocusManager} from '../../focus_manager.js';
1211
import type {BlockStyle} from '../../theme.js';
1312
import * as dom from '../../utils/dom.js';
@@ -113,26 +112,6 @@ export class PathObject extends BasePathObject {
113112
}
114113
}
115114

116-
override updateReplacementFade(enable: boolean) {
117-
this.setClass_('blocklyReplaceable', enable);
118-
}
119-
120-
override updateShapeForInputHighlight(conn: Connection, enable: boolean) {
121-
const name = conn.getParentInput()!.name;
122-
const outlinePath = this.getOutlinePath(name);
123-
if (!outlinePath) {
124-
return;
125-
}
126-
if (enable) {
127-
outlinePath.setAttribute(
128-
'filter',
129-
'url(#' + this.constants.replacementGlowFilterId + ')',
130-
);
131-
} else {
132-
outlinePath.removeAttribute('filter');
133-
}
134-
}
135-
136115
/**
137116
* Method that's called when the drawer is about to draw the block.
138117
*/

packages/blockly/core/renderers/zelos/renderer.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
// Former goog.module ID: Blockly.zelos.Renderer
88

99
import type {BlockSvg} from '../../block_svg.js';
10+
import {ConnectionType} from '../../connection_type.js';
11+
import type {RenderedConnection} from '../../rendered_connection.js';
1012
import type {BlockStyle} from '../../theme.js';
1113
import * as blockRendering from '../common/block_rendering.js';
1214
import type {RenderInfo as BaseRenderInfo} from '../common/info.js';
@@ -86,6 +88,19 @@ export class Renderer extends BaseRenderer {
8688
override getConstants(): ConstantProvider {
8789
return this.constants_;
8890
}
91+
92+
/**
93+
* Determine whether or not to highlight a connection.
94+
*
95+
* @param connection The connection to determine whether or not to highlight.
96+
* @returns True if we should highlight the connection.
97+
*/
98+
override shouldHighlightConnection(connection: RenderedConnection): boolean {
99+
return (
100+
super.shouldHighlightConnection(connection) ||
101+
connection.type === ConnectionType.INPUT_VALUE
102+
);
103+
}
89104
}
90105

91106
blockRendering.register('zelos', Renderer);

packages/blockly/core/theme.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,6 @@ export namespace Theme {
215215
cursorColour?: string;
216216
selectedGlowColour?: string;
217217
selectedGlowOpacity?: number;
218-
replacementGlowColour?: string;
219-
replacementGlowOpacity?: number;
220218
}
221219

222220
export interface FontStyle {

0 commit comments

Comments
 (0)