This document provides a detailed record of the enhancement process for PanTool, upgrading it from a simple panning tool to a comprehensive tool that supports complete mind map interactions. This enhancement maintains the original panning functionality while adding complete interaction support including hover, click, double-click, and more.
Original PanTool Analysis
Functional Limitations
The original PanTool located at blocksuite/affine/gfx/pointer/src/tools/pan-tool.ts only implemented basic panning functionality:
Backward compatibility: Do not break existing panning logic
Event dispatch priority: Prioritize dispatching to interactivity system, then handle tool-specific logic
Code reuse: Reuse mature patterns from DefaultTool
Clear responsibility separation: Separate panning logic vs interaction logic
Implementation Steps
1. Import Dependencies
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Original imports import { on } from'@blocksuite/affine-shared/utils'; importtype { PointerEventState } from'@blocksuite/std'; import { BaseTool, MouseButton, typeToolOptions } from'@blocksuite/std/gfx'; import { Signal } from'@preact/signals-core';
// New imports import { BaseTool, InteractivityIdentifier, // New - interactivity system identifier MouseButton, typeToolOptions, } from'@blocksuite/std/gfx'; import { signal } from'@preact/signals-core'; // Updated - using new signal API
Change Notes:
Added InteractivityIdentifier for accessing the interaction system
Changed Signal to signal to use the new API
Organized import order to comply with linting rules
Event dispatch priority: Let interactivity system handle first, as other Extensions might need this event
Maintain original logic: Panning state management remains unchanged
Parameter usage: Correctly use event parameters to avoid linter warnings
4. Add Complete Interaction Methods
click - Click Interaction
1 2 3 4
overrideclick(e: PointerEventState): void { // Dispatch click events to interactivity system for mind map expand/collapse functionality this.interactivity?.dispatchEvent('click', e); }
Functionality:
Mind map node expand/collapse
Button click responses
Selection operations
pointerMove - Hover Functionality
1 2 3 4
overridepointerMove(e: PointerEventState): void { // Dispatch pointer move events to interactivity system for hover functionality this.interactivity?.dispatchEvent('pointermove', e); }
Functionality:
Element hover highlighting
Collapse button show/hide
Cursor style changes
Tooltip display
pointerDown/pointerUp - Complete Mouse Lifecycle
1 2 3 4 5 6 7 8 9
overridepointerDown(e: PointerEventState): void { // Dispatch pointerdown events to interactivity system this.interactivity?.dispatchEvent('pointerdown', e); }
overridepointerUp(e: PointerEventState): void { // Dispatch pointerup events to interactivity system this.interactivity?.dispatchEvent('pointerup', e); }
Functionality:
Press/release state management
Drag preparation and ending
Complex interaction state machines
doubleClick - Double-Click Operations
1 2 3 4
overridedoubleClick(e: PointerEventState): void { // Dispatch double-click events to interactivity system this.interactivity?.dispatchEvent('dblclick', e); }
sequenceDiagram participant User as User Operation participant Browser as Browser participant TC as ToolController participant PT as PanTool participant IS as Interactivity System participant MV as MindMapView