Add is_shortened to Label (#4858)

Add is_shortened to Label
This commit is contained in:
Peter Badida 2017-01-05 01:48:09 +01:00 committed by matham
parent 03e52a08e5
commit 3decc2fe99
3 changed files with 92 additions and 22 deletions

View File

@ -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

View File

@ -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)]
)

View File

@ -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.