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 18:38:50 -04:00
committed by GitHub
parent 0f160e614e
commit ed226c476e
4 changed files with 52 additions and 14 deletions
+46 -12
View File
@@ -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