Browse Source

Wrote a pygame button

interface-2
Lev 3 years ago
parent
commit
f5c61c5aa5
  1. 5
      degeon_py/active_chat.py
  2. 99
      degeon_py/button.py
  3. 13
      degeon_py/input_field.py

5
degeon_py/active_chat.py

@ -85,9 +85,10 @@ class ActiveChat:
surface.blit(input_field_surface, (0, self.height - input_field_surface.get_height()))
return surface
def process_event(self, event: pygame.event.Event):
def process_event(self, event: pygame.event.Event) -> typing.Optional[str]:
"""
Process a click: select the necessary chat if this click is in the widget
Process clicks in the active chat widget. Return a message to send if needed
:param event: a pygame event
:return: A message to send if there is one
"""
self.input_field.process_event(event)

99
degeon_py/button.py

@ -0,0 +1,99 @@
import pygame
import typing
from config import font, WHITE, BLUE, BLACK
from dataclasses import dataclass
@dataclass
class Button:
"""
Just a button element for pygame
Attributes:
:param text (str): Text on the button
:param top_left ((int, int)): the coordinates of the top-left point of the button
:param width (int): the width of the button
:param height (int): the height of the button
:param padding (int): padding - the distance between rectangle border and button content
:param bg_color (Color): the background color
:param text_color (Color): color of the text
:param hovered_color (Color): the background color when the button is hovered
:param hovered_text_color (Color): the text color when the button is hovered
:param pressed_color (Color): the background color when the button is pressed
:param pressed_text_color (Color): the text color when the button is pressed
"""
text: str
top_left: typing.Tuple[int, int]
width: int
height: int
padding: int = 5
bg_color: pygame.Color = BLUE
text_color: pygame.Color = WHITE
hovered_color: pygame.Color = (BLUE * 3 + WHITE) // 4
hovered_text_color: pygame.Color = BLACK
pressed_color: pygame.Color = (BLUE + WHITE * 3) // 4
pressed_text_color: pygame.Color = BLACK
is_hovered: bool = False
is_pressed: bool = False
@property
def bottom(self) -> int:
"""
Return the y coordinate of the bottom of the button
:return: y_bottom
"""
return self.top_left[1] + self.height
@property
def right(self) -> int:
"""
Return the x coordinate of the right edge of the button
:return: x_right
"""
return self.top_left[0] + self.width
def get_colors(self) -> typing.Tuple[pygame.Color, pygame.Color]:
"""
Get background and text color considering hovered and pressed states
:return: the button's background color and the button's text color
"""
if self.is_pressed:
return self.pressed_color, self.pressed_text_color
if self.is_hovered:
return self.hovered_color, self.hovered_text_color
return self.bg_color, self.text_color
def render(self) -> pygame.Surface:
"""
Draw the button
:return: a pygame surface with the button
"""
surface: pygame.Surface = pygame.Surface((self.width, self.height))
bg_color, text_color = self.get_colors()
surface.fill(bg_color)
text_surface: pygame.Surface = font.render(self.text, True, text_color)
text_height: int = self.height - 2 * self.padding
text_width: int = round(text_surface.get_width() * text_height / text_surface.get_height())
text_surface: pygame.Surface = pygame.transform.scale(text_surface, (text_width, text_height))
surface.blit(text_surface, ((self.width - text_width) // 2, self.padding))
return surface
def process_event(self, event: pygame.event.Event) -> bool:
"""
Process a pygame event. If it's a click on this button, return true
:param event: a pygame event
:return: True if there was a click on the button
"""
# if this is a mouse event
if event.type in [pygame.MOUSEBUTTONUP, pygame.MOUSEMOTION, pygame.MOUSEBUTTONDOWN]:
# if the mouse event is inside the button
if self.top_left[0] <= event.pos[0] < self.bottom and self.top_left[1] <= event.pos[1] < self.right:
if event.type == pygame.MOUSEBUTTONUP:
self.is_pressed = False
return True
elif event.type == pygame.MOUSEBUTTONDOWN:
self.is_hovered = False
self.is_pressed = True
elif event.type == pygame.MOUSEMOTION:
self.is_hovered = True
return False

13
degeon_py/input_field.py

@ -43,7 +43,7 @@ class TextField:
surface.blit(
message_text,
(
(self.width - message_text.get_width()) // 2,
0, # or, if we want to center, `(self.width - message_text.get_width()) // 2,`
(self.height - message_text.get_height()) // 2
)
)
@ -58,7 +58,6 @@ class TextField:
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
print(self.is_focused)
if self.is_focused and hasattr(event, 'key') and event.type == 768:
if event.key == pygame.K_BACKSPACE:
self.value = self.value[:-1]
@ -71,3 +70,13 @@ class TextField:
self.value = self.value[:self.cursor_position] + event.unicode + self.value[self.cursor_position:]
self.cursor_position += 1
# print(self.is_focused, event.type, getattr(event, 'key', None), getattr(event, 'unicode', None), 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

Loading…
Cancel
Save