コード例 #1
0
 def _rebuild_shadow(self, new_image, text_render_rect):
     shadow_text_render = render_white_text_alpha_black_bg(self.font, self.text)
     apply_colour_to_surface(self.text_shadow_colour, shadow_text_render)
     for y_pos in range(-self.text_shadow_size, self.text_shadow_size + 1):
         shadow_text_rect = pygame.Rect((text_render_rect.x + self.text_shadow_offset[0],
                                         text_render_rect.y + self.text_shadow_offset[1]
                                         + y_pos),
                                        text_render_rect.size)
         basic_blit(new_image, shadow_text_render, shadow_text_rect)
     for x_pos in range(-self.text_shadow_size, self.text_shadow_size + 1):
         shadow_text_rect = pygame.Rect((text_render_rect.x + self.text_shadow_offset[0]
                                         + x_pos,
                                         text_render_rect.y + self.text_shadow_offset[1]),
                                        text_render_rect.size)
         basic_blit(new_image, shadow_text_render, shadow_text_rect)
     for x_and_y in range(-self.text_shadow_size, self.text_shadow_size + 1):
         shadow_text_rect = pygame.Rect(
             (text_render_rect.x + self.text_shadow_offset[0] + x_and_y,
              text_render_rect.y + self.text_shadow_offset[1] + x_and_y),
             text_render_rect.size)
         basic_blit(new_image, shadow_text_render, shadow_text_rect)
     for x_and_y in range(-self.text_shadow_size, self.text_shadow_size + 1):
         shadow_text_rect = pygame.Rect(
             (text_render_rect.x + self.text_shadow_offset[0] - x_and_y,
              text_render_rect.y + self.text_shadow_offset[1] + x_and_y),
             text_render_rect.size)
         basic_blit(new_image, shadow_text_render, shadow_text_rect)
コード例 #2
0
    def redraw(self):
        """
        Renders the 'chunk' text to the 'rendered_chunk' surface.

        """
        if self.style.underline or (self.is_hovered and self.link_hover_underline) or \
                (self.link_normal_underline and not self.is_hovered):
            self.font.set_underline(True)

        if len(self.chunk) > 0:
            if isinstance(self.colour, ColourGradient):
                self.rendered_chunk = render_white_text_alpha_black_bg(self.font, self.chunk)
                self.colour.apply_gradient_to_surface(self.rendered_chunk)
            else:
                if isinstance(self.bg_colour, ColourGradient) or self.bg_colour.a != 255:
                    self.rendered_chunk = render_white_text_alpha_black_bg(self.font, self.chunk)
                    apply_colour_to_surface(self.colour, self.rendered_chunk)
                else:
                    self.rendered_chunk = self.font.render(self.chunk,
                                                           True,
                                                           self.colour,
                                                           self.bg_colour).convert_alpha()
        else:
            self.rendered_chunk = pygame.surface.Surface((0, 0),
                                                         flags=pygame.SRCALPHA,
                                                         depth=32)

        self.font.set_underline(False)

        new_metrics = self.font.metrics(self.chunk)
        new_ascent = self.font.get_ascent()
        new_width = self.font.size(self.chunk)[0]
        new_height = self.font.size(self.chunk)[1]
        new_advance = sum(new_metrics[i][4] for i in range(len(self.chunk))
                          if len(new_metrics[i]) == 5)
        if (new_ascent == self.ascent and new_width == self.width and
                new_height == self.height and new_advance == self.advance):
            self.metrics_changed_after_redraw = False
        else:
            self.metrics_changed_after_redraw = True
            self.ascent = new_ascent
            self.width = new_width
            self.height = new_height
            self.advance = new_advance
            self.rect = pygame.Rect(self.position, (self.width, self.height))
コード例 #3
0
 def _redraw_unselected_text(self):
     """
     Redraw text where none has been selected by a user.
     """
     self.text_surface = render_white_text_alpha_black_bg(font=self.font,
                                                          text=self.text)
     if self.is_enabled:
         if isinstance(self.text_colour, ColourGradient):
             self.text_colour.apply_gradient_to_surface(self.text_surface)
         else:
             apply_colour_to_surface(self.text_colour, self.text_surface)
     else:
         if isinstance(self.disabled_text_colour, ColourGradient):
             self.disabled_text_colour.apply_gradient_to_surface(
                 self.text_surface)
         else:
             apply_colour_to_surface(self.disabled_text_colour,
                                     self.text_surface)
