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
This commit is contained in:
Guldoman 2022-11-01 23:38:50 +01:00 committed by GitHub
parent 0f160e614e
commit ed226c476e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 14 deletions

View File

@ -6,6 +6,8 @@ config.message_timeout = 5
config.mouse_wheel_scroll = 50 * SCALE config.mouse_wheel_scroll = 50 * SCALE
config.animate_drag_scroll = false config.animate_drag_scroll = false
config.scroll_past_end = true 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.file_size_limit = 10
config.ignore_files = { config.ignore_files = {
-- folders -- folders

View File

@ -62,6 +62,8 @@ function DocView:new(doc)
self.font = "code_font" self.font = "code_font"
self.last_x_offset = {} self.last_x_offset = {}
self.ime_selection = { from = 0, size = 0 } 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 end

View File

@ -19,9 +19,15 @@ local Object = require "core.object"
---@class core.scrollbar : core.object ---@class core.scrollbar : core.object
local Scrollbar = Object:extend() local Scrollbar = Object:extend()
---@param direction "v" | "h" @Vertical or Horizontal ---@class ScrollbarOptions
---@param alignment "s" | "e" @Start or End (left to right, top to bottom) ---@field direction "v" | "h" @Vertical or Horizontal
function Scrollbar:new(direction, alignment) ---@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 ---Position information of the owner
self.rect = { self.rect = {
x = 0, y = 0, w = 0, h = 0, 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` ---What is currently being hovered. `thumb` implies` track`
self.hovering = { track = false, thumb = false } self.hovering = { track = false, thumb = false }
---@type "v" | "h"@Vertical or Horizontal ---@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) ---@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 ---@type number @Private. Used to keep track of animations
self.expand_percent = 0 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 end
@ -91,9 +114,11 @@ function Scrollbar:_get_thumb_rect_normal()
then then
return 0, 0, 0, 0 return 0, 0, 0, 0
end 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 along_size = math.max(20, nr.along_size * nr.along_size / sz)
local across_size = style.scrollbar_size local across_size = scrollbar_size
across_size = across_size + (style.expanded_scrollbar_size - style.scrollbar_size) * self.expand_percent across_size = across_size + (expanded_scrollbar_size - scrollbar_size) * self.expand_percent
return return
nr.across + nr.across_size - across_size, nr.across + nr.across_size - across_size,
nr.along + self.percent * nr.scrollable * (nr.along_size - along_size) / (sz - nr.along_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 if sz <= nr.along_size or sz == math.huge then
return 0, 0, 0, 0 return 0, 0, 0, 0
end end
local across_size = style.scrollbar_size local scrollbar_size = self.contracted_size or style.scrollbar_size
across_size = across_size + (style.expanded_scrollbar_size - style.scrollbar_size) * self.expand_percent 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 return
nr.across + nr.across_size - across_size, nr.across + nr.across_size - across_size,
nr.along, nr.along,
@ -132,12 +159,13 @@ end
function Scrollbar:_overlaps_normal(x, y) function Scrollbar:_overlaps_normal(x, y)
local sx, sy, sw, sh = self:_get_thumb_rect_normal() local sx, sy, sw, sh = self:_get_thumb_rect_normal()
local scrollbar_size = self.contracted_size or style.scrollbar_size
local result 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" result = "thumb"
else else
sx, sy, sw, sh = self:_get_track_rect_normal() 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" result = "track"
end end
end end
@ -270,7 +298,13 @@ function Scrollbar:update()
local dt = 60 / config.fps local dt = 60 / config.fps
rate = 1 - common.clamp(1 - rate, 1e-8, 1 - 1e-8)^(config.animation_rate * dt) rate = 1 - common.clamp(1 - rate, 1e-8, 1 - 1e-8)^(config.animation_rate * dt)
end end
if not self.force_status then
self.expand_percent = common.lerp(self.expand_percent, dest, rate) 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 end
if diff > 1e-8 then if diff > 1e-8 then
core.redraw = true core.redraw = true

View File

@ -59,8 +59,8 @@ function View:new()
self.scroll = { x = 0, y = 0, to = { x = 0, y = 0 } } self.scroll = { x = 0, y = 0, to = { x = 0, y = 0 } }
self.cursor = "arrow" self.cursor = "arrow"
self.scrollable = false self.scrollable = false
self.v_scrollbar = Scrollbar("v", "e") self.v_scrollbar = Scrollbar({direction = "v", alignment = "e"})
self.h_scrollbar = Scrollbar("h", "e") self.h_scrollbar = Scrollbar({direction = "h", alignment = "e"})
self.current_scale = SCALE self.current_scale = SCALE
end end