mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
fix: gestures handling icons (#7101)
* fix: add handling icon clicks to the gesture system * fix: error message
This commit is contained in:
@@ -199,7 +199,7 @@ export class BlockSvg
|
||||
}
|
||||
for (const icon of this.getIcons()) {
|
||||
if (isIcon(icon)) {
|
||||
// icon.initView();
|
||||
icon.initView(this.createIconPointerDownListener(icon));
|
||||
icon.updateEditable();
|
||||
} else {
|
||||
// TODO (#7042): Remove old icon handling.
|
||||
@@ -1051,7 +1051,7 @@ export class BlockSvg
|
||||
override addIcon<T extends IIcon>(icon: T): T {
|
||||
super.addIcon(icon);
|
||||
if (this.rendered) {
|
||||
// icon.initView();
|
||||
icon.initView(this.createIconPointerDownListener(icon));
|
||||
icon.applyColour();
|
||||
icon.updateEditable();
|
||||
// TODO: Change this based on #7024.
|
||||
@@ -1061,6 +1061,20 @@ export class BlockSvg
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a pointer down event listener for the icon to append to its
|
||||
* root svg.
|
||||
*/
|
||||
private createIconPointerDownListener(icon: IIcon) {
|
||||
return (e: PointerEvent) => {
|
||||
if (this.isDeadOrDying()) return;
|
||||
const gesture = this.workspace.getGesture(e);
|
||||
if (gesture) {
|
||||
gesture.setStartIcon(icon);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
override removeIcon(type: string): boolean {
|
||||
const removed = super.removeIcon(type);
|
||||
if (this.rendered) {
|
||||
|
||||
@@ -36,6 +36,7 @@ import {Coordinate} from './utils/coordinate.js';
|
||||
import {WorkspaceCommentSvg} from './workspace_comment_svg.js';
|
||||
import {WorkspaceDragger} from './workspace_dragger.js';
|
||||
import type {WorkspaceSvg} from './workspace_svg.js';
|
||||
import type {IIcon} from './interfaces/i_icon.js';
|
||||
|
||||
/**
|
||||
* Note: In this file "start" refers to pointerdown
|
||||
@@ -72,6 +73,12 @@ export class Gesture {
|
||||
*/
|
||||
private startField: Field | null = null;
|
||||
|
||||
/**
|
||||
* The icon that the gesture started on, or null if it did not start on an
|
||||
* icon.
|
||||
*/
|
||||
private startIcon: IIcon | null = null;
|
||||
|
||||
/**
|
||||
* The block that the gesture started on, or null if it did not start on a
|
||||
* block.
|
||||
@@ -614,9 +621,9 @@ export class Gesture {
|
||||
}
|
||||
this.isEnding_ = true;
|
||||
// The ordering of these checks is important: drags have higher priority
|
||||
// than clicks. Fields have higher priority than blocks; blocks have
|
||||
// higher priority than workspaces. The ordering within drags does not
|
||||
// matter, because the three types of dragging are exclusive.
|
||||
// than clicks. Fields and icons have higher priority than blocks; blocks
|
||||
// have higher priority than workspaces. The ordering within drags does
|
||||
// not matter, because the three types of dragging are exclusive.
|
||||
if (this.bubbleDragger) {
|
||||
this.bubbleDragger.endBubbleDrag(e, this.currentDragDeltaXY);
|
||||
} else if (this.blockDragger) {
|
||||
@@ -628,6 +635,8 @@ export class Gesture {
|
||||
this.doBubbleClick();
|
||||
} else if (this.isFieldClick()) {
|
||||
this.doFieldClick();
|
||||
} else if (this.isIconClick()) {
|
||||
this.doIconClick();
|
||||
} else if (this.isBlockClick()) {
|
||||
this.doBlockClick();
|
||||
} else if (this.isWorkspaceClick()) {
|
||||
@@ -917,7 +926,7 @@ export class Gesture {
|
||||
private doFieldClick() {
|
||||
if (!this.startField) {
|
||||
throw new Error(
|
||||
'Cannot do a field click because the start field is ' + 'undefined'
|
||||
'Cannot do a field click because the start field is undefined'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -930,6 +939,17 @@ export class Gesture {
|
||||
this.bringBlockToFront();
|
||||
}
|
||||
|
||||
/** Execute an icon click. */
|
||||
private doIconClick() {
|
||||
if (!this.startIcon) {
|
||||
throw new Error(
|
||||
'Cannot do an icon click because the start icon is undefined'
|
||||
);
|
||||
}
|
||||
|
||||
this.startIcon.onClick();
|
||||
}
|
||||
|
||||
/** Execute a block click. */
|
||||
private doBlockClick() {
|
||||
// Block click in an autoclosing flyout.
|
||||
@@ -1015,6 +1035,23 @@ export class Gesture {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the icon that a gesture started on.
|
||||
*
|
||||
* @param icon The icon the gesture started on.
|
||||
* @internal
|
||||
*/
|
||||
setStartIcon(icon: IIcon) {
|
||||
if (this.gestureHasStarted) {
|
||||
throw Error(
|
||||
'Tried to call gesture.setStartIcon, ' +
|
||||
'but the gesture had already been started.'
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.startIcon) this.startIcon = icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the bubble that a gesture started on
|
||||
*
|
||||
@@ -1112,7 +1149,12 @@ export class Gesture {
|
||||
// A block click starts on a block, never escapes the drag radius, and is
|
||||
// not a field click.
|
||||
const hasStartBlock = !!this.startBlock;
|
||||
return hasStartBlock && !this.hasExceededDragRadius && !this.isFieldClick();
|
||||
return (
|
||||
hasStartBlock &&
|
||||
!this.hasExceededDragRadius &&
|
||||
!this.isFieldClick() &&
|
||||
!this.isIconClick()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1132,6 +1174,11 @@ export class Gesture {
|
||||
);
|
||||
}
|
||||
|
||||
/** @return Whether this gesture is a click on an icon. */
|
||||
private isIconClick(): boolean {
|
||||
return !!this.startIcon && !this.hasExceededDragRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this gesture is a click on a workspace. This should only be called
|
||||
* when ending a gesture (pointerup).
|
||||
|
||||
@@ -124,7 +124,7 @@ suite('Icon', function () {
|
||||
);
|
||||
});
|
||||
|
||||
test.skip('initView is called by headful blocks during initSvg', function () {
|
||||
test('initView is called by headful blocks during initSvg', function () {
|
||||
const workspace = createWorkspaceSvg();
|
||||
const block = createUninitializedBlock(workspace);
|
||||
const icon = new MockIcon();
|
||||
@@ -142,7 +142,7 @@ suite('Icon', function () {
|
||||
);
|
||||
});
|
||||
|
||||
test.skip(
|
||||
test(
|
||||
'initView is called by headful blocks that are currently ' +
|
||||
'rendered when the icon is added',
|
||||
function () {
|
||||
|
||||
Reference in New Issue
Block a user