mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 05:43:46 +03:00
Upload
This commit is contained in:
286
lua/vgui/dtilelayout.lua
Normal file
286
lua/vgui/dtilelayout.lua
Normal file
@@ -0,0 +1,286 @@
|
||||
--[[
|
||||
| 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_iSpaceX", "SpaceX" )
|
||||
AccessorFunc( PANEL, "m_iSpaceY", "SpaceY" )
|
||||
AccessorFunc( PANEL, "m_iBorder", "Border" )
|
||||
AccessorFunc( PANEL, "m_iBaseSize", "BaseSize" )
|
||||
AccessorFunc( PANEL, "m_iMinHeight", "MinHeight" )
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self:SetDropPos( "46" )
|
||||
self:SetMinHeight( 1 )
|
||||
|
||||
self:SetSpaceX( 0 )
|
||||
self:SetSpaceY( 0 )
|
||||
self:SetBorder( 0 )
|
||||
self:SetBaseSize( 64 )
|
||||
|
||||
self.LastW = 0
|
||||
self.LastH = 0
|
||||
|
||||
self.Tiles = {}
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Layout()
|
||||
|
||||
self.LastW = 0
|
||||
self.LastH = 0
|
||||
self:InvalidateLayout()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:FitsInTile( x, y, w, h )
|
||||
|
||||
for a = x, x + ( w - 1 ) do
|
||||
for b = y, y + ( h - 1 ) do
|
||||
|
||||
if ( self:GetTile( a, b ) == 1 ) then
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function PANEL:FindFreeTile( x, y, w, h )
|
||||
|
||||
x = x or 1
|
||||
y = y or 1
|
||||
|
||||
local span = math.floor( ( self:GetWide() - self:GetBorder() * 2 + self:GetSpaceX() ) / ( self:GetBaseSize() + self:GetSpaceX() ) )
|
||||
if ( span < 1 ) then span = 1 end
|
||||
|
||||
for i = 1, span do
|
||||
|
||||
-- Too long to fit on this line
|
||||
if ( ( i + ( w - 1 ) ) > span ) then
|
||||
|
||||
-- If we're on the first part
|
||||
-- and the line is empty
|
||||
-- add it. It might be too long to fit on anyway
|
||||
if ( i == 1 && self:FitsInTile( i, y, w, h ) ) then
|
||||
return i, y
|
||||
end
|
||||
|
||||
break
|
||||
end
|
||||
|
||||
if ( self:FitsInTile( i, y, w, h ) ) then
|
||||
return i, y
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return self:FindFreeTile( 1, y + 1, w, h )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:ClearTiles()
|
||||
|
||||
self.Tiles = {}
|
||||
|
||||
end
|
||||
|
||||
function PANEL:GetTile( x, y )
|
||||
|
||||
if ( !self.Tiles[y] ) then
|
||||
return nil
|
||||
end
|
||||
|
||||
return self.Tiles[y][x]
|
||||
|
||||
end
|
||||
|
||||
function PANEL:SetTile( x, y, val )
|
||||
|
||||
if ( !self.Tiles[y] ) then
|
||||
self.Tiles[y] = {}
|
||||
end
|
||||
|
||||
self.Tiles[y][x] = val
|
||||
|
||||
end
|
||||
|
||||
function PANEL:ConsumeTiles( x, y, w, h )
|
||||
|
||||
for a = x, x + ( w - 1 ) do
|
||||
for b = y, y + ( h - 1 ) do
|
||||
self:SetTile( a, b, 1 )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:LayoutTiles()
|
||||
|
||||
local StartLine = 1
|
||||
local tilesize = self:GetBaseSize()
|
||||
local MaxWidth = math.floor( ( self:GetWide() - self:GetBorder() * 2 + self:GetSpaceX() ) / ( tilesize + self:GetSpaceX() ) )
|
||||
|
||||
self:ClearTiles()
|
||||
|
||||
for k, v in ipairs( self:GetChildren() ) do
|
||||
|
||||
if ( !v:IsVisible() ) then continue end
|
||||
|
||||
local w = math.ceil( v:GetWide() / ( tilesize + self:GetSpaceX() ) )
|
||||
local h = math.ceil( v:GetTall() / ( tilesize + self:GetSpaceY() ) )
|
||||
|
||||
if ( v.OwnLine ) then
|
||||
w = MaxWidth
|
||||
end
|
||||
|
||||
local x, y = self:FindFreeTile( 1, StartLine, w, h )
|
||||
|
||||
v:SetPos( self:GetBorder() + ( x - 1 ) * ( tilesize + self:GetSpaceX() ), self:GetBorder() + ( y - 1 ) * ( tilesize + self:GetSpaceY() ) )
|
||||
|
||||
self:ConsumeTiles( x, y, w, h )
|
||||
|
||||
if ( v.OwnLine ) then
|
||||
StartLine = y + 1
|
||||
end
|
||||
|
||||
LastX = x
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
|
||||
local ShouldLayout = false
|
||||
|
||||
if ( self.LastW != self:GetWide() ) then ShouldLayout = true end
|
||||
if ( self.LastH != self:GetTall() ) then ShouldLayout = true end
|
||||
|
||||
self.LastW = self:GetWide()
|
||||
self.LastH = self:GetTall()
|
||||
|
||||
if ( ShouldLayout ) then
|
||||
self:LayoutTiles()
|
||||
end
|
||||
|
||||
local w, h = self:ChildrenSize()
|
||||
h = math.max( h + self:GetBorder(), self:GetMinHeight() )
|
||||
|
||||
self:SetHeight( h )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnModified()
|
||||
|
||||
-- Override me
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnChildRemoved()
|
||||
|
||||
-- A panel got removed, we gotta recompress z positions
|
||||
for k, v in pairs( self:GetChildren() ) do
|
||||
v:SetZPos( k )
|
||||
end
|
||||
|
||||
self:Layout()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnChildAdded( child )
|
||||
|
||||
-- Set the Z position for child ordering. Without this self:GetChildren() might return unpredictable results
|
||||
child:SetZPos( self:ChildCount() )
|
||||
|
||||
local dn = self:GetDnD()
|
||||
if ( dn ) then
|
||||
child:Droppable( self:GetDnD() )
|
||||
end
|
||||
|
||||
if ( self:IsSelectionCanvas() ) then
|
||||
child:SetSelectable( true )
|
||||
end
|
||||
|
||||
self:Layout()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Copy()
|
||||
|
||||
local copy = vgui.Create( "DTileLayout", self:GetParent() )
|
||||
copy:CopyBase( self )
|
||||
copy:SetSortable( self:GetSortable() )
|
||||
copy:SetDnD( self:GetDnD() )
|
||||
copy:SetSpaceX( self:GetSpaceX() )
|
||||
copy:SetSpaceY( self:GetSpaceY() )
|
||||
copy:SetBorder( self:GetBorder() )
|
||||
copy:SetSelectionCanvas( self:GetSelectionCanvas() )
|
||||
copy.OnModified = self.OnModified
|
||||
|
||||
copy:CopyContents( self )
|
||||
|
||||
return copy
|
||||
|
||||
end
|
||||
|
||||
function PANEL:CopyContents( from )
|
||||
|
||||
for k, v in ipairs( from:GetChildren() ) do
|
||||
|
||||
v:Copy():SetParent( self )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
|
||||
|
||||
local pnl = vgui.Create( ClassName )
|
||||
pnl:MakeDroppable( "ExampleDraggable", false )
|
||||
pnl:SetWide( 196 )
|
||||
pnl:SetUseLiveDrag( true )
|
||||
pnl:SetSelectionCanvas( true )
|
||||
pnl:SetSpaceX( 4 )
|
||||
pnl:SetSpaceY( 8 )
|
||||
pnl:SetBorder( 10 )
|
||||
pnl:SetBaseSize( 32 )
|
||||
|
||||
for i = 1, 10 do
|
||||
|
||||
local btn = pnl:Add( "DButton" )
|
||||
btn:SetSize( 32, 32 )
|
||||
btn:SetText( i )
|
||||
|
||||
end
|
||||
|
||||
local btn_br = pnl:Add( "DButton" )
|
||||
btn_br:SetSize( 32, 32 )
|
||||
btn_br:SetText( "<br>" )
|
||||
btn_br.OwnLine = true
|
||||
|
||||
for i = 1, 10 do
|
||||
|
||||
local btn = pnl:Add( "DButton" )
|
||||
btn:SetSize( 32, 32 )
|
||||
btn:SetText( 10 + i )
|
||||
|
||||
end
|
||||
|
||||
PropertySheet:AddSheet( ClassName, pnl, nil, true, true )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "DTileLayout", "", PANEL, "DDragBase" )
|
||||
Reference in New Issue
Block a user