From d4914e7511a8cc48e09d55515aec1ab8af84991a Mon Sep 17 00:00:00 2001 From: myk002 Date: Sun, 11 Sep 2022 19:33:01 -0700 Subject: [PATCH] implement mouse click reactions for scrollbar --- docs/Lua API.rst | 5 +++++ library/lua/gui/widgets.lua | 39 +++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index fee502b80..b97c1b314 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4046,6 +4046,11 @@ It has the following attributes: :scrollbar_fg: Specifies the pen for the scroll icons and the active part of the bar. Default is ``COLOR_LIGHTGREEN`` (the same as the native DF help screens). :scrollbar_bg: Specifies the pen for the background part of the scrollbar. Default is ``COLOR_CYAN`` (the same as the native DF help screens). +If the scrollbar is shown, it will react to mouse clicks on the scrollbar itself. +Clicking on the arrows at the top or the bottom will scroll by one line, and +clicking on the unfilled portion of the scrollbar will scroll by a half page in +that direction. + The text itself is represented as a complex structure, and passed to the object via the ``text`` argument of the constructor, or via the ``setText`` method, as one of: diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index e85ac2d3c..d81fbf6b9 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -682,8 +682,7 @@ function Label:onRenderBody(dc) end function Label:onRenderFrame(dc, rect) - if self._show_scrollbar - then + if self._show_scrollbar then local x = self._show_scrollbar == 'left' and self.frame_body.x1-dc.x1-1 or self.frame_body.x2-dc.x1+1 @@ -695,7 +694,35 @@ function Label:onRenderFrame(dc, rect) end end +function Label:click_scrollbar() + if not self._show_scrollbar then return end + local rect = self.frame_body + local x, y = dscreen.getMousePos() + + if self._show_scrollbar == 'left' and x ~= rect.x1-1 or x ~= rect.x2+1 then + return + end + if y < rect.y1 or y > rect.y2 then + return + end + + if y == rect.y1 then + return -1 + elseif y == rect.y2 then + return 1 + else + local pos, height = get_scrollbar_pos_and_height(self) + if y < rect.y1 + pos then + return '-halfpage' + elseif y > rect.y1 + pos + height then + return '+halfpage' + end + end + return nil +end + function Label:scroll(nlines) + if not nlines then return end if type(nlines) == 'string' then if nlines == '+page' then nlines = self.frame_body.height @@ -713,12 +740,16 @@ function Label:scroll(nlines) n = math.min(n, self:getTextHeight() - self.frame_body.height + 1) n = math.max(n, 1) self.start_line_num = n + return nlines end function Label:onInput(keys) if is_disabled(self) then return false end - if keys._MOUSE_L_DOWN and self:getMousePos() and self.on_click then - self:on_click() + if keys._MOUSE_L_DOWN then + if not self:scroll(self:click_scrollbar()) and + self:getMousePos() and self.on_click then + self:on_click() + end end if keys._MOUSE_R_DOWN and self:getMousePos() and self.on_rclick then self:on_rclick()