Ejemplo n.º 1
0
class UpdateListbox(Listbox):
    """Listbox with a function called on selection change"""
    def _on_selection_change(self):
        self.update_func(self.list_pos)

    _list_pos = widget.call_on_change("__list_pos", _on_selection_change)
    _list = widget.call_on_change("__list", _on_selection_change)

    def __init__(self, *args, **kwargs):
        self.update_func = kwargs.pop("update_func", lambda value: None)
        super(UpdateListbox, self).__init__(*args, **kwargs)
Ejemplo n.º 2
0
class FastText(Text):
    """
       Reduces font searches by assuming a monospace font and single-line text.
    """
    text = widget.call_on_change("_text", text_changed)
    old_len = 0
    maybe_needs_refont = False
Ejemplo n.º 3
0
class UpdateEditableText(EditableText):
    def _on_text_change(self):
        self.update_func(self.text)

    _text = widget.call_on_change("__text", _on_text_change)

    def __init__(self, *args, **kwargs):
        self.update_func = kwargs.pop("update_func", lambda value: None)
        super(UpdateEditableText, self).__init__(*args, **kwargs)
Ejemplo n.º 4
0
class UpdateSlider(Slider):
    def _on_slider_move(self):
        self.update_func(self.slider_pos)

    _slider_pos = widget.call_on_change("__slider_pos", _on_slider_move)

    def __init__(self, *args, **kwargs):
        self.update_func = kwargs.pop("update_func", lambda value: None)
        super(UpdateSlider, self).__init__(*args, **kwargs)
Ejemplo n.º 5
0
class ChunkedText(Text):
    def update_text(self):
        self.text = "".join(self.chunks)

    chunks = widget.call_on_change("__chunks", update_text)

    def __init__(self, *args, **kwargs):
        chunks = kwargs.pop("chunks", ())
        super(ChunkedText, self).__init__(*args, **kwargs)

        self.chunks = chunks
