Files
wnsrc/lua/vgui/dhorizontalscroller.lua
lifestorm 9c918c46e5 Upload
2024-08-04 23:12:27 +03:00

228 lines
4.9 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_iOverlap", "Overlap" )
AccessorFunc( PANEL, "m_bShowDropTargets", "ShowDropTargets", FORCE_BOOL )
function PANEL:Init()
self.Panels = {}
self.OffsetX = 0
self.FrameTime = 0
self.pnlCanvas = vgui.Create( "DDragBase", self )
self.pnlCanvas:SetDropPos( "6" )
self.pnlCanvas:SetUseLiveDrag( false )
self.pnlCanvas.OnModified = function() self:OnDragModified() end
self.pnlCanvas.UpdateDropTarget = function( Canvas, drop, pnl )
if ( !self:GetShowDropTargets() ) then return end
DDragBase.UpdateDropTarget( Canvas, drop, pnl )
end
self.pnlCanvas.OnChildAdded = function( Canvas, child )
local dn = Canvas:GetDnD()
if ( dn ) then
child:Droppable( dn )
child.OnDrop = function()
local x, y = Canvas:LocalCursorPos()
local closest, id = self.pnlCanvas:GetClosestChild( x, Canvas:GetTall() / 2 ), 0
for k, v in pairs( self.Panels ) do
if ( v == closest ) then id = k break end
end
table.RemoveByValue( self.Panels, child )
table.insert( self.Panels, id, child )
self:InvalidateLayout()
return child
end
end
end
self:SetOverlap( 0 )
self.btnLeft = vgui.Create( "DButton", self )
self.btnLeft:SetText( "" )
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.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonRight", panel, w, h ) end
end
function PANEL:GetCanvas()
return self.pnlCanvas
end
function PANEL:ScrollToChild( panel )
-- make sure our size is all good
self:InvalidateLayout( true )
local x, y = self.pnlCanvas:GetChildPosition( panel )
local w, h = panel:GetSize()
x = x + w * 0.5
x = x - self:GetWide() * 0.5
self:SetScroll( x )
end
function PANEL:SetScroll( x )
self.OffsetX = x
self:InvalidateLayout( true )
end
function PANEL:SetUseLiveDrag( bool )
self.pnlCanvas:SetUseLiveDrag( bool )
end
function PANEL:MakeDroppable( name, allowCopy )
self.pnlCanvas:MakeDroppable( name, allowCopy )
end
function PANEL:AddPanel( pnl )
table.insert( self.Panels, pnl )
pnl:SetParent( self.pnlCanvas )
self:InvalidateLayout( true )
end
function PANEL:Clear()
self.pnlCanvas:Clear()
self.Panels = {}
end
function PANEL:OnMouseWheeled( dlta )
self.OffsetX = self.OffsetX + dlta * -30
self:InvalidateLayout( true )
return true
end
function PANEL:Think()
-- Hmm.. This needs to really just be done in one place
-- and made available to everyone.
local FrameRate = VGUIFrameTime() - self.FrameTime
self.FrameTime = VGUIFrameTime()
if ( self.btnRight:IsDown() ) then
self.OffsetX = self.OffsetX + ( 500 * FrameRate )
self:InvalidateLayout( true )
end
if ( self.btnLeft:IsDown() ) then
self.OffsetX = self.OffsetX - ( 500 * FrameRate )
self:InvalidateLayout( true )
end
if ( dragndrop.IsDragging() ) then
local x, y = self:LocalCursorPos()
if ( x < 30 ) then
self.OffsetX = self.OffsetX - ( 350 * FrameRate )
elseif ( x > self:GetWide() - 30 ) then
self.OffsetX = self.OffsetX + ( 350 * FrameRate )
end
self:InvalidateLayout( true )
end
end
function PANEL:PerformLayout()
local w, h = self:GetSize()
self.pnlCanvas:SetTall( h )
local x = 0
for k, v in pairs( self.Panels ) do
if ( !IsValid( v ) ) then continue end
if ( !v:IsVisible() ) then continue end
v:SetPos( x, 0 )
v:SetTall( h )
if ( v.ApplySchemeSettings ) then v:ApplySchemeSettings() end
x = x + v:GetWide() - self.m_iOverlap
end
self.pnlCanvas:SetWide( x + self.m_iOverlap )
if ( w < self.pnlCanvas:GetWide() ) then
self.OffsetX = math.Clamp( self.OffsetX, 0, self.pnlCanvas:GetWide() - self:GetWide() )
else
self.OffsetX = 0
end
self.pnlCanvas.x = self.OffsetX * -1
self.btnLeft:SetSize( 15, 15 )
self.btnLeft:AlignLeft( 4 )
self.btnLeft:AlignBottom( 5 )
self.btnRight:SetSize( 15, 15 )
self.btnRight:AlignRight( 4 )
self.btnRight:AlignBottom( 5 )
self.btnLeft:SetVisible( self.pnlCanvas.x < 0 )
self.btnRight:SetVisible( self.pnlCanvas.x + self.pnlCanvas:GetWide() > self:GetWide() )
end
function PANEL:OnDragModified()
-- Override me
end
function PANEL:GenerateExample( classname, sheet, w, h )
local scroller = vgui.Create( "DHorizontalScroller" )
scroller:Dock( TOP )
scroller:SetHeight( 64 )
scroller:DockMargin( 5, 50, 5, 50 )
scroller:SetOverlap( -4 )
for i = 0, 16 do
local img = vgui.Create( "DImage", scroller )
img:SetImage( "scripted/breen_fakemonitor_1" )
scroller:AddPanel( img )
end
sheet:AddSheet( classname, scroller, nil, true, true )
end
derma.DefineControl( "DHorizontalScroller", "", PANEL, "Panel" )