Source code for wolfhece._builtin_plugins.dot_picker.companion

"""
Dot Picker — example companion plugin.

Demonstrates the minimal pattern:
  * right-click adds a point
  * Ctrl+Z removes the last point
  * Esc deactivates

This file is a simplified wrapper around
:class:`wolfhece._plugin_factory.PointPickerCompanion`.
Import the factory class directly in your own code if you only need the
behaviour without the plugin infrastructure.
"""
from dataclasses import dataclass

from wolfhece.plugins.factory import PointPickerCompanion, PointPickerModel
from wolfhece.plugins.abc import MenuItem, MultiStepSpec, StepSpec
from wolfhece._viewer_plugin_handlers import MouseContext


@dataclass
[docs] class DotPickerModel(PointPickerModel): """Business state for the Dot Picker plugin. Keeps domain operations explicit for the built-in plugin example while reusing the base point-picker state structure. """
[docs] def clear_points(self) -> None: self.reset()
[docs] class DotPickerCompanion(PointPickerCompanion): """Point-picker companion exposed as a plugin. Adds a *"Dot Picker"* entry to the viewer's menu bar. Inherits all interaction logic from :class:`PointPickerCompanion`. """
[docs] def create_model(self) -> DotPickerModel: return DotPickerModel()
@property
[docs] def model_state(self) -> DotPickerModel: return self.model # type: ignore[return-value]
[docs] def build(self) -> None: """Keep explicit build override for backwards compatibility.""" super().build()
[docs] def menu_spec(self): return ('Dot Picker', [ MenuItem('Pick points…', self._on_pick, 'Right-click to collect points'), MenuItem('Clear points', self._on_clear, 'Remove all collected points'), ])
[docs] def actions_spec(self): return [ MultiStepSpec( 'pick', primary=True, start_message='Right-click: add | Left-click: select | Ctrl+Z: undo | Esc: stop', steps=[ StepSpec( hint='Right-click: add | Left-click: select | Ctrl+Z: undo | Esc: stop', rdown=self._rdown, ldown=self._ldown, key=self._key, paint=self._paint, ) ], ), ]
[docs] def start(self) -> None: """Activate the pick action (called by the plugin manager).""" self.proxy.start_action( 'pick', 'Right-click: add | Left-click: select | Ctrl+Z: undo | Esc: stop', )
# -- menu handlers -------------------------------------------------------
[docs] def _on_pick(self, ctx: MouseContext) -> None: self.start()
[docs] def _on_clear(self, ctx: MouseContext) -> None: self.model_state.clear_points() self.proxy.force_redraw() self.proxy.set_status('Dot Picker: all points cleared.')