Browse Source

Rendering messages in interface

master
Alexey 3 years ago committed by ennucore
parent
commit
b501b69f64
  1. 22
      degeon_py/active_chat.py
  2. 5
      degeon_py/config.py
  3. 42
      degeon_py/message.py

22
degeon_py/active_chat.py

@ -1,11 +1,15 @@
from __future__ import annotations from __future__ import annotations
import typing
from dataclasses import dataclass from dataclasses import dataclass
import pygame import pygame
from config import HEIGHT, WIDTH, CHAT_SELECTOR_WIDTH, DARKER_BLUE, CHAT_PREVIEW_HEIGHT, BLUE, WHITE, font, DARK_BLUE from config import HEIGHT, WIDTH, CHAT_SELECTOR_WIDTH, DARKER_BLUE, CHAT_PREVIEW_HEIGHT, BLUE, WHITE, font, DARK_BLUE, \
MESSAGE_HEIGHT
import degeon_core as dc import degeon_core as dc
from message import Message
@dataclass @dataclass
class ActiveChat: class ActiveChat:
@ -35,6 +39,15 @@ class ActiveChat:
""" """
return cls(chat=chat, **kwargs) return cls(chat=chat, **kwargs)
def get_messages(self) -> typing.Iterable[Message]:
"""
Get an iterator over all messages in this chat in the backwards order
This function creates a python `message.Message` object from rust instances
:return: an iterator of `message.Message` objects
"""
for msg in reversed(self.chat.messages):
yield Message(text=msg.get_content_py().text, is_from_me=False)
def get_header(self) -> pygame.Surface: def get_header(self) -> pygame.Surface:
""" """
Render a pygame surface with the header. Render a pygame surface with the header.
@ -56,6 +69,13 @@ class ActiveChat:
surface: pygame.Surface = pygame.Surface((self.width, self.height)) surface: pygame.Surface = pygame.Surface((self.width, self.height))
surface.fill(DARKER_BLUE) surface.fill(DARKER_BLUE)
# Render messages
# This is the y0 for the last message
last_message_y = self.height - 60
for i, message in zip(range(30), self.get_messages()):
msg_surface = message.render()
surface.blit(msg_surface, (0, last_message_y - (MESSAGE_HEIGHT + 30) * (i + 1)))
# Render header
header = self.get_header() header = self.get_header()
surface.blit(header, (0, 10)) surface.blit(header, (0, 10))
return surface return surface

5
degeon_py/config.py

@ -2,9 +2,12 @@ import pygame
pygame.init() pygame.init()
# Fontss
font = pygame.font.Font('CRC35.otf', 25) font = pygame.font.Font('CRC35.otf', 25)
font_large = pygame.font.Font('CRC35.otf', 35) font_large = pygame.font.Font('CRC35.otf', 35)
# Colors used in the app
RED = 0xFF0000 RED = 0xFF0000
BLUE = 0x0000FF BLUE = 0x0000FF
YELLOW = 0xFFC91F YELLOW = 0xFFC91F
@ -18,9 +21,11 @@ DARK_BLUE = 0x282e46
DARKER_BLUE = 0x202033 DARKER_BLUE = 0x202033
GREY = 0x383e4F GREY = 0x383e4F
# Geometrical parameters
WIDTH = 1000 WIDTH = 1000
HEIGHT = 800 HEIGHT = 800
CHAT_PREVIEW_HEIGHT = 80 CHAT_PREVIEW_HEIGHT = 80
CHAT_SELECTOR_WIDTH = WIDTH // 3 CHAT_SELECTOR_WIDTH = WIDTH // 3
MESSAGE_HEIGHT = 60
FPS = 30 FPS = 30

42
degeon_py/message.py

@ -0,0 +1,42 @@
from __future__ import annotations
from dataclasses import dataclass
import pygame
from config import WIDTH, CHAT_SELECTOR_WIDTH, MESSAGE_HEIGHT, font, BLUE, DARK_BLUE, WHITE, DARKER_BLUE
@dataclass
class Message:
"""
The message (for now, it consists only of text)
Attributes:
:param text (str): the message text
:param is_from_me (bool): False if the message is not from the current user
:param chat_width (int): the width of the active chat widget
"""
text: str
is_from_me: bool
chat_width: int = WIDTH - CHAT_SELECTOR_WIDTH - 10
height: int = MESSAGE_HEIGHT
def render(self) -> pygame.Surface:
"""
Creates a surface with a rectangle and the message text written on it
:return: the surface with rendered message
"""
surface = pygame.Surface((self.chat_width, self.height))
surface.fill(DARKER_BLUE)
bg_color = BLUE * self.is_from_me + DARK_BLUE * (not self.is_from_me)
text_surface: pygame.Surface = font.render(self.text, True, WHITE)
padding = 5
# Size of the scaled text surface
blit_height = self.height - padding * 2
blit_width = round(text_surface.get_width() * blit_height / text_surface.get_height())
x = 0 if not self.is_from_me else self.chat_width - blit_width - padding * 2
pygame.draw.rect(surface, bg_color, (x, 0, blit_width + padding * 2, self.height))
text_surface = pygame.transform.smoothscale(text_surface, (blit_width, blit_height))
surface.blit(text_surface, (x + padding, padding))
return surface
Loading…
Cancel
Save