Skip to content

Commit

Permalink
feat!: change gestures to look at selected when dragging (#7991)
Browse files Browse the repository at this point in the history
* feat: change gestures to look at selected when dragging

* chore: fix tests

* chore: format

* chore: PR comments
  • Loading branch information
BeksOmega authored Apr 4, 2024
1 parent e75a4fb commit ed403d0
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 200 deletions.
3 changes: 2 additions & 1 deletion blocks/procedures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {config} from '../core/config.js';
import {defineBlocks} from '../core/common.js';
import '../core/icons/comment_icon.js';
import '../core/icons/warning_icon.js';
import * as common from '../core/common.js';

/** A dictionary of the block definitions provided by this module. */
export const blocks: {[key: string]: BlockDefinition} = {};
Expand Down Expand Up @@ -1157,7 +1158,7 @@ const PROCEDURE_CALL_COMMON = {
const def = Procedures.getDefinition(name, workspace);
if (def) {
(workspace as WorkspaceSvg).centerOnBlock(def.id);
(def as BlockSvg).select();
common.setSelected(def as BlockSvg);
}
},
});
Expand Down
42 changes: 2 additions & 40 deletions core/block_svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,56 +241,18 @@ export class BlockSvg
return this.style.colourTertiary;
}

/**
* Selects this block. Highlights the block visually and fires a select event
* if the block is not already selected.
*/
/** Selects this block. Highlights the block visually. */
select() {
if (this.isShadow() && this.getParent()) {
// Shadow blocks should not be selected.
this.getParent()!.select();
return;
}
if (common.getSelected() === this) {
return;
}
let oldId = null;
if (common.getSelected()) {
oldId = common.getSelected()!.id;
// Unselect any previously selected block.
eventUtils.disable();
try {
common.getSelected()!.unselect();
} finally {
eventUtils.enable();
}
}
const event = new (eventUtils.get(eventUtils.SELECTED))(
oldId,
this.id,
this.workspace.id,
);
eventUtils.fire(event);
common.setSelected(this);
this.addSelect();
}

/**
* Unselects this block. Unhighlights the block and fires a select (false)
* event if the block is currently selected.
*/
/** Unselects this block. Unhighlights the blockv visually. */
unselect() {
if (common.getSelected() !== this) {
return;
}
const event = new (eventUtils.get(eventUtils.SELECTED))(
this.id,
null,
this.workspace.id,
);
event.workspaceId = this.workspace.id;
eventUtils.fire(event);
common.setSelected(null);
this.removeSelect();
}

Expand Down
19 changes: 17 additions & 2 deletions core/bubbles/bubble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ import {Rect} from '../utils/rect.js';
import {Size} from '../utils/size.js';
import {Svg} from '../utils/svg.js';
import {WorkspaceSvg} from '../workspace_svg.js';
import * as common from '../common.js';
import {ISelectable} from '../blockly.js';
import * as idGenerator from '../utils/idgenerator.js';

