Source code for simvx.core.ui.modal

"""Modal helper Controls: auto-injected by ``Control.show_modal()``.

The backdrop sits as the first child of a modal Control purely for *drawing*
(``DimBackdrop`` paints a translucent overlay). It does NOT participate in
hit-testing: ``mouse_filter=False`` makes the router walk through it. Outside-
click dismissal is the router's responsibility (``UIInputManager`` emits
``cancel_requested`` and calls ``close_modal()`` when a press lands outside
every widget in the modal subtree and the modal has
``dismiss_on_outside_click=True``).

This split keeps the backdrop a pure visual primitive and lets full-screen
modals (e.g. ``FileDialog``) own click routing for their entire surface
without the backdrop swallowing card-area clicks.
"""

from ..descriptors import Property
from ..properties import Colour
from .core import Control
from .enums import AnchorPreset

__all__ = ["ModalBackdrop", "DimBackdrop"]


[docs] class ModalBackdrop(Control): """Hit-test-transparent overlay auto-injected into modal Controls.""" def __init__(self, **kwargs): super().__init__(**kwargs) self.set_anchor_preset(AnchorPreset.FULL_RECT) self.mouse_filter = False # router walks past this; clicks fall through self.z_index = -4096 # min of CanvasItem.z_index range
[docs] def on_draw(self, renderer): # Plain ``ModalBackdrop`` is transparent: subclasses dim the screen. pass
[docs] class DimBackdrop(ModalBackdrop): """Modal backdrop that paints a translucent overlay behind the dialog.""" dim_colour = Property(Colour((0, 0, 0, 0.5)), group="Appearance", hint="Translucent fill behind the modal")
[docs] def on_draw(self, renderer): x, y, w, h = self.get_global_rect() renderer.draw_rect((x, y), (w, h), colour=self.dim_colour, filled=True)