Source code for irsim.gui.mouse_control
from typing import Any, Optional
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.axes import Axes
from matplotlib.backend_bases import MouseButton
[docs]
class MouseControl:
def __init__(self, ax: Axes, zoom_factor: float = 1.1) -> None:
"""
Initialize MouseControl with comprehensive mouse interaction functionality.
Mouse Controls:
- Mouse Move: Track cursor position and update current axes
- Middle Click (Wheel Click): Reset zoom to original view
- Scroll Up: Zoom in (centered on mouse position)
- Scroll Down: Zoom out (centered on mouse position)
Args:
ax: The matplotlib axes to control
zoom_factor (float): Factor by which to zoom in/out. Default is 1.1.
Higher values = more aggressive zooming.
Attributes:
mouse_pos: The current mouse position
left_click_pos: The position of the left click
right_click_pos: The position of the right click
"""
self.zoom_factor = zoom_factor
self.mouse_pos = None
self.left_click_pos = None
self.right_click_pos = None
self.current_axes = ax
self.init_xlim = ax.get_xlim()
self.init_ylim = ax.get_ylim()
# Connect event handlers
plt.connect("motion_notify_event", self.on_move)
plt.connect("button_press_event", self.on_click)
plt.connect("button_release_event", self.on_release)
plt.connect("scroll_event", self.on_scroll)
[docs]
def on_move(self, event: Any) -> None:
"""Handle mouse movement events.
Args:
event: Matplotlib mouse motion event.
"""
if event.inaxes:
self.mouse_pos = (event.xdata, event.ydata)
# self.current_axes = event.inaxes
else:
self.mouse_pos = None
self.current_axes = None
[docs]
def on_click(self, event: Any) -> None:
"""Handle mouse click events.
Args:
event: Matplotlib mouse button event.
"""
if event.button is MouseButton.LEFT:
self.left_click_pos = (
np.round((event.xdata, event.ydata), 2)
if event.inaxes is not None
else None
)
elif event.button is MouseButton.RIGHT:
self.right_click_pos = (
np.round((event.xdata, event.ydata), 2)
if event.inaxes is not None
else None
)
elif event.button is MouseButton.MIDDLE:
# Middle mouse button (wheel click) resets zoom
self.reset_zoom(event.inaxes)
[docs]
def on_release(self, event: Any) -> None:
"""Handle mouse release events.
Args:
event: Matplotlib mouse button release event.
"""
if event.button is MouseButton.LEFT:
self.left_click_pos = None
elif event.button is MouseButton.RIGHT:
self.right_click_pos = None
[docs]
def reset_zoom(self, ax: Optional[Axes] = None) -> None:
"""
Reset zoom to original view.
Args:
ax: Matplotlib axes to reset. If None, uses current axes.
"""
if ax is None:
ax = self.current_axes
if ax is not None:
ax.set_xlim(self.init_xlim)
ax.set_ylim(self.init_ylim)
ax.figure.canvas.draw()
[docs]
def set_zoom_factor(self, factor: float) -> None:
"""
Set the zoom factor.
Args:
factor (float): New zoom factor (>1 for more aggressive zooming).
"""
self.zoom_factor = max(1.1, float(factor)) # Minimum factor of 1.1