factor text wrapping out of TooltipLabel into WrappedLabel

develop
myk002 2022-04-22 09:53:10 -07:00
parent 809f9316fd
commit ed5523152c
No known key found for this signature in database
GPG Key ID: 8A39CA0FA0C16E78
3 changed files with 62 additions and 32 deletions

@ -3864,28 +3864,43 @@ The Label widget implements the following methods:
Computes the width of the text.
TooltipLabel class
WrappedLabel class
------------------
This Label subclass represents text that you want to be able to dynamically
hide, like help text in a tooltip.
wrap. This frees you from having to pre-split long strings into multiple lines
in the Label ``text`` list.
It has the following attributes:
:text_to_wrap: The string (or a table of strings or a function that returns a
string or a table of strings) to display. The text will be autowrapped to
the width of the widget, though any existing newlines will be kept.
:indent: The number of spaces to indent the text from the left margin. The
default is ``0``.
The displayed text is refreshed and rewrapped whenever the widget bounds change.
To force a refresh (to pick up changes in the string that ``text_to_wrap``
returns, for example), all ``updateLayout()`` on this widget or on a widget that
contains this widget.
TooltipLabel class
------------------
This WrappedLabel subclass represents text that you want to be able to
dynamically hide, like help text in a tooltip.
It has the following attributes:
:tooltip: The string (or a table of strings or a function that returns a string
or a table of strings) to display. The text will be autowrapped to the
width of the widget, though any existing newlines will be kept.
:show_tooltip: Boolean or a callback; if true, the widget is visible. Defaults
to ``true``.
:indent: The number of spaces to indent the tooltip from the left margin. The
default is ``2``.
:show_tooltip: Boolean or a callback; if true, the widget is visible.
The ``text_pen`` attribute of the ``Label`` class is overridden with a default
of COLOR_GREY.
of ``COLOR_GREY`` and the ``indent`` attribute of the ``WrappedLabel`` class is
overridden with a default of ``2``.
Note that the text of the tooltip is only refreshed when the widget layout is
updated (i.e. ``updateLayout()`` is called on this widget or a widget that
contains this widget) and the tooltip needs to be rewrapped.
The text of the tooltip can be passed in the inherited ``text_to_wrap``
attribute so it can be autowrapped, or in the basic ``text`` attribute if no
wrapping is required.
HotkeyLabel class
-----------------

@ -80,7 +80,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- New string class function: ``string:escape_pattern()`` escapes regex special characters within a string
- ``widgets.Panel``: if ``autoarrange_subviews`` is set, ``Panel``\s will now automatically lay out widgets vertically according to their current height. This allows you to have widgets dynamically change height or become visible/hidden and you don't have to worry about recalculating frame layouts
- ``widgets.ResizingPanel``: new ``Panel`` subclass that automatically recalculates it's own frame height based on the size, position, and visibility of its subviews
- ``widgets.TooltipLabel``: new ``Label`` subclass that provides tooltip-like behavior
- ``widgets.WrappedLabel``: new ``Label`` subclass that provides autowrapping of text
- ``widgets.TooltipLabel``: new ``WrappedLabel`` subclass that provides tooltip-like behavior
- ``widgets.HotkeyLabel``: new ``Label`` subclass that displays and reacts to hotkeys
- ``widgets.CycleHotkeyLabel``: new ``Label`` subclass that allows users to cycle through a list of options by pressing a hotkey
- ``widgets.ToggleHotkeyLabel``: new ``CycleHotkeyLabel`` subclass that toggles between ``On`` and ``Off`` states

@ -494,41 +494,55 @@ function Label:onInput(keys)
end
------------------
-- TooltipLabel --
-- WrappedLabel --
------------------
TooltipLabel = defclass(TooltipLabel, Label)
WrappedLabel = defclass(WrappedLabel, Label)
TooltipLabel.ATTRS{
tooltip=DEFAULT_NIL,
show_tooltip=true,
indent=2,
text_pen=COLOR_GREY,
WrappedLabel.ATTRS{
text_to_wrap=DEFAULT_NIL,
indent=0,
}
function TooltipLabel:getWrappedTooltip()
local tooltip = getval(self.tooltip)
if type(tooltip) == 'table' then
tooltip = table.concat(tooltip, NEWLINE)
function WrappedLabel:getWrappedText(width)
if not self.text_to_wrap then return nil end
local text_to_wrap = getval(self.text_to_wrap)
if type(text_to_wrap) == 'table' then
text_to_wrap = table.concat(text_to_wrap, NEWLINE)
end
return tooltip:wrap(self.frame_body.width - self.indent)
end
function TooltipLabel:preUpdateLayout()
self.visible = getval(self.show_tooltip)
return text_to_wrap:wrap(width - self.indent)
end
-- we can't set the text in init() since we may not yet have a frame that we
-- can get wrapping bounds from.
function TooltipLabel:postComputeFrame()
function WrappedLabel:postComputeFrame()
local wrapped_text = self:getWrappedText(self.frame_body.width)
if not wrapped_text then return end
local text = {}
for _,line in ipairs(self:getWrappedTooltip():split(NEWLINE)) do
for _,line in ipairs(wrapped_text:split(NEWLINE)) do
table.insert(text, {gap=self.indent, text=line})
-- a trailing newline will get ignored so we don't have to manually trim
table.insert(text, NEWLINE)
end
self:setText(text)
end
------------------
-- TooltipLabel --
------------------
TooltipLabel = defclass(TooltipLabel, WrappedLabel)
TooltipLabel.ATTRS{
show_tooltip=DEFAULT_NIL,
indent=2,
text_pen=COLOR_GREY,
}
function TooltipLabel:preUpdateLayout()
self.visible = getval(self.show_tooltip)
end
-----------------
-- HotkeyLabel --
-----------------