refactor: moving connector label to connector view (#11738)

### Changed
Moved connector label moving logic from `default-tool` to connector view.

#### Other infrastructure changes:​​
- Gfx element view now can handles drag events
- Added `context.preventDefault()` support to bypass built-in interactions in extension
- Handle the pointer events in element view will bypass the built-in interactions automatically

> The built-in interactions include element dragging, click selection, drag-to-scale operations, etc.
This commit is contained in:
doouding
2025-04-22 08:18:24 +00:00
parent 21bf009553
commit e0e84d302d
12 changed files with 305 additions and 130 deletions
@@ -5,7 +5,7 @@ import { Bound, Point } from '@blocksuite/global/gfx';
import type { PointerEventState } from '../../event/state/pointer.js';
import { GfxExtension, GfxExtensionIdentifier } from '../extension.js';
import type { GfxModel } from '../model/model.js';
import type { SupportedEvents } from './event.js';
import { createInteractionContext, type SupportedEvents } from './event.js';
import {
type InteractivityActionAPI,
type InteractivityEventAPI,
@@ -30,16 +30,6 @@ export const InteractivityIdentifier = GfxExtensionIdentifier(
'interactivity-manager'
) as ServiceIdentifier<InteractivityManager>;
const CAMEL_CASE_MAP: {
[key in ExtensionPointerHandler]: keyof GfxViewEventManager;
} = {
click: 'click',
dblclick: 'dblClick',
pointerdown: 'pointerDown',
pointermove: 'pointerMove',
pointerup: 'pointerUp',
};
export class InteractivityManager extends GfxExtension {
static override key = 'interactivity-manager';
@@ -78,20 +68,26 @@ export class InteractivityManager extends GfxExtension {
}
/**
* Dispatch the event to canvas elements
* Dispatch event to extensions and gfx view.
* @param eventName
* @param evt
* @returns
*/
dispatch(eventName: ExtensionPointerHandler, evt: PointerEventState) {
const handlerName = CAMEL_CASE_MAP[eventName];
this.canvasEventHandler[handlerName](evt);
dispatchEvent(eventName: ExtensionPointerHandler, evt: PointerEventState) {
const { context, preventDefaultState } = createInteractionContext(evt);
const extensions = this.interactExtensions;
extensions.forEach(ext => {
(ext.event as InteractivityEventAPI).emit(eventName, evt);
(ext.event as InteractivityEventAPI).emit(eventName, context);
});
const handledByView =
this.canvasEventHandler.dispatch(eventName, evt) ?? false;
return {
preventDefaultState,
handledByView,
};
}
dispatchOnSelected(evt: PointerEventState) {
@@ -126,6 +122,14 @@ export class InteractivityManager extends GfxExtension {
return false;
}
/**
* Initialize drag operation for elements.
* Handles drag start, move and end events automatically.
* Note: Call this when mouse is already down.
*
* @param options
* @returns
*/
initializeDrag(options: DragInitializationOption) {
let cancelledByExt = false;