From 3decc2fe995565d54d17b25c841e206117c1a9cd Mon Sep 17 00:00:00 2001 From: Peter Badida Date: Thu, 5 Jan 2017 01:48:09 +0100 Subject: [PATCH] Add is_shortened to Label (#4858) Add is_shortened to Label --- kivy/core/text/__init__.py | 10 +++++ kivy/core/text/markup.py | 92 +++++++++++++++++++++++++++++--------- kivy/uix/label.py | 12 +++++ 3 files changed, 92 insertions(+), 22 deletions(-) diff --git a/kivy/core/text/__init__.py b/kivy/core/text/__init__.py index 975aab1fd..2af28b619 100644 --- a/kivy/core/text/__init__.py +++ b/kivy/core/text/__init__.py @@ -217,6 +217,7 @@ class LabelBase(object): self.options = options self.texture = None + self.is_shortened = False self.resolve_font_name() @staticmethod @@ -395,6 +396,7 @@ class LabelBase(object): dir = opts['shorten_from'][0] elps = textwidth('...')[0] if elps > uw: + self.is_shortened = True if textwidth('..')[0] <= uw: return '..' else: @@ -412,6 +414,7 @@ class LabelBase(object): l1 = textwidth(text[:e1])[0] l2 = textwidth(text[s2 + 1:])[0] if e1 == -1 or l1 + l2 > uw: + self.is_shortened = True if len(c): opts['split_str'] = '' res = self.shorten(text, margin) @@ -424,6 +427,7 @@ class LabelBase(object): # both word fits, and there's at least on split_str if s2 == e1: # there's only on split_str + self.is_shortened = True return chr('{0}...{1}').format(text[:e1], text[s2 + 1:]) # both the first and last word fits, and they start/end at diff pos @@ -459,6 +463,7 @@ class LabelBase(object): l1 = textwidth(text[:max(0, e1)])[0] # if split_str if s2 == -1 or l2 + l1 > uw: + self.is_shortened = True if len(c): opts['split_str'] = '' res = self.shorten(text, margin) @@ -469,6 +474,7 @@ class LabelBase(object): # both word fits, and there's at least on split_str if s2 == e1: # there's only on split_str + self.is_shortened = True return chr('{0}...{1}').format(text[:e1], text[s2 + 1:]) # both the first and last word fits, and they start/end at diff pos @@ -479,6 +485,7 @@ class LabelBase(object): break ss2 = f_rev(0, s2 - offset) + self.is_shortened = True return chr('{0}...{1}').format(text[:e1], text[s2 + 1:]) def _default_line_options(self, lines): @@ -603,8 +610,11 @@ class LabelBase(object): text = self.text if strip: text = text.strip() + + self.is_shortened = False if uw is not None and options['shorten']: text = self.shorten(text) + self._cached_lines = lines = [] if not text: return 0, 0 diff --git a/kivy/core/text/markup.py b/kivy/core/text/markup.py index bd89ceb17..3a78f741b 100644 --- a/kivy/core/text/markup.py +++ b/kivy/core/text/markup.py @@ -236,16 +236,25 @@ class MarkupLabel(MarkupLabelBase): opts = copy(options) extents = self.get_cached_extents() opts['space_width'] = extents(' ')[0] - w, h, clipped = layout_text(item, lines, (w, h), - (uw_temp, uhh), opts, extents, True, False) + w, h, clipped = layout_text( + item, lines, (w, h), (uw_temp, uhh), + opts, extents, + append_down=True, + complete=False + ) if len(lines): # remove any trailing spaces from the last line old_opts = self.options self.options = copy(opts) - w, h, clipped = layout_text('', lines, (w, h), (uw_temp, uhh), - self.options, self.get_cached_extents(), True, True) + w, h, clipped = layout_text( + '', lines, (w, h), (uw_temp, uhh), + self.options, self.get_cached_extents(), + append_down=True, + complete=True + ) self.options = old_opts + self.is_shortened = False if shorten: options['_ref'] = None # no refs for you! options['_anchor'] = None @@ -351,10 +360,18 @@ class MarkupLabel(MarkupLabelBase): # split that word into left/right and push right till uww l_text = empty.join(parts[w][:idxs[w][-1]]) r_text = empty.join(parts[w][idxs[w][-1]:]) - left = LayoutWord(word.options, - self.get_extents(l_text)[0], word.lh, l_text) - right = LayoutWord(word.options, - self.get_extents(r_text)[0], word.lh, r_text) + left = LayoutWord( + word.options, + self.get_extents(l_text)[0], + word.lh, + l_text + ) + right = LayoutWord( + word.options, + self.get_extents(r_text)[0], + word.lh, + r_text + ) left.lw = max(left.lw, word.lw + diff - right.lw) self.options = old_opts @@ -624,8 +641,13 @@ class MarkupLabel(MarkupLabelBase): lw = sum([word.lw for word in line]) if lw <= uw: lh = max([word.lh for word in line] + [0]) * line_height - return lw + 2 * xpad, lh + 2 * ypad, [LayoutLine(0, 0, - lw, lh, 1, 0, line)] + self.is_shortened = False + return ( + lw + 2 * xpad, + lh + 2 * ypad, + [LayoutLine(0, 0, lw, lh, 1, 0, line)] + ) + elps_opts = copy(old_opts) if 'ellipsis_options' in old_opts: @@ -636,16 +658,27 @@ class MarkupLabel(MarkupLabelBase): # find the size of ellipsis that'll fit elps_s = textwidth('...') if elps_s[0] > uw: # even ellipsis didn't fit... + self.is_shortened = True s = textwidth('..') if s[0] <= uw: - return (s[0] + 2 * xpad, s[1] * line_height + 2 * ypad, - [LayoutLine(0, 0, s[0], s[1], 1, 0, [LayoutWord(old_opts, - s[0], s[1], '..')])]) + return ( + s[0] + 2 * xpad, + s[1] * line_height + 2 * ypad, + [LayoutLine( + 0, 0, s[0], s[1], 1, 0, + [LayoutWord(old_opts, s[0], s[1], '..')])] + ) + else: s = textwidth('.') - return (s[0] + 2 * xpad, s[1] * line_height + 2 * ypad, - [LayoutLine(0, 0, s[0], s[1], 1, 0, [LayoutWord(old_opts, - s[0], s[1], '.')])]) + return ( + s[0] + 2 * xpad, + s[1] * line_height + 2 * ypad, + [LayoutLine( + 0, 0, s[0], s[1], 1, 0, + [LayoutWord(old_opts, s[0], s[1], '.')])] + ) + elps = LayoutWord(elps_opts, elps_s[0], elps_s[1], '...') uw -= elps_s[0] # Restore old opts @@ -664,6 +697,7 @@ class MarkupLabel(MarkupLabelBase): old_opts['split_str'] = '' res = self.shorten_post(lines, w, h, margin) self.options['split_str'] = c + self.is_shortened = True return res line1 = line[:w1] last_word = line[w1] @@ -679,8 +713,12 @@ class MarkupLabel(MarkupLabelBase): lw = sum([word.lw for word in line1]) lh = max([word.lh for word in line1]) * line_height self.options = old_opts - return lw + 2 * xpad, lh + 2 * ypad, [LayoutLine(0, 0, - lw, lh, 1, 0, line1)] + self.is_shortened = True + return ( + lw + 2 * xpad, + lh + 2 * ypad, + [LayoutLine(0, 0, lw, lh, 1, 0, line1)] + ) # now we know that both the first and last word fit, and that # there's at least one instances of the split_str in the line @@ -723,6 +761,7 @@ class MarkupLabel(MarkupLabelBase): old_opts['split_str'] = '' res = self.shorten_post(lines, w, h, margin) self.options['split_str'] = c + self.is_shortened = True return res first_word = line[w2] first_text = first_word.text[s2 + 1:] @@ -737,8 +776,12 @@ class MarkupLabel(MarkupLabelBase): lw = sum([word.lw for word in line1]) lh = max([word.lh for word in line1]) * line_height self.options = old_opts - return lw + 2 * xpad, lh + 2 * ypad, [LayoutLine(0, 0, - lw, lh, 1, 0, line1)] + self.is_shortened = True + return ( + lw + 2 * xpad, + lh + 2 * ypad, + [LayoutLine(0, 0, lw, lh, 1, 0, line1)] + ) # now we know that both the first and last word fit, and that # there's at least one instances of the split_str in the line @@ -775,5 +818,10 @@ class MarkupLabel(MarkupLabelBase): lw = sum([word.lw for word in line1]) lh = max([word.lh for word in line1]) * line_height self.options = old_opts - return lw + 2 * xpad, lh + 2 * ypad, [LayoutLine(0, 0, - lw, lh, 1, 0, line1)] + if uw < lw: + self.is_shortened = True + return ( + lw + 2 * xpad, + lh + 2 * ypad, + [LayoutLine(0, 0, lw, lh, 1, 0, line1)] + ) diff --git a/kivy/uix/label.py b/kivy/uix/label.py index 6b9d0a452..7d32ebedd 100644 --- a/kivy/uix/label.py +++ b/kivy/uix/label.py @@ -345,6 +345,7 @@ class Label(Widget): (self.halign == 'justify' or self.strip) and not self._label.text.strip()): self.texture_size = (0, 0) + self.is_shortened = False if mrkup: self.refs, self._label._refs = {}, {} self.anchors, self._label._anchors = {}, {} @@ -373,6 +374,7 @@ class Label(Widget): if texture is not None: self.texture = self._label.texture self.texture_size = list(self.texture.size) + self.is_shortened = self._label.is_shortened def on_touch_down(self, touch): if super(Label, self).on_touch_down(touch): @@ -736,6 +738,16 @@ class Label(Widget): defaults to `center`. ''' + is_shortened = BooleanProperty(False) + '''This property indicates if :attr:`text` was rendered with or without + shortening when :attr:`shorten` is True. + + .. versionadded:: 1.9.2 + + :attr:`is_shortened` is a :class:`~kivy.properties.BooleanProperty` and + defaults to False. + ''' + split_str = StringProperty('') '''The string used to split the :attr:`text` while shortening the string when :attr:`shorten` is True.