Skip to content

Commit

Permalink
fix: gestures handling icons (#7101)
Browse files Browse the repository at this point in the history
* fix: add handling icon clicks to the gesture system

* fix: error message
  • Loading branch information
BeksOmega authored May 22, 2023
1 parent 2b50ef2 commit d90d005
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 9 deletions.
18 changes: 16 additions & 2 deletions core/block_svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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) {
Expand Down
57 changes: 52 additions & 5 deletions core/gesture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand All @@ -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()) {
Expand Down Expand Up @@ -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'
);
}

Expand All @@ -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.
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -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()
);
}

/**
Expand All @@ -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).
Expand Down
4 changes: 2 additions & 2 deletions tests/mocha/icon_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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 () {
Expand Down

0 comments on commit d90d005

Please sign in to comment.