mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
Upload
This commit is contained in:
308
lua/vgui/dvscrollbar.lua
Normal file
308
lua/vgui/dvscrollbar.lua
Normal file
@@ -0,0 +1,308 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
--[[
|
||||
|
||||
DVScrollBar
|
||||
|
||||
Usage:
|
||||
|
||||
Place this control in your panel. You will ideally have another panel or
|
||||
control which is bigger than the original panel. This is the Canvas.
|
||||
|
||||
scrollbar:SetUp( _barsize_, _canvassize_ ) should be called whenever
|
||||
the size of your 'canvas' changes.
|
||||
|
||||
scrollbar:GetOffset() can be called to get the offset of the canvas.
|
||||
You should call this in your PerformLayout function and set the Y
|
||||
pos of your canvas to this value.
|
||||
|
||||
Example:
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
local Wide = self:GetWide()
|
||||
local YPos = 0
|
||||
|
||||
-- Place the scrollbar
|
||||
self.VBar:SetPos( self:GetWide() - 16, 0 )
|
||||
self.VBar:SetSize( 16, self:GetTall() )
|
||||
|
||||
-- Make sure the scrollbar knows how big our canvas is
|
||||
self.VBar:SetUp( self:GetTall(), self.pnlCanvas:GetTall() )
|
||||
|
||||
-- Get data from the scrollbar
|
||||
YPos = self.VBar:GetOffset()
|
||||
|
||||
-- If the scrollbar is enabled make the canvas thinner so it will fit in.
|
||||
if ( self.VBar.Enabled ) then Wide = Wide - 16 end
|
||||
|
||||
-- Position the canvas according to the scrollbar's data
|
||||
self.pnlCanvas:SetPos( self.Padding, YPos + self.Padding )
|
||||
self.pnlCanvas:SetSize( Wide - self.Padding * 2, self.pnlCanvas:GetTall() )
|
||||
|
||||
end
|
||||
|
||||
--]]
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
AccessorFunc( PANEL, "m_HideButtons", "HideButtons" )
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.Offset = 0
|
||||
self.Scroll = 0
|
||||
self.CanvasSize = 1
|
||||
self.BarSize = 1
|
||||
|
||||
self.btnUp = vgui.Create( "DButton", self )
|
||||
self.btnUp:SetText( "" )
|
||||
self.btnUp.DoClick = function( s ) s:GetParent():AddScroll( -1 ) end
|
||||
self.btnUp.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonUp", panel, w, h ) end
|
||||
|
||||
self.btnDown = vgui.Create( "DButton", self )
|
||||
self.btnDown:SetText( "" )
|
||||
self.btnDown.DoClick = function( s ) s:GetParent():AddScroll( 1 ) end
|
||||
self.btnDown.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonDown", 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 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( 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", "VScrollBar", self, w, h )
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnMousePressed()
|
||||
|
||||
local x, y = self:CursorPos()
|
||||
|
||||
local PageSize = self.BarSize
|
||||
|
||||
if ( y > self.btnGrip.y ) 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( 0, gui.MouseY() )
|
||||
|
||||
-- Uck.
|
||||
y = y - self.btnUp:GetTall()
|
||||
y = y - self.HoldPos
|
||||
|
||||
local BtnHeight = self:GetWide()
|
||||
if ( self:GetHideButtons() ) then BtnHeight = 0 end
|
||||
|
||||
local TrackSize = self:GetTall() - BtnHeight * 2 - self.btnGrip:GetTall()
|
||||
|
||||
y = y / TrackSize
|
||||
|
||||
self:SetScroll( y * 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( 0, gui.MouseY() )
|
||||
self.HoldPos = y
|
||||
|
||||
self.btnGrip.Depressed = true
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
local Wide = self:GetWide()
|
||||
local BtnHeight = Wide
|
||||
if ( self:GetHideButtons() ) then BtnHeight = 0 end
|
||||
local Scroll = self:GetScroll() / self.CanvasSize
|
||||
local BarSize = math.max( self:BarScale() * ( self:GetTall() - ( BtnHeight * 2 ) ), 10 )
|
||||
local Track = self:GetTall() - ( BtnHeight * 2 ) - BarSize
|
||||
Track = Track + 1
|
||||
|
||||
Scroll = Scroll * Track
|
||||
|
||||
self.btnGrip:SetPos( 0, BtnHeight + Scroll )
|
||||
self.btnGrip:SetSize( Wide, BarSize )
|
||||
|
||||
if ( BtnHeight > 0 ) then
|
||||
self.btnUp:SetPos( 0, 0 )
|
||||
self.btnUp:SetSize( Wide, BtnHeight )
|
||||
|
||||
self.btnDown:SetPos( 0, self:GetTall() - BtnHeight )
|
||||
self.btnDown:SetSize( Wide, BtnHeight )
|
||||
|
||||
self.btnUp:SetVisible( true )
|
||||
self.btnDown:SetVisible( true )
|
||||
else
|
||||
self.btnUp:SetVisible( false )
|
||||
self.btnDown:SetVisible( false )
|
||||
self.btnDown:SetSize( Wide, BtnHeight )
|
||||
self.btnUp:SetSize( Wide, BtnHeight )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "DVScrollBar", "A Scrollbar", PANEL, "Panel" )
|
||||
Reference in New Issue
Block a user