예제 #1
0
    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
예제 #2
0
 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
예제 #3
0
    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)
예제 #4
0
 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
예제 #6
0
 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
예제 #7
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
예제 #8
0
    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
예제 #9
0
    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
예제 #12
0
    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
예제 #13
0
    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
예제 #14
0
    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
예제 #15
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
예제 #16
0
    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
예제 #18
0
    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
예제 #19
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
예제 #20
0
    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()
예제 #23
0
    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
예제 #24
0
    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)