mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
423 lines
8.5 KiB
Lua
423 lines
8.5 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/
|
|
--]]
|
|
|
|
do
|
|
local PANEL = vgui.Register("pac_horizontal_scrollbar", {}, "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( self ) self: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( self ) self: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.btnGrip.Paint = function(panel,w,h)
|
|
local skin = panel:GetSkin()
|
|
if ( panel:GetDisabled() ) then
|
|
skin.tex.Scroller.ButtonH_Disabled( 0, 0, w, h )
|
|
elseif ( panel.Depressed ) then
|
|
return skin.tex.Scroller.ButtonH_Down( 0, 0, w, h )
|
|
elseif ( panel.Hovered ) then
|
|
return skin.tex.Scroller.ButtonH_Hover( 0, 0, w, h )
|
|
else
|
|
skin.tex.Scroller.ButtonH_Normal( 0, 0, w, h )
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
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:Value()
|
|
|
|
return self.Pos
|
|
|
|
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 OnVScroll function use that, if
|
|
-- not then invalidate layout (which can be pretty slow)
|
|
|
|
local func = self:GetParent().OnVScroll
|
|
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( anim, pnl, fraction )
|
|
|
|
pnl:SetScroll( Lerp( fraction, anim.StartPos, anim.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 )
|
|
|
|
self:GetSkin().tex.Scroller.TrackH(0,0,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( x, y )
|
|
|
|
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 BtnHeight = self:GetTall()
|
|
if ( self:GetHideButtons() ) then BtnHeight = 0 end
|
|
|
|
local TrackSize = self:GetWide() - BtnHeight * 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 Wide = self:GetTall()
|
|
local BtnHeight = Wide
|
|
if ( self:GetHideButtons() ) then BtnHeight = 0 end
|
|
local Scroll = self:GetScroll() / self.CanvasSize
|
|
local BarSize = math.max( self:BarScale() * ( self:GetWide() - ( BtnHeight * 2 ) ), 10 )
|
|
local Track = self:GetWide() - ( BtnHeight * 2 ) - BarSize
|
|
Track = Track + 1
|
|
|
|
Scroll = Scroll * Track
|
|
|
|
self.btnGrip:SetPos( BtnHeight + Scroll, 0 )
|
|
self.btnGrip:SetSize( BarSize, Wide )
|
|
|
|
if ( BtnHeight > 0 ) then
|
|
self.btnLeft:SetPos( 0, 0, Wide, Wide )
|
|
self.btnLeft:SetSize( BtnHeight, Wide )
|
|
|
|
self.btnRight:SetPos( self:GetWide() - BtnHeight, 0 )
|
|
self.btnRight:SetSize(BtnHeight, Wide )
|
|
|
|
self.btnLeft:SetVisible( true )
|
|
self.btnRight:SetVisible( true )
|
|
else
|
|
self.btnLeft:SetVisible( false )
|
|
self.btnRight:SetVisible( false )
|
|
self.btnRight:SetSize( BtnHeight, Wide )
|
|
self.btnLeft:SetSize( BtnHeight, Wide )
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
|
|
do
|
|
local PANEL = vgui.Register("pac_scrollpanel_horizontal", {}, "DPanel")
|
|
|
|
AccessorFunc( PANEL, "Padding", "Padding" )
|
|
AccessorFunc( PANEL, "pnlCanvas", "Canvas" )
|
|
|
|
function PANEL:Init()
|
|
|
|
self.pnlCanvas = vgui.Create( "Panel", self )
|
|
self.pnlCanvas.OnMousePressed = function( self, code ) self:GetParent():OnMousePressed( code ) end
|
|
self.pnlCanvas:SetMouseInputEnabled( true )
|
|
self.pnlCanvas.PerformLayout = function( pnl )
|
|
|
|
self:PerformLayout()
|
|
self:InvalidateParent()
|
|
|
|
end
|
|
|
|
-- Create the scroll bar
|
|
self.VBar = vgui.Create( "pac_horizontal_scrollbar", self )
|
|
self.VBar:Dock( BOTTOM )
|
|
|
|
self:SetPadding( 0 )
|
|
self:SetMouseInputEnabled( true )
|
|
|
|
-- This turns off the engine drawing
|
|
self:SetPaintBackgroundEnabled( false )
|
|
self:SetPaintBorderEnabled( false )
|
|
self:SetPaintBackground( false )
|
|
|
|
end
|
|
|
|
function PANEL:AddItem( pnl )
|
|
|
|
pnl:SetParent( self:GetCanvas() )
|
|
|
|
end
|
|
|
|
function PANEL:OnChildAdded( child )
|
|
|
|
self:AddItem( child )
|
|
|
|
end
|
|
|
|
function PANEL:SizeToContents()
|
|
|
|
self:SetSize( self.pnlCanvas:GetSize() )
|
|
|
|
end
|
|
|
|
function PANEL:GetVBar()
|
|
|
|
return self.VBar
|
|
|
|
end
|
|
|
|
function PANEL:GetCanvas()
|
|
|
|
return self.pnlCanvas
|
|
|
|
end
|
|
|
|
function PANEL:InnerWidth()
|
|
|
|
return self:GetCanvas():GetTall()
|
|
|
|
end
|
|
|
|
function PANEL:Rebuild()
|
|
|
|
self:GetCanvas():SizeToChildren( true, false )
|
|
|
|
-- Although this behaviour isn't exactly implied, center vertically too
|
|
if ( self.m_bNoSizing && self:GetCanvas():GetWide() < self:GetWide() ) then
|
|
|
|
self:GetCanvas():SetPos( ( self:GetWide() - self:GetCanvas():GetWide() ) * 0.5, 0 )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
function PANEL:OnMouseWheeled( dlta )
|
|
|
|
return self.VBar:OnMouseWheeled( dlta )
|
|
|
|
end
|
|
|
|
function PANEL:OnVScroll( iOffset )
|
|
|
|
self.pnlCanvas:SetPos( iOffset, 0 )
|
|
|
|
end
|
|
|
|
function PANEL:ScrollToChild( panel )
|
|
|
|
self:PerformLayout()
|
|
|
|
local x, y = self.pnlCanvas:GetChildPosition( panel )
|
|
local w, h = panel:GetSize()
|
|
|
|
x = x + w * 0.5
|
|
x = x - self:GetWide() * 0.5
|
|
|
|
self.VBar:AnimateTo( x, 0.5, 0, 0.5 )
|
|
|
|
end
|
|
|
|
function PANEL:PerformLayout()
|
|
|
|
local Tall = self.pnlCanvas:GetWide()
|
|
local Wide = self:GetWide()
|
|
local YPos = 0
|
|
|
|
self:Rebuild()
|
|
|
|
self.VBar:SetUp( self:GetWide(), self.pnlCanvas:GetWide() )
|
|
YPos = self.VBar:GetOffset()
|
|
|
|
if ( self.VBar.Enabled ) then Wide = Wide - self.VBar:GetWide() end
|
|
|
|
self.pnlCanvas:SetPos( YPos, 0 )
|
|
self.pnlCanvas:SetWide( Wide )
|
|
|
|
self:Rebuild()
|
|
|
|
if ( Tall != self.pnlCanvas:GetWide() ) then
|
|
self.VBar:SetScroll( self.VBar:GetScroll() ) -- Make sure we are not too far down!
|
|
end
|
|
|
|
end
|
|
|
|
function PANEL:Clear()
|
|
|
|
return self.pnlCanvas:Clear()
|
|
|
|
end
|
|
end |