I am trying to make GUI elements using pygame (I know it's odd, but they are to be used inside a pygame made game). Here is a very simplified piece of code of how a UI element class looks like in my code:
import pygame
from typing import Tuple
class UIElement(pygame.Surface):
def __init__(self, size: Tuple[int, int]) -> None:
super().__init__(size)
self.children = {}
def draw(self) -> None:
...
Note that the class is just an extension of the pygame.Surface class. Now, what I would like to do is make those elements resizable, for example if the size is not prior knowledge, implementing a method with this signature:
def resize(self, size: Tuple[int, int]) -> None:
...
However, pygame doesn't allow for Surface objects to be resized in-place, which forces me to create a new UIElement instance with the right size. I would like this new instance to be a copy of my first instance, except for the size of the pygame.Surface, and this new instance should replace the first one. How would I do it from within the first instance with my resize method?
I looked through the copy module, but it doesn't seem to fit my issue.
Furthermore, I know it may seem simpler to just add a surface attribute to my class, which would be holding the pygame.Surface object, and set a new value for this attribute when needed but this would force me to go through tremendous architecture redesign work and I would prefer to avoid it.
If you have any idea as how to fix my issue, I would appreciate it.
CodePudding user response:
No you can't. I suggest using the simple approach. UIElement should not be a subclass of pygame.Surface. The pygame.Surface object should only be an attribute of the UIElement. All your problems are caused by inheritance.
A pygame.Surface object cannot be resized. A Surface is just a proxy object for an internally managed, SDL surface object with immutable size. PyGame has no API to change the object under the hood. All you can do is to create a new Surface with a different size and use pygame.transform.scale() to set the content of the scaled Surface:
class UIElement(pygame.Surface):
# [...]
def resize(self, size):
scaled_element = UIElement(size)
pygame.transform.scale(self, size, scaled_element)
scaled_element.children = self.children
return scaled_element
