123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- import asyncio
- from inspect import signature
- from pydantic import BaseModel
- import traceback
- from typing import Any, Awaitable, Callable, List, Optional, Union
- from .elements.element import Element
- class EventArguments(BaseModel):
- class Config:
- arbitrary_types_allowed = True
- sender: Element
- class ClickEventArguments(EventArguments):
- pass
- class UploadEventArguments(EventArguments):
- files: List[bytes]
- class ValueChangeEventArguments(EventArguments):
- value: Any
- class KeyboardAction(BaseModel):
- keypress: bool
- keydown: bool
- keyup: bool
- repeat: bool
- class KeyboardModifiers(BaseModel):
- alt: bool
- ctrl: bool
- meta: bool
- shift: bool
- class KeyboardKey(BaseModel):
- name: str
- code: str
- location: int
- def __eq__(self, other: str) -> bool:
- return self.name == other or self.code == other
- def __repr__(self):
- return str(self.name)
- @property
- def is_cursorkey(self):
- return self.code.startswith('Arrow')
- @property
- def number(self) -> Optional[int]:
- """Integer value of a number key."""
- return int(self.code.removeprefix('Digit')) if self.code.startswith('Digit') else None
- @property
- def backspace(self) -> bool:
- return self.name == 'Backspace'
- @property
- def tab(self) -> bool:
- return self.name == 'Tab'
- @property
- def enter(self) -> bool:
- return self.name == 'enter'
- @property
- def shift(self) -> bool:
- return self.name == 'Shift'
- @property
- def control(self) -> bool:
- return self.name == 'Control'
- @property
- def alt(self) -> bool:
- return self.name == 'Alt'
- @property
- def pause(self) -> bool:
- return self.name == 'Pause'
- @property
- def caps_lock(self) -> bool:
- return self.name == 'CapsLock'
- @property
- def escape(self) -> bool:
- return self.name == 'Escape'
- @property
- def space(self) -> bool:
- return self.name == 'Space'
- @property
- def page_up(self) -> bool:
- return self.name == 'PageUp'
- @property
- def page_down(self) -> bool:
- return self.name == 'PageDown'
- @property
- def end(self) -> bool:
- return self.name == 'End'
- @property
- def home(self) -> bool:
- return self.name == 'Home'
- @property
- def arrow_left(self) -> bool:
- return self.name == 'ArrowLeft'
- @property
- def arrow_up(self) -> bool:
- return self.name == 'ArrowUp'
- @property
- def arrow_right(self) -> bool:
- return self.name == 'ArrowRight'
- @property
- def arrow_down(self) -> bool:
- return self.name == 'ArrowDown'
- @property
- def print_screen(self) -> bool:
- return self.name == 'PrintScreen'
- @property
- def insert(self) -> bool:
- return self.name == 'Insert'
- @property
- def delete(self) -> bool:
- return self.name == 'Delete'
- @property
- def meta(self) -> bool:
- return self.name == 'Meta'
- @property
- def f1(self) -> bool:
- return self.name == 'F1'
- @property
- def f2(self) -> bool:
- return self.name == 'F2'
- @property
- def f3(self) -> bool:
- return self.name == 'F3'
- @property
- def f4(self) -> bool:
- return self.name == 'F4'
- @property
- def f5(self) -> bool:
- return self.name == 'F5'
- @property
- def f6(self) -> bool:
- return self.name == 'F6'
- @property
- def f7(self) -> bool:
- return self.name == 'F7'
- @property
- def f8(self) -> bool:
- return self.name == 'F8'
- @property
- def f9(self) -> bool:
- return self.name == 'F9'
- @property
- def f10(self) -> bool:
- return self.name == 'F10'
- @property
- def f11(self) -> bool:
- return self.name == 'F11'
- @property
- def f12(self) -> bool:
- return self.name == 'F12'
- class KeyEventArguments(EventArguments):
- class Config:
- arbitrary_types_allowed = True
- action: KeyboardAction
- key: KeyboardKey
- modifiers: KeyboardModifiers
- def handle_event(handler: Optional[Union[Callable, Awaitable]], arguments: EventArguments):
- try:
- if handler is None:
- return
- no_arguments = not signature(handler).parameters
- result = handler() if no_arguments else handler(arguments)
- if asyncio.iscoroutinefunction(handler):
- async def async_handler():
- try:
- await result
- except Exception:
- traceback.print_exc()
- asyncio.get_event_loop().create_task(async_handler())
- return False
- else:
- return result
- except Exception:
- traceback.print_exc()
|