def rebuild(self): """ Rebuild whatever needs building. """ self.set_dimensions((self.relative_rect.width, -1)) theming_parameters = { 'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'disabled_bg': self.disabled_background_colour, 'disabled_border': self.disabled_border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius } if self.shape == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal', 'disabled'], self.ui_manager) elif self.shape == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal', 'disabled'], self.ui_manager) self.background_and_border = self.drawable_shape.get_fresh_surface() if self.text_image is None: self.text_image = pygame.surface.Surface(self.text_image_rect.size, flags=pygame.SRCALPHA, depth=32) if isinstance(self.background_colour, ColourGradient): self.text_image.fill(pygame.Color("#FFFFFFFF")) self.background_colour.apply_gradient_to_surface(self.text_image) else: self.text_image.fill(self.background_colour) self.set_image(self.background_and_border.copy()) line_height = self.font.size(' ')[1] self.cursor = pygame.Rect( (self.text_image_rect.x + self.padding[0] - self.start_text_offset, self.text_image_rect.y + self.padding[1]), (1, line_height)) # setup for drawing self.redraw()
def redraw(self): """ Redraws the health bar rectangles and text onto the underlying sprite's image surface. Takes a little while so we only do it when the health has changed. """ theming_parameters = {'normal_bg': self.bar_unfilled_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius, 'filled_bar': self.bar_filled_colour, 'filled_bar_width': int(self.capacity_width * self.health_percentage)} if self.shape_type == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape_type == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape(self.rect, theming_parameters, ['normal'], self.ui_manager) self.image = self.drawable_shape.get_surface('normal') health_display_string = str(self.current_health) + "/" + str(self.health_capacity) self.background_text = self.font.render(health_display_string, True, self.text_shadow_colour) if type(self.text_colour) != ColourGradient: self.foreground_text = self.font.render(health_display_string, True, self.text_colour) else: self.foreground_text = self.font.render(health_display_string, True, pygame.Color('#FFFFFFFF')) self.text_colour.apply_gradient_to_surface(self.foreground_text) self.image.blit(self.background_text, self.background_text.get_rect(centerx=int(self.rect.width/2), centery=int(self.rect.height/2) + 1)) self.image.blit(self.background_text, self.background_text.get_rect(centerx=int(self.rect.width/2), centery=int(self.rect.height/2) - 1)) self.image.blit(self.background_text, self.background_text.get_rect(centerx=int(self.rect.width/2) + 1, centery=int(self.rect.height/2))) self.image.blit(self.background_text, self.background_text.get_rect(centerx=int(self.rect.width/2) - 1, centery=int(self.rect.height/2))) self.image.blit(self.foreground_text, self.foreground_text.get_rect(centerx=int(self.rect.width/2), centery=int(self.rect.height/2)))
def test_on_fresh_drawable_shape_ready(self, _init_pygame, default_ui_manager): element = UIElement(relative_rect=pygame.Rect(0, 0, 50, 50), manager=default_ui_manager, container=None, starting_height=0, layer_thickness=1) element.drawable_shape = RectDrawableShape(containing_rect=element.rect, theming_parameters={'normal_bg': pygame.Color('#FFFF00'), 'normal_border': pygame.Color('#FF0000'), 'border_width': 1, 'shadow_width': 1}, states=['normal'], manager=default_ui_manager) element.drawable_shape.states['normal'].has_fresh_surface = True element.on_fresh_drawable_shape_ready() assert element.image is not None
def rebuild(self): """ A complete rebuild of the drawable shape used by this button. """ theming_parameters = {'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'normal_image': self.background_image, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius} if self.shape_type == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape_type == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape(self.rect, theming_parameters, ['normal'], self.ui_manager) self.on_fresh_drawable_shape_ready()
def redraw(self): """ Redraw the status bar when something, other than it's position has changed. """ theming_parameters = {'normal_bg': self.bar_unfilled_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius, 'filled_bar': self.bar_filled_colour, 'filled_bar_width_percentage': self.percent_full, 'follow_sprite_offset': self.follow_sprite_offset} text = self.status_text() if text: text_parameters = {'font': self.font, 'text': text, 'normal_text': self.text_colour, 'normal_text_shadow': self.text_shadow_colour, 'text_shadow': (1, 0, 0, self.text_shadow_colour, False), 'text_horiz_alignment': self.text_horiz_alignment, 'text_vert_alignment': self.text_vert_alignment, 'text_horiz_alignment_padding': self.text_horiz_alignment_padding, 'text_vert_alignment_padding': self.text_vert_alignment_padding, } theming_parameters.update(text_parameters) if self.shape == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape(self.rect, theming_parameters, ['normal'], self.ui_manager) self.set_image(self.drawable_shape.get_fresh_surface())
def rebuild(self): """ Rebuild the closed state from theming parameters and dimensions. """ theming_parameters = { 'normal_bg': self.drop_down_menu_ui.background_colour, 'normal_border': self.drop_down_menu_ui.border_colour, 'disabled_bg': self.drop_down_menu_ui.disabled_background_colour, 'disabled_border': self.drop_down_menu_ui.disabled_border_colour, 'border_width': self.drop_down_menu_ui.border_width, 'shadow_width': self.drop_down_menu_ui.shadow_width, 'shape_corner_radius': self.drop_down_menu_ui.shape_corner_radius } if self.drop_down_menu_ui.shape == 'rectangle': self.drop_down_menu_ui.drawable_shape = RectDrawableShape( self.drop_down_menu_ui.rect, theming_parameters, ['normal', 'disabled'], self.ui_manager) elif self.drop_down_menu_ui.shape == 'rounded_rectangle': shape_rect = self.drop_down_menu_ui.rect self.drop_down_menu_ui.drawable_shape = RoundedRectangleShape( shape_rect, theming_parameters, ['normal', 'disabled'], self.ui_manager) self.drop_down_menu_ui.set_image( self.drop_down_menu_ui.drawable_shape.get_fresh_surface()) # extra if self.open_button is not None: expand_button_symbol = '▼' if self.expand_direction is not None: if self.expand_direction == 'up': expand_button_symbol = '▲' elif self.expand_direction == 'down': expand_button_symbol = '▼' self.open_button.set_text(expand_button_symbol)
def redraw(self): """ Redraws the health bar rectangles and text onto the underlying sprite's image surface. Takes a little while so we only do it when the health has changed. """ health_display_string = str(self.current_health) + "/" + str( self.health_capacity) theming_parameters = { 'normal_bg': self.bar_unfilled_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius, 'filled_bar': self.bar_filled_colour, 'filled_bar_width_percentage': self.health_percentage, 'font': self.font, 'text': health_display_string, 'normal_text': self.text_colour, 'text_shadow': self.text_shadow_colour, 'text_horiz_alignment': self.text_horiz_alignment, 'text_vert_alignment': self.text_vert_alignment, 'text_horiz_alignment_padding': self.text_horiz_alignment_padding, 'text_vert_alignment_padding': self.text_vert_alignment_padding, } if self.shape == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal'], self.ui_manager) self.set_image(self.drawable_shape.get_fresh_surface())
def rebuild(self): # shape for expanded drop down is a little trick because it is two rectangles, one on top of the other # forming an 'L' shape (or an inverted L if dropping down) if self.expand_direction == 'down': overall_background_rect = pygame.Rect(self.drop_down_menu_ui.rect.topleft, (self.drop_down_menu_ui.rect.width + 50, self.base_position_rect.height * (1 + len(self.options_list)) + 2 * self.drop_down_menu_ui.shadow_width + 2 * self.drop_down_menu_ui.border_width)) options_background_rect = pygame.Rect(self.drop_down_menu_ui.rect.topleft, (self.base_position_rect.width - self.close_button_width + 2 * self.drop_down_menu_ui.shadow_width + 2 * self.drop_down_menu_ui.border_width, self.base_position_rect.height * (1 + len(self.options_list)) + 2 * self.drop_down_menu_ui.shadow_width + 2 * self.drop_down_menu_ui.border_width)) self.rect_height_offset = 0 self.selected_option_rect = pygame.Rect((0, 0), self.drop_down_menu_ui.rect.size) else: # need to adjust the position of the rect so it appears in the right position self.rect_height_offset = self.base_position_rect.height * len(self.options_list) self.drop_down_menu_ui.rect.y = self.drop_down_menu_ui.rect.y - self.rect_height_offset self.drop_down_menu_ui.relative_rect.y = self.drop_down_menu_ui.relative_rect.y - self.rect_height_offset self.selected_option_rect = pygame.Rect((0, self.rect_height_offset), self.drop_down_menu_ui.rect.size) overall_background_rect = pygame.Rect(self.drop_down_menu_ui.rect.topleft, (self.drop_down_menu_ui.rect.width + 50, self.base_position_rect.height * (1 + len(self.options_list)) + 2 * self.drop_down_menu_ui.shadow_width + 2 * self.drop_down_menu_ui.border_width)) options_background_rect = pygame.Rect(self.drop_down_menu_ui.rect.topleft, (self.base_position_rect.width - self.close_button_width + 2 * self.drop_down_menu_ui.shadow_width + 2 * self.drop_down_menu_ui.border_width, self.base_position_rect.height * (1 + len(self.options_list)) + 2 * self.drop_down_menu_ui.shadow_width + 2 * self.drop_down_menu_ui.border_width)) self.drop_down_menu_ui.image = pygame.Surface(overall_background_rect.size, flags=pygame.SRCALPHA) self.drop_down_menu_ui.image.fill(pygame.Color('#00000000')) theming_parameters = {'normal_bg': self.drop_down_menu_ui.background_colour, 'normal_border': self.drop_down_menu_ui.border_colour, 'border_width': self.drop_down_menu_ui.border_width, 'shadow_width': self.drop_down_menu_ui.shadow_width, 'shape_corner_radius': self.drop_down_menu_ui.shape_corner_radius} if self.drop_down_menu_ui.shape_type == 'rectangle': drawable_shape = RectDrawableShape(self.selected_option_rect, theming_parameters, ['normal'], self.ui_manager) self.drop_down_menu_ui.image.blit(drawable_shape.get_surface('normal'), self.selected_option_rect.topleft) self.drop_down_menu_ui.image.fill(pygame.Color('#00000000'), pygame.Rect((0, 0), (options_background_rect.width - self.drop_down_menu_ui.shadow_width - self.drop_down_menu_ui.border_width, options_background_rect.height))) options_drawable_shape = RectDrawableShape(options_background_rect, theming_parameters, ['normal'], self.ui_manager) self.drop_down_menu_ui.image.blit(options_drawable_shape.get_surface('normal'), (0, 0)) elif self.drop_down_menu_ui.shape_type == 'rounded_rectangle': drawable_shape = RoundedRectangleShape(self.selected_option_rect, theming_parameters, ['normal'], self.ui_manager) self.drop_down_menu_ui.image.blit(drawable_shape.get_surface('normal'), self.selected_option_rect.topleft) self.drop_down_menu_ui.image.fill(pygame.Color('#00000000'), pygame.Rect((0, 0), (options_background_rect.width - self.drop_down_menu_ui.shadow_width - self.drop_down_menu_ui.border_width, options_background_rect.height))) options_drawable_shape = RoundedRectangleShape(options_background_rect, theming_parameters, ['normal'], self.ui_manager) self.drop_down_menu_ui.image.blit(options_drawable_shape.get_surface('normal'), (0, 0)) # extra if self.close_button is not None: expand_button_symbol = '▼' if self.expand_direction is not None: if self.expand_direction == 'up': expand_button_symbol = '▲' elif self.expand_direction == 'down': expand_button_symbol = '▼' self.close_button.set_text(expand_button_symbol)
def rebuild(self): """ Rebuild whatever needs building. """ if self.scroll_bar is not None: self.scroll_bar.kill() # The text_wrap_area is the part of the text box that we try to keep the text inside # of so that none of it overlaps. Essentially we start with the containing box, # subtract the border, then subtract the padding, then if necessary subtract the width # of the scroll bar self.rounded_corner_offset = int(self.shape_corner_radius - (math.sin(math.pi / 4) * self.shape_corner_radius)) self.text_wrap_rect = pygame.Rect( (self.rect[0] + self.padding[0] + self.border_width + self.shadow_width + self.rounded_corner_offset), (self.rect[1] + self.padding[1] + self.border_width + self.shadow_width + self.rounded_corner_offset), max(1, (self.rect[2] - (self.padding[0] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - (2 * self.rounded_corner_offset))), max(1, (self.rect[3] - (self.padding[1] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - (2 * self.rounded_corner_offset)))) if self.wrap_to_height or self.rect[3] == -1: self.text_wrap_rect.height = -1 if self.rect[2] == -1: self.text_wrap_rect.width = -1 drawable_area_size = (self.text_wrap_rect[2], self.text_wrap_rect[3]) # This gives us the height of the text at the 'width' of the text_wrap_area self.parse_html_into_style_data() if self.text_box_layout is not None: if self.wrap_to_height or self.rect[3] == -1 or self.rect[2] == -1: final_text_area_size = self.text_box_layout.layout_rect.size new_dimensions = ( (final_text_area_size[0] + (self.padding[0] * 2) + (self.border_width * 2) + (self.shadow_width * 2) + (2 * self.rounded_corner_offset)), (final_text_area_size[1] + (self.padding[1] * 2) + (self.border_width * 2) + (self.shadow_width * 2) + (2 * self.rounded_corner_offset))) self.set_dimensions(new_dimensions) # need to regen this because it was dynamically generated drawable_area_size = (max( 1, (self.rect[2] - (self.padding[0] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - (2 * self.rounded_corner_offset))), max(1, (self.rect[3] - (self.padding[1] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - (2 * self.rounded_corner_offset)))) elif self.text_box_layout.layout_rect.height > self.text_wrap_rect[ 3]: # We need a scrollbar because our text is longer than the space we # have to display it. This also means we need to parse the text again. text_rect_width = (self.rect[2] - (self.padding[0] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - self.rounded_corner_offset - self.scroll_bar_width) self.text_wrap_rect = pygame.Rect( (self.rect[0] + self.padding[0] + self.border_width + self.shadow_width + self.rounded_corner_offset), (self.rect[1] + self.padding[1] + self.border_width + self.shadow_width + self.rounded_corner_offset), max(1, text_rect_width), max(1, (self.rect[3] - (self.padding[1] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - (2 * self.rounded_corner_offset)))) self.parse_html_into_style_data() percentage_visible = (self.text_wrap_rect[3] / self.text_box_layout.layout_rect.height) scroll_bar_position = (self.relative_rect.right - self.border_width - self.shadow_width - self.scroll_bar_width, self.relative_rect.top + self.border_width + self.shadow_width) scroll_bar_rect = pygame.Rect( scroll_bar_position, (self.scroll_bar_width, self.rect.height - (2 * self.border_width) - (2 * self.shadow_width))) self.scroll_bar = UIVerticalScrollBar(scroll_bar_rect, percentage_visible, self.ui_manager, self.ui_container, parent_element=self, visible=self.visible) self.join_focus_sets(self.scroll_bar) else: new_dimensions = (self.rect[2], self.rect[3]) self.set_dimensions(new_dimensions) theming_parameters = { 'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius } if self.shape == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal'], self.ui_manager) self.background_surf = self.drawable_shape.get_fresh_surface() if self.scroll_bar is not None: height_adjustment = int(self.scroll_bar.start_percentage * self.text_box_layout.layout_rect.height) else: height_adjustment = 0 if self.rect.width <= 0 or self.rect.height <= 0: return drawable_area = pygame.Rect((0, height_adjustment), drawable_area_size) new_image = pygame.surface.Surface(self.rect.size, flags=pygame.SRCALPHA, depth=32) new_image.fill(pygame.Color(0, 0, 0, 0)) basic_blit(new_image, self.background_surf, (0, 0)) basic_blit( new_image, self.text_box_layout.finalised_surface, (self.padding[0] + self.border_width + self.shadow_width + self.rounded_corner_offset, self.padding[1] + self.border_width + self.shadow_width + self.rounded_corner_offset), drawable_area) self.set_image(new_image) self.link_hover_chunks = [] self.text_box_layout.add_chunks_to_hover_group(self.link_hover_chunks) self.should_trigger_full_rebuild = False self.full_rebuild_countdown = self.time_until_full_rebuild_after_changing_size
def rebuild(self): """ Rebuild anything that might need rebuilding. """ border_and_shadow = self.border_width + self.shadow_width self.background_rect = pygame.Rect((border_and_shadow + self.relative_rect.x, border_and_shadow + self.relative_rect.y), (self.relative_rect.width - (2 * border_and_shadow), self.relative_rect.height - (2 * border_and_shadow))) theming_parameters = {'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius} if self.shape_type == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape_type == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape(self.rect, theming_parameters, ['normal'], self.ui_manager) self.set_image(self.drawable_shape.get_surface('normal')) if self.button_container is None: self.button_container = UIContainer(self.background_rect, manager=self.ui_manager, container=self.ui_container, anchors=self.anchors, object_id='#horiz_scrollbar_buttons_container') else: self.button_container.set_dimensions(self.background_rect.size) self.button_container.set_relative_position(self.background_rect.topleft) # Things below here depend on theme data so need to be updated on a rebuild if self.arrow_buttons_enabled: self.arrow_button_width = self.default_button_width if self.left_button is None: self.left_button = UIButton(pygame.Rect((0, 0), (self.arrow_button_width, self.background_rect.height)), '◀', self.ui_manager, container=self.button_container, starting_height=1, parent_element=self, object_id='#left_button', anchors={'left': 'left', 'right': 'left', 'top': 'top', 'bottom': 'bottom'} ) if self.right_button is None: self.right_button = UIButton(pygame.Rect((-self.arrow_button_width, 0), (self.arrow_button_width, self.background_rect.height)), '▶', self.ui_manager, container=self.button_container, starting_height=1, parent_element=self, object_id='#right_button', anchors={'left': 'right', 'right': 'right', 'top': 'top', 'bottom': 'bottom'}) else: self.arrow_button_width = 0 if self.left_button is not None: self.left_button.kill() self.left_button = None if self.right_button is not None: self.right_button.kill() self.right_button = None self.scrollable_width = (self.background_rect.width - self.sliding_button_width - (2 * self.arrow_button_width)) self.right_limit_position = self.scrollable_width self.scroll_position = self.scrollable_width / 2 if self.sliding_button is not None: sliding_x_pos = int((self.background_rect.width / 2) - (self.sliding_button_width / 2)) self.sliding_button.set_relative_position((sliding_x_pos, 0)) self.sliding_button.set_dimensions((self.sliding_button_width, self.background_rect.height)) self.sliding_button.set_hold_range((self.background_rect.width, 100)) self.set_current_value(self.current_value)
def rebuild(self): """ Rebuilds the window when the theme has changed. """ if self._window_root_container is None: self._window_root_container = UIContainer(pygame.Rect(self.relative_rect.x + self.shadow_width, self.relative_rect.y + self.shadow_width, self.relative_rect.width - (2 * self.shadow_width), self.relative_rect.height - (2 * self.shadow_width)), manager=self.ui_manager, starting_height=1, is_window_root_container=True, container=None, parent_element=self, object_id="#window_root_container") if self.window_element_container is None: window_container_rect = pygame.Rect(self.border_width, self.title_bar_height, (self._window_root_container.relative_rect.width - (2 * self.border_width)), (self._window_root_container.relative_rect.height - self.title_bar_height - self.border_width)) self.window_element_container = UIContainer(window_container_rect, self.ui_manager, starting_height=0, container=self._window_root_container, parent_element=self, object_id="#window_element_container", anchors={'top': 'top', 'bottom': 'bottom', 'left': 'left', 'right': 'right'}) theming_parameters = {'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius} if self.shape_type == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape_type == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape(self.rect, theming_parameters, ['normal'], self.ui_manager) self.set_image(self.drawable_shape.get_surface('normal')) self.set_dimensions(self.relative_rect.size) if self.window_element_container is not None: element_container_width = (self._window_root_container.relative_rect.width - (2 * self.border_width)) element_container_height = (self._window_root_container.relative_rect.height - self.title_bar_height) self.window_element_container.set_dimensions((element_container_width, element_container_height)) self.window_element_container.set_relative_position((self.border_width, self.title_bar_height)) if self.enable_title_bar: if self.title_bar is not None: self.title_bar.set_dimensions((self._window_root_container.relative_rect.width - self.title_bar_button_width, self.title_bar_height)) else: title_bar_width = (self._window_root_container.relative_rect.width - self.title_bar_button_width) self.title_bar = UIButton(relative_rect=pygame.Rect(0, 0, title_bar_width, self.title_bar_height), text=self.window_display_title, manager=self.ui_manager, container=self._window_root_container, parent_element=self, object_id='#title_bar', anchors={'top': 'top', 'bottom': 'top', 'left': 'left', 'right': 'right'} ) self.title_bar.set_hold_range((100, 100)) if self.enable_close_button: if self.close_window_button is not None: close_button_pos = (-self.title_bar_button_width, 0) self.close_window_button.set_dimensions((self.title_bar_button_width, self.title_bar_height)) self.close_window_button.set_relative_position(close_button_pos) else: close_rect = pygame.Rect((-self.title_bar_button_width, 0), (self.title_bar_button_width, self.title_bar_height)) self.close_window_button = UIButton(relative_rect=close_rect, text='╳', manager=self.ui_manager, container=self._window_root_container, parent_element=self, object_id='#close_button', anchors={'top': 'top', 'bottom': 'top', 'left': 'right', 'right': 'right'} ) else: if self.close_window_button is not None: self.close_window_button.kill() self.close_window_button = None else: if self.title_bar is not None: self.title_bar.kill() self.title_bar = None if self.close_window_button is not None: self.close_window_button.kill() self.close_window_button = None
def rebuild(self): """ A complete rebuild of the drawable shape used by this button. """ self.rect.width = -1 if self.dynamic_width else self.rect.width self.relative_rect.width = -1 if self.dynamic_width else self.relative_rect.width self.rect.height = -1 if self.dynamic_height else self.rect.height self.relative_rect.height = -1 if self.dynamic_height else self.relative_rect.height theming_parameters = { 'normal_bg': self.colours['normal_bg'], 'normal_text': self.colours['normal_text'], 'normal_text_shadow': self.colours['normal_text_shadow'], 'normal_border': self.colours['normal_border'], 'normal_image': self.normal_image, 'hovered_bg': self.colours['hovered_bg'], 'hovered_text': self.colours['hovered_text'], 'hovered_text_shadow': self.colours['hovered_text_shadow'], 'hovered_border': self.colours['hovered_border'], 'hovered_image': self.hovered_image, 'disabled_bg': self.colours['disabled_bg'], 'disabled_text': self.colours['disabled_text'], 'disabled_text_shadow': self.colours['disabled_text_shadow'], 'disabled_border': self.colours['disabled_border'], 'disabled_image': self.disabled_image, 'selected_bg': self.colours['selected_bg'], 'selected_text': self.colours['selected_text'], 'selected_text_shadow': self.colours['selected_text_shadow'], 'selected_border': self.colours['selected_border'], 'selected_image': self.selected_image, 'active_bg': self.colours['active_bg'], 'active_border': self.colours['active_border'], 'active_text': self.colours['active_text'], 'active_text_shadow': self.colours['active_text_shadow'], 'active_image': self.selected_image, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'font': self.font, 'text': translate(self.text), 'text_shadow': (self.text_shadow_size, self.text_shadow_offset[0], self.text_shadow_offset[1], self.colours['normal_text_shadow'], True), 'text_horiz_alignment': self.text_horiz_alignment, 'text_vert_alignment': self.text_vert_alignment, 'text_horiz_alignment_padding': self.text_horiz_alignment_padding, 'text_horiz_alignment_method': self.text_horiz_alignment_method, 'text_vert_alignment_padding': self.text_vert_alignment_padding, 'shape_corner_radius': self.shape_corner_radius, 'transitions': self.state_transitions } if self.shape == 'rectangle': self.drawable_shape = RectDrawableShape( self.rect, theming_parameters, ['normal', 'hovered', 'disabled', 'selected', 'active'], self.ui_manager) elif self.shape == 'ellipse': self.drawable_shape = EllipseDrawableShape( self.rect, theming_parameters, ['normal', 'hovered', 'disabled', 'selected', 'active'], self.ui_manager) elif self.shape == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal', 'hovered', 'disabled', 'selected', 'active'], self.ui_manager) self.on_fresh_drawable_shape_ready() if self.relative_rect.width == -1 or self.relative_rect.height == -1: self.dynamic_width = self.relative_rect.width == -1 self.dynamic_height = self.relative_rect.height == -1 self.set_dimensions(self.image.get_size()) # if we have anchored the left side of our button to the right of it's container then # changing the width is going to mess up the horiz position as well. new_left = self.relative_rect.left new_top = self.relative_rect.top if self.anchors['left'] == 'right' and self.dynamic_width: left_offset = self.dynamic_dimensions_orig_top_left[0] new_left = left_offset - self.relative_rect.width # if we have anchored the top side of our button to the bottom of it's container then # changing the height is going to mess up the vert position as well. if self.anchors['top'] == 'bottom' and self.dynamic_height: top_offset = self.dynamic_dimensions_orig_top_left[1] new_top = top_offset - self.relative_rect.height self.set_relative_position((new_left, new_top))
def rebuild(self): """ Rebuild anything that might need rebuilding. """ self.border_rect = pygame.Rect( (self.shadow_width, self.shadow_width), (self.rect.width - (2 * self.shadow_width), self.rect.height - (2 * self.shadow_width))) self.relative_background_rect = pygame.Rect( (self.border_width + self.shadow_width, self.border_width + self.shadow_width), (self.border_rect.width - (2 * self.border_width), self.border_rect.height - (2 * self.border_width))) self.background_rect = pygame.Rect( (self.relative_background_rect.x + self.relative_rect.x, self.relative_background_rect.y + self.relative_rect.y), self.relative_background_rect.size) self.scrollable_height = self.background_rect.height - ( 2 * self.button_height) self.bottom_limit = self.scrollable_height x_pos = self.relative_rect.x + self.shadow_width + self.border_width y_pos = self.relative_rect.y + self.scroll_position + self.shadow_width + self.border_width + self.button_height self.sliding_rect_position = pygame.math.Vector2(x_pos, y_pos) theming_parameters = { 'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius } if self.shape_type == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape_type == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal'], self.ui_manager) self.image = self.drawable_shape.get_surface('normal') if self.top_button is not None: self.top_button.set_relative_position( self.background_rect.topleft), self.top_button.set_dimensions( (self.background_rect.width, self.button_height)) if self.bottom_button is not None: bottom_button_y = self.background_rect.y + self.background_rect.height - self.button_height self.bottom_button.set_relative_position( (self.background_rect.x, bottom_button_y)), self.bottom_button.set_dimensions( (self.background_rect.width, self.button_height)) if self.sliding_button is not None: scroll_bar_height = int(self.scrollable_height * self.visible_percentage) self.sliding_button.set_relative_position( self.sliding_rect_position) self.sliding_button.set_dimensions( (self.background_rect.width, scroll_bar_height)) self.sliding_button.set_hold_range( (100, self.background_rect.height))
def rebuild(self): """ Rebuild anything that might need rebuilding. """ border_and_shadow = self.border_width + self.shadow_width self.background_rect = pygame.Rect( (border_and_shadow + self.relative_rect.x, border_and_shadow + self.relative_rect.y), (self.relative_rect.width - (2 * border_and_shadow), self.relative_rect.height - (2 * border_and_shadow))) theming_parameters = { 'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius } if self.shape == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal'], self.ui_manager) self.set_image(self.drawable_shape.get_surface('normal')) if self.button_container is None: self.button_container = UIContainer( self.background_rect, manager=self.ui_manager, container=self.ui_container, anchors=self.anchors, object_id='#horiz_scrollbar_buttons_container') else: self.button_container.set_dimensions(self.background_rect.size) self.button_container.set_relative_position( self.background_rect.topleft) if self.enable_arrow_buttons: self.arrow_button_width = self.button_width if self.left_button is None: self.left_button = UIButton(pygame.Rect( (0, 0), (self.arrow_button_width, self.background_rect.height)), '◀', self.ui_manager, container=self.button_container, starting_height=1, parent_element=self, object_id="#left_button", anchors={ 'left': 'left', 'right': 'left', 'top': 'top', 'bottom': 'bottom' }) if self.right_button is None: self.right_button = UIButton(pygame.Rect( (-self.arrow_button_width, 0), (self.arrow_button_width, self.background_rect.height)), '▶', self.ui_manager, container=self.button_container, starting_height=1, parent_element=self, object_id="#right_button", anchors={ 'left': 'right', 'right': 'right', 'top': 'top', 'bottom': 'bottom' }) else: self.arrow_button_width = 0 if self.left_button is not None: self.left_button.kill() self.left_button = None if self.right_button is not None: self.right_button.kill() self.right_button = None self.scrollable_width = self.background_rect.width - ( 2 * self.arrow_button_width) self.right_limit = self.scrollable_width scroll_bar_width = max( 5, int(self.scrollable_width * self.visible_percentage)) self.scroll_position = min(max(self.scroll_position, self.left_limit), self.right_limit - scroll_bar_width) x_pos = (self.scroll_position + self.arrow_button_width) y_pos = 0 self.sliding_rect_position = pygame.math.Vector2(x_pos, y_pos) if self.sliding_button is not None: self.sliding_button.set_relative_position( self.sliding_rect_position) self.sliding_button.set_dimensions( (scroll_bar_width, self.background_rect.height)) self.sliding_button.set_hold_range( (self.background_rect.width, 100))
def rebuild(self): """ """ border_rect_width = self.rect.width - (self.shadow_width * 2) border_rect_height = self.rect.height - (self.shadow_width * 2) self.border_rect = pygame.Rect((self.shadow_width, self.shadow_width), (border_rect_width, border_rect_height)) background_rect_width = border_rect_width - (self.border_width * 2) background_rect_height = border_rect_height - (self.border_width * 2) self.background_rect = pygame.Rect( (self.shadow_width + self.border_width, self.shadow_width + self.border_width), (background_rect_width, background_rect_height)) self.text_block_rect = pygame.Rect( (self.border_width, self.menu_bar_height), (self.border_rect.width - self.border_width, (self.border_rect.height - self.menu_bar_height - self.done_button_vertical_space))) theming_parameters = { 'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius } if self.shape_type == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape_type == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal'], self.ui_manager) self.image = self.drawable_shape.get_surface('normal') self.get_container( ).relative_rect.width = self.rect.width - self.shadow_width * 2 self.get_container( ).relative_rect.height = self.rect.height - self.shadow_width * 2 self.get_container( ).relative_rect.x = self.relative_rect.x + self.shadow_width self.get_container( ).relative_rect.y = self.relative_rect.y + self.shadow_width self.get_container().update_containing_rect_position() if self.menu_bar is not None: self.menu_bar.set_dimensions( ((self.rect.width - (self.shadow_width * 2)) - self.close_button_width, self.menu_bar_height)) if self.close_window_button is not None: self.close_window_button.set_relative_position( ((self.rect.width - self.shadow_width * 2) - self.close_button_width, 0)) if self.dismiss_button is not None: self.dismiss_button.set_relative_position( ((self.rect.width / 2) + 45, (self.border_rect.height - self.done_button_vertical_start))) if self.text_block is not None: self.text_block.set_relative_position(self.text_block_rect.topleft) self.text_block.set_dimensions(self.text_block_rect.size)
def rebuild(self): """ Rebuild whatever needs building. """ ''' The text_wrap_area is the part of the text box that we try to keep the text inside of so that none of it overlaps. Essentially we start with the containing box, subtract the border, then subtract the padding, then if necessary subtract the width of the scroll bar''' self.rounded_corner_offset = int(self.shape_corner_radius - (math.sin(math.pi / 4) * self.shape_corner_radius)) self.text_wrap_rect = [ (self.rect[0] + self.padding[0] + self.border_width + self.shadow_width + self.rounded_corner_offset), (self.rect[1] + self.padding[1] + self.border_width + self.shadow_width + self.rounded_corner_offset), (self.rect[2] - (self.padding[0] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - (2 * self.rounded_corner_offset)), (self.rect[3] - (self.padding[1] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - (2 * self.rounded_corner_offset)) ] if self.rect[3] == -1: self.text_wrap_rect[3] = -1 self.parse_html_into_style_data( ) # This gives us the height of the text at the 'width' of the text_wrap_area if self.formatted_text_block is not None: if self.wrap_to_height or self.rect[3] == -1: final_text_area_size = self.formatted_text_block.final_dimensions self.rect.size = [ (final_text_area_size[0] + (self.padding[0] * 2) + (self.border_width * 2) + (self.shadow_width * 2) + (2 * self.rounded_corner_offset)), (final_text_area_size[1] + (self.padding[1] * 2) + (self.border_width * 2) + (self.shadow_width * 2) + (2 * self.rounded_corner_offset)) ] elif self.formatted_text_block.final_dimensions[ 1] > self.text_wrap_rect[3]: # We need a scrollbar because our text is longer than the space we have to display it. # this also means we need to parse the text again. text_rect_width = (self.rect[2] - (self.padding[0] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - self.rounded_corner_offset - self.scroll_bar_width) self.text_wrap_rect = [ (self.rect[0] + self.padding[0] + self.border_width + self.shadow_width + self.rounded_corner_offset), (self.rect[1] + self.padding[1] + self.border_width + self.shadow_width + self.rounded_corner_offset), text_rect_width, (self.rect[3] - (self.padding[1] * 2) - (self.border_width * 2) - (self.shadow_width * 2) - (2 * self.rounded_corner_offset)) ] self.parse_html_into_style_data() percentage_visible = self.text_wrap_rect[ 3] / self.formatted_text_block.final_dimensions[1] scroll_bar_position = (self.relative_rect.right - self.border_width - self.shadow_width - self.scroll_bar_width, self.relative_rect.top + self.border_width + self.shadow_width) if self.scroll_bar is not None: self.scroll_bar.kill() self.scroll_bar = UIVerticalScrollBar(pygame.Rect( scroll_bar_position, (self.scroll_bar_width, self.rect.height - (2 * self.border_width) - (2 * self.shadow_width))), percentage_visible, self.ui_manager, self.ui_container, parent_element=self) else: self.rect.size = [self.rect[2], self.rect[3]] theming_parameters = { 'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius } if self.shape_type == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape_type == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal'], self.ui_manager) self.background_surf = self.drawable_shape.get_surface('normal') if self.scroll_bar is not None: height_adjustment = int( self.scroll_bar.start_percentage * self.formatted_text_block.final_dimensions[1]) else: height_adjustment = 0 drawable_area = pygame.Rect( (0, height_adjustment), (self.text_wrap_rect[2], self.text_wrap_rect[3])) self.image = pygame.Surface(self.rect.size, flags=pygame.SRCALPHA, depth=32) self.image.fill(pygame.Color(0, 0, 0, 0)) self.image.blit(self.background_surf, (0, 0)) self.image.blit( self.formatted_text_block.block_sprite, (self.padding[0] + self.border_width + self.shadow_width + self.rounded_corner_offset, self.padding[1] + self.border_width + self.shadow_width + self.rounded_corner_offset), drawable_area) self.formatted_text_block.add_chunks_to_hover_group( self.link_hover_chunks)
def rebuild(self): """ Rebuild anything that might need rebuilding. """ border_and_shadow = self.border_width + self.shadow_width self.background_rect = pygame.Rect( (border_and_shadow + self.relative_rect.x, border_and_shadow + self.relative_rect.y), (self.relative_rect.width - (2 * border_and_shadow), self.relative_rect.height - (2 * border_and_shadow))) theming_parameters = { 'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'disabled_bg': self.disabled_background_colour, 'disabled_border': self.disabled_border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius } if self.shape == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal', 'disabled'], self.ui_manager) elif self.shape == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal', 'disabled'], self.ui_manager) self.set_image(self.drawable_shape.get_fresh_surface()) if self.button_container is None: self.button_container = UIContainer( self.background_rect, manager=self.ui_manager, container=self.ui_container, anchors=self.anchors, object_id='#vert_scrollbar_buttons_container', visible=self.visible) self.join_focus_sets(self.button_container) else: self.button_container.set_dimensions(self.background_rect.size) self.button_container.set_relative_position( self.background_rect.topleft) if self.enable_arrow_buttons: self.arrow_button_height = self.button_height if self.top_button is None: self.top_button = UIButton(pygame.Rect( (0, 0), (self.background_rect.width, self.arrow_button_height)), '▲', self.ui_manager, container=self.button_container, starting_height=1, parent_element=self, object_id=ObjectID( "#top_button", "@arrow_button"), anchors={ 'left': 'left', 'right': 'right', 'top': 'top', 'bottom': 'top' }) self.join_focus_sets(self.top_button) if self.bottom_button is None: self.bottom_button = UIButton(pygame.Rect( (0, -self.arrow_button_height), (self.background_rect.width, self.arrow_button_height)), '▼', self.ui_manager, container=self.button_container, starting_height=1, parent_element=self, object_id=ObjectID( "#bottom_button", "@arrow_button"), anchors={ 'left': 'left', 'right': 'right', 'top': 'bottom', 'bottom': 'bottom' }) self.join_focus_sets(self.bottom_button) else: self.arrow_button_height = 0 if self.top_button is not None: self.top_button.kill() self.top_button = None if self.bottom_button is not None: self.bottom_button.kill() self.bottom_button = None self.scrollable_height = self.background_rect.height - ( 2 * self.arrow_button_height) self.bottom_limit = self.scrollable_height scroll_bar_height = max( 5, int(self.scrollable_height * self.visible_percentage)) self.scroll_position = min(max(self.scroll_position, self.top_limit), self.bottom_limit - scroll_bar_height) x_pos = 0 y_pos = (self.scroll_position + self.arrow_button_height) self.sliding_rect_position = pygame.math.Vector2(x_pos, y_pos) if self.sliding_button is not None: self.sliding_button.set_relative_position( self.sliding_rect_position) self.sliding_button.set_dimensions( (self.background_rect.width, scroll_bar_height)) self.sliding_button.set_hold_range( (100, self.background_rect.height))
def rebuild(self): """ Rebuild anything that might need rebuilding. """ relative_background_rect = pygame.Rect( (self.border_width + self.shadow_width, self.border_width + self.shadow_width), (self.rect.width - (2 * self.shadow_width) - (2 * self.border_width), self.rect.height - (2 * self.shadow_width) - (2 * self.border_width))) self.background_rect = pygame.Rect( (relative_background_rect.x + self.relative_rect.x, relative_background_rect.y + self.relative_rect.y), relative_background_rect.size) theming_parameters = { 'normal_bg': self.background_colour, 'normal_border': self.border_colour, 'border_width': self.border_width, 'shadow_width': self.shadow_width, 'shape_corner_radius': self.shape_corner_radius } if self.shape_type == 'rectangle': self.drawable_shape = RectDrawableShape(self.rect, theming_parameters, ['normal'], self.ui_manager) elif self.shape_type == 'rounded_rectangle': self.drawable_shape = RoundedRectangleShape( self.rect, theming_parameters, ['normal'], self.ui_manager) self.image = self.drawable_shape.get_surface('normal') # Things below here depend on theme data so need to be updated on a rebuild self.scrollable_width = self.background_rect.width - ( 3 * self.button_width) self.right_limit_position = self.scrollable_width self.scroll_position = self.scrollable_width / 2 if self.sliding_button is not None: sliding_x_pos = self.background_rect.x + self.background_rect.width / 2 - self.button_width / 2 self.sliding_button.set_relative_position( (sliding_x_pos, self.background_rect.y)) self.sliding_button.set_dimensions( (self.button_width, self.background_rect.height)) self.sliding_button.set_hold_range( (self.background_rect.width, 100)) self.set_current_value(self.current_value) if self.left_button is not None: self.left_button.set_relative_position( self.background_rect.topleft), self.left_button.set_dimensions( (self.button_width, self.background_rect.height)) if self.right_button is not None: self.right_button.set_relative_position( (self.background_rect.x + self.background_rect.width - self.button_width, self.background_rect.y)), self.right_button.set_dimensions( (self.button_width, self.background_rect.height))