/**
* The abstract pop-up bubble class. This creates a UI that looks like a speech
* bubble, where it has a "tail" that points to the block, and a "head" that
* displays arbitrary svg elements.
*/
export abstract class Bubble implements IBubble {
export abstract class Bubble implements IBubble, ISelectable {
/** The width of the border around the bubble. */
static readonly BORDER_WIDTH = 6;

Expand Down Expand Up @@ -50,6 +53,8 @@ export abstract class Bubble implements IBubble {
/** Distance between arrow point and anchor point. */
static readonly ANCHOR_RADIUS = 8;

public id: string;

/** The SVG group containing all parts of the bubble. */
protected svgRoot: SVGGElement;

Expand Down Expand Up @@ -89,10 +94,11 @@ export abstract class Bubble implements IBubble {
* when automatically positioning.
*/
constructor(
protected readonly workspace: WorkspaceSvg,
public readonly workspace: WorkspaceSvg,
protected anchor: Coordinate,
protected ownerRect?: Rect,
) {
this.id = idGenerator.getNextUniqueId();
this.svgRoot = dom.createSvgElement(
Svg.G,
{'class': 'blocklyBubble'},
Expand Down Expand Up @@ -209,6 +215,7 @@ export abstract class Bubble implements IBubble {
/** Passes the pointer event off to the gesture system. */
private onMouseDown(e: PointerEvent) {
this.workspace.getGesture(e)?.handleBubbleStart(e, this);
common.setSelected(this);
}

/** Positions the bubble relative to its anchor. Does not render its tail. */
Expand Down Expand Up @@ -640,4 +647,12 @@ export abstract class Bubble implements IBubble {
revertDrag(): void {
this.dragStrategy.revertDrag();
}

select(): void {
// Bubbles don't have any visual for being selected.
}

unselect(): void {
// Bubbles don't have any visual for being selected.
}
}
2 changes: 1 addition & 1 deletion core/bubbles/mini_workspace_bubble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class MiniWorkspaceBubble extends Bubble {
/** @internal */
constructor(
workspaceOptions: BlocklyOptions,
protected readonly workspace: WorkspaceSvg,
public readonly workspace: WorkspaceSvg,
protected anchor: Coordinate,
protected ownerRect?: Rect,
) {
Expand Down
2 changes: 1 addition & 1 deletion core/bubbles/text_bubble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class TextBubble extends Bubble {

constructor(
private text: string,
protected readonly workspace: WorkspaceSvg,
public readonly workspace: WorkspaceSvg,
protected anchor: Coordinate,
protected ownerRect?: Rect,
) {
Expand Down
2 changes: 1 addition & 1 deletion core/bubbles/textinput_bubble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class TextInputBubble extends Bubble {
* when automatically positioning.
*/
constructor(
protected readonly workspace: WorkspaceSvg,
public readonly workspace: WorkspaceSvg,
protected anchor: Coordinate,
protected ownerRect?: Rect,
) {
Expand Down
3 changes: 2 additions & 1 deletion core/clipboard/block_paster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {Coordinate} from '../utils/coordinate.js';
import {WorkspaceSvg} from '../workspace_svg.js';
import * as eventUtils from '../events/utils.js';
import {config} from '../config.js';
import * as common from '../common.js';

export class BlockPaster implements IPaster<BlockCopyData, BlockSvg> {
static TYPE = 'block';
Expand Down Expand Up @@ -43,7 +44,7 @@ export class BlockPaster implements IPaster<BlockCopyData, BlockSvg> {
if (eventUtils.isEnabled() && !block.isShadow()) {
eventUtils.fire(new (eventUtils.get(eventUtils.BLOCK_CREATE))(block));
}
block.select();
common.setSelected(block);
return block;
}
}
Expand Down
9 changes: 8 additions & 1 deletion core/comments/rendered_workspace_comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import * as dom from '../utils/dom.js';
import {IDraggable} from '../interfaces/i_draggable.js';
import {CommentDragStrategy} from '../dragging/comment_drag_strategy.js';
import * as browserEvents from '../browser_events.js';
import * as common from '../common.js';
import {ISelectable} from '../interfaces/i_selectable.js';

export class RenderedWorkspaceComment
extends WorkspaceComment
implements IBoundedElement, IRenderedElement, IDraggable
implements IBoundedElement, IRenderedElement, IDraggable, ISelectable
{
/** The class encompassing the svg elements making up the workspace comment. */
private view: CommentView;
Expand Down Expand Up @@ -159,6 +161,7 @@ export class RenderedWorkspaceComment
const gesture = this.workspace.getGesture(e);
if (gesture) {
gesture.handleCommentStart(e, this);
common.setSelected(this);
}
}

Expand Down Expand Up @@ -186,4 +189,8 @@ export class RenderedWorkspaceComment
revertDrag(): void {
this.dragStrategy.revertDrag();
}

select(): void {}

unselect(): void {}
}
12 changes: 12 additions & 0 deletions core/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {BlockDefinition, Blocks} from './blocks.js';
import type {Connection} from './connection.js';
import type {Workspace} from './workspace.js';
import type {WorkspaceSvg} from './workspace_svg.js';
import * as eventUtils from './events/utils.js';

/** Database of all workspaces. */
const WorkspaceDB_ = Object.create(null);
Expand Down Expand Up @@ -105,7 +106,18 @@ export function getSelected(): ISelectable | null {
* @internal
*/
export function setSelected(newSelection: ISelectable | null) {
if (selected === newSelection) return;

const event = new (eventUtils.get(eventUtils.SELECTED))(
selected?.id ?? null,
newSelection?.id ?? null,
newSelection?.workspace.id ?? selected?.workspace.id ?? '',
);
eventUtils.fire(event);

selected?.unselect();
selected = newSelection;
selected?.select();
}

/**
Expand Down
5 changes: 3 additions & 2 deletions core/contextmenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import * as WidgetDiv from './widgetdiv.js';
import {WorkspaceCommentSvg} from './workspace_comment_svg.js';
import type {WorkspaceSvg} from './workspace_svg.js';
import * as Xml from './xml.js';
import * as common from './common.js';

/**
* Which block is the context menu attached to?
Expand Down Expand Up @@ -261,7 +262,7 @@ export function callbackFactory(
if (eventUtils.isEnabled() && !newBlock.isShadow()) {
eventUtils.fire(new (eventUtils.get(eventUtils.BLOCK_CREATE))(newBlock));
}
newBlock.select();
common.setSelected(newBlock);
return newBlock;
};
}
Expand Down Expand Up @@ -374,7 +375,7 @@ export function workspaceCommentOption(
if (ws.rendered) {
comment.initSvg();
comment.render();
comment.select();
common.setSelected(comment);
}
}

Expand Down
5 changes: 4 additions & 1 deletion core/dragging/block_drag_strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ export class BlockDragStrategy implements IDragStrategy {
this.block.isOwnMovable() &&
!this.block.isShadow() &&
!this.block.isDeadOrDying() &&
!this.workspace.options.readOnly
!this.workspace.options.readOnly &&
// We never drag blocks in the flyout, only create new blocks that are
// dragged.
!this.block.isInFlyout
);
}

Expand Down
Loading

0 comments on commit ed403d0

Please sign in to comment.