# Copyright 2025–2026 European Union
# Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
# SPDX-License-Identifier: EUPL-1.2
"""
Mouse state management module for radioviz application.
This module provides functionality for handling mouse events in matplotlib
figures. It defines a set of mouse button constants and a data class for
representing mouse events with both pixel and data coordinates.
.. versionadded:: 1.0.0
"""
from dataclasses import dataclass
from enum import IntEnum
from matplotlib.backend_bases import MouseButton as MPL_MouseButton
from matplotlib.backend_bases import MouseEvent as MPL_MouseEvent
[docs]
@dataclass
class MouseEvent:
"""
Data class representing a mouse event.
This class encapsulates all relevant information about a mouse event,
including pixel coordinates, data coordinates, button pressed, keyboard
modifier keys, and the target axis.
"""
x_pixel: int = 0
"""int: X coordinate in pixel units."""
y_pixel: int = 0
"""int: Y coordinate in pixel units."""
x_data: float = 0.0
"""float: X coordinate in data units."""
y_data: float = 0.0
"""float: Y coordinate in data units."""
button: MouseButton = MouseButton.Left
"""MouseButton: The mouse button that was pressed."""
key: str = ''
"""str: Keyboard modifier key pressed during the event."""
target_axis: str = ''
"""str: Name of the target axis where the event occurred."""
[docs]
@classmethod
def from_mpl_mouse_event(cls, event: MPL_MouseEvent) -> 'MouseEvent':
"""
Create a MouseEvent instance from a matplotlib MouseEvent.
Convert a matplotlib MouseEvent object into a radioviz MouseEvent
data class, mapping the relevant attributes and handling button
conversion properly.
:param event: The matplotlib mouse event to convert
:type event: MPL_MouseEvent
:return: A new MouseEvent instance with converted values
:rtype: MouseEvent
"""
new_event = cls()
new_event.x_pixel = event.x
new_event.y_pixel = event.y
new_event.x_data = event.xdata if event.xdata is not None else 0.0
new_event.y_data = event.ydata if event.ydata is not None else 0.0
if isinstance(event.button, MPL_MouseButton):
new_event.button = MouseButton(event.button.value)
else:
if event.button == 'up':
new_event.button = MouseButton.Up
elif event.button == 'down':
new_event.button = MouseButton.Down
else:
new_event.button = MouseButton.NoButton
new_event.key = event.key or ''
if event.inaxes is None:
new_event.target_axis = 'no name'
else:
new_event.target_axis = getattr(event.inaxes, 'radioviz_name', 'no name')
return new_event