IronForce is a decentralized network, Degeon is a messenger built on it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
2.9 KiB

import time
import typing
import pygame
from config import font, MESSAGE_HEIGHT, WIDTH, CHAT_SELECTOR_WIDTH, HEIGHT, WHITE, DARKER_BLUE, GREY
from utils import render_text
from dataclasses import dataclass
@dataclass
class TextField:
"""
Field for message input
"""
value: str = ''
width: int = WIDTH - CHAT_SELECTOR_WIDTH - 140
height: int = MESSAGE_HEIGHT * 1.5
top_left_corner: typing.Tuple[int, int] = (CHAT_SELECTOR_WIDTH, HEIGHT - MESSAGE_HEIGHT * 2)
is_focused: bool = False
placeholder: str = ''
cursor_position: int = 0
def render(self) -> pygame.Surface:
"""
Render the text field onto a pygame surface
:return: a surface with the field
"""
surface = pygame.Surface((self.width, self.height))
surface.fill(WHITE)
padding = 5
pygame.draw.rect(surface, DARKER_BLUE, (padding, padding, self.width - padding * 2, self.height - padding * 2))
if not self.value and self.placeholder:
placeholder_text: pygame.Surface = font.render(self.placeholder, True, (GREY + WHITE) // 2)
surface.blit(
placeholder_text,
(
(self.width - placeholder_text.get_width()) // 2,
(self.height - placeholder_text.get_height()) // 2
)
)
if self.value:
render_text(surface, (10, 10), font, self.value, WHITE, self.cursor_position if time.time() % 1 < 0.5 else None)
return surface
def process_event(self, event: pygame.event.Event):
"""
Handle a typing event or a click (to focus)
:param event: a pygame event
"""
# If we have a click, we should focus the field if the click was inside or unfocus if it was outside
if event.type == pygame.MOUSEBUTTONUP:
self.is_focused = self.top_left_corner[0] <= event.pos[0] < self.top_left_corner[0] + self.width \
and self.top_left_corner[1] <= event.pos[1] < self.top_left_corner[1] + self.height
if self.is_focused and hasattr(event, 'key') and event.type == 768:
if event.key == pygame.K_BACKSPACE:
self.value = self.value[:-1]
self.cursor_position -= 1
elif event.key == pygame.K_LEFT:
self.cursor_position -= 1
elif event.key == pygame.K_RIGHT:
self.cursor_position += 1
elif event.unicode:
self.value = self.value[:self.cursor_position] + event.unicode + self.value[self.cursor_position:]
self.cursor_position += 1
self.cursor_position = max(0, min(self.cursor_position, len(self.value)))
def collect(self) -> str:
"""
Get the current value and clear the field
:return: the value of the text input
"""
value = self.value
self.value = ''
self.cursor_position = 0
return value