コード例 #4
0
    def _draw_text_with_grad_or_col(
        self, text: str, col_or_grad: Union[ColourGradient, pygame.Color]
    ) -> pygame.surface.Surface:
        """
        Draw text to a surface using either a colour or gradient.

        :param text: The text to render.
        :param col_or_grad: A colour or a colour gradient.

        :return: A surface with the text on.

        """
        text_surface = render_white_text_alpha_black_bg(font=self.font,
                                                        text=text)
        if isinstance(col_or_grad, ColourGradient):
            col_or_grad.apply_gradient_to_surface(text_surface)
        else:
            apply_colour_to_surface(col_or_grad, text_surface)
        return text_surface
コード例 #5
0
    def set_visual_debug_mode(self, activate_mode: bool):
        """
        Enables a debug mode for the element which displays layer information on top of it in
        a tiny font.

        :param activate_mode: True or False to enable or disable the mode.

        """
        if activate_mode:
            default_font = self.ui_manager.get_theme().get_font_dictionary(
            ).get_default_font()
            layer_text_render = render_white_text_alpha_black_bg(
                default_font, "UI Layer: " + str(self._layer))

            if self.image is not None:
                self.pre_debug_image = self.image.copy()
                # check if our surface is big enough to hold the debug info,
                # if not make a new, bigger copy
                make_new_larger_surface = False
                surf_width = self.image.get_width()
                surf_height = self.image.get_height()
                if self.image.get_width() < layer_text_render.get_width():
                    make_new_larger_surface = True
                    surf_width = layer_text_render.get_width()
                if self.image.get_height() < layer_text_render.get_height():
                    make_new_larger_surface = True
                    surf_height = layer_text_render.get_height()

                if make_new_larger_surface:
                    new_surface = pygame.surface.Surface(
                        (surf_width, surf_height),
                        flags=pygame.SRCALPHA,
                        depth=32)
                    basic_blit(new_surface, self.image, (0, 0))
                    self.set_image(new_surface)
                basic_blit(self.image, layer_text_render, (0, 0))
            else:
                self.set_image(layer_text_render)
            self._visual_debug_mode = True
        else:
            self.rebuild()
            self._visual_debug_mode = False
コード例 #6
0
    def rebuild(self):
        """
        Re-render the text to the label's underlying sprite image. This allows us to change what
        the displayed text is or remake it with different theming (if the theming has changed).
        """

        text_size = self.font.size(self.text)
        if text_size[1] > self.relative_rect.height or text_size[0] > self.relative_rect.width:
            width_overlap = self.relative_rect.width - text_size[0]
            height_overlap = self.relative_rect.height - text_size[1]
            warn_text = ('Label Rect is too small for text: '
                         '' + self.text + ' - size diff: ' + str((width_overlap, height_overlap)))
            warnings.warn(warn_text, UserWarning)

        new_image = pygame.surface.Surface(self.relative_rect.size,
                                           flags=pygame.SRCALPHA,
                                           depth=32)

        if isinstance(self.bg_colour, ColourGradient):
            new_image.fill(pygame.Color('#FFFFFFFF'))
            self.bg_colour.apply_gradient_to_surface(new_image)
            text_render = render_white_text_alpha_black_bg(self.font, self.text)
            if self.is_enabled:
                if isinstance(self.text_colour, ColourGradient):
                    self.text_colour.apply_gradient_to_surface(text_render)
                else:
                    apply_colour_to_surface(self.text_colour, text_render)
            else:
                if isinstance(self.disabled_text_colour, ColourGradient):
                    self.disabled_text_colour.apply_gradient_to_surface(text_render)
                else:
                    apply_colour_to_surface(self.disabled_text_colour, text_render)
        else:
            new_image.fill(self.bg_colour)
            if self.is_enabled:
                if isinstance(self.text_colour, ColourGradient):
                    text_render = render_white_text_alpha_black_bg(self.font, self.text)
                    self.text_colour.apply_gradient_to_surface(text_render)
                else:
                    if self.bg_colour.a != 255 or self.text_shadow:
                        text_render = render_white_text_alpha_black_bg(self.font, self.text)
                        apply_colour_to_surface(self.text_colour, text_render)
                    else:
                        text_render = self.font.render(self.text, True,
                                                       self.text_colour, self.bg_colour)
                        text_render = text_render.convert_alpha()
            else:
                if isinstance(self.disabled_text_colour, ColourGradient):
                    text_render = render_white_text_alpha_black_bg(self.font, self.text)
                    self.disabled_text_colour.apply_gradient_to_surface(text_render)
                else:
                    if self.bg_colour.a != 255 or self.text_shadow:
                        text_render = render_white_text_alpha_black_bg(self.font, self.text)
                        apply_colour_to_surface(self.disabled_text_colour, text_render)
                    else:
                        text_render = self.font.render(self.text, True,
                                                       self.disabled_text_colour, self.bg_colour)
                        text_render = text_render.convert_alpha()
        text_render_rect = text_render.get_rect(centerx=int(self.rect.width / 2),
                                                centery=int(self.rect.height / 2))

        if self.text_shadow:
            self._rebuild_shadow(new_image, text_render_rect)

        basic_blit(new_image, text_render, text_render_rect)

        self.set_image(new_image)
