92 lines
2.9 KiB
Python
92 lines
2.9 KiB
Python
from collections import deque
|
|
from multiprocessing import Process
|
|
|
|
import pygame
|
|
from pygame.time import Clock
|
|
|
|
from . import BG_COLOR
|
|
from .MessageView import MessageView
|
|
|
|
|
|
class App(Process):
|
|
def __init__(self, chat_processes, plugins):
|
|
super().__init__()
|
|
self._chat_processes = chat_processes
|
|
self._plugins = plugins
|
|
|
|
self.size = self.width, self.height = 500, 1200
|
|
self._title = 'Chat monitor'
|
|
self._scroll_speed = 20
|
|
self._max_fps = 60
|
|
|
|
self.chat_log = deque(maxlen=100)
|
|
self._log_scroll = 0
|
|
self._running = False
|
|
self._display_surf = None
|
|
|
|
@property
|
|
def deamon(self):
|
|
return True
|
|
|
|
def setup(self):
|
|
pygame.init()
|
|
pygame.display.set_caption(self._title)
|
|
self._display_surf = pygame.display.set_mode(self.size)
|
|
self._running = True
|
|
|
|
def on_event(self, event):
|
|
if event.type == pygame.QUIT:
|
|
self._running = False
|
|
elif event.type == pygame.KEYDOWN:
|
|
for process in self._chat_processes:
|
|
bound_action = process.keybinds.get(event.key)
|
|
if bound_action is not None:
|
|
process.control_pipe.send(bound_action)
|
|
|
|
def tick(self, dt):
|
|
for process in self._chat_processes:
|
|
if not process.message_queue.empty():
|
|
message = process.message_queue.get()
|
|
for plugin in self._plugins:
|
|
message = plugin.on_message(message)
|
|
if message is None:
|
|
break
|
|
else:
|
|
message_view = MessageView(message, self.size)
|
|
self.chat_log.append(message_view)
|
|
self._log_scroll += message_view.rect.height
|
|
|
|
for message in self.chat_log:
|
|
message.tick(dt)
|
|
|
|
for plugin in self._plugins:
|
|
plugin.tick(dt)
|
|
|
|
if (self._log_scroll > 0):
|
|
self._log_scroll -= min(max((dt / 1000) * (self._log_scroll) * self._scroll_speed, 0.25), self.height / 4)
|
|
else:
|
|
self._log_scroll = 0
|
|
|
|
def draw(self):
|
|
self._display_surf.fill(BG_COLOR)
|
|
current_height = int(self.height + self._log_scroll)
|
|
for message in list(reversed(self.chat_log)):
|
|
message_rect = message.rect
|
|
if current_height > 0 and current_height < self.height + message_rect.height:
|
|
self._display_surf.blit(message.draw(), (0, current_height - message_rect.height))
|
|
current_height -= message_rect.height
|
|
pygame.display.flip()
|
|
|
|
def cleanup(self):
|
|
pygame.quit()
|
|
|
|
def run(self):
|
|
self.setup()
|
|
clock = Clock()
|
|
while self._running:
|
|
for event in pygame.event.get():
|
|
self.on_event(event)
|
|
dt = clock.tick(self._max_fps)
|
|
self.tick(dt)
|
|
self.draw()
|
|
self.cleanup()
|