"""Dike companion object for WolfMapViewer.
All dike-simulation management logic lives here (DikeWolf objects, menu,
event dispatch, creation). Injectors are *not* part of this companion —
they register themselves via ``WolfMapViewer.add_object(which='injector')``
when ``DikeWolf.set_injector()`` is called.
``WolfMapViewer`` holds a single instance as ``self._dike = DikeManager(self)``
and exposes one-line delegators so that external callers remain unaffected.
"""
from __future__ import annotations
import logging
from enum import Enum
from typing import TYPE_CHECKING
import wx
from .PyTranslate import _
try:
from .dike import DikeWolf
_AVAILABLE = True
except Exception:
_AVAILABLE = False
if TYPE_CHECKING:
from .PyDraw import WolfMapViewer
__all__ = ['DikeManager']
[docs]
class DikeManager:
"""Companion object that owns dike-simulation state.
Instantiated unconditionally as ``viewer._dike = DikeManager(viewer)``
inside ``WolfMapViewer.__init__``. If the *wolfpydike* package is not
installed, ``available`` is ``False`` and all operations are no-ops or
log an error.
"""
[docs]
available: bool = _AVAILABLE
def __init__(self, viewer: 'WolfMapViewer') -> None:
# ── Object registry ──────────────────────────────────────────────
[docs]
self.mydikes: list['DikeWolf'] = []
[docs]
self.active: 'DikeWolf | None' = None
# ── Menu state (lazy-built) ───────────────────────────────────────
# ------------------------------------------------------------------
# Object registration (called by WolfMapViewer.add_object)
# ------------------------------------------------------------------
[docs]
def register(self, newobj: 'DikeWolf') -> None:
"""Add *newobj* to the registry and make it the active dike."""
self.mydikes.append(newobj)
self.active = newobj
# ------------------------------------------------------------------
# Menu construction (idempotent)
# ------------------------------------------------------------------
# ------------------------------------------------------------------
# Menu event handler
# ------------------------------------------------------------------
[docs]
def _active_guard(self) -> bool:
"""Return True if available and active dike exists, log and return False otherwise."""
if not _AVAILABLE:
logging.error('WolfPyDike not installed — please install wolfpydike via pip')
return False
if self.active is None:
logging.warning(_('No active dike -- Please activate a dike first'))
return False
return True
[docs]
def _on_lumped(self, event: wx.MenuEvent) -> None:
if self._active_guard():
self.active.run_lumped()
[docs]
def _on_injector(self, event: wx.MenuEvent) -> None:
if self._active_guard():
self.active.set_injector()
[docs]
def _on_coupled(self, event: wx.MenuEvent) -> None:
if self._active_guard():
self.active.run_2Dcoupled()
[docs]
def _on_triang(self, event: wx.MenuEvent) -> None:
if self._active_guard():
self.active.show_triangulation()
[docs]
def _on_discharge(self, event: wx.MenuEvent) -> None:
if self._active_guard():
self.active.plot_mainOutputs(0)
[docs]
def _on_levels(self, event: wx.MenuEvent) -> None:
if self._active_guard():
self.active.plot_mainOutputs(1)
[docs]
def _on_breach(self, event: wx.MenuEvent) -> None:
if self._active_guard():
self.active.plot_mainOutputs(2)
[docs]
def _on_params(self, event: wx.MenuEvent) -> None:
if self._active_guard():
self.active.show_properties()
# ------------------------------------------------------------------
# Object creation (called by WolfMapViewer menu handlers)
# ------------------------------------------------------------------
[docs]
def new_dike(self, itemlabel: str) -> None:
"""Handle 'Create dike...' and 'Add dike...' menu items."""
if not _AVAILABLE:
logging.error('WolfPyDike not installed — please install wolfpydike via pip')
return
viewer = self._viewer
newobj = DikeWolf(mapviewer=viewer)
if _('Add dike...') in itemlabel:
try:
newobj.load_results()
except Exception:
logging.error(_('Error in loading dike results - Aborting !'))
return
viewer.add_object(which='dike', newobj=newobj, ToCheck=True)
self.menu_build()