diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 94eaa1165..d436bdd5c 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -3928,11 +3928,14 @@ It has the following attributes: :auto_width: Sets self.frame.w from the text width. :on_click: A callback called when the label is clicked (optional) :on_rclick: A callback called when the label is right-clicked (optional) -:scroll_keys: Specifies which keys the label should react to as a table. Default is ``STANDARDSCROLL`` (up or down arrows, page up or down). +:scroll_keys: Specifies which keys the label should react to as a table. The table should map + keys to the number of lines to scroll as positive or negative integers or one of the keywords + supported by the ``scroll`` method. The default is up/down arrows scrolling by one line and page + up/down scrolling by one page. :show_scroll_icons: Controls scroll icons' behaviour: ``false`` for no icons, ``'right'`` or ``'left'`` for - icons next to the text in an additional column (``frame_inset`` is adjusted to have ``.r`` or ``.l`` greater than ``0``), - ``nil`` same as ``'right'`` but changes ``frame_inset`` only if a scroll icon is actually necessary - (if ``getTextHeight()`` is greater than ``frame_body.height``). Default is ``nil``. + icons next to the text in an additional column (``frame_inset`` is adjusted to have ``.r`` or ``.l`` greater than ``0``), + ``nil`` same as ``'right'`` but changes ``frame_inset`` only if a scroll icon is actually necessary + (if ``getTextHeight()`` is greater than ``frame_body.height``). Default is ``nil``. :up_arrow_icon: The symbol for scroll up arrow. Default is ``string.char(24)`` (``↑``). :down_arrow_icon: The symbol for scroll down arrow. Default is ``string.char(25)`` (``↓``). :scroll_icon_pen: Specifies the pen for scroll icons. Default is ``COLOR_LIGHTCYAN``. @@ -4024,6 +4027,12 @@ The Label widget implements the following methods: Computes the width of the text. +* ``label:scroll(nlines)`` + + This method takes the number of lines to scroll as positive or negative + integers or one of the following keywords: ``+page``, ``-page``, + ``+halfpage``, or ``-halfpage``. + WrappedLabel class ------------------ diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 5765992af..3ac74bb52 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -652,6 +652,19 @@ function Label:onRenderFrame(dc, rect) end function Label:scroll(nlines) + if type(nlines) == 'string' then + if nlines == '+page' then + nlines = self.frame_body.height + elseif nlines == '-page' then + nlines = -self.frame_body.height + elseif nlines == '+halfpage' then + nlines = math.ceil(self.frame_body.height/2) + elseif nlines == '-halfpage' then + nlines = -math.ceil(self.frame_body.height/2) + else + error(('unhandled scroll keyword: "%s"'):format(nlines)) + end + end local n = self.start_line_num + nlines n = math.min(n, self:getTextHeight() - self.frame_body.height + 1) n = math.max(n, 1) @@ -668,11 +681,6 @@ function Label:onInput(keys) end for k,v in pairs(self.scroll_keys) do if keys[k] then - if v == '+page' then - v = self.frame_body.height - elseif v == '-page' then - v = -self.frame_body.height - end self:scroll(v) end end diff --git a/test/library/gui/widgets.Label.lua b/test/library/gui/widgets.Label.lua index 4e6222e3a..9a5d462fa 100644 --- a/test/library/gui/widgets.Label.lua +++ b/test/library/gui/widgets.Label.lua @@ -18,7 +18,7 @@ function test.correct_frame_body_with_scroll_icons() t[#t+1] = NEWLINE end - function fs:init(args) + function fs:init() self:addviews{ widgets.Label{ view_id = 'text', @@ -39,7 +39,7 @@ function test.correct_frame_body_with_few_text_lines() t[#t+1] = NEWLINE end - function fs:init(args) + function fs:init() self:addviews{ widgets.Label{ view_id = 'text', @@ -60,7 +60,7 @@ function test.correct_frame_body_without_show_scroll_icons() t[#t+1] = NEWLINE end - function fs:init(args) + function fs:init() self:addviews{ widgets.Label{ view_id = 'text', @@ -74,3 +74,43 @@ function test.correct_frame_body_without_show_scroll_icons() local o = fs{} expect.eq(o.subviews.text.frame_body.width, 10, "Label's frame_body.x2 and .width should not change with show_scroll_icons = false.") end + +function test.scroll() + local t = {} + for i = 1, 12 do + t[#t+1] = tostring(i) + t[#t+1] = NEWLINE + end + + function fs:init() + self:addviews{ + widgets.Label{ + view_id = 'text', + frame_inset = 0, + text = t, + }, + } + end + + local o = fs{frame_height=3} + local txt = o.subviews.text + expect.eq(1, txt.start_line_num) + + txt:scroll(1) + expect.eq(2, txt.start_line_num) + txt:scroll('+page') + expect.eq(5, txt.start_line_num) + txt:scroll('+halfpage') + expect.eq(7, txt.start_line_num) + txt:scroll('-halfpage') + expect.eq(5, txt.start_line_num) + txt:scroll('-page') + expect.eq(2, txt.start_line_num) + txt:scroll(-1) + expect.eq(1, txt.start_line_num) + + txt:scroll(-1) + expect.eq(1, txt.start_line_num) + txt:scroll(100) + expect.eq(10, txt.start_line_num) +end