The Straightener tool is a simple tool that replaces a segment of a curve with a straight line. While writing it, I've noticed that it takes a lot of code to do this simple task. Most of the code doesn't have anything to do with what the tool is supposed to actually do, but instead it has to do with rendering and implementing interactive components.
So a new "Widget" class was born. A widget is a GUI element that simply interacts with the user but does not perform any actions by itself. It's "dumb". With two instances of a simple "Draggable" widget that have their snapping property set to a particular curve, implementing the Straightener tool became much easier and straightforward. The tool owns two draggable widgets, and will listen to drag events from the widgets and recompute the curve on the fly.
Internally, there is a resident tool "WidgetRunner" that will process input messages and pass them to the active widgets. If no widgets process the messages, they will be passed to the other active tools.
This should allow for increased code reuse and simplify the implementation of new tools. Now I still have to figure out how to go about ensuring multi-step tools like the Straightener tool can be notified about certain user actions that could disrupt their operation.
Oh, the reason the tool will probably be discarded is that the current "handles" tool can be extended to accomplish the same functionality and more without having to introduce another tool. Furthermore, the Draw tool will be enhanced to allow the user to re-draw a part of a curve by holding down a keyboard key or switching a toggle in the Tool Settings window, which should be a faster way to do the same thing. On the other hand, extending the Straightener tool to add other modes of curve segment manipulation (and renaming it to reflect it) could be considered. We'll see.