Files
wnsrc/lua/sui/vgui/sui_scroll_panel.lua
lifestorm 94063e4369 Upload
2024-08-04 22:55:00 +03:00

208 lines
4.7 KiB
Lua

--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local math = math
local table = table
local pairs = pairs
local RealFrameTime = RealFrameTime
local TDLib = sui.TDLib
local SUI, NAME = CURRENT_SUI, CURRENT_SUI.name
local RoundedBox = sui.TDLib.LibClasses.RoundedBox
local Panel = {}
AccessorFunc(Panel, "m_bFromBottom", "FromBottom", FORCE_BOOL)
AccessorFunc(Panel, "m_bVBarPadding", "VBarPadding", FORCE_NUMBER)
Panel:SetVBarPadding(0)
Panel.NoOverrideClear = true
-- VBar
local starting_scroll_speed = 3
local vbar_OnMouseWheeled = function(s, delta)
s.scroll_speed = s.scroll_speed + (14 * RealFrameTime() --[[ slowly increase scroll speed ]])
s:AddScroll(delta * -s.scroll_speed)
end
-- default set scroll clamps amount
local vbar_SetScroll = function(s, amount)
if not s.Enabled then s.Scroll = 0 return end
s.scroll_target = amount
s:InvalidateLayout()
end
-- ¯\_(ツ)_/¯ https://github.com/Facepunch/garrysmod/blob/cd3d894288b847e3d081570129963d4089e36261/garrysmod/lua/vgui/dvscrollbar.lua#L234
local vbar_OnCursorMoved = function(s, _, y)
if s.Dragging then
y = y - s.HoldPos
y = y / (s:GetTall() - s:GetWide() * 2 - s.btnGrip:GetTall())
s.scroll_target = y * s.CanvasSize
end
end
local vbar_Think = function(s)
local frame_time = RealFrameTime() * 14
local scroll_target = s.scroll_target
s.Scroll = Lerp(frame_time, s.Scroll, scroll_target)
if not s.Dragging then
s.scroll_target = Lerp(frame_time, scroll_target, math.Clamp(scroll_target, 0, s.CanvasSize))
end
-- now start slowing it down!!!
s.scroll_speed = Lerp(frame_time / 14, s.scroll_speed, starting_scroll_speed)
end
local vbar_Paint = function(s, w, h)
TDLib.RoundedBox(s.vertices, 3, 0, 0, w, h, SUI.GetColor("scroll"))
end
local vbarGrip_Paint = function(s, w, h)
TDLib.RoundedBox(s.vertices, 3, 0, 0, w, h, SUI.GetColor("scroll_grip"))
end
local vbar_PerformLayout = function(s, w, h)
local scroll = s:GetScroll() / s.CanvasSize
local bar_size = math.max(s:BarScale() * h, 10)
local track = (h - bar_size) + 1
scroll = scroll * track
s.btnGrip.y = scroll
s.btnGrip:SetSize(w, bar_size)
end
--
function Panel:Init()
local canvas = self:GetCanvas()
canvas:SUI_TDLib()
local children = {}
function canvas:OnChildAdded(child)
table.insert(children, child)
end
function canvas:OnChildRemoved(child)
for i = 1, #children do
local v = children[i]
if v == child then
table.remove(children, i)
return
end
end
end
canvas.GetChildren = function()
return children
end
canvas.children = children
local vbar = self.VBar
vbar:SetHideButtons(true)
vbar.btnUp:SetVisible(false)
vbar.btnDown:SetVisible(false)
vbar.vertices = {}
vbar.scroll_target = 0
vbar.scroll_speed = starting_scroll_speed
vbar.OnMouseWheeled = vbar_OnMouseWheeled
vbar.SetScroll = vbar_SetScroll
vbar.OnCursorMoved = vbar_OnCursorMoved
vbar.Think = vbar_Think
vbar.Paint = vbar_Paint
vbar.PerformLayout = vbar_PerformLayout
vbar.btnGrip.vertices = {}
vbar.btnGrip.Paint = vbarGrip_Paint
self:ScaleChanged()
SUI.OnScaleChanged(self, self.ScaleChanged)
end
function Panel:OnChildAdded(child)
self:AddItem(child)
self:ChildAdded(child)
end
function Panel:ChildAdded()
end
function Panel:ScaleChanged()
local w = SUI.Scale(4)
self.VBar:SetWide(w)
self.VBar.btnDown:SetSize(w, 0)
self.VBar.btnUp:SetSize(w, 0)
end
function Panel:Paint(w, h)
local outline = SUI.GetColor("scroll_panel_outline")
if outline then
TDLib.DrawOutlinedBox(3, 0, 0, w, h, SUI.GetColor("scroll_panel"), outline, 1)
else
RoundedBox(self, "Background", 3, 0, 0, w, h, SUI.GetColor("scroll_panel"))
end
end
function Panel:ScrollToBottom()
local vbar = self.VBar
for k, anim in pairs(vbar.m_AnimList or {}) do
anim:Think(vbar, 1)
vbar.m_AnimList[k] = nil
end
self:InvalidateParent(true)
self:InvalidateChildren(true)
vbar:SetScroll(vbar.CanvasSize)
end
function Panel:PerformLayoutInternal(w, h)
w = w or self:GetWide()
h = h or self:GetTall()
local canvas = self.pnlCanvas
self:Rebuild()
local vbar = self.VBar
vbar:SetUp(h, canvas:GetTall())
if vbar.Enabled then
w = w - vbar:GetWide() - self.m_bVBarPadding
end
canvas:SetWide(w)
self:Rebuild()
end
function Panel:Think()
local canvas = self.pnlCanvas
local vbar = self.VBar
if vbar.Enabled then
canvas.y = -vbar.Scroll
else
if self:GetFromBottom() then
canvas._y = Lerp(14 * RealFrameTime(), canvas._y or canvas.y, self:GetTall() - canvas:GetTall())
else
canvas._y = Lerp(14 * RealFrameTime(), canvas._y or canvas.y, -vbar.Scroll)
end
canvas.y = canvas._y
end
end
sui.register("ScrollPanel", Panel, "DScrollPanel")