def test_set_relative_position(self, _init_pygame, default_ui_manager, _display_surface_return_none): test_container = UIContainer(relative_rect=pygame.Rect(50, 50, 300, 250), manager=default_ui_manager) scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(80, 100, 30, 200), visible_percentage=0.25, manager=default_ui_manager, container=test_container) scroll_bar.set_relative_position((50, 50)) # try to click on the scroll bar's top button default_ui_manager.process_events(pygame.event.Event(pygame.MOUSEBUTTONDOWN, {'button': 1, 'pos': (115, 105)})) # if we successfully clicked on the moved scroll bar then this button should be True assert scroll_bar.top_button.held is True default_ui_manager.process_events(pygame.event.Event(pygame.MOUSEBUTTONDOWN, {'button': 1, 'pos': (115, 295)})) # if we successfully clicked on the moved scroll bar then this button should be True assert scroll_bar.bottom_button.held is True default_ui_manager.process_events(pygame.event.Event(pygame.MOUSEBUTTONDOWN, {'button': 1, 'pos': (115, 150)})) # if we successfully clicked on the moved scroll bar then this button should be True assert scroll_bar.sliding_button.held is True
def test_creation(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect( 100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) assert scroll_bar.image is not None
def test_show_hide_rendering(self, _init_pygame, default_ui_manager, _display_surface_return_none): resolution = (400, 400) empty_surface = pygame.Surface(resolution) empty_surface.fill(pygame.Color(0, 0, 0)) surface = empty_surface.copy() manager = UIManager(resolution) scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 400, 400), visible_percentage=0.25, manager=manager, visible=0) manager.update(0.01) manager.draw_ui(surface) assert compare_surfaces(empty_surface, surface) surface.fill(pygame.Color(0, 0, 0)) scroll_bar.show() manager.update(0.01) manager.draw_ui(surface) assert not compare_surfaces(empty_surface, surface) surface.fill(pygame.Color(0, 0, 0)) scroll_bar.hide() manager.update(0.01) manager.draw_ui(surface) assert compare_surfaces(empty_surface, surface)
def test_redraw_scroll_bar(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) scroll_bar.redraw_scrollbar() assert scroll_bar.sliding_button is not None
def test_rebuild(self, _init_pygame, default_ui_manager): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect( 100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) scroll_bar.rebuild() assert scroll_bar.image is not None
def test_reset_scroll_position(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) scroll_bar.reset_scroll_position() assert scroll_bar.scroll_position == 0.0 and scroll_bar.start_percentage == 0.0
def test_process_event(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) scroll_bar.hovered = True assert scroll_bar.process_event(pygame.event.Event(pygame.MOUSEWHEEL, {'y': 0.5})) is True assert scroll_bar.process_event(pygame.event.Event(pygame.MOUSEWHEEL, {'y': -0.5})) is True
def test_check_has_moved_recently(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) # move the scroll bar a bit scroll_bar.bottom_button.held = True scroll_bar.update(0.2) assert scroll_bar.check_has_moved_recently() is True
def test_rebuild_from_theme_data_bad_values(self, _init_pygame, _display_surface_return_none): manager = UIManager((800, 600), os.path.join("tests", "data", "themes", "ui_vertical_scroll_bar_bad_values.json")) scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150), visible_percentage=1.0, manager=manager) assert scroll_bar.image is not None
def test_kill(self, _init_pygame, default_ui_manager): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect( 100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) # should kill everything scroll_bar.kill() assert scroll_bar.alive() is False and scroll_bar.sliding_button.alive( ) is False
def test_rebuild_from_theme_data_non_default(self, _init_pygame): manager = UIManager( (800, 600), os.path.join("tests", "data", "themes", "ui_vertical_scroll_bar_non_default.json")) scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect( 100, 100, 30, 150), visible_percentage=0.1, manager=manager) assert scroll_bar.image is not None
def test_last_focus_vert_scrollbar(self, _init_pygame, default_ui_manager): test_scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150), visible_percentage=0.5, manager=default_ui_manager) default_ui_manager.select_focus_element(test_scroll_bar) found_bar = test_scroll_bar is default_ui_manager.get_last_focused_vert_scrollbar() default_ui_manager.clear_last_focused_from_vert_scrollbar(test_scroll_bar) no_last_focused_scroll_bar = default_ui_manager.get_last_focused_vert_scrollbar() is None assert found_bar is True and no_last_focused_scroll_bar is True
def test_set_dimensions(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(0, 100, 30, 200), visible_percentage=0.25, manager=default_ui_manager) scroll_bar.set_dimensions((60, 100)) # try to click on the slider default_ui_manager.process_events(pygame.event.Event(pygame.MOUSEBUTTONDOWN, {'button': 1, 'pos': (40, 195)})) # if we successfully clicked on the moved slider then this button should be True assert scroll_bar.bottom_button.held is True
def test_set_visible_percentage(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) scroll_bar.start_percentage = 0.9 scroll_bar.set_visible_percentage(0.2) assert scroll_bar.visible_percentage == 0.2 scroll_bar.set_visible_percentage(-0.2) assert scroll_bar.visible_percentage == 0.0 scroll_bar.set_visible_percentage(1.9) assert scroll_bar.visible_percentage == 1.0
def test_check_update_buttons(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) # scroll down a bit then up again to exercise update scroll_bar.bottom_button.held = True scroll_bar.update(0.3) scroll_bar.bottom_button.held = False scroll_bar.top_button.held = True scroll_bar.update(0.3) assert scroll_bar.check_has_moved_recently() is True
def test_check_update_sliding_bar(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(0, 0, 30, 150), visible_percentage=0.7, manager=default_ui_manager) # scroll down a bit then up again to exercise update default_ui_manager.mouse_position = (15, 100) scroll_bar.sliding_button.held = True scroll_bar.update(0.3) assert scroll_bar.grabbed_slider is True scroll_bar.sliding_button.held = False scroll_bar.update(0.3) assert scroll_bar.grabbed_slider is False
def test_process_event(self, _init_pygame, default_ui_manager): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect( 100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) scroll_bar.select() assert scroll_bar.process_event( pygame.event.Event(pygame.MOUSEWHEEL, {'y': 0.5})) is True assert scroll_bar.process_event( pygame.event.Event(pygame.MOUSEWHEEL, {'y': -0.5})) is True del pygame.MOUSEWHEEL scroll_bar.process_event( pygame.event.Event(pygame.MOUSEBUTTONDOWN, {'y': -0.5})) assert pygame.MOUSEWHEEL == -1
def test_hide(self, _init_pygame, default_ui_manager, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 0, 200, 30), visible_percentage=0.25, manager=default_ui_manager) assert scroll_bar.visible == 1 assert scroll_bar.button_container.visible == 1 assert scroll_bar.sliding_button.visible == 1 assert scroll_bar.top_button.visible == 1 assert scroll_bar.bottom_button.visible == 1 scroll_bar.hide() assert scroll_bar.visible == 0 assert scroll_bar.button_container.visible == 0 assert scroll_bar.sliding_button.visible == 0 assert scroll_bar.top_button.visible == 0 assert scroll_bar.bottom_button.visible == 0
def test_kill(self, _init_pygame, default_ui_manager: IUIManagerInterface, _display_surface_return_none): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(100, 100, 30, 150), visible_percentage=0.7, manager=default_ui_manager) assert len(default_ui_manager.get_root_container().elements) == 2 assert len(default_ui_manager.get_sprite_group().sprites()) == 6 scroll_bar_sprites = [default_ui_manager.get_root_container(), scroll_bar, scroll_bar.button_container, scroll_bar.top_button, scroll_bar.bottom_button, scroll_bar.sliding_button] assert default_ui_manager.get_sprite_group().sprites() == scroll_bar_sprites scroll_bar.kill() assert len(default_ui_manager.get_root_container().elements) == 0 assert len(default_ui_manager.get_sprite_group().sprites()) == 1 empty_sprites = [default_ui_manager.get_root_container()] assert default_ui_manager.get_sprite_group().sprites() == empty_sprites
def test_disable(self, _init_pygame: None, default_ui_manager: UIManager, _display_surface_return_none: None): scroll_bar = UIVerticalScrollBar(relative_rect=pygame.Rect(0, 100, 30, 200), visible_percentage=0.25, manager=default_ui_manager) scroll_bar.disable() # process a mouse button down event scroll_bar.bottom_button.process_event( pygame.event.Event(pygame.MOUSEBUTTONDOWN, {'button': 1, 'pos': scroll_bar.bottom_button.rect.center})) scroll_bar.update(0.1) # process a mouse button up event scroll_bar.bottom_button.process_event( pygame.event.Event(pygame.MOUSEBUTTONUP, {'button': 1, 'pos': scroll_bar.bottom_button.rect.center})) assert scroll_bar.scroll_position == 0.0 and scroll_bar.is_enabled is False
def set_item_list(self, new_item_list: Union[List[str], List[Tuple[str, str]]]): """ Set a new string list (or tuple of strings & ids list) as the item list for this selection list. This will change what is displayed in the list. Tuples should be arranged like so: (list_text, object_ID) - list_text: displayed in the UI - object_ID: used for theming and events :param new_item_list: The new list to switch to. Can be a list of strings or tuples. """ self._raw_item_list = new_item_list self.item_list = [] # type: List[Dict] for new_item in new_item_list: if isinstance(new_item, str): new_item_list_item = { 'text': new_item, 'button_element': None, 'selected': False, 'object_id': '#item_list_item' } elif isinstance(new_item, tuple): new_item_list_item = { 'text': new_item[0], 'button_element': None, 'selected': False, 'object_id': new_item[1] } else: raise ValueError('Invalid item list') self.item_list.append(new_item_list_item) self.total_height_of_list = self.list_item_height * len(self.item_list) self.lowest_list_pos = ( self.total_height_of_list - self.list_and_scroll_bar_container.relative_rect.height) inner_visible_area_height = self.list_and_scroll_bar_container.relative_rect.height if self.total_height_of_list > inner_visible_area_height: # we need a scroll bar self.current_scroll_bar_width = self.scroll_bar_width percentage_visible = inner_visible_area_height / max( self.total_height_of_list, 1) if self.scroll_bar is not None: self.scroll_bar.reset_scroll_position() self.scroll_bar.set_visible_percentage(percentage_visible) self.scroll_bar.start_percentage = 0 else: self.scroll_bar = UIVerticalScrollBar( pygame.Rect(-self.scroll_bar_width, 0, self.scroll_bar_width, inner_visible_area_height), visible_percentage=percentage_visible, manager=self.ui_manager, parent_element=self, container=self.list_and_scroll_bar_container, anchors={ 'left': 'right', 'right': 'right', 'top': 'top', 'bottom': 'bottom' }) self.join_focus_sets(self.scroll_bar) else: if self.scroll_bar is not None: self.scroll_bar.kill() self.scroll_bar = None self.current_scroll_bar_width = 0 # create button list container if self.item_list_container is not None: self.item_list_container.clear() if (self.item_list_container.relative_rect.width != (self.list_and_scroll_bar_container.relative_rect.width - self.current_scroll_bar_width)): container_dimensions = ( self.list_and_scroll_bar_container.relative_rect.width - self.current_scroll_bar_width, self.list_and_scroll_bar_container.relative_rect.height) self.item_list_container.set_dimensions(container_dimensions) else: self.item_list_container = UIContainer( pygame.Rect( 0, 0, self.list_and_scroll_bar_container.relative_rect.width - self.current_scroll_bar_width, self.list_and_scroll_bar_container.relative_rect.height), manager=self.ui_manager, starting_height=0, parent_element=self, container=self.list_and_scroll_bar_container, object_id='#item_list_container', anchors={ 'left': 'left', 'right': 'right', 'top': 'top', 'bottom': 'bottom' }) self.join_focus_sets(self.item_list_container) item_y_height = 0 for item in self.item_list: if item_y_height <= self.item_list_container.relative_rect.height: button_rect = pygame.Rect( 0, item_y_height, self.item_list_container.relative_rect.width, self.list_item_height) item['button_element'] = UIButton( relative_rect=button_rect, text=item['text'], manager=self.ui_manager, parent_element=self, container=self.item_list_container, object_id=ObjectID(object_id=item['object_id'], class_id='@selection_list_item'), allow_double_clicks=self.allow_double_clicks, anchors={ 'left': 'left', 'right': 'right', 'top': 'top', 'bottom': 'top' }) self.join_focus_sets(item['button_element']) item_y_height += self.list_item_height else: break
def _sort_out_element_container_scroll_bars(self): """ This creates, re-sizes or removes the scrollbars after resizing, but not after the scroll bar has been moved. Instead it tries to keep the scrollbars in the same approximate position they were in before resizing """ self._check_scroll_bars_and_adjust() need_horiz_scroll_bar, need_vert_scroll_bar = self._check_scroll_bars_and_adjust() if need_vert_scroll_bar: vis_percent = self._view_container.rect.height / self.scrolling_height if self.vert_scroll_bar is None: self.scroll_bar_width = 20 scroll_bar_rect = pygame.Rect(-self.scroll_bar_width, 0, self.scroll_bar_width, self._view_container.rect.height) self.vert_scroll_bar = UIVerticalScrollBar(relative_rect=scroll_bar_rect, visible_percentage=vis_percent, manager=self.ui_manager, container=self._root_container, parent_element=self, anchors={'left': 'right', 'right': 'right', 'top': 'top', 'bottom': 'bottom'}) else: start_percent = ((self._view_container.rect.top - self.scrollable_container.rect.top) / self.scrolling_height) self.vert_scroll_bar.start_percentage = start_percent self.vert_scroll_bar.set_visible_percentage(vis_percent) self.vert_scroll_bar.set_dimensions((self.scroll_bar_width, self._view_container.rect.height)) else: self._remove_vert_scrollbar() if need_horiz_scroll_bar: vis_percent = self._view_container.rect.width / self.scrolling_width if self.horiz_scroll_bar is None: self.scroll_bar_height = 20 scroll_bar_rect = pygame.Rect(0, -self.scroll_bar_height, self._view_container.rect.width, self.scroll_bar_height) self.horiz_scroll_bar = UIHorizontalScrollBar(relative_rect=scroll_bar_rect, visible_percentage=vis_percent, manager=self.ui_manager, container=self._root_container, parent_element=self, anchors={'left': 'left', 'right': 'right', 'top': 'bottom', 'bottom': 'bottom'}) else: start_percent = ((self._view_container.rect.left - self.scrollable_container.rect.left) / self.scrolling_width) self.horiz_scroll_bar.start_percentage = start_percent self.horiz_scroll_bar.set_visible_percentage(vis_percent) self.horiz_scroll_bar.set_dimensions((self._view_container.rect.width, self.scroll_bar_height)) else: self._remove_horiz_scrollbar()
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 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)