Split vertical and horizontal scrollbar-related functions and variables

This commit is contained in:
Guldoman
2021-08-30 17:58:22 +02:00
committed by Francesco
parent 4a03aec073
commit 92bbb30d06
2 changed files with 72 additions and 63 deletions
+62 -51
View File
@@ -51,77 +51,84 @@ function View:get_name()
return "---"
end
-- Returns `y, x` for compatibility
function View:get_scrollable_size()
return math.huge, 0 -- TODO: invert y and x
return math.huge
end
function View:get_scrollbar_rect() -- TODO: make plugins use `View:get_scrollbars_rect`
local rect = self:get_get_scrollbars_rect()
return rect.x, rect.y, rect.w, rect.h
function View:get_h_scrollable_size()
return 0
end
function View:get_scrollbars_rect()
local v_sizes = { x = 0, y = 0, w = 0, h = 0 }
local h_sizes = { x = 0, y = 0, w = 0, h = 0 }
local v_sz, h_sz = self:get_scrollable_size()
h_sz = h_sz or 0 -- FIXME: not every subclass returns the second value
if v_sz > self.size.y and v_sz ~= math.huge then
local h = math.max(20, self.size.y * self.size.y / v_sz)
v_sizes.x = self.position.x + self.size.x - style.scrollbar_size
v_sizes.y = self.position.y + self.scroll.y * (self.size.y - h) / (v_sz - self.size.y)
v_sizes.w = style.scrollbar_size
v_sizes.h = h
function View:get_scrollbar_rect()
local sz = self:get_scrollable_size()
if sz <= self.size.y or sz == math.huge then
return 0, 0, 0, 0
end
local h = math.max(20, self.size.y * self.size.y / sz)
return
self.position.x + self.size.x - style.scrollbar_size,
self.position.y + self.scroll.y * (self.size.y - h) / (sz - self.size.y),
style.scrollbar_size,
h
end
if h_sz > self.size.x and h_sz ~= math.huge then
local w = math.max(20, self.size.x * self.size.x / h_sz)
h_sizes.x = self.position.x + self.scroll.x * (self.size.x - w) / (h_sz - self.size.x)
h_sizes.y = self.position.y + self.size.y - style.scrollbar_size
h_sizes.w = w
h_sizes.h = style.scrollbar_size
function View:get_h_scrollbar_rect()
local sz = self:get_h_scrollable_size()
if sz <= self.size.x or sz == math.huge then
return 0, 0, 0, 0
end
return v_sizes, h_sizes
local w = math.max(20, self.size.x * self.size.x / sz)
return
self.position.x + self.scroll.x * (self.size.x - w) / (sz - self.size.x),
self.position.y + self.size.y - style.scrollbar_size,
w,
style.scrollbar_size
end
function View:scrollbar_overlaps_point(x, y)
local v, h = self:get_scrollbars_rect()
local v_overlap = x >= v.x - v.w * 3 and x < v.x + v.w and y >= v.y and y < v.y + v.h
local h_overlap = x >= h.x and x < h.x + h.w and y >= h.y - h.h * 3 and y <= h.y + h.h
return v_overlap, not v_overlap and h_overlap -- precedence to vertical scrollbar
local sx, sy, sw, sh = self:get_scrollbar_rect()
return x >= sx - sw * 3 and x < sx + sw and y >= sy and y <= sy + sh
end
function View:h_scrollbar_overlaps_point(x, y)
local sx, sy, sw, sh = self:get_h_scrollbar_rect()
return x >= sx and x <= sx + sw and y > sy - sh * 3 and y <= sy + sh
end
function View:on_mouse_pressed(button, x, y, clicks)
self.dragging_v_scrollbar, self.dragging_h_scrollbar = self:scrollbar_overlaps_point(x, y)
self.dragging_scrollbar = self.dragging_v_scrollbar -- TODO: make plugins use `self.dragging_v_scrollbar`
return self.dragging_v_scrollbar or self.dragging_h_scrollbar
if self:scrollbar_overlaps_point(x, y) then
self.dragging_scrollbar = true
return true
elseif self:h_scrollbar_overlaps_point(x, y) then
self.dragging_h_scrollbar = true
return true
end
end
function View:on_mouse_released(button, x, y)
self.dragging_v_scrollbar = false
self.dragging_scrollbar = false
self.dragging_h_scrollbar = false
self.dragging_scrollbar = self.dragging_v_scrollbar -- TODO: make plugins use `self.dragging_v_scrollbar`
end
function View:on_mouse_moved(x, y, dx, dy)
if self.dragging_v_scrollbar then
local v_sz,_ = self:get_scrollable_size()
local delta = v_sz / self.size.y * dy
if self.dragging_scrollbar then
local delta = self:get_scrollable_size() / self.size.y * dy
self.scroll.to.y = self.scroll.to.y + delta
elseif self.dragging_h_scrollbar then
local _,h_sz = self:get_scrollable_size()
local delta = h_sz / self.size.x * dx
local delta = self:get_h_scrollable_size() / self.size.x * dx
self.scroll.to.x = self.scroll.to.x + delta
end
self.hovered_v_scrollbar, self.hovered_h_scrollbar = self:scrollbar_overlaps_point(x, y)
self.hovered_scrollbar = self.hovered_v_scrollbar -- TODO: make plugins use `self.hovered_v_scrollbar`
self.hovered_scrollbar = self:scrollbar_overlaps_point(x, y)
self.hovered_h_scrollbar = self:h_scrollbar_overlaps_point(x, y)
end
@@ -156,10 +163,8 @@ end
function View:clamp_scroll_position()
local scrollsize_y, scrollsize_x = self:get_scrollable_size()
scrollsize_x = scrollsize_x or 0 -- FIXME: not every subclass returns the second value
local max_x = scrollsize_x - self.size.x
local max_y = scrollsize_y - self.size.y
local max_x = self:get_h_scrollable_size() - self.size.x
local max_y = self:get_scrollable_size() - self.size.y
self.scroll.to.x = common.clamp(self.scroll.to.x, 0, max_x)
self.scroll.to.y = common.clamp(self.scroll.to.y, 0, max_y)
end
@@ -180,13 +185,19 @@ end
function View:draw_scrollbar()
local v, h = self:get_scrollbars_rect()
local v_highlight = self.hovered_v_scrollbar or self.dragging_v_scrollbar
local h_highlight = self.hovered_h_scrollbar or self.dragging_h_scrollbar
local v_color = v_highlight and style.scrollbar2 or style.scrollbar
local h_color = h_highlight and style.scrollbar2 or style.scrollbar
renderer.draw_rect(v.x, v.y, v.w, v.h, v_color)
renderer.draw_rect(h.x, h.y, h.w, h.h, h_color)
local x, y, w, h = self:get_scrollbar_rect()
local highlight = self.hovered_scrollbar or self.dragging_scrollbar
local color = highlight and style.scrollbar2 or style.scrollbar
renderer.draw_rect(x, y, w, h, color)
end
function View:draw_h_scrollbar()
local x, y, w, h = self:get_h_scrollbar_rect()
local highlight = self.hovered_h_scrollbar and not self.hovered_scrollbar
or self.dragging_h_scrollbar
local color = highlight and style.scrollbar2 or style.scrollbar
renderer.draw_rect(x, y, w, h, color)
end