Source code for wolfhece._menu_companion_template
"""
Template module for menu-based companions.
Purpose
-------
This file is a starter kit to create new companions following the same
structure used in existing managers such as:
- _qdfidf_manager.py
- _simtools2d_manager.py
- _weir_manager.py
- _particlesystem_manager.py
How to use
----------
1) Copy this file and rename class/module to your feature.
2) Instantiate it in WolfMapViewer.__init__.
3) Call menu_build() from the same place where other companion menus are built.
4) Replace example handlers with your business logic.
Integration sketch in PyDraw.py
-------------------------------
from ._my_feature_manager import MyFeatureManager
...
self._my_feature_mgr = MyFeatureManager(self)
...
self._my_feature_mgr.menu_build()
"""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
import wx
from ._action_kind import ActionKind
from .PyTranslate import _
if TYPE_CHECKING:
from .PyDraw import WolfMapViewer
[docs]
class MenuCompanionTemplate:
"""Reusable template for a menu-based companion manager."""
def __init__(self, viewer: "WolfMapViewer") -> None:
# ------------------------------------------------------------------
# Menu build
# ------------------------------------------------------------------
# ------------------------------------------------------------------
# Shared guards and helpers
# ------------------------------------------------------------------
[docs]
def _require_active_array(self) -> bool:
"""Return True if an active array exists, else log and abort."""
if self._viewer.active_array is None:
logging.warning(_("No active array - activate/select one first"))
return False
return True
[docs]
def _show_error(self, message: str) -> None:
"""Show a standard error dialog."""
dlg = wx.MessageDialog(self._viewer, message, _("Error"), wx.OK | wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
# ------------------------------------------------------------------
# Example event handlers
# ------------------------------------------------------------------
[docs]
def _on_check_context(self, event: wx.MenuEvent) -> None:
"""Minimal action showing guard usage."""
if not self._require_active_array():
return
logging.info(_("Context check OK"))
[docs]
def _on_pick(self, event: wx.MenuEvent) -> None:
"""Interactive action example (ActionKind driven)."""
self._viewer.start_action(
ActionKind.PICK_WEIR,
_("Right click to pick nearest element (template message)"),
)
[docs]
def _on_run_tool(self, event: wx.MenuEvent) -> None:
"""Long action example with progress dialog and final refresh."""
if not self._require_active_array():
return
v = self._viewer
pg = wx.ProgressDialog(
_("Running template tool"),
_("Working..."),
maximum=100,
parent=v,
style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE,
)
try:
pg.Pulse(_("Preparing data..."))
# TODO: Replace with real operation.
pg.Update(50, _("Computing..."))
# TODO: Replace with real operation.
pg.Update(100, _("Done"))
v.Refresh()
finally:
pg.Destroy()
[docs]
def _on_export(self, event: wx.MenuEvent) -> None:
"""Export-like action with explicit try/except error flow."""
if not self._require_active_array():
return
try:
# TODO: Replace with real export logic.
logging.info(_("Template export executed"))
except Exception as ex:
logging.exception("Template export failed")
self._show_error(_("Export failed: {}").format(ex))