fix: gestures handling icons (#7101)

* fix: add handling icon clicks to the gesture system

* fix: error message
This commit is contained in:
Beka Westberg
2023-05-22 13:10:42 -07:00
committed by GitHub
parent 2b50ef2a64
commit d90d00570f
3 changed files with 70 additions and 9 deletions

View File

@@ -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) {

View File

@@ -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).

View File

@@ -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 () {