コード例 #7
0
    def rebuild_images_and_text(self, image_state_str: str, state_str: str,
                                text_colour_state_str: str):
        """
        Rebuilds any text or image used by a specific state in the drawable shape. Effectively
        this means adding them on top of whatever is already in the state's surface. As such it
        should generally be called last in the process of building up a finished drawable shape
        state.

        :param image_state_str: image ID of the state we are going to be adding images and text to.
        :param state_str: normal ID of the state we are going to be adding images and text to.
        :param text_colour_state_str: text ID of the state we are going to be adding images and
                                      text to.

        """
        # Draw any themed images
        if image_state_str in self.theming and self.theming[
                image_state_str] is not None:
            image_rect = self.theming[image_state_str].get_rect()
            image_rect.center = (int(self.containing_rect.width / 2),
                                 int(self.containing_rect.height / 2))
            basic_blit(self.states[state_str].surface,
                       self.theming[image_state_str], image_rect)
        # Draw any text
        if 'text' in self.theming and 'font' in self.theming and self.theming[
                'text'] is not None:
            if len(self.theming['text']
                   ) > 0 and text_colour_state_str in self.theming:
                text_surface = render_white_text_alpha_black_bg(
                    font=self.theming['font'], text=self.theming['text'])
                if isinstance(self.theming[text_colour_state_str],
                              ColourGradient):
                    self.theming[
                        text_colour_state_str].apply_gradient_to_surface(
                            text_surface)
                else:
                    apply_colour_to_surface(
                        self.theming[text_colour_state_str], text_surface)
            else:
                text_surface = None

            if 'text_shadow' in self.theming:
                text_shadow = render_white_text_alpha_black_bg(
                    font=self.theming['font'], text=self.theming['text'])
                apply_colour_to_surface(self.theming['text_shadow'],
                                        text_shadow)

                basic_blit(
                    self.states[state_str].surface, text_shadow,
                    (self.aligned_text_rect.x, self.aligned_text_rect.y + 1))
                basic_blit(
                    self.states[state_str].surface, text_shadow,
                    (self.aligned_text_rect.x, self.aligned_text_rect.y - 1))
                basic_blit(
                    self.states[state_str].surface, text_shadow,
                    (self.aligned_text_rect.x + 1, self.aligned_text_rect.y))
                basic_blit(
                    self.states[state_str].surface, text_shadow,
                    (self.aligned_text_rect.x - 1, self.aligned_text_rect.y))

            if text_surface is not None and self.aligned_text_rect is not None:
                basic_blit(self.states[state_str].surface, text_surface,
                           self.aligned_text_rect)
