mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
95 lines
3.8 KiB
Python
95 lines
3.8 KiB
Python
from __future__ import annotations
|
|
|
|
import numpy as np
|
|
|
|
from manimlib.event_handler.event_listner import EventListner
|
|
from manimlib.event_handler.event_type import EventType
|
|
|
|
|
|
class EventDispatcher(object):
|
|
def __init__(self):
|
|
self.event_listners: dict[
|
|
EventType, list[EventListner]
|
|
] = {
|
|
event_type: []
|
|
for event_type in EventType
|
|
}
|
|
self.mouse_point = np.array((0., 0., 0.))
|
|
self.mouse_drag_point = np.array((0., 0., 0.))
|
|
self.pressed_keys: set[int] = set()
|
|
self.draggable_object_listners: list[EventListner] = []
|
|
|
|
def add_listner(self, event_listner: EventListner):
|
|
assert(isinstance(event_listner, EventListner))
|
|
self.event_listners[event_listner.event_type].append(event_listner)
|
|
return self
|
|
|
|
def remove_listner(self, event_listner: EventListner):
|
|
assert(isinstance(event_listner, EventListner))
|
|
try:
|
|
while event_listner in self.event_listners[event_listner.event_type]:
|
|
self.event_listners[event_listner.event_type].remove(event_listner)
|
|
except:
|
|
# raise ValueError("Handler is not handling this event, so cannot remove it.")
|
|
pass
|
|
return self
|
|
|
|
def dispatch(self, event_type: EventType, **event_data):
|
|
if event_type == EventType.MouseMotionEvent:
|
|
self.mouse_point = event_data["point"]
|
|
elif event_type == EventType.MouseDragEvent:
|
|
self.mouse_drag_point = event_data["point"]
|
|
elif event_type == EventType.KeyPressEvent:
|
|
self.pressed_keys.add(event_data["symbol"]) # Modifiers?
|
|
elif event_type == EventType.KeyReleaseEvent:
|
|
self.pressed_keys.difference_update({event_data["symbol"]}) # Modifiers?
|
|
elif event_type == EventType.MousePressEvent:
|
|
self.draggable_object_listners = [
|
|
listner
|
|
for listner in self.event_listners[EventType.MouseDragEvent]
|
|
if listner.mobject.is_point_touching(self.mouse_point)
|
|
]
|
|
elif event_type == EventType.MouseReleaseEvent:
|
|
self.draggable_object_listners = []
|
|
|
|
propagate_event = None
|
|
|
|
if event_type == EventType.MouseDragEvent:
|
|
for listner in self.draggable_object_listners:
|
|
assert(isinstance(listner, EventListner))
|
|
propagate_event = listner.callback(listner.mobject, event_data)
|
|
if propagate_event is not None and propagate_event is False:
|
|
return propagate_event
|
|
|
|
elif event_type.value.startswith('mouse'):
|
|
for listner in self.event_listners[event_type]:
|
|
if listner.mobject.is_point_touching(self.mouse_point):
|
|
propagate_event = listner.callback(
|
|
listner.mobject, event_data)
|
|
if propagate_event is not None and propagate_event is False:
|
|
return propagate_event
|
|
|
|
elif event_type.value.startswith('key'):
|
|
for listner in self.event_listners[event_type]:
|
|
propagate_event = listner.callback(listner.mobject, event_data)
|
|
if propagate_event is not None and propagate_event is False:
|
|
return propagate_event
|
|
|
|
return propagate_event
|
|
|
|
def get_listners_count(self) -> int:
|
|
return sum([len(value) for key, value in self.event_listners.items()])
|
|
|
|
def get_mouse_point(self) -> np.ndarray:
|
|
return self.mouse_point
|
|
|
|
def get_mouse_drag_point(self) -> np.ndarray:
|
|
return self.mouse_drag_point
|
|
|
|
def is_key_pressed(self, symbol: int) -> bool:
|
|
return (symbol in self.pressed_keys)
|
|
|
|
__iadd__ = add_listner
|
|
__isub__ = remove_listner
|
|
__call__ = dispatch
|
|
__len__ = get_listners_count
|