From 171aad76979193b7fc3862b038227011123c65a3 Mon Sep 17 00:00:00 2001 From: coppermouse <124282214+coppermouse@users.noreply.github.com> Date: Wed, 3 May 2023 21:58:29 +0200 Subject: [PATCH 1/2] improve menu parent container code. making a common class to handle that logic. also fix lower case path issue --- engine/game/game.py | 2 +- engine/uimenu/uimenu.py | 59 ++++++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/engine/game/game.py b/engine/game/game.py index a1bdff920..7c6161b2d 100644 --- a/engine/game/game.py +++ b/engine/game/game.py @@ -204,7 +204,7 @@ def __init__(self, main_dir, error_log): self.module = int(self.config["USER"]["module"]) self.module_list = csv_read(self.data_dir, "module_list.csv", ("module",)) # get module list - self.module_folder = str(self.module_list[self.module][0]).strip("/") + self.module_folder = str(self.module_list[self.module][0]).strip("/").lower() Game.module_dir = os.path.join(self.data_dir, "module", self.module_folder) Game.ui_font = csv_read(self.module_dir, "ui_font.csv", ("ui",), header_key=True) for item in Game.ui_font: # add ttf file extension for font data reading. diff --git a/engine/uimenu/uimenu.py b/engine/uimenu/uimenu.py index 64a4ba5a9..91819af0e 100644 --- a/engine/uimenu/uimenu.py +++ b/engine/uimenu/uimenu.py @@ -336,7 +336,39 @@ def change_state(self, text): self.event = False -class BrownMenuButton(UIMenu): +class Containerable: + + """ + Containerables are UI elements that have another element inside them. + It can also be that they are inside another element. + When something is inside something else it adjusts its position to it. + + To be inside another element, set that element on the parent attribute. + element_inside.parent = element_to_be_inside + + Also Containerables can be inside anything that implements "get_rect". + For examples Surfaces. + """ + + def get_rect(self): + # to be a able to contain something is must have a rect + raise NotImplementedError() + + def get_relative_position_inside_container(self): + # to be a able to contained by something it must have a relative position inside container + raise NotImplementedError() + + # TODO: have a get_size_method + + def update(self): # TODO: rename to get_adjusted_rect_to_inside_container + if self.parent is not None: # TODO: call a get_in_container() method + pos = self.get_relative_position_inside_container() + self.rect = pygame.rect.Rect(*[ + self.parent.get_rect()[i] - self.image.get_size()[i] // 2 + (pos[i] + 1) * self.parent.get_rect()[ + i + 2] * 0.5 for i in range(2)], *self.image.get_size()) + + +class BrownMenuButton(UIMenu, Containerable): @classmethod @lru_cache @@ -382,6 +414,9 @@ def __init__(self, pos, text="", width=200, parent=None): self.rect = self.button_normal_image.get_rect(center=self.pos) self.event = False + def get_relative_position_inside_container(self): + return self.pos + def update(self, mouse_pos, mouse_up, mouse_down): self.mouse_over = False self.image = self.button_normal_image @@ -391,10 +426,7 @@ def update(self, mouse_pos, mouse_up, mouse_down): if mouse_up: self.event = True - if self.parent is not None: - self.rect = pygame.rect.Rect(*[ - self.parent.get_rect()[i] - self.image.get_size()[i] // 2 + (self.pos[i] + 1) * self.parent.get_rect()[ - i + 2] * 0.5 for i in range(2)], *self.image.get_size()) + Containerable.update(self) def change_state(self, text): pass @@ -1112,25 +1144,20 @@ def pop(self, pos, text_input): self.rect = self.image.get_rect(bottomleft=self.pos) -class BoxUI(UIMenu): +class BoxUI(UIMenu, Containerable): def __init__(self, size, parent): UIMenu.__init__(self) self.parent = parent self.size = size - self.calculate_rect() self.image = pygame.Surface(size) self.image.fill("#222a2e") self._layer = -1 # NOTE: not sure if this is good since underscore indicate it is a private variable but it works for now + self.pos = (0,0) + Containerable.update(self) + + def get_relative_position_inside_container(self): + return (0,0) def get_rect(self): return self.rect - - def calculate_rect(self): - # TODO: atm the box is always in center. it should be able to have a position. - # make a common method to caclulate position if have parent. (the expression used in MenuButton is good) - x, y = [self.parent.get_size()[i] // 2 - (self.size[i] * 0.5) for i in range(2)] - self.rect = (x, y, *self.size) - - def update(self, *args): - self.calculate_rect() From e70dfd02d2b4761b35b0f0da428e8c9267a930bd Mon Sep 17 00:00:00 2001 From: coppermouse <124282214+coppermouse@users.noreply.github.com> Date: Thu, 4 May 2023 11:58:49 +0200 Subject: [PATCH 2/2] broke down containerable-class into two classes. no update on container-class, it now has a method that return the adjusted postion and it up for the implemented class to assign that value in its own class --- engine/uimenu/uimenu.py | 49 ++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/engine/uimenu/uimenu.py b/engine/uimenu/uimenu.py index 91819af0e..a832a99b0 100644 --- a/engine/uimenu/uimenu.py +++ b/engine/uimenu/uimenu.py @@ -336,39 +336,26 @@ def change_state(self, text): self.event = False -class Containerable: +class Container: - """ - Containerables are UI elements that have another element inside them. - It can also be that they are inside another element. - When something is inside something else it adjusts its position to it. - - To be inside another element, set that element on the parent attribute. - element_inside.parent = element_to_be_inside - - Also Containerables can be inside anything that implements "get_rect". - For examples Surfaces. - """ - def get_rect(self): - # to be a able to contain something is must have a rect raise NotImplementedError() + +class Containable: + def get_relative_position_inside_container(self): - # to be a able to contained by something it must have a relative position inside container raise NotImplementedError() - # TODO: have a get_size_method + def get_size(self): + raise NotImplementedError() - def update(self): # TODO: rename to get_adjusted_rect_to_inside_container - if self.parent is not None: # TODO: call a get_in_container() method - pos = self.get_relative_position_inside_container() - self.rect = pygame.rect.Rect(*[ - self.parent.get_rect()[i] - self.image.get_size()[i] // 2 + (pos[i] + 1) * self.parent.get_rect()[ - i + 2] * 0.5 for i in range(2)], *self.image.get_size()) + def get_adjusted_rect_to_be_inside_container(self, container): + pos = self.get_relative_position_inside_container() + return pygame.rect.Rect(*[container.get_rect()[i] - self.get_size()[i] // 2 + (pos[i] + 1) * container.get_rect()[i+2] // 2 for i in range(2)], *self.get_size()) -class BrownMenuButton(UIMenu, Containerable): +class BrownMenuButton(UIMenu, Containable): @classmethod @lru_cache @@ -426,7 +413,10 @@ def update(self, mouse_pos, mouse_up, mouse_down): if mouse_up: self.event = True - Containerable.update(self) + self.rect = self.get_adjusted_rect_to_be_inside_container(self.parent) + + def get_size(self): + return self.image.get_size() def change_state(self, text): pass @@ -1144,7 +1134,7 @@ def pop(self, pos, text_input): self.rect = self.image.get_rect(bottomleft=self.pos) -class BoxUI(UIMenu, Containerable): +class BoxUI(UIMenu, Containable, Container): def __init__(self, size, parent): UIMenu.__init__(self) @@ -1153,11 +1143,14 @@ def __init__(self, size, parent): self.image = pygame.Surface(size) self.image.fill("#222a2e") self._layer = -1 # NOTE: not sure if this is good since underscore indicate it is a private variable but it works for now - self.pos = (0,0) - Containerable.update(self) + self.pos = (0, 0) + self.rect = self.get_adjusted_rect_to_be_inside_container(self.parent) def get_relative_position_inside_container(self): - return (0,0) + return (0, 0) def get_rect(self): return self.rect + + def get_size(self): + return self.image.get_size()