--[[ | 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")