コード例 #8
0
    def _redraw_selected_text(self):
        """
        Redraw text where some has been selected by a user.
        """
        low_end = min(self.select_range[0], self.select_range[1])
        high_end = max(self.select_range[0], self.select_range[1])
        pre_select_area_text = self.text[:low_end]
        select_area_text = self.text[low_end:high_end]
        post_select_area_text = self.text[high_end:]
        pre_select_area_surface = None
        post_select_area_surface = None

        overall_size = self.font.size(self.text)
        advances = [
            letter_metrics[4]
            for letter_metrics in self.font.metrics(self.text)
        ]
        pre_select_width = sum(advances[:low_end])
        select_area_width = sum(advances[low_end:high_end])

        if len(pre_select_area_text) > 0:
            pre_select_area_surface = self._draw_text_with_grad_or_col(
                pre_select_area_text, self.text_colour)

        if isinstance(self.selected_bg_colour, ColourGradient):
            select_area_surface = pygame.surface.Surface(
                (select_area_width, overall_size[1]),
                flags=pygame.SRCALPHA,
                depth=32)
            select_area_surface.fill(pygame.Color('#FFFFFFFF'))
            self.selected_bg_colour.apply_gradient_to_surface(
                select_area_surface)

            alpha_text = self._draw_text_with_grad_or_col(
                select_area_text, self.selected_text_colour)

            basic_blit(select_area_surface, alpha_text, (0, 0))
        else:
            if isinstance(self.selected_text_colour, ColourGradient):
                select_area_surface = pygame.surface.Surface(
                    (select_area_width, overall_size[1]),
                    flags=pygame.SRCALPHA,
                    depth=32)
                select_area_surface.fill(self.selected_bg_colour)

                alpha_text = render_white_text_alpha_black_bg(
                    font=self.font, text=select_area_text)
                self.selected_text_colour.apply_gradient_to_surface(alpha_text)
                basic_blit(select_area_surface, alpha_text, (0, 0))

            else:
                select_area_surface = self.font.render(
                    select_area_text, True, self.selected_text_colour,
                    self.selected_bg_colour).convert_alpha()
        if len(post_select_area_text) > 0:
            post_select_area_surface = self._draw_text_with_grad_or_col(
                post_select_area_text, self.text_colour)

        self.text_surface = pygame.surface.Surface(overall_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)

        if pre_select_area_surface is not None:
            basic_blit(self.text_surface, pre_select_area_surface, (0, 0))

        basic_blit(self.text_surface, select_area_surface,
                   (pre_select_width, 0))

        if post_select_area_surface is not None:
            basic_blit(self.text_surface, post_select_area_surface,
                       (pre_select_width + select_area_width, 0))
コード例 #9
0
    def __init__(self,
                 font_size: int,
                 font_name: str,
                 chunk: str,
                 style: CharStyle,
                 colour: Union[pygame.Color, ColourGradient],
                 bg_colour: Union[pygame.Color, ColourGradient],
                 is_link: bool,
                 link_href: str,
                 link_style: CharStyle,
                 position: Tuple[int, int],
                 font_dictionary: UIFontDictionary):

        self.style = style
        self.chunk = chunk
        self.font_size = font_size
        self.font_name = font_name
        self.is_link = is_link
        self.link_href = link_href
        self.link_style = link_style

        self.font = font_dictionary.find_font(font_size, font_name,
                                              self.style.bold, self.style.italic)

        if self.is_link:
            self.normal_colour = self.link_style['link_text']
            self.hover_colour = self.link_style['link_hover']
            self.selected_colour = self.link_style['link_selected']
            self.link_normal_underline = self.link_style['link_normal_underline']
            self.link_hover_underline = self.link_style['link_hover_underline']
        else:
            self.normal_colour = colour
            self.hover_colour = None
            self.selected_colour = None
            self.link_normal_underline = False
            self.link_hover_underline = False

        self.colour = self.normal_colour
        self.bg_colour = bg_colour
        self.position = position

        self.is_hovered = False
        self.is_selected = False

        if self.style.underline or (self.is_hovered and self.link_hover_underline) or \
                (self.link_normal_underline and not self.is_hovered):
            self.font.set_underline(True)

        if len(self.chunk) > 0:
            if not isinstance(self.colour, ColourGradient):
                if isinstance(self.bg_colour, ColourGradient) or self.bg_colour.a != 255:
                    self.rendered_chunk = render_white_text_alpha_black_bg(self.font, self.chunk)
                    apply_colour_to_surface(self.colour, self.rendered_chunk)
                else:
                    self.rendered_chunk = self.font.render(self.chunk,
                                                           True,
                                                           self.colour,
                                                           self.bg_colour).convert_alpha()
            else:
                self.rendered_chunk = render_white_text_alpha_black_bg(self.font, self.chunk)
                self.colour.apply_gradient_to_surface(self.rendered_chunk)
        else:
            self.rendered_chunk = pygame.surface.Surface((0, 0),
                                                         flags=pygame.SRCALPHA,
                                                         depth=32)
        metrics = self.font.metrics(self.chunk)
        self.ascent = self.font.get_ascent()
        self.width = self.font.size(self.chunk)[0]
        self.height = self.font.size(self.chunk)[1]
        self.advance = 0
        for i in range(len(self.chunk)):
            if len(metrics[i]) == 5:
                self.advance += metrics[i][4]

        self.rect = pygame.Rect(self.position, (self.width, self.height))
        self.metrics_changed_after_redraw = False

        self.unset_underline_style()