Ejemplo n.º 6
0
class Text(widget.BorderedWidget):
    text = widget.call_on_change("_text", resize_redraw)
    shrink_factor = widget.call_on_change("_shrink_factor", resize_redraw)
    underline = widget.call_on_change("_underline", resize_redraw)
    wrap = widget.call_on_change("_wrap", resize_redraw)
    bold = widget.call_on_change("_bold", resize_redraw)

    align = widget.causes_redraw("_align")
    valign = widget.causes_redraw("_valign")

    color = widget.auto_reconfig("_color", "resolved", g.resolve_color_alias)
    resolved_color = widget.causes_redraw("_resolved_color")
    base_font = widget.auto_reconfig("_base_font", "resolved",
                                     g.resolve_font_alias)
    resolved_base_font = widget.call_on_change("_resolved_base_font",
                                               resize_redraw)

    text_size = widget.auto_reconfig("_text_size", "resolved",
                                     g.resolve_text_size)
    resolved_text_size = widget.causes_redraw("_resolved_text_size")

    def __init__(self,
                 parent,
                 pos,
                 size=(0, .05),
                 anchor=constants.TOP_LEFT,
                 text=None,
                 base_font=None,
                 shrink_factor=0.875,
                 color=None,
                 align=constants.CENTER,
                 valign=constants.MID,
                 underline=-1,
                 wrap=True,
                 bold=False,
                 text_size="default",
                 **kwargs):
        kwargs.setdefault("background_color", "text_background")
        kwargs.setdefault("border_color", "text_border")
        super(Text, self).__init__(parent, pos, size, anchor, **kwargs)

        self.text = text
        self.base_font = base_font or "normal"
        self.color = color or "text"
        self.shrink_factor = shrink_factor
        self.underline = underline
        self.align = align
        self.valign = valign
        self.wrap = wrap
        self.bold = bold
        self.text_size = text_size

    max_size = property(lambda self: min(
        len(self.resolved_base_font) - 1,
        convert_font_size(self._resolved_text_size)))
    font = property(lambda self: self._font)

    def pick_font(self, dimensions):
        nice_size = self.pick_font_size(dimensions, False)
        mean_size = self.pick_font_size(dimensions)

        size = max(nice_size, mean_size - convert_font_size(5))

        return self.resolved_base_font[size]

    def font_bisect(self, test_font):
        left = 0
        right = (self.max_size or len(self.resolved_base_font) - 1) + 1

        def test_size(size):
            font = self.resolved_base_font[size]
            font.set_bold(self.bold)
            result = test_font(font)
            font.set_bold(False)

            return result

        return do_bisect(left, right, test_size)

    def pick_font_size(self, dimensions, break_words=True):
        if dimensions[0]:
            width = int(dimensions[0] * self.shrink_factor)
        else:
            width = None
        height = int(dimensions[1] * self.shrink_factor)

        basic_line_count = self.text.count("\n") + 1

        def test_size(test_font):
            too_wide = False
            if width:
                if self.wrap:
                    try:
                        lines = split_wrap(self.text, test_font, width,
                                           break_words)
                    except WrapError:
                        lines = []
                        too_wide = True
                else:
                    lines = split_wrap(self.text, test_font, 0)
                    for line in lines:
                        if test_font.size(line)[0] > width:
                            too_wide = True
                            break
                line_count = len(lines)
            else:
                line_count = basic_line_count

            too_tall = (test_font.get_linesize() * line_count) > height

            return not (too_tall or too_wide)

        return self.font_bisect(test_size)

    def size_using_font(self, font, width=0):
        #Calculate the size of the text block.
        raw_width, raw_height = size_of_block(self.text, font, width)

        #Adjust for shrink_factor and borders.
        width = int(raw_width / self.shrink_factor) + 4
        height = int(raw_height / self.shrink_factor) + 4

        return width, height

    def calc_text_size(self, initial_dimensions):
        if not (initial_dimensions[0] and initial_dimensions[1]):
            if not self.max_size:
                raise ValueError("No font size given, but a dimension is 0.")

            max_font = self.resolved_base_font[self.max_size]
            if initial_dimensions[0] == initial_dimensions[1] == 0:
                # No size specified, use the natural size of the max font.
                width, height = self.size_using_font(max_font)
                return (width, height), max_font
            elif not initial_dimensions[1]:
                # Width specified, use the size of the max font, word-wrapped.
                text_width = int(
                    (initial_dimensions[0] - 4) * self.shrink_factor)
                width, height = self.size_using_font(max_font,
                                                     width=text_width)
                return (initial_dimensions[0], height), max_font
            else:
                # Height specified.  Try the natural size of the max font.
                width, height = self.size_using_font(max_font)

                if height <= initial_dimensions[1]:
                    return (width, initial_dimensions[1]), max_font
                else:
                    # Too tall.  Run a binary search to find the largest font
                    # size that fits.
                    def test_size(font):
                        width, raw_height = size_of_block(self.text, font)
                        height = int(raw_height / self.shrink_factor) + 4
                        return height <= initial_dimensions[1]

                    font_size = self.font_bisect(test_size)
                    font = self.resolved_base_font[font_size]
                    width, height = self.size_using_font(font)

                    return (width, initial_dimensions[1]), font
        else:
            # Both sizes specified.  Search for a usable font size.
            return initial_dimensions, self.pick_font(initial_dimensions)

    def _calc_size(self):
        base_size = list(super(Text, self)._calc_size())

        if self.text is None:
            return tuple(base_size)
        else:
            # Determine the true size and font of the text area.
            text_size, font = self.calc_text_size(base_size)
            self._font = font
            return tuple(text_size)

    def redraw(self):
        super(Text, self).redraw()

        if self.text != None:
            self.print_text()

    def print_text(self):
        # Mark the character to be underlined (if any).
        no_underline = [self.resolved_color, None, False]
        underline = [self.resolved_color, None, True]
        styles = [no_underline + [0]]
        if 0 <= self.underline < len(self.text):
            styles.insert(0, underline + [self.underline + 1])
            if self.underline != 0:
                styles.insert(0, no_underline + [self.underline])

        self.font.set_bold(self.bold)
        # Print the string itself.
        print_string(self.surface, self.text, (3, 2), self.font, styles,
                     self.align, self.valign, self.real_size, self.wrap)
        self.font.set_bold(False)