Lev
3 years ago
2 changed files with 132 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,132 @@
|
||||
from __future__ import annotations |
||||
import typing |
||||
|
||||
import pygame |
||||
import degeon_core as dc |
||||
from dataclasses import dataclass, field |
||||
from abc import ABC |
||||
|
||||
# Configuration variables and loading |
||||
pygame.init() |
||||
font = pygame.font.Font('CRC35.otf', 25) |
||||
FPS = 30 |
||||
|
||||
RED = 0xFF0000 |
||||
BLUE = 0x0000FF |
||||
YELLOW = 0xFFC91F |
||||
GREEN = 0x00FF00 |
||||
MAGENTA = 0xFF03B8 |
||||
CYAN = 0x00FFCC |
||||
BLACK = 0x000 |
||||
WHITE = 0xFFFFFF |
||||
DARK_BLUE = 0x282e46 |
||||
GREY = 0x383e4F |
||||
COLORS = [RED, BLUE, YELLOW, GREEN, MAGENTA, CYAN] |
||||
|
||||
WIDTH = 900 |
||||
HEIGHT = 700 |
||||
|
||||
|
||||
@dataclass |
||||
class ChatSelector: |
||||
""" |
||||
The widget with the list of chats. |
||||
It's a dataclass, it should be initialized using the `from_chats` classmethod |
||||
|
||||
Attributes: |
||||
chats (List[dc.Chat]): list of all chats, where each chat is a native Rust struct Chat |
||||
active_chat (int): the index of the current selected chat |
||||
hovered_chat (int or None): the index of the current hovered chat |
||||
width (int): the width of this widget |
||||
height (int): the height of this widget |
||||
chat_height (int): height of one chat |
||||
""" |
||||
chats: typing.List['dc.Chat'] = field(default_factory=list) |
||||
active_chat: int = 0 |
||||
hovered_chat: typing.Optional[int] = None |
||||
width: int = WIDTH // 3 |
||||
height: int = HEIGHT |
||||
chat_height: int = HEIGHT // 10 |
||||
|
||||
def render(self) -> pygame.Surface: |
||||
""" |
||||
Creates a pygame surface and draws the list of chats on it |
||||
:return: the surface with the chat selector |
||||
""" |
||||
surface: pygame.Surface = pygame.Surface((self.width, self.chat_height * len(self.chats))) |
||||
for i, chat in enumerate(self.chats): |
||||
bg_color, text_color = DARK_BLUE, WHITE |
||||
if i == self.hovered_chat: |
||||
bg_color = GREY |
||||
if i == self.active_chat: |
||||
bg_color = BLUE |
||||
title_surface: pygame.Surface = font.render(chat.profile.name, True, text_color) |
||||
pygame.draw.rect(surface, bg_color, (0, i * self.chat_height + 1, self.width, self.chat_height - 2)) |
||||
surface.blit(title_surface, (i * self.chat_height + 10)) |
||||
return surface |
||||
|
||||
def process_event(self, event: pygame.event.Event): |
||||
""" |
||||
Process a click: select the necessary chat if this click is in the widget |
||||
:param event: pygame event |
||||
""" |
||||
if event.type == pygame.MOUSEBUTTONUP and event.pos[0] < self.width: |
||||
self.active_chat = event.pos[1] // self.chat_height |
||||
self.hovered_chat = None |
||||
if event.type == pygame.MOUSEMOTION: |
||||
if 0 < event.pos[0] < self.width \ |
||||
and 0 < event.pos[1] < min(self.height, len(self.chats) * self.chat_height) - 2: |
||||
self.hovered_chat = event.pos[1] // self.chat_height |
||||
else: |
||||
self.hovered_chat = None |
||||
|
||||
@classmethod |
||||
def from_chats(cls, chats: typing.List['dc.Chat'], **kwargs) -> ChatSelector: |
||||
return cls(chats, **kwargs) |
||||
|
||||
|
||||
@dataclass |
||||
class ActiveChat: |
||||
""" |
||||
The widget with the current chat |
||||
|
||||
Attributes: |
||||
:param chat (dc.Chat): the chat (Rust Chat type) |
||||
""" |
||||
|
||||
chat: 'dc.Chat' |
||||
|
||||
|
||||
@dataclass |
||||
class Degeon: |
||||
""" |
||||
The main class with everything connected to the app: the data, the |
||||
|
||||
Attributes |
||||
""" |
||||
core: 'dc.Degeon' |
||||
chat_selector: ChatSelector |
||||
has_profile_popup_opened: bool = False |
||||
has_no_peers_popup: bool = False |
||||
|
||||
@classmethod |
||||
def new(cls) -> Degeon: |
||||
""" |
||||
Create a new default instance with settings from file |
||||
:return: a Degeon instance |
||||
""" |
||||
pass # todo |
||||
|
||||
def render(self, screen: pygame.Surface): |
||||
""" |
||||
Render everything on the screen |
||||
:param screen: the main screen |
||||
""" |
||||
chats_surface = self.chat_selector.render() |
||||
screen.blit(chats_surface, (0, 0)) |
||||
|
||||
def tick(self): |
||||
""" |
||||
Handle incoming messages, update chats, create no_peers popup if necessary |
||||
""" |
||||
pass # todo |
Loading…
Reference in new issue