Learnify - In-depth Analysis of Tool Switching Mechanism

Overview

This document provides a detailed analysis of the core mechanism for tool switching in BlockSuite, with a particular focus on the full process of switching from DefaultTool to PanTool.

Core Components

1. ToolController (blocksuite/framework/std/src/gfx/tool/tool-controller.ts)

ToolController is the core class responsible for managing tools, including registration, switching, and event routing.

Key Method

setTool<T extends BaseTool>(toolType: ToolType<T>, options?: ToolOptions<T>): void

The entry method for tool switching, performing the complete switching process:

setTool = <T extends BaseTool>(toolType: ToolType<T>, options?: ToolOptions<T>): void => {
  const toolNameStr = toolType.toolName;

  // 1. Trigger beforeToolUpdate hook
  const beforeUpdateCtx = this._createBuiltInHookCtx('beforeToolUpdate', {
    toolName: toolNameStr,
  });
  this._builtInHookSlot.next(beforeUpdateCtx.slotCtx);

  if (beforeUpdateCtx.prevented) {
    return; // Hook can block switching
  }

  // 2. Clear current selection
  this.gfx.selection.set({ elements: [] });

  // 3. Deactivate current tool
  this.currentTool$.peek()?.deactivate();

  // 4. Set new tool name (critical step!)
  this.currentToolName$.value = toolNameStr;

  // 5. Activate new tool
  const currentTool = this.currentTool$.peek();
  currentTool?.activate(options);

  // 6. Trigger afterToolUpdate hook
  const afterUpdateCtx = this._createBuiltInHookCtx('afterToolUpdate', {
    toolName: toolNameStr,
  });
  this._builtInHookSlot.next(afterUpdateCtx.slotCtx);
};