class Child(EventMethodDispatcher):
def __init__(self, parent):
self._parent = parent
- if parent is None:
- return
- for parent in (parent, getattr(parent, "parent", None)):
- if isinstance(parent, Parent):
- parent.children.append(self)
- break
+ if parent is not None:
+ parent.children.append(self)
@property
def parent(self):
def font(self):
return self.root.font
- @cached_property
+ @property
def surf(self):
parent = self.parent
while not hasattr(parent, "surf"):
from .button import Button
from .label import Label
from .modal import Modal
+from .rect import Rect
class MessageBox(Modal):
def __init__(self, parent, rect, message):
super().__init__(parent)
self.rect = rect
+ Rect(self, self.rect, "black", "gray")
self.label = Label(self, pygame.Rect(rect.center, (10, 10)), "")
self.add_buttons()
self.message = message
self.deactivate,
)
- def draw(self):
- pygame.draw.rect(self.surf, "black", self.rect)
- pygame.draw.rect(self.surf, "gray", self.rect, 1)
- super().draw()
-
@property
def message(self):
return self.label.value
class Modal(FocusableMixin, Parent, Child):
def __init__(self, parent):
super().__init__(parent)
- self.draw = self._check_active(self._wrap_draw(self.draw))
+ self.draw = self._check_active(self.draw)
self.update = self._check_active(self.update)
self.handle_event = self._check_active(self.handle_event)
self.activate = self._check_active(self.activate, False)
return None
return inner
- def _wrap_draw(self, method):
- def inner():
- tintsurf = pygame.Surface(self.surf.get_size(), pygame.SRCALPHA, 32)
- tintsurf.fill(pygame.Color(0x80))
- self.surf.blit(tintsurf, (0, 0))
- return method()
- return inner
-
def activate(self):
super().activate()
self.root.stop_event = True
self.dirty = True
def draw(self):
+ tintsurf = pygame.Surface(self.surf.get_size(), pygame.SRCALPHA, 32)
+ tintsurf.fill(pygame.Color(0x80))
+ self.surf.blit(tintsurf, (0, 0))
super().draw()
--- /dev/null
+import pygame
+
+from .base import Child
+
+
+class Rect(Child):
+ def __init__(self, parent, rect, background_color, border_color):
+ super().__init__(parent)
+ self.rect = rect
+ self.background_color = background_color
+ self.border_color = border_color
+
+ def draw(self):
+ if self.background_color:
+ pygame.draw.rect(self.surf, self.background_color, self.rect)
+ if self.border_color:
+ pygame.draw.rect(self.surf, self.border_color, self.rect, 1)
def __init__(self, parent, rect, surf_size):
super().__init__(parent)
self.rect = rect
- self.__dict__["surf"] = pygame.Surface(surf_size, pygame.SRCALPHA, 32)
+ self._surf = pygame.Surface(surf_size, pygame.SRCALPHA, 32)
self.scroll_x = 0
self.scroll_y = 0
+ @property
+ def surf(self):
+ return self._surf
+
def get_subsurf(self):
- size = self.surf.get_size()
- return self.surf.subsurface(
+ size = self._surf.get_size()
+ return self._surf.subsurface(
pygame.Rect(
(self.scroll_x, self.scroll_y),
(
def __init__(self, parent, rect, labels, groups, active):
super().__init__(parent)
self.labels = labels
- # ...why do we have to reparent these items?
- for group in groups:
- for item in group:
- item.parent = self
self.groups = groups
self.active = active
num_labels = len(labels)
- self.children.clear()
self.buttons = [
Button(
self,
)
for i in range(num_labels)
]
- self.children.extend(self.groups[active])
+ self.update_children()
- def update_children(self, i):
- if self.active == i:
- return
- self.active = i
+ def update_children(self, i=None):
+ if i is not None:
+ if self.active == i:
+ return
+ self.active = i
for i, (button, group) in enumerate(zip(self.buttons, self.groups)):
is_group_active = i == self.active
if button.is_active != is_group_active:
button.is_active = is_group_active
self.dirty = True
for item in group:
+ if item.parent is not self:
+ item.parent = self
is_child_active = item in self.children
if is_group_active == is_child_active:
continue