2023-03-26 09:51:11 +02:00
|
|
|
import abc
|
2023-03-26 17:01:28 +02:00
|
|
|
import uuid
|
2023-03-26 09:51:11 +02:00
|
|
|
from typing import Optional
|
|
|
|
|
|
|
|
import pygame
|
|
|
|
from pygame import Surface
|
|
|
|
|
2023-03-26 11:13:34 +02:00
|
|
|
from sprite.BoundingBox import BoundingBox
|
2023-03-26 09:51:11 +02:00
|
|
|
from sprite.PositionScale import PositionScale
|
2023-03-26 12:46:41 +02:00
|
|
|
from physics.TickData import TickData
|
|
|
|
from ui_elements import CoordinateTransform
|
2023-03-26 09:51:11 +02:00
|
|
|
|
|
|
|
|
|
|
|
class UiElement:
|
|
|
|
def __init__(self):
|
|
|
|
self.position_scale = PositionScale()
|
|
|
|
self.visible = True
|
2023-03-26 11:13:34 +02:00
|
|
|
self.click_listeners = []
|
|
|
|
|
2023-03-27 14:38:52 +02:00
|
|
|
self.bounding_box = BoundingBox(0, 0, 0, 0)
|
|
|
|
|
2023-03-26 17:01:28 +02:00
|
|
|
self.uuid = uuid.uuid4()
|
|
|
|
|
2023-03-26 11:13:34 +02:00
|
|
|
def add_click_listener(self, listener):
|
|
|
|
self.click_listeners.append(listener)
|
|
|
|
|
|
|
|
def remove_click_listener(self, listener):
|
|
|
|
self.click_listeners.remove(listener)
|
|
|
|
|
|
|
|
def click(self, click_event):
|
|
|
|
for listener in self.click_listeners:
|
|
|
|
listener(self, click_event)
|
2023-03-26 09:51:11 +02:00
|
|
|
|
|
|
|
@abc.abstractmethod
|
2023-03-26 12:46:41 +02:00
|
|
|
def tick(self, tick_data: TickData):
|
2023-03-26 11:13:34 +02:00
|
|
|
pass
|
2023-03-26 09:51:11 +02:00
|
|
|
|
|
|
|
@abc.abstractmethod
|
|
|
|
def render_sprite_image(self) -> Optional[Surface]:
|
2023-03-26 11:13:34 +02:00
|
|
|
pass
|
|
|
|
|
|
|
|
@abc.abstractmethod
|
|
|
|
def get_bounding_box(self) -> BoundingBox:
|
|
|
|
pass
|
2023-03-26 09:51:11 +02:00
|
|
|
|
|
|
|
def draw(self, screen: pygame.Surface, screen_transform: PositionScale):
|
|
|
|
if not self.visible:
|
|
|
|
return
|
|
|
|
|
|
|
|
image = self.render_sprite_image()
|
|
|
|
|
|
|
|
if image is not None:
|
2023-03-27 14:38:52 +02:00
|
|
|
target_position = CoordinateTransform.transform_world_to_screen(self.position_scale.position,
|
|
|
|
screen_transform)
|
2023-03-26 09:51:11 +02:00
|
|
|
|
2023-03-26 11:13:34 +02:00
|
|
|
screen_scale = screen_transform.scale
|
2023-03-26 09:51:11 +02:00
|
|
|
object_scale = self.position_scale.scale
|
|
|
|
|
|
|
|
target_size = (int(screen_scale[0] * object_scale[0] * image.get_width()),
|
|
|
|
int(screen_scale[1] * object_scale[1] * image.get_height()))
|
|
|
|
|
2023-03-26 11:13:34 +02:00
|
|
|
target_image = UiElement.get_scaled_image(image, target_size)
|
2023-03-26 09:51:11 +02:00
|
|
|
screen.blit(target_image, target_position)
|
|
|
|
|
2023-03-26 11:13:34 +02:00
|
|
|
@staticmethod
|
|
|
|
def get_scaled_image(image, resize):
|
2023-03-26 09:51:11 +02:00
|
|
|
return pygame.transform.scale(image, resize)
|