From 2797061b04122e36cb54f0b1d234dfe4eba9d5ea Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 4 Nov 2020 18:06:50 -0800 Subject: [PATCH 1/5] scroll Label text when height exceeds viewrect --- library/lua/gui/widgets.lua | 54 ++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 99733b84b..07f2b0eb3 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -235,9 +235,13 @@ end function render_text(obj,dc,x0,y0,pen,dpen,disabled) local width = 0 for iline,line in ipairs(obj.text_lines) do + if dc and obj.start_line_num and iline < obj.start_line_num then + goto continue + end local x = 0 if dc then - dc:seek(x+x0,y0+iline-1) + local offset = (obj.start_line_num or 1) - 1 + dc:seek(x+x0,y0+iline-offset-1) end for _,token in ipairs(line) do token.line = iline @@ -323,6 +327,7 @@ function render_text(obj,dc,x0,y0,pen,dpen,disabled) token.x2 = x end width = math.max(width, x) + ::continue:: end obj.text_width = width end @@ -340,6 +345,13 @@ end Label = defclass(Label, Widget) +STANDARDSCROLL = { + STANDARDSCROLL_UP = -1, + STANDARDSCROLL_DOWN = 1, + STANDARDSCROLL_PAGEUP = '-page', + STANDARDSCROLL_PAGEDOWN = '+page', +} + Label.ATTRS{ text_pen = COLOR_WHITE, text_dpen = COLOR_DARKGREY, -- disabled @@ -350,9 +362,11 @@ Label.ATTRS{ auto_width = false, on_click = DEFAULT_NIL, on_rclick = DEFAULT_NIL, + scroll_keys = STANDARDSCROLL, } function Label:init(args) + self.start_line_num = 1 self:setText(args.text) if not self.text_hpen then self.text_hpen = ((tonumber(self.text_pen) or tonumber(self.text_pen.fg) or 0) + 8) % 16 @@ -399,16 +413,33 @@ function Label:onRenderBody(dc) render_text(self,dc,0,0,text_pen,self.text_dpen,is_disabled(self)) end +function Label:scroll(nlines) + local n = self.start_line_num + nlines + n = math.min(n, self:getTextHeight() - self.frame_body.height) + n = math.max(n, 1) + self.start_line_num = n +end + function Label:onInput(keys) - if not is_disabled(self) then - if keys._MOUSE_L_DOWN and self:getMousePos() and self.on_click then - self:on_click() - end - if keys._MOUSE_R_DOWN and self:getMousePos() and self.on_rclick then - self:on_rclick() + if is_disabled(self) then return false end + if keys._MOUSE_L_DOWN and self:getMousePos() and self.on_click then + self:on_click() + end + if keys._MOUSE_R_DOWN and self:getMousePos() and self.on_rclick then + self:on_rclick() + 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) + return true end - return check_text_keys(self, keys) end + return check_text_keys(self, keys) end ---------- @@ -417,13 +448,6 @@ end List = defclass(List, Widget) -STANDARDSCROLL = { - STANDARDSCROLL_UP = -1, - STANDARDSCROLL_DOWN = 1, - STANDARDSCROLL_PAGEUP = '-page', - STANDARDSCROLL_PAGEDOWN = '+page', -} - SECONDSCROLL = { SECONDSCROLL_UP = -1, SECONDSCROLL_DOWN = 1, From dac9538fd9b5de0aa87ac13dc979a7100ccb5c8b Mon Sep 17 00:00:00 2001 From: myk002 Date: Mon, 11 Jan 2021 15:02:12 -0800 Subject: [PATCH 2/5] let navigation keys propagate so other components can use them for simultaneous control --- library/lua/gui/widgets.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 07f2b0eb3..2d056a599 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -436,7 +436,7 @@ function Label:onInput(keys) v = -self.frame_body.height end self:scroll(v) - return true + return false end end return check_text_keys(self, keys) From 97309e45f51082c1f1ebda824baec2583a347a6a Mon Sep 17 00:00:00 2001 From: myk002 Date: Mon, 11 Jan 2021 15:02:58 -0800 Subject: [PATCH 3/5] update changelog --- docs/changelog.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index fdc7c13e7..09559ff62 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -36,6 +36,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Fixes - `embark-assistant`: fixed order of factors when calculating min temperature +## Misc Improvements +- Lua widget library Label class (used in all standard message boxes) is now scrollable with Up/Down/PgUp/PgDn keys + # 0.47.04-r4 ## Fixes From d4fbf4261fc0c00fbd93a8aeb8dbbe0250349a62 Mon Sep 17 00:00:00 2001 From: myk002 Date: Tue, 12 Jan 2021 23:27:14 -0800 Subject: [PATCH 4/5] address review comments --- library/lua/gui/widgets.lua | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index 2d056a599..d9d8d4bf4 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -234,11 +234,10 @@ end function render_text(obj,dc,x0,y0,pen,dpen,disabled) local width = 0 - for iline,line in ipairs(obj.text_lines) do - if dc and obj.start_line_num and iline < obj.start_line_num then - goto continue - end - local x = 0 + -- note that lines outside of the containing frame are not displayed, so + -- we only have to bound the start condition, not the end condition + for iline = dc and obj.start_line_num or 1, #obj.text_lines do + local x, line = 0, obj.text_lines[iline] if dc then local offset = (obj.start_line_num or 1) - 1 dc:seek(x+x0,y0+iline-offset-1) @@ -327,7 +326,6 @@ function render_text(obj,dc,x0,y0,pen,dpen,disabled) token.x2 = x end width = math.max(width, x) - ::continue:: end obj.text_width = width end From 5a2181d55eb860809828d389d774f1e056fe6b1e Mon Sep 17 00:00:00 2001 From: myk002 Date: Wed, 13 Jan 2021 22:02:22 -0800 Subject: [PATCH 5/5] don't render overflow text --- library/lua/gui/widgets.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index d9d8d4bf4..29d5aa827 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -234,13 +234,14 @@ end function render_text(obj,dc,x0,y0,pen,dpen,disabled) local width = 0 - -- note that lines outside of the containing frame are not displayed, so - -- we only have to bound the start condition, not the end condition for iline = dc and obj.start_line_num or 1, #obj.text_lines do local x, line = 0, obj.text_lines[iline] if dc then local offset = (obj.start_line_num or 1) - 1 - dc:seek(x+x0,y0+iline-offset-1) + local y = y0 + iline - offset - 1 + -- skip text outside of the containing frame + if y > dc.height - 1 then break end + dc:seek(x+x0, y) end for _,token in ipairs(line) do token.line = iline