Skip to content

Porting and drastical rewrite to reach compatibility with 3b1b/manim again #3107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions manim/_config/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import configparser
import copy
import errno
import importlib

Check notice

Code scanning / CodeQL

Unused import

Import of 'importlib' is not used.
import inspect

Check notice

Code scanning / CodeQL

Unused import

Import of 'inspect' is not used.
import logging
import os
import re
Expand Down
3 changes: 3 additions & 0 deletions manim/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@
DEGREES: float = TAU / 360
"""The exchange rate between radians and degrees."""

RADIANS: float = 1.0

Check notice

Code scanning / CodeQL

Unused global variable

The global variable 'RADIANS' is not used.
"""Just a default to select for camera."""

# Video qualities
QUALITIES: dict[str, dict[str, str | int | None]] = {
"fourk_quality": {
Expand Down
5 changes: 5 additions & 0 deletions manim/event_handler/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from manim.event_handler.event_dispatcher import EventDispatcher

# This is supposed to be a Singleton
# i.e., during runtime there should be only one object of Event Dispatcher
EVENT_DISPATCHER = EventDispatcher()
91 changes: 91 additions & 0 deletions manim/event_handler/event_dispatcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
from __future__ import annotations

import numpy as np

from manim.event_handler.event_listener import EventListener
from manim.event_handler.event_type import EventType


class EventDispatcher:
def __init__(self):
self.event_listeners: dict[EventType, list[EventListener]] = {
event_type: [] for event_type in EventType
}
self.mouse_point = np.array((0.0, 0.0, 0.0))
self.mouse_drag_point = np.array((0.0, 0.0, 0.0))
self.pressed_keys: set[int] = set()
self.draggable_object_listeners: list[EventListener] = []

def add_listener(self, event_listener: EventListener):
assert isinstance(event_listener, EventListener)
self.event_listeners[event_listener.event_type].append(event_listener)
return self

def remove_listener(self, event_listener: EventListener):
assert isinstance(event_listener, EventListener)
try:
while event_listener in self.event_listeners[event_listener.event_type]:
self.event_listeners[event_listener.event_type].remove(event_listener)
except Exception:
# 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_listeners = [
listener
for listener in self.event_listeners[EventType.MouseDragEvent]
if listener.mobject.is_point_touching(self.mouse_point)
]
elif event_type == EventType.MouseReleaseEvent:
self.draggable_object_listeners = []

propagate_event = None

if event_type == EventType.MouseDragEvent:
for listener in self.draggable_object_listeners:
assert isinstance(listener, EventListener)
propagate_event = listener.callback(listener.mobject, event_data)
if propagate_event is not None and propagate_event is False:
return propagate_event

elif event_type.value.startswith("mouse"):
for listener in self.event_listeners[event_type]:
if listener.mobject.is_point_touching(self.mouse_point):
propagate_event = listener.callback(listener.mobject, event_data)
if propagate_event is not None and propagate_event is False:
return propagate_event

elif event_type.value.startswith("key"):
for listener in self.event_listeners[event_type]:
propagate_event = listener.callback(listener.mobject, event_data)
if propagate_event is not None and propagate_event is False:
return propagate_event

return propagate_event

def get_listeners_count(self) -> int:
return sum([len(value) for key, value in self.event_listeners.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_listener
__isub__ = remove_listener
__call__ = dispatch
__len__ = get_listeners_count
34 changes: 34 additions & 0 deletions manim/event_handler/event_listener.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from typing import Callable

import manim.mobject.opengl.opengl_mobject as glmob
from manim.event_handler.event_type import EventType


class EventListener:
def __init__(
self,
mobject: glmob.OpenGLMobject,
event_type: EventType,
event_callback: Callable[[glmob.OpenGLMobject, dict[str, str]], None],
):
self.mobject = mobject
self.event_type = event_type
self.callback = event_callback

def __eq__(self, o: object) -> bool:
return_val = False
if isinstance(o, EventListener):
try:
return_val = (
self.callback == o.callback
and self.mobject == o.mobject
and self.event_type == o.event_type
)
except Exception:

Check notice

Code scanning / CodeQL

Empty except

'except' clause does nothing but pass and there is no explanatory comment.
pass
return return_val
11 changes: 11 additions & 0 deletions manim/event_handler/event_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from enum import Enum


class EventType(Enum):
MouseMotionEvent = "mouse_motion_event"
MousePressEvent = "mouse_press_event"
MouseReleaseEvent = "mouse_release_event"
MouseDragEvent = "mouse_drag_event"
MouseScrollEvent = "mouse_scroll_event"
KeyPressEvent = "key_press_event"
KeyReleaseEvent = "key_release_event"
Loading