diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 64b6dbf0d..a0764df99 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -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 ----------------- diff --git a/docs/changelog.txt b/docs/changelog.txt index 330f6e8b2..1a3bf64b4 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -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 diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 7a83346b1..9306a75fa 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -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 -- -----------------