Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: gestures handling icons #7101

Merged
merged 2 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 a field click because the start field is undefined'
BeksOmega marked this conversation as resolved.
Show resolved Hide resolved
);
}

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