From ed226c476e5fe70399c7c5149b762ffcdc75091a Mon Sep 17 00:00:00 2001 From: Guldoman Date: Tue, 1 Nov 2022 23:38:50 +0100 Subject: [PATCH] Add more options to `Scrollbar` (#1174) * Make `Scrollbar` accept a table for its options * Add `force_status`, `{expanded,shrinked}_size` options to `Scrollbar` * Add `Scrollbar:set_forced_status` * Add `config.force_scrollbar_status` to force `DocView` scrollbars status --- data/core/config.lua | 2 ++ data/core/docview.lua | 2 ++ data/core/scrollbar.lua | 58 ++++++++++++++++++++++++++++++++--------- data/core/view.lua | 4 +-- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/data/core/config.lua b/data/core/config.lua index b6007c0a..03c0c84c 100644 --- a/data/core/config.lua +++ b/data/core/config.lua @@ -6,6 +6,8 @@ config.message_timeout = 5 config.mouse_wheel_scroll = 50 * SCALE config.animate_drag_scroll = false config.scroll_past_end = true +---@type "expanded" | "contracted" | false @Force the scrollbar status of the DocView +config.force_scrollbar_status = false config.file_size_limit = 10 config.ignore_files = { -- folders diff --git a/data/core/docview.lua b/data/core/docview.lua index 19b9cebd..4ce54d2f 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -62,6 +62,8 @@ function DocView:new(doc) self.font = "code_font" self.last_x_offset = {} self.ime_selection = { from = 0, size = 0 } + self.v_scrollbar:set_forced_status(config.force_scrollbar_status) + self.h_scrollbar:set_forced_status(config.force_scrollbar_status) end diff --git a/data/core/scrollbar.lua b/data/core/scrollbar.lua index b185e8eb..48ae0fa0 100644 --- a/data/core/scrollbar.lua +++ b/data/core/scrollbar.lua @@ -19,9 +19,15 @@ local Object = require "core.object" ---@class core.scrollbar : core.object local Scrollbar = Object:extend() ----@param direction "v" | "h" @Vertical or Horizontal ----@param alignment "s" | "e" @Start or End (left to right, top to bottom) -function Scrollbar:new(direction, alignment) +---@class ScrollbarOptions +---@field direction "v" | "h" @Vertical or Horizontal +---@field alignment "s" | "e" @Start or End (left to right, top to bottom) +---@field force_status "expanded" | "contracted" | false @Force the scrollbar status +---@field expanded_size number? @Override the default value specified by `style.expanded_scrollbar_size` +---@field contracted_size number? @Override the default value specified by `style.scrollbar_size` + +---@param options ScrollbarOptions +function Scrollbar:new(options) ---Position information of the owner self.rect = { x = 0, y = 0, w = 0, h = 0, @@ -44,11 +50,28 @@ function Scrollbar:new(direction, alignment) ---What is currently being hovered. `thumb` implies` track` self.hovering = { track = false, thumb = false } ---@type "v" | "h"@Vertical or Horizontal - self.direction = direction or "v" + self.direction = options.direction or "v" ---@type "s" | "e" @Start or End (left to right, top to bottom) - self.alignment = alignment or "e" + self.alignment = options.alignment or "e" ---@type number @Private. Used to keep track of animations self.expand_percent = 0 + ---@type "expanded" | "contracted" | false @Force the scrollbar status + self.force_status = options.force_status + self:set_forced_status(options.force_status) + ---@type number? @Override the default value specified by `style.expanded_scrollbar_size` + self.contracted_size = options.contracted_size + ---@type number? @Override the default value specified by `style.scrollbar_size` + self.expanded_size = options.expanded_size +end + + +---Set the status the scrollbar is forced to keep +---@param status "expanded" | "contracted" | false @The status to force +function Scrollbar:set_forced_status(status) + self.force_status = status + if self.force_status == "expanded" then + self.expand_percent = 1 + end end @@ -91,9 +114,11 @@ function Scrollbar:_get_thumb_rect_normal() then return 0, 0, 0, 0 end + local scrollbar_size = self.contracted_size or style.scrollbar_size + local expanded_scrollbar_size = self.expanded_size or style.expanded_scrollbar_size local along_size = math.max(20, nr.along_size * nr.along_size / sz) - local across_size = style.scrollbar_size - across_size = across_size + (style.expanded_scrollbar_size - style.scrollbar_size) * self.expand_percent + local across_size = scrollbar_size + across_size = across_size + (expanded_scrollbar_size - scrollbar_size) * self.expand_percent return nr.across + nr.across_size - across_size, nr.along + self.percent * nr.scrollable * (nr.along_size - along_size) / (sz - nr.along_size), @@ -114,8 +139,10 @@ function Scrollbar:_get_track_rect_normal() if sz <= nr.along_size or sz == math.huge then return 0, 0, 0, 0 end - local across_size = style.scrollbar_size - across_size = across_size + (style.expanded_scrollbar_size - style.scrollbar_size) * self.expand_percent + local scrollbar_size = self.contracted_size or style.scrollbar_size + local expanded_scrollbar_size = self.expanded_size or style.expanded_scrollbar_size + local across_size = scrollbar_size + across_size = across_size + (expanded_scrollbar_size - scrollbar_size) * self.expand_percent return nr.across + nr.across_size - across_size, nr.along, @@ -132,12 +159,13 @@ end function Scrollbar:_overlaps_normal(x, y) local sx, sy, sw, sh = self:_get_thumb_rect_normal() + local scrollbar_size = self.contracted_size or style.scrollbar_size local result - if x >= sx - style.scrollbar_size * 3 and x <= sx + sw and y >= sy and y <= sy + sh then + if x >= sx - scrollbar_size * 3 and x <= sx + sw and y >= sy and y <= sy + sh then result = "thumb" else sx, sy, sw, sh = self:_get_track_rect_normal() - if x >= sx - style.scrollbar_size * 3 and x <= sx + sw and y >= sy and y <= sy + sh then + if x >= sx - scrollbar_size * 3 and x <= sx + sw and y >= sy and y <= sy + sh then result = "track" end end @@ -270,7 +298,13 @@ function Scrollbar:update() local dt = 60 / config.fps rate = 1 - common.clamp(1 - rate, 1e-8, 1 - 1e-8)^(config.animation_rate * dt) end - self.expand_percent = common.lerp(self.expand_percent, dest, rate) + if not self.force_status then + self.expand_percent = common.lerp(self.expand_percent, dest, rate) + elseif self.force_status == "expanded" then + self.expand_percent = 1 + elseif self.force_status == "contracted" then + self.expand_percent = 0 + end end if diff > 1e-8 then core.redraw = true diff --git a/data/core/view.lua b/data/core/view.lua index aab5ba05..77378b90 100644 --- a/data/core/view.lua +++ b/data/core/view.lua @@ -59,8 +59,8 @@ function View:new() self.scroll = { x = 0, y = 0, to = { x = 0, y = 0 } } self.cursor = "arrow" self.scrollable = false - self.v_scrollbar = Scrollbar("v", "e") - self.h_scrollbar = Scrollbar("h", "e") + self.v_scrollbar = Scrollbar({direction = "v", alignment = "e"}) + self.h_scrollbar = Scrollbar({direction = "h", alignment = "e"}) self.current_scale = SCALE end