def build_layout(self): # internal static object cannot fall out of the layer # otherwise the code will crash col = math.ceil(self.width / GRID_WIDTH) row = math.ceil(self.height / GRID_HEIGHT) layout = [[None for c in range(col)] for r in range(row)] if hasattr(self, "contents"): for key, (obj, pos, dim) in self.contents.items(): # O(A) if dim == (0, 0): continue row_tl, col_tl = find_point_loc(pos, layout) dim = dim[0] - GRID_WIDTH, dim[1] - GRID_HEIGHT row_br, col_br = find_point_loc(calc_offset(pos, dim), layout) assert row_tl <= row_br, "Building layout problem{0}{1}".format( row_tl, row_br) assert col_tl <= col_tl, "Building layout problem{0}{1}".format( col_tl, col_br) for r in range(row_tl, row_br + 1): for c in range(col_tl, col_br + 1): layout[r][c] = key self.layout = layout else: raise Exception( "contents should be created before build_layout method is called, {0}" .format(self)) return None
def draw_box(self, surface, offset): super().draw_box_bg(surface, offset) for key, (obj, pos, dim) in self.contents.items(): if key == "exit": new_offset = calc_offset(offset, pos) obj.draw_box(surface, new_offset) else: surface.blit(obj, pos)
def draw_box(self, surface, offset): # O(n) self.draw_box_bg(surface, offset) if hasattr(self, "contents"): for name, (obj, rel_pos, dim) in self.contents.items(): new_offset = calc_offset(offset, rel_pos) obj.draw_box(surface, new_offset) if hasattr(self, "objects"): for key, objs in self.objects.items(): for obj in objs: obj.draw_box(surface, offset)
def draw(self, surface, offset): # O(n) """ :param surface: pygame.surface :param offset: menu's abs top-left pos :return: None """ self.draw_bg(surface, offset) if hasattr(self, "contents"): for name, (obj, rel_pos, dim) in self.contents.items(): new_offset = calc_offset(offset, rel_pos) obj.draw(surface, new_offset) if hasattr(self, "objects"): for key, objs in self.objects.items(): for obj in objs: obj.draw(surface, offset)
def run(self, click_command, mouse_pos, offset): # mouse_pos => abs_mouse_pos # handle background commands for command in self.get_commands(): self.handle_command(command) # run the static game if self.hover rel_mouse_pos = calc_rel_pos(mouse_pos, offset) # check hover for key, (obj, ref, dim) in self.contents.items(): if isInside(rel_mouse_pos, calcVertices(ref[0], ref[1], dim[0], dim[1])): if self.mouse_is_on != key: if self.mouse_is_on is not None and hasattr( self.contents[self.mouse_is_on][0], "un_hover"): self.contents[self.mouse_is_on][0].un_hover() if hasattr(obj, "do_hover"): obj.do_hover() self.mouse_is_on = key break else: if self.mouse_is_on is not None and hasattr( self.contents[self.mouse_is_on][0], "un_hover"): self.contents[self.mouse_is_on][0].un_hover() self.mouse_is_on = None if click_command == 1: if not isInside(rel_mouse_pos, calcVertices(0, 0, self.width, self.height)): # return OFF_FOCUS, self return RETURN, None else: # otherwise call content button if self.mouse_is_on is not None and hasattr( self.contents[self.mouse_is_on][0], "onclick"): obj, ref, dim = self.contents[self.mouse_is_on] new_offset = calc_offset(offset, ref) # when onclick, reset the button to its initial state self.contents[self.mouse_is_on][0].un_hover( ) # assert a clickable object must be hoverable self.mouse_is_on = None return obj.onclick(click_command, mouse_pos, new_offset) return None, None