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

350 lines
7.6 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 = {
Init = function( self )
self:SetContentAlignment( 4 )
self:SetTextInset( 5, 0 )
self:SetFont( "DermaDefaultBold" )
end,
DoClick = function( self )
self:GetParent():Toggle()
end,
UpdateColours = function( self, skin )
if ( !self:GetParent():GetExpanded() ) then
self:SetExpensiveShadow( 0, Color( 0, 0, 0, 200 ) )
return self:SetTextStyleColor( skin.Colours.Category.Header_Closed )
end
self:SetExpensiveShadow( 1, Color( 0, 0, 0, 100 ) )
return self:SetTextStyleColor( skin.Colours.Category.Header )
end,
Paint = function( self )
-- Do nothing!
end,
GenerateExample = function()
-- Do nothing!
end
}
derma.DefineControl( "DCategoryHeader", "Category Header", PANEL, "DButton" )
local PANEL = {}
AccessorFunc( PANEL, "m_bSizeExpanded", "Expanded", FORCE_BOOL )
AccessorFunc( PANEL, "m_iContentHeight", "StartHeight" )
AccessorFunc( PANEL, "m_fAnimTime", "AnimTime" )
AccessorFunc( PANEL, "m_bDrawBackground", "PaintBackground", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDrawBackground", "DrawBackground", FORCE_BOOL ) -- deprecated
AccessorFunc( PANEL, "m_iPadding", "Padding" )
AccessorFunc( PANEL, "m_pList", "List" )
function PANEL:Init()
self.Header = vgui.Create( "DCategoryHeader", self )
self.Header:Dock( TOP )
self.Header:SetSize( 20, 20 )
self:SetSize( 16, 16 )
self:SetExpanded( true )
self:SetMouseInputEnabled( true )
self:SetAnimTime( 0.2 )
self.animSlide = Derma_Anim( "Anim", self, self.AnimSlide )
self:SetPaintBackground( true )
self:DockMargin( 0, 0, 0, 2 )
self:DockPadding( 0, 0, 0, 0 )
end
function PANEL:Add( strName )
local button = vgui.Create( "DButton", self )
button.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "CategoryButton", panel, w, h ) end
button.UpdateColours = function( panel, skin )
if ( panel.AltLine ) then
if ( !panel:IsEnabled() ) then return panel:SetTextStyleColor( skin.Colours.Category.LineAlt.Text_Disabled ) end
if ( panel.Depressed || panel.m_bSelected ) then return panel:SetTextStyleColor( skin.Colours.Category.LineAlt.Text_Selected ) end
if ( panel.Hovered ) then return panel:SetTextStyleColor( skin.Colours.Category.LineAlt.Text_Hover ) end
return panel:SetTextStyleColor( skin.Colours.Category.LineAlt.Text )
end
if ( !panel:IsEnabled() ) then return panel:SetTextStyleColor( skin.Colours.Category.Line.Text_Disabled ) end
if ( panel.Depressed || panel.m_bSelected ) then return panel:SetTextStyleColor( skin.Colours.Category.Line.Text_Selected ) end
if ( panel.Hovered ) then return panel:SetTextStyleColor( skin.Colours.Category.Line.Text_Hover ) end
return panel:SetTextStyleColor( skin.Colours.Category.Line.Text )
end
button:SetHeight( 17 )
button:SetTextInset( 4, 0 )
button:SetContentAlignment( 4 )
button:DockMargin( 1, 0, 1, 0 )
button.DoClickInternal = function()
if ( self:GetList() ) then
self:GetList():UnselectAll()
else
self:UnselectAll()
end
button:SetSelected( true )
end
button:Dock( TOP )
button:SetText( strName )
self:InvalidateLayout( true )
self:UpdateAltLines()
return button
end
function PANEL:UnselectAll()
for k, v in ipairs( self:GetChildren() ) do
if ( v.SetSelected ) then
v:SetSelected( false )
end
end
end
function PANEL:UpdateAltLines()
for k, v in ipairs( self:GetChildren() ) do
v.AltLine = k % 2 != 1
end
end
function PANEL:Think()
self.animSlide:Run()
end
function PANEL:SetLabel( strLabel )
self.Header:SetText( strLabel )
end
function PANEL:SetHeaderHeight( height )
self.Header:SetTall( height )
end
function PANEL:GetHeaderHeight()
return self.Header:GetTall()
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "CollapsibleCategory", self, w, h )
return false
end
function PANEL:SetContents( pContents )
self.Contents = pContents
self.Contents:SetParent( self )
self.Contents:Dock( FILL )
if ( !self:GetExpanded() ) then
self.OldHeight = self:GetTall()
elseif ( self:GetExpanded() && IsValid( self.Contents ) && self.Contents:GetTall() < 1 ) then
self.Contents:SizeToChildren( false, true )
self.OldHeight = self.Contents:GetTall()
self:SetTall( self.OldHeight )
end
self:InvalidateLayout( true )
end
function PANEL:SetExpanded( expanded )
self.m_bSizeExpanded = tobool( expanded )
if ( !self:GetExpanded() ) then
if ( !self.animSlide.Finished && self.OldHeight ) then return end
self.OldHeight = self:GetTall()
end
end
function PANEL:Toggle()
self:SetExpanded( !self:GetExpanded() )
self.animSlide:Start( self:GetAnimTime(), { From = self:GetTall() } )
self:InvalidateLayout( true )
self:GetParent():InvalidateLayout()
self:GetParent():GetParent():InvalidateLayout()
local open = "1"
if ( !self:GetExpanded() ) then open = "0" end
self:SetCookie( "Open", open )
self:OnToggle( self:GetExpanded() )
end
function PANEL:OnToggle( expanded )
-- Do nothing / For developers to overwrite
end
function PANEL:DoExpansion( b )
if ( self:GetExpanded() == b ) then return end
self:Toggle()
end
function PANEL:PerformLayout()
if ( IsValid( self.Contents ) ) then
if ( self:GetExpanded() ) then
self.Contents:InvalidateLayout( true )
self.Contents:SetVisible( true )
else
self.Contents:SetVisible( false )
end
end
if ( self:GetExpanded() ) then
if ( IsValid( self.Contents ) && #self.Contents:GetChildren() > 0 ) then self.Contents:SizeToChildren( false, true ) end
self:SizeToChildren( false, true )
else
if ( IsValid( self.Contents ) && !self.OldHeight ) then self.OldHeight = self.Contents:GetTall() end
self:SetTall( self:GetHeaderHeight() )
end
-- Make sure the color of header text is set
self.Header:ApplySchemeSettings()
self.animSlide:Run()
self:UpdateAltLines()
end
function PANEL:OnMousePressed( mcode )
if ( !self:GetParent().OnMousePressed ) then return end
return self:GetParent():OnMousePressed( mcode )
end
function PANEL:AnimSlide( anim, delta, data )
self:InvalidateLayout()
self:InvalidateParent()
if ( anim.Started ) then
if ( !IsValid( self.Contents ) && ( self.OldHeight || 0 ) < self.Header:GetTall() ) then
-- We are not using self.Contents and our designated height is less
-- than the header size, something is clearly wrong, try to rectify
self.OldHeight = 0
for id, pnl in ipairs( self:GetChildren() ) do
self.OldHeight = self.OldHeight + pnl:GetTall()
end
end
if ( self:GetExpanded() ) then
data.To = math.max( self.OldHeight, self:GetTall() )
else
data.To = self:GetTall()
end
end
if ( IsValid( self.Contents ) ) then self.Contents:SetVisible( true ) end
self:SetTall( Lerp( delta, data.From, data.To ) )
end
function PANEL:LoadCookies()
local Open = self:GetCookieNumber( "Open", 1 ) == 1
self:SetExpanded( Open )
self:InvalidateLayout( true )
self:GetParent():InvalidateLayout()
self:GetParent():GetParent():InvalidateLayout()
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetLabel( "Category List Test Category" )
ctrl:SetSize( 300, 300 )
ctrl:SetPadding( 10 )
ctrl:SetHeaderHeight( 32 )
-- The contents can be any panel, even a DPanelList
local Contents = vgui.Create( "DButton" )
Contents:SetText( "This is the content of the control" )
ctrl:SetContents( Contents )
ctrl:InvalidateLayout( true )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DCollapsibleCategory", "Collapsable Category Panel", PANEL, "Panel" )