KiCad Tool Framework

Rationale

Currently all editing tools in pcbnew reside in a single, enormous class (PCB_EDIT_FRAME) entangled with numerous editing methods in the model & a bunch of global/static functions and variables. Such code is very difficult to maintain and extend.

Requirements

  • Each tool belongs to one of following categories:
    - interactive, such as a PCB router - that once activated take a group of keyboard/mouse events and process them until an exit event is received. Only one interactive tool can be active at a time.
    - batch, which are run once in response to a UI/Scripting command (such as DRC)
  • Interactive tools are implemented as (hierarchical) state machines. An interactive tool can call another interactive or batch tool (for example, drag tool internally calls selection tool to know what to drag).
  • Each tool has a predefined activation event, and accepts a predefined range of keyboard/mouse events, assigned on-the-fly. Tools can exit when they want or when application-wide exit event is received (i.e. pressing Esc).
  • In general, tools are not allowed to draw anything that doesn't go through the View, unless there exists a very good reason for doing so (an example is drawing transparent selection boxes or moving large groups of items)
  • One tool = one class. Tools must not use non-trivial static methods and must never, ever, have any global states. Main tool interface must not have any wx dependencies. If the tool needs special GUI other than a menu entry, shortcut and button in a toolbar or the right-click menu (e.g. a settings dialog/docker window), it must be handled by a separate, non-public class.
  • Tools are registered within an application-wide tool manager via a factory class/function. This allows for adding tools as DLL/DSO plugins.
  • Tools use KiCad-internal event format, that works with native board units and follows gestures & shortcuts set in application preferences. A big advantage of this approach is the ability to drive a tool with a series of events from a script. For instance, an automatic BGA fanouter script could simply run the P&S tool with a click-move-click series of events for each pad instead of calculating every breakout trace itself.

Status

  • Specification ready.
  • All the tools are already ported to the Tool Framework. Some of them lack minor functionality (e.g. context menus).
  • Tools can be invoked using hotkeys, menu, toolbar or by calling InvokeTool() function from another tool.
  • It is possible to have a few interactive tools active at the same time. In such case, the most recently activated tool gets all events as first. Then it may choose to pass received events further to other tools, or stop them.