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

267 lines
5.4 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 PANEL = {}
AccessorFunc( PANEL, "m_HideButtons", "HideButtons" )
function PANEL:Init()
self.Offset = 0
self.Scroll = 0
self.CanvasSize = 1
self.BarSize = 1
self.btnLeft = vgui.Create( "DButton", self )
self.btnLeft:SetText( "" )
self.btnLeft.DoClick = function( s ) s:GetParent():AddScroll( -1 ) end
self.btnLeft.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonLeft", panel, w, h ) end
self.btnRight = vgui.Create( "DButton", self )
self.btnRight:SetText( "" )
self.btnRight.DoClick = function( s ) s:GetParent():AddScroll( 1 ) end
self.btnRight.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonRight", panel, w, h ) end
self.btnGrip = vgui.Create( "DScrollBarGrip", self )
self:SetSize( 15, 15 )
self:SetHideButtons( false )
end
function PANEL:SetEnabled( b )
if ( !b ) then
self.Offset = 0
self:SetScroll( 0 )
self.HasChanged = true
end
self:SetMouseInputEnabled( b )
self:SetVisible( b )
-- We're probably changing the width of something in our parent
-- by appearing or hiding, so tell them to re-do their layout.
if ( self.Enabled != b ) then
self:GetParent():InvalidateLayout()
if ( self:GetParent().OnScrollbarAppear ) then
self:GetParent():OnScrollbarAppear()
end
end
self.Enabled = b
end
function PANEL:BarScale()
if ( self.BarSize == 0 ) then return 1 end
return self.BarSize / ( self.CanvasSize + self.BarSize )
end
function PANEL:SetUp( _barsize_, _canvassize_ )
self.BarSize = _barsize_
self.CanvasSize = math.max( _canvassize_ - _barsize_, 1 )
self:SetEnabled( _canvassize_ > _barsize_ )
self:InvalidateLayout()
end
function PANEL:OnMouseWheeled( dlta )
if ( !self:IsVisible() ) then return false end
-- We return true if the scrollbar changed.
-- If it didn't, we feed the mousehweeling to the parent panel
return self:AddScroll( dlta * -2 )
end
function PANEL:AddScroll( dlta )
local OldScroll = self:GetScroll()
dlta = dlta * 25
self:SetScroll( self:GetScroll() + dlta )
return OldScroll != self:GetScroll()
end
function PANEL:SetScroll( scrll )
if ( !self.Enabled ) then self.Scroll = 0 return end
self.Scroll = math.Clamp( scrll, 0, self.CanvasSize )
self:InvalidateLayout()
-- If our parent has a OnHScroll function use that, if
-- not then invalidate layout (which can be pretty slow)
local func = self:GetParent().OnHScroll
if ( func ) then
func( self:GetParent(), self:GetOffset() )
else
self:GetParent():InvalidateLayout()
end
end
function PANEL:AnimateTo( scrll, length, delay, ease )
local anim = self:NewAnimation( length, delay, ease )
anim.StartPos = self.Scroll
anim.TargetPos = scrll
anim.Think = function( anm, pnl, fraction )
pnl:SetScroll( Lerp( fraction, anm.StartPos, anm.TargetPos ) )
end
end
function PANEL:GetScroll()
if ( !self.Enabled ) then self.Scroll = 0 end
return self.Scroll
end
function PANEL:GetOffset()
if ( !self.Enabled ) then return 0 end
return self.Scroll * -1
end
function PANEL:Think()
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "HScrollBar", self, w, h )
return true
end
function PANEL:OnMousePressed()
local x, y = self:CursorPos()
local PageSize = self.BarSize
if ( x > self.btnGrip.x ) then
self:SetScroll( self:GetScroll() + PageSize )
else
self:SetScroll( self:GetScroll() - PageSize )
end
end
function PANEL:OnMouseReleased()
self.Dragging = false
self.DraggingCanvas = nil
self:MouseCapture( false )
self.btnGrip.Depressed = false
end
function PANEL:OnCursorMoved( lx, ly )
if ( !self.Enabled ) then return end
if ( !self.Dragging ) then return end
local x, y = self:ScreenToLocal( gui.MouseX(), 0 )
-- Uck.
x = x - self.btnLeft:GetWide()
x = x - self.HoldPos
local BtnWidth = self:GetTall()
if ( self:GetHideButtons() ) then BtnWidth = 0 end
local TrackSize = self:GetWide() - BtnWidth * 2 - self.btnGrip:GetWide()
x = x / TrackSize
self:SetScroll( x * self.CanvasSize )
end
function PANEL:Grip()
if ( !self.Enabled ) then return end
if ( self.BarSize == 0 ) then return end
self:MouseCapture( true )
self.Dragging = true
local x, y = self.btnGrip:ScreenToLocal( gui.MouseX(), 0 )
self.HoldPos = x
self.btnGrip.Depressed = true
end
function PANEL:PerformLayout()
local Tall = self:GetTall()
local BtnWidth = Tall
if ( self:GetHideButtons() ) then BtnWidth = 0 end
local Scroll = self:GetScroll() / self.CanvasSize
local BarSize = math.max( self:BarScale() * ( self:GetWide() - ( BtnWidth * 2 ) ), 10 )
local Track = self:GetWide() - ( BtnWidth * 2 ) - BarSize
Track = Track + 1
Scroll = Scroll * Track
self.btnGrip:SetPos( BtnWidth + Scroll, 0 )
self.btnGrip:SetSize( BarSize, Tall )
if ( BtnWidth > 0 ) then
self.btnLeft:SetPos( 0, 0 )
self.btnLeft:SetSize( BtnWidth, Tall )
self.btnRight:SetPos( self:GetWide() - BtnWidth, 0 )
self.btnRight:SetSize( BtnWidth, Tall )
self.btnLeft:SetVisible( true )
self.btnRight:SetVisible( true )
else
self.btnLeft:SetVisible( false )
self.btnRight:SetVisible( false )
self.btnRight:SetSize( BtnWidth, Tall )
self.btnLeft:SetSize( BtnWidth, Tall )
end
end
derma.DefineControl( "DHScrollBar", "A Horizontal Scrollbar", PANEL, "Panel" )