This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 0e770b2b49
commit 94063e4369
7342 changed files with 1718932 additions and 14 deletions

255
lua/vgui/DPanPanel.lua Normal file
View File

@@ -0,0 +1,255 @@
--[[
| 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, "pnlCanvas", "Canvas" )
function PANEL:Init()
self.pnlCanvas = vgui.Create( "Panel", self )
self:GetCanvas().OnMousePressed = function( s, code )
s:GetParent():OnMousePressed( code )
end
self:GetCanvas():SetMouseInputEnabled( true )
self:GetCanvas().PerformLayout = function( pnl )
self:PerformLayout()
self:InvalidateParent()
end
function self.pnlCanvas:Think()
local mousex = math.Clamp( gui.MouseX(), 1, ScrW() - 1 )
local mousey = math.Clamp( gui.MouseY(), 1, ScrH() - 1 )
if ( self.Dragging ) then
local x = mousex - self.Dragging[1]
local y = mousey - self.Dragging[2]
self:SetPos( x, y )
self:PerformLayout()
end
if ( self.Hovered ) then
self:SetCursor( "sizeall" )
return
end
self:SetCursor( "arrow" )
end
function self.pnlCanvas:OnMousePressed( keyCode )
self.Dragging = { gui.MouseX() - self.x, gui.MouseY() - self.y }
self:MouseCapture( true )
end
function self.pnlCanvas:OnMouseReleased( keyCode )
self.Dragging = nil
self.Sizing = nil
self:MouseCapture( false )
self:InvalidateParent()
end
self:SetMouseInputEnabled( true )
--This turns off the engine drawing
self:SetPaintBackgroundEnabled( false )
self:SetPaintBorderEnabled( false )
self:SetPaintBackground( false )
end
function PANEL:Think()
if ( self.Hovered ) then
self:SetCursor( "sizeall" )
return
end
self:SetCursor( "arrow" )
end
function PANEL:OnMousePressed( ... )
self.pnlCanvas:OnMousePressed( ... )
end
function PANEL:OnMouseReleased( ... )
self.pnlCanvas:OnMouseReleased( ... )
end
function PANEL:AddItem( pnl )
pnl:SetParent( self:GetCanvas() )
end
function PANEL:OnChildAdded( child )
self:AddItem( child )
-- Anchor all children to top-left (so they are all snug)
local can = self:GetCanvas()
local mx, my
for _, p in pairs( can:GetChildren() ) do
local x, y = p:GetPos()
mx = mx or x
my = my or y
if ( x < mx ) then mx = x end
if ( y < my ) then my = y end
end
if ( mx ) then
for _, p in pairs( can:GetChildren() ) do
local x, y = p:GetPos()
p:SetPos( x - mx, y - my )
end
local x, y = can:GetPos()
can:SetPos( x + mx, y + my )
end
end
function PANEL:SizeToContents()
self:SetSize( self:GetCanvas():GetSize() )
end
function PANEL:OnScroll( x, y )
self:GetCanvas():SetPos( x, y )
end
function PANEL:ScrollToChild( panel )
self:PerformLayout()
local x, y = self:GetCanvas():GetChildPosition( panel )
local w, h = panel:GetSize()
y = y + h * 0.5
x = x + w * 0.5
y = y - self:GetTall() * 0.5
x = x - self:GetWide() * 0.5
self:OnScroll( x, y )
end
function PANEL:PerformLayout()
local can = self:GetCanvas()
can:SizeToChildren( true, true )
-- Restrict movement to the size of this panel
local x, y, w, h = can:GetBounds()
if ( w > self:GetWide() ) then
if ( x > 0 ) then
can:SetPos( 0, y )
x = 0
end
--right
if ( x + w < self:GetWide() ) then
local nx = self:GetWide() - w
can:SetPos( nx, y )
x = nx
end
end
if ( w < self:GetWide() ) then
if ( x < 0 ) then
can:SetPos( 0, y )
x = 0
end
--left
if ( x + w > self:GetWide() ) then
local nx = self:GetWide() - w
can:SetPos( nx, y )
x = nx
end
end
if ( h > self:GetTall() ) then
if ( y > 0 ) then
can:SetPos( x, 0 )
y = 0
end
--up
if ( y + h < self:GetTall() ) then
local ny = self:GetTall() - h
can:SetPos( x, ny )
y = ny
end
end
if ( h < self:GetTall() ) then
if ( y < 0 ) then
can:SetPos( x, 0 )
y = 0
end
--down
if ( y + h > self:GetTall() ) then
local ny = self:GetTall() - h
can:SetPos( x, ny )
y = ny
end
end
end
function PANEL:Clear() return self:GetCanvas():Clear() end
function PANEL:GenerateExample( class, propsheet, width, height )
local dpan = vgui.Create( "Panel" )
dpan:Dock( FILL )
propsheet:AddSheet( class, dpan )
local dpl = vgui.Create( "DPanel", dpan )
dpl:SetSize( 200, 200 )
dpl:SetPos( 100, 100 )
local panl = vgui.Create( "DPanPanel", dpl )
panl:Dock( FILL )
local bl1 = panl:Add( "DButton" )
bl1:SetText( "Small" )
local bl2 = panl:Add( "DButton" )
bl2:SetPos( 100, 100 )
bl2:SetText( "Contents" )
local dpr = vgui.Create( "DPanel", dpan )
dpr:SetWide( width / 2 )
dpr:SetSize( 200, 200 )
dpr:SetPos( 310, 100 )
local panr = vgui.Create( "DPanPanel", dpr )
panr:Dock( FILL )
local br1 = panr:Add( "DButton" )
br1:SetText( "Big" )
local br2 = panr:Add( "DButton" )
br2:SetPos( 300, 300 )
br2:SetText( "Contents" )
end
derma.DefineControl( "DPanPanel", "", PANEL, "DPanel" )

67
lua/vgui/contextbase.lua Normal file
View File

@@ -0,0 +1,67 @@
--[[
| 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 = {}
function PANEL:Init()
self.Label = vgui.Create( "DLabel", self )
self.Label:SetText( "" )
self.Label:SetDark( true )
end
function PANEL:SetConVar( cvar )
self.ConVarValue = cvar
end
function PANEL:ConVar()
return self.ConVarValue
end
function PANEL:ControlValues( kv )
self:SetConVar( kv.convar or "" )
self.Label:SetText( kv.label or "" )
end
function PANEL:PerformLayout()
local y = 5
self.Label:SetPos( 5, y )
self.Label:SetWide( self:GetWide() )
y = y + self.Label:GetTall()
y = y + 5
return y
end
function PANEL:TestForChanges()
-- You should override this function and use it to
-- check whether your convar value changed
end
function PANEL:Think()
if ( self.NextPoll && self.NextPoll > CurTime() ) then return end
self.NextPoll = CurTime() + 0.1
self:TestForChanges()
end
vgui.Register( "ContextBase", PANEL, "Panel" )

View File

@@ -0,0 +1,186 @@
--[[
| 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_bFirstPerson", "FirstPerson" )
AccessorFunc( PANEL, "m_iMoveScale", "MovementScale" )
function PANEL:Init()
self.mx = 0
self.my = 0
self.aLookAngle = angle_zero
self:SetMovementScale( 1 )
end
function PANEL:OnMousePressed( mousecode )
self:SetCursor( "none" )
self:MouseCapture( true )
self.Capturing = true
self.MouseKey = mousecode
self:SetFirstPerson( true )
self:CaptureMouse()
if ( !IsValid( self.Entity ) ) then
self.OrbitPoint = vector_origin
self.OrbitDistance = ( self.OrbitPoint - self.vCamPos ):Length()
return
end
-- Helpers for the orbit movement
local mins, maxs = self.Entity:GetModelBounds()
local center = ( mins + maxs ) / 2
local hit1 = util.IntersectRayWithPlane( self.vCamPos, self.aLookAngle:Forward(), vector_origin, Vector( 0, 0, 1 ) )
self.OrbitPoint = hit1
local hit2 = util.IntersectRayWithPlane( self.vCamPos, self.aLookAngle:Forward(), vector_origin, Vector( 0, 1, 0 ) )
if ( ( !hit1 and hit2 ) or hit2 and hit2:Distance( self.Entity:GetPos() ) < hit1:Distance( self.Entity:GetPos() ) ) then self.OrbitPoint = hit2 end
local hit3 = util.IntersectRayWithPlane( self.vCamPos, self.aLookAngle:Forward(), vector_origin, Vector( 1, 0, 0 ) )
if ( ( ( !hit1 or !hit2 ) and hit3 ) or hit3 and hit3:Distance( self.Entity:GetPos() ) < hit2:Distance( self.Entity:GetPos() ) ) then self.OrbitPoint = hit3 end
self.OrbitPoint = self.OrbitPoint or center
self.OrbitDistance = ( self.OrbitPoint - self.vCamPos ):Length()
end
function PANEL:Think()
if ( !self.Capturing ) then return end
if ( self.m_bFirstPerson ) then
return self:FirstPersonControls()
end
end
function PANEL:CaptureMouse()
local x, y = input.GetCursorPos()
local dx = x - self.mx
local dy = y - self.my
local centerx, centery = self:LocalToScreen( self:GetWide() * 0.5, self:GetTall() * 0.5 )
input.SetCursorPos( centerx, centery )
self.mx = centerx
self.my = centery
return dx, dy
end
local function IsKeyBindDown( cmd )
-- Yes, this is how engine does it for input.LookupBinding
for keyCode = 1, BUTTON_CODE_LAST do
if ( input.LookupKeyBinding( keyCode ) == cmd and input.IsKeyDown( keyCode ) ) then
return true
end
end
return false
end
function PANEL:FirstPersonControls()
local x, y = self:CaptureMouse()
local scale = self:GetFOV() / 180
x = x * -0.5 * scale
y = y * 0.5 * scale
if ( self.MouseKey == MOUSE_LEFT ) then
if ( input.IsShiftDown() ) then y = 0 end
self.aLookAngle = self.aLookAngle + Angle( y * 4, x * 4, 0 )
self.vCamPos = self.OrbitPoint - self.aLookAngle:Forward() * self.OrbitDistance
return
end
-- Look around
self.aLookAngle = self.aLookAngle + Angle( y, x, 0 )
self.aLookAngle.p = math.Clamp( self.aLookAngle.p, -90, 90 )
local Movement = vector_origin
if ( IsKeyBindDown( "+forward" ) or input.IsKeyDown( KEY_UP ) ) then
Movement = Movement + self.aLookAngle:Forward()
end
if ( IsKeyBindDown( "+back" ) or input.IsKeyDown( KEY_DOWN ) ) then
Movement = Movement - self.aLookAngle:Forward()
end
if ( IsKeyBindDown( "+moveleft" ) or input.IsKeyDown( KEY_LEFT ) ) then
Movement = Movement - self.aLookAngle:Right()
end
if ( IsKeyBindDown( "+moveright" ) or input.IsKeyDown( KEY_RIGHT ) ) then
Movement = Movement + self.aLookAngle:Right()
end
if ( IsKeyBindDown( "+jump" ) or input.IsKeyDown( KEY_SPACE ) ) then
Movement = Movement + vector_up
end
if ( IsKeyBindDown( "+duck" ) or input.IsKeyDown( KEY_LCONTROL ) ) then
Movement = Movement - vector_up
end
local speed = 0.5
if ( input.IsShiftDown() ) then speed = 4.0 end
self.vCamPos = self.vCamPos + Movement * speed * self:GetMovementScale()
end
function PANEL:OnMouseWheeled( dlta )
local scale = self:GetFOV() / 180
self.fFOV = math.Clamp( self.fFOV + dlta * -10.0 * scale, 0.001, 179 )
end
function PANEL:OnMouseReleased( mousecode )
self:SetCursor( "arrow" )
self:MouseCapture( false )
self.Capturing = false
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetSize( 300, 300 )
ctrl:SetModel( "models/props_junk/PlasticCrate01a.mdl" )
ctrl:GetEntity():SetSkin( 2 )
ctrl:SetLookAng( Angle( 45, 0, 0 ) )
ctrl:SetCamPos( Vector( -20, 0, 20 ) )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DAdjustableModelPanel", "A panel containing a model", PANEL, "DModelPanel" )

81
lua/vgui/dalphabar.lua Normal file
View File

@@ -0,0 +1,81 @@
--[[
| 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 = {}
local matGradient = Material( "vgui/gradient-u" )
local matGrid = Material( "gui/alpha_grid.png", "nocull" )
AccessorFunc( PANEL, "m_Value", "Value" )
AccessorFunc( PANEL, "m_BarColor", "BarColor" )
function PANEL:Init()
self:SetBarColor( color_white )
self:SetSize( 26, 26 )
self:SetValue( 1 )
end
function PANEL:OnCursorMoved( x, y )
if ( !input.IsMouseDown( MOUSE_LEFT ) ) then return end
local fHeight = y / self:GetTall()
fHeight = 1 - math.Clamp( fHeight, 0, 1 )
self:SetValue( fHeight )
self:OnChange( fHeight )
end
function PANEL:OnMousePressed( mcode )
self:MouseCapture( true )
self:OnCursorMoved( self:CursorPos() )
end
function PANEL:OnMouseReleased( mcode )
self:MouseCapture( false )
self:OnCursorMoved( self:CursorPos() )
end
function PANEL:OnChange( fAlpha )
end
function PANEL:Paint( w, h )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( matGrid )
local size = 128
for i = 0, math.ceil( h / size ) do
surface.DrawTexturedRect( w / 2 - size / 2, i * size, size, size )
end
surface.SetDrawColor( self.m_BarColor )
surface.SetMaterial( matGradient )
surface.DrawTexturedRect( 0, 0, w, h )
surface.DrawTexturedRect( 0, 0, w, h )
surface.SetDrawColor( 0, 0, 0, 250 )
self:DrawOutlinedRect()
surface.DrawRect( 0, ( 1 - self.m_Value ) * h - 2, w, 3 )
surface.SetDrawColor( 255, 255, 255, 250 )
surface.DrawRect( 0, ( 1 - self.m_Value ) * h - 1, w, 1 )
end
derma.DefineControl( "DAlphaBar", "", PANEL, "DPanel" )

102
lua/vgui/dbinder.lua Normal file
View File

@@ -0,0 +1,102 @@
--[[
| 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_iSelectedNumber", "SelectedNumber" )
Derma_Install_Convar_Functions( PANEL )
function PANEL:Init()
self:SetSelectedNumber( 0 )
self:SetSize( 60, 30 )
end
function PANEL:UpdateText()
local str = input.GetKeyName( self:GetSelectedNumber() )
if ( !str ) then str = "NONE" end
str = language.GetPhrase( str )
self:SetText( str )
end
function PANEL:DoClick()
self:SetText( "PRESS A KEY" )
input.StartKeyTrapping()
self.Trapping = true
end
function PANEL:DoRightClick()
self:SetText( "NONE" )
self:SetValue( 0 )
end
function PANEL:SetSelectedNumber( iNum )
self.m_iSelectedNumber = iNum
self:ConVarChanged( iNum )
self:UpdateText()
self:OnChange( iNum )
end
function PANEL:Think()
if ( input.IsKeyTrapping() && self.Trapping ) then
local code = input.CheckKeyTrapping()
if ( code ) then
if ( code == KEY_ESCAPE ) then
self:SetValue( self:GetSelectedNumber() )
else
self:SetValue( code )
end
self.Trapping = false
end
end
self:ConVarNumberThink()
end
function PANEL:SetValue( iNumValue )
self:SetSelectedNumber( iNumValue )
end
function PANEL:GetValue()
return self:GetSelectedNumber()
end
function PANEL:OnChange( iNum )
end
derma.DefineControl( "DBinder", "", PANEL, "DButton" )

View File

@@ -0,0 +1,59 @@
--[[
| 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_bgColor", "BackgroundColor" )
function PANEL:Init()
self.matPoint = Material( "gui/point.png" )
self:DockPadding( 0, 0, 0, 32 )
self:SetBackgroundColor( Color( 190, 190, 190, 230 ) )
end
function PANEL:OpenForPos( x, y, w, h )
local center = x
x = x - w * 0.5
if ( x < 10 ) then x = 10 end
y = y - h - 64
if ( y < 10 ) then y = 10 end
self:SetPos( x, y )
self:SetSize( w, h )
self.Center = center - x
end
function PANEL:PerformLayout()
end
function PANEL:Paint( w, h )
local top = h - 32
draw.RoundedBox( 8, 0, 0, w, top, self.m_bgColor )
local tipx = self.Center - 32
if ( tipx < 8 ) then tipx = 8 end
if ( tipx > w - 64 - 8 ) then tipx = w - 64 - 8 end
surface.SetDrawColor( self.m_bgColor )
surface.SetMaterial( self.matPoint )
surface.DrawTexturedRect( self.Center - 32, top, 64, 32 )
end
derma.DefineControl( "DBubbleContainer", "", PANEL, "DPanel" )

176
lua/vgui/dbutton.lua Normal file
View File

@@ -0,0 +1,176 @@
--[[
| 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_bBorder", "DrawBorder", FORCE_BOOL )
function PANEL:Init()
self:SetContentAlignment( 5 )
--
-- These are Lua side commands
-- Defined above using AccessorFunc
--
self:SetDrawBorder( true )
self:SetPaintBackground( true )
self:SetTall( 22 )
self:SetMouseInputEnabled( true )
self:SetKeyboardInputEnabled( true )
self:SetCursor( "hand" )
self:SetFont( "DermaDefault" )
end
function PANEL:IsDown()
return self.Depressed
end
function PANEL:SetImage( img )
if ( !img ) then
if ( IsValid( self.m_Image ) ) then
self.m_Image:Remove()
end
return
end
if ( !IsValid( self.m_Image ) ) then
self.m_Image = vgui.Create( "DImage", self )
end
self.m_Image:SetImage( img )
self.m_Image:SizeToContents()
self:InvalidateLayout()
end
PANEL.SetIcon = PANEL.SetImage
function PANEL:SetMaterial( mat )
if ( !mat ) then
if ( IsValid( self.m_Image ) ) then
self.m_Image:Remove()
end
return
end
if ( !IsValid( self.m_Image ) ) then
self.m_Image = vgui.Create( "DImage", self )
end
self.m_Image:SetMaterial( mat )
self.m_Image:SizeToContents()
self:InvalidateLayout()
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "Button", self, w, h )
--
-- Draw the button text
--
return false
end
function PANEL:UpdateColours( skin )
if ( !self:IsEnabled() ) then return self:SetTextStyleColor( skin.Colours.Button.Disabled ) end
if ( self:IsDown() || self.m_bSelected ) then return self:SetTextStyleColor( skin.Colours.Button.Down ) end
if ( self.Hovered ) then return self:SetTextStyleColor( skin.Colours.Button.Hover ) end
return self:SetTextStyleColor( skin.Colours.Button.Normal )
end
function PANEL:PerformLayout( w, h )
--
-- If we have an image we have to place the image on the left
-- and make the text align to the left, then set the inset
-- so the text will be to the right of the icon.
--
if ( IsValid( self.m_Image ) ) then
local targetSize = math.min( self:GetWide() - 4, self:GetTall() - 4 )
local imgW, imgH = self.m_Image.ActualWidth, self.m_Image.ActualHeight
local zoom = math.min( targetSize / imgW, targetSize / imgH, 1 )
local newSizeX = math.ceil( imgW * zoom )
local newSizeY = math.ceil( imgH * zoom )
self.m_Image:SetWide( newSizeX )
self.m_Image:SetTall( newSizeY )
if ( self:GetWide() < self:GetTall() ) then
self.m_Image:SetPos( 4, ( self:GetTall() - self.m_Image:GetTall() ) * 0.5 )
else
self.m_Image:SetPos( 2 + ( targetSize - self.m_Image:GetWide() ) * 0.5, ( self:GetTall() - self.m_Image:GetTall() ) * 0.5 )
end
self:SetTextInset( self.m_Image:GetWide() + 16, 0 )
end
DLabel.PerformLayout( self, w, h )
end
function PANEL:SetConsoleCommand( strName, strArgs )
self.DoClick = function( slf, val )
RunConsoleCommand( strName, strArgs )
end
end
function PANEL:SizeToContents()
local w, h = self:GetContentSize()
self:SetSize( w + 8, h + 4 )
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetText( "Example Button" )
ctrl:SetWide( 200 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
local PANEL = derma.DefineControl( "DButton", "A standard Button", PANEL, "DLabel" )
PANEL = table.Copy( PANEL )
function PANEL:SetActionFunction( func )
self.DoClick = function( slf, val ) func( slf, "Command", 0, 0 ) end
end
-- No example for this control. Should we remove this completely?
function PANEL:GenerateExample( class, tabs, w, h )
end
derma.DefineControl( "Button", "Backwards Compatibility", PANEL, "DLabel" )

View File

@@ -0,0 +1,349 @@
--[[
| 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" )

View File

@@ -0,0 +1,81 @@
--[[
| 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 = {}
function PANEL:Init()
self.pnlCanvas:DockPadding( 2, 2, 2, 2 )
end
function PANEL:AddItem( item )
item:Dock( TOP )
DScrollPanel.AddItem( self, item )
self:InvalidateLayout()
end
function PANEL:Add( name )
local Category = vgui.Create( "DCollapsibleCategory", self )
Category:SetLabel( name )
Category:SetList( self )
self:AddItem( Category )
return Category
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "CategoryList", self, w, h )
return false
end
function PANEL:UnselectAll()
for k, v in ipairs( self:GetChildren() ) do
if ( v.UnselectAll ) then
v:UnselectAll()
end
end
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetSize( 300, 300 )
local Cat = ctrl:Add( "Test category with text contents" )
Cat:Add( "Item 1" )
Cat:Add( "Item 2" )
-- The contents can be any panel, even a DPanelList
local Cat2 = ctrl:Add( "Test category with panel contents" )
Cat2:SetTall( 100 )
local Contents = vgui.Create( "DButton" )
Contents:SetText( "This is the content of the category" )
Cat2:SetContents( Contents )
ctrl:InvalidateLayout( true )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DCategoryList", "", PANEL, "DScrollPanel" )

205
lua/vgui/dcheckbox.lua Normal file
View File

@@ -0,0 +1,205 @@
--[[
| 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_bChecked", "Checked", FORCE_BOOL )
Derma_Hook( PANEL, "Paint", "Paint", "CheckBox" )
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "CheckBox" )
Derma_Hook( PANEL, "PerformLayout", "Layout", "CheckBox" )
Derma_Install_Convar_Functions( PANEL )
function PANEL:Init()
self:SetSize( 15, 15 )
self:SetText( "" )
end
function PANEL:IsEditing()
return self.Depressed
end
function PANEL:SetValue( val )
if ( tonumber( val ) == 0 ) then val = 0 end -- Tobool bugs out with "0.00"
val = tobool( val )
self:SetChecked( val )
self.m_bValue = val
self:OnChange( val )
if ( val ) then val = "1" else val = "0" end
self:ConVarChanged( val )
self:SetCookie( "checked", val )
end
function PANEL:DoClick()
self:Toggle()
end
function PANEL:Toggle()
self:SetValue( !self:GetChecked() )
end
function PANEL:OnChange( bVal )
-- For override
end
function PANEL:Think()
self:ConVarStringThink()
end
function PANEL:LoadCookies()
self:SetValue( self:GetCookie( "checked" ) )
end
-- No example for this control
function PANEL:GenerateExample( class, tabs, w, h )
end
derma.DefineControl( "DCheckBox", "Simple Checkbox", PANEL, "DButton" )
--[[---------------------------------------------------------
DCheckBoxLabel
-----------------------------------------------------------]]
local PANEL = {}
AccessorFunc( PANEL, "m_iIndent", "Indent" )
function PANEL:Init()
self:SetTall( 16 )
self.Button = vgui.Create( "DCheckBox", self )
self.Button.OnChange = function( _, val ) self:OnChange( val ) end
self.Label = vgui.Create( "DLabel", self )
self.Label:SetMouseInputEnabled( true )
self.Label.DoClick = function() self:Toggle() end
end
function PANEL:SetDark( b )
self.Label:SetDark( b )
end
function PANEL:SetBright( b )
self.Label:SetBright( b )
end
function PANEL:SetConVar( cvar )
self.Button:SetConVar( cvar )
end
function PANEL:SetValue( val )
self.Button:SetValue( val )
end
function PANEL:SetChecked( val )
self.Button:SetChecked( val )
end
function PANEL:GetChecked( val )
return self.Button:GetChecked()
end
function PANEL:Toggle()
self.Button:Toggle()
end
function PANEL:PerformLayout()
local x = self.m_iIndent || 0
self.Button:SetSize( 15, 15 )
self.Button:SetPos( x, math.floor( ( self:GetTall() - self.Button:GetTall() ) / 2 ) )
self.Label:SizeToContents()
self.Label:SetPos( x + self.Button:GetWide() + 9, math.floor( ( self:GetTall() - self.Label:GetTall() ) / 2 ) )
end
function PANEL:SetTextColor( color )
self.Label:SetTextColor( color )
end
function PANEL:SizeToContents()
self:InvalidateLayout( true ) -- Update the size of the DLabel and the X offset
self:SetWide( self.Label.x + self.Label:GetWide() )
self:SetTall( math.max( self.Button:GetTall(), self.Label:GetTall() ) )
self:InvalidateLayout() -- Update the positions of all children
end
function PANEL:SetText( text )
self.Label:SetText( text )
self:SizeToContents()
end
function PANEL:SetFont( font )
self.Label:SetFont( font )
self:SizeToContents()
end
function PANEL:GetText()
return self.Label:GetText()
end
-- Just pass this to the checkbox itself.
function PANEL:SetCookieName( str )
self.Button:SetCookieName( str )
end
function PANEL:Paint()
end
function PANEL:OnChange( bVal )
-- For override
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetText( "CheckBox" )
ctrl:SetWide( 200 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DCheckBoxLabel", "Simple Checkbox", PANEL, "DPanel" )

86
lua/vgui/dcolorbutton.lua Normal file
View File

@@ -0,0 +1,86 @@
--[[
| 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 = {}
local matGrid = Material( "gui/alpha_grid.png", "nocull" )
AccessorFunc( PANEL, "m_bBorder", "DrawBorder", FORCE_BOOL )
AccessorFunc( PANEL, "m_bSelected", "Selected", FORCE_BOOL )
AccessorFunc( PANEL, "m_Color", "Color" )
AccessorFunc( PANEL, "m_PanelID", "ID" )
function PANEL:Init()
self:SetSize( 10, 10 )
self:SetMouseInputEnabled( true )
self:SetText( "" )
self:SetCursor( "hand" )
self:SetZPos( 0 )
self:SetColor( Color( 255, 0, 255 ) )
end
function PANEL:IsDown()
return self.Depressed
end
function PANEL:SetColor( color, hideTooltip )
if ( !hideTooltip ) then
local colorStr = "R: " .. color.r .. "\nG: " .. color.g .. "\nB: " .. color.b .. "\nA: " .. color.a
self:SetTooltip( colorStr )
end
self.m_Color = color
end
function PANEL:Paint( w, h )
if ( self:GetColor().a < 255 ) then -- Grid for Alpha
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( matGrid )
local size = math.max( 128, math.max( w, h ) )
local x, y = w / 2 - size / 2, h / 2 - size / 2
surface.DrawTexturedRect( x, y , size, size )
end
surface.SetDrawColor( self:GetColor() )
self:DrawFilledRect()
surface.SetDrawColor( 0, 0, 0, 200 )
surface.DrawRect( 0, 0, w, 1 )
surface.DrawRect( 0, 0, 1, h )
return false
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetSize( 64, 64 )
ctrl:SetColor( Color( 255, 0, 0, 128 ) )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DColorButton", "A Color Button", PANEL, "DLabel" )

87
lua/vgui/dcolorcombo.lua Normal file
View File

@@ -0,0 +1,87 @@
--[[
| 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_Color", "Color" )
function PANEL:Init()
self:SetSize( 256, 256 )
self:BuildControls()
self:SetColor( color_white )
end
function PANEL:BuildControls()
--
-- Mixer
--
local mixer = self:Add( "DColorMixer" )
mixer:Dock( FILL )
mixer:DockMargin( 8, 0, 8, 8 )
mixer:SetPalette( false )
mixer:SetAlphaBar( false )
mixer:SetWangs( false )
mixer.ValueChanged = function( slf, color )
self.m_bEditing = true
self:OnValueChanged( color )
self.m_Color = color
self.m_bEditing = false
end
self.Mixer = mixer
self:AddSheet( "", mixer, "icon16/color_wheel.png" )
--
-- Palettes
--
local ctrl = self:Add( "DColorPalette" )
ctrl:Dock( FILL )
ctrl:DockMargin( 8, 0, 8, 8 )
ctrl:SetButtonSize( 16 )
ctrl:SetNumRows( 35 )
ctrl:Reset()
ctrl.OnValueChanged = function( slf, color )
self.m_bEditing = true
self.Mixer:SetColor( color )
self:OnValueChanged( color )
self.m_Color = color
self.m_bEditing = false
end
self.Palette = ctrl
self:AddSheet( "", ctrl, "icon16/palette.png" )
end
function PANEL:IsEditing()
return self.m_bEditing
end
function PANEL:OnValueChanged( newcol )
-- For override
end
function PANEL:SetColor( newcol )
self.m_Color = newcol
self.Mixer:SetColor( newcol )
self.Palette:SetColor( newcol )
end
derma.DefineControl( "DColorCombo", "", PANEL, "DPropertySheet" )

124
lua/vgui/dcolorcube.lua Normal file
View File

@@ -0,0 +1,124 @@
--[[
| 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_Hue", "Hue" )
AccessorFunc( PANEL, "m_BaseRGB", "BaseRGB" )
AccessorFunc( PANEL, "m_OutRGB", "RGB" )
AccessorFunc( PANEL, "m_DefaultColor", "DefaultColor" )
function PANEL:Init()
self:SetImage( "vgui/minixhair" )
self.Knob:NoClipping( false )
self.BGSaturation = vgui.Create( "DImage", self )
self.BGSaturation:SetImage( "vgui/gradient-r" )
self.BGValue = vgui.Create( "DImage", self )
self.BGValue:SetImage( "vgui/gradient-d" )
self.BGValue:SetImageColor( color_black )
self:SetBaseRGB( Color( 255, 0, 0 ) )
self:SetRGB( Color( 255, 0, 0 ) )
self:SetColor( Color( 255, 0, 0 ) )
self:SetLockX( nil )
self:SetLockY( nil )
self:SetDefaultColor( color_white )
end
function PANEL:PerformLayout( w, h )
DSlider.PerformLayout( self, w, h )
self.BGSaturation:StretchToParent( 0, 0, 0, 0 )
self.BGSaturation:SetZPos( -9 )
self.BGValue:StretchToParent( 0, 0, 0, 0 )
self.BGValue:SetZPos( -8 )
end
function PANEL:ResetToDefaultValue()
self:SetColor( self:GetDefaultColor() )
self:OnUserChanged( self.m_OutRGB )
end
function PANEL:Paint()
surface.SetDrawColor( self.m_BaseRGB.r, self.m_BaseRGB.g, self.m_BaseRGB.b, 255 )
self:DrawFilledRect()
end
function PANEL:PaintOver()
surface.SetDrawColor( 0, 0, 0, 250 )
self:DrawOutlinedRect()
end
function PANEL:TranslateValues( x, y )
self:UpdateColor( x, y )
self:OnUserChanged( self.m_OutRGB )
return x, y
end
function PANEL:UpdateColor( x, y )
x = x or self:GetSlideX()
y = y or self:GetSlideY()
local value = 1 - y
local saturation = 1 - x
local h = ColorToHSV( self.m_BaseRGB )
local color = HSVToColor( h, saturation, value )
self:SetRGB( color )
end
function PANEL:OnUserChanged( color )
-- Override me
end
function PANEL:SetColor( color )
local h, s, v = ColorToHSV( color )
self:SetBaseRGB( HSVToColor( h, 1, 1 ) )
self:SetSlideY( 1 - v )
self:SetSlideX( 1 - s )
self:UpdateColor()
end
function PANEL:SetBaseRGB( color )
self.m_BaseRGB = color
self:UpdateColor()
end
derma.DefineControl( "DColorCube", "", PANEL, "DSlider" )

395
lua/vgui/dcolormixer.lua Normal file
View File

@@ -0,0 +1,395 @@
--[[
| 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_ConVarR", "ConVarR" )
AccessorFunc( PANEL, "m_ConVarG", "ConVarG" )
AccessorFunc( PANEL, "m_ConVarB", "ConVarB" )
AccessorFunc( PANEL, "m_ConVarA", "ConVarA" )
AccessorFunc( PANEL, "m_bPalette", "Palette", FORCE_BOOL )
AccessorFunc( PANEL, "m_bAlpha", "AlphaBar", FORCE_BOOL )
AccessorFunc( PANEL, "m_bWangsPanel", "Wangs", FORCE_BOOL )
AccessorFunc( PANEL, "m_Color", "Color" )
local BarWide = 26
local function CreateWangFunction( self, colindex )
local function OnValueChanged( ptxt, strvar )
if ( ptxt.notuserchange ) then return end
local targetValue = tonumber( strvar ) or 0
self:GetColor()[ colindex ] = targetValue
if ( colindex == "a" ) then
self.Alpha:SetBarColor( ColorAlpha( self:GetColor(), 255 ) )
self.Alpha:SetValue( targetValue / 255 )
else
self.HSV:SetColor( self:GetColor() )
local h, s, v = ColorToHSV( self.HSV:GetBaseRGB() )
self.RGB.LastY = ( 1 - h / 360 ) * self.RGB:GetTall()
end
self:UpdateColor( self:GetColor() )
end
return OnValueChanged
end
function PANEL:Init()
self.Palette = vgui.Create( "DColorPalette", self )
self.Palette:Dock( BOTTOM )
self.Palette:SetTall( 75 )
self.Palette:SetButtonSize( 16 )
self.Palette:DockMargin( 0, 8, 0, 0 )
self.Palette:Reset()
self.Palette.DoClick = function( ctrl, color, btn )
self:SetColor( Color( color.r, color.g, color.b, self:GetAlphaBar() and color.a or 255 ) )
end
self.Palette.OnRightClickButton = function( ctrl, btn )
local m = DermaMenu()
m:AddOption( "Save Color", function() ctrl:SaveColor( btn, self:GetColor() ) end )
m:AddOption( "Reset Palette", function() ctrl:ResetSavedColors() end )
m:Open()
end
self:SetPalette( true )
-- The label
self.label = vgui.Create( "DLabel", self )
self.label:SetText( "" )
self.label:Dock( TOP )
self.label:SetDark( true )
self.label:SetVisible( false )
--The number stuff
self.WangsPanel = vgui.Create( "Panel", self )
self.WangsPanel:SetWide( 50 )
self.WangsPanel:Dock( RIGHT )
self.WangsPanel:DockMargin( 4, 0, 0, 0 )
self:SetWangs( true )
self.txtR = self.WangsPanel:Add( "DNumberWang" )
self.txtR:SetDecimals( 0 )
self.txtR:SetMinMax( 0, 255 )
self.txtR:SetTall( 20 )
self.txtR:Dock( TOP )
self.txtR:DockMargin( 0, 0, 0, 0 )
self.txtR:SetTextColor( Color( 150, 0, 0, 255 ) )
self.txtG = self.WangsPanel:Add( "DNumberWang" )
self.txtG:SetDecimals( 0 )
self.txtG:SetMinMax( 0, 255 )
self.txtG:SetTall( 20 )
self.txtG:Dock( TOP )
self.txtG:DockMargin( 0, 4, 0, 0 )
self.txtG:SetTextColor( Color( 0, 150, 0, 255 ) )
self.txtB = self.WangsPanel:Add( "DNumberWang" )
self.txtB:SetDecimals( 0 )
self.txtB:SetMinMax( 0, 255 )
self.txtB:SetTall( 20 )
self.txtB:Dock( TOP )
self.txtB:DockMargin( 0, 4, 0, 0 )
self.txtB:SetTextColor( Color( 0, 0, 150, 255 ) )
self.txtA = self.WangsPanel:Add( "DNumberWang" )
self.txtA:SetDecimals( 0 )
self.txtA:SetMinMax( 0, 255 )
self.txtA:SetTall( 20 )
self.txtA:Dock( TOP )
self.txtA:DockMargin( 0, 4, 0, 0 )
self.txtA:SetTextColor( Color( 80, 80, 80, 255 ) )
self.txtR.OnValueChanged = CreateWangFunction( self, "r" )
self.txtG.OnValueChanged = CreateWangFunction( self, "g" )
self.txtB.OnValueChanged = CreateWangFunction( self, "b" )
self.txtA.OnValueChanged = CreateWangFunction( self, "a" )
-- The colouring stuff
self.HSV = vgui.Create( "DColorCube", self )
self.HSV:Dock( FILL )
self.HSV.OnUserChanged = function( ctrl, color )
color.a = self:GetColor().a
self:UpdateColor( color )
end
self.RGB = vgui.Create( "DRGBPicker", self )
self.RGB:Dock( RIGHT )
self.RGB:SetWidth( BarWide )
self.RGB:DockMargin( 4, 0, 0, 0 )
self.RGB.OnChange = function( ctrl, color )
self:SetBaseColor( color )
end
self.Alpha = vgui.Create( "DAlphaBar", self )
self.Alpha:DockMargin( 4, 0, 0, 0 )
self.Alpha:Dock( RIGHT )
self.Alpha:SetWidth( BarWide )
self.Alpha.OnChange = function( ctrl, fAlpha )
self:GetColor().a = math.floor( fAlpha * 255 )
self:UpdateColor( self:GetColor() )
end
self:SetAlphaBar( true )
-- Layout
self:SetColor( Color( 255, 0, 0, 255 ) )
self:SetSize( 256, 230 )
self:InvalidateLayout()
self.NextConVarCheck = 0
end
function PANEL:SetLabel( text )
if ( !text or text == "" ) then
self.label:SetVisible( false )
return
end
self.label:SetText( text )
self.label:SetVisible( true )
self:InvalidateLayout()
end
function PANEL:SetPalette( bEnabled )
self.m_bPalette = bEnabled
self.Palette:SetVisible( bEnabled )
self:InvalidateLayout()
end
function PANEL:SetAlphaBar( bEnabled )
self.m_bAlpha = bEnabled
self.Alpha:SetVisible( bEnabled )
self.txtA:SetVisible( bEnabled )
self:InvalidateLayout()
end
function PANEL:SetWangs( bEnabled )
self.m_bWangsPanel = bEnabled
self.WangsPanel:SetVisible( bEnabled )
self:InvalidateLayout()
end
function PANEL:SetConVarR( cvar )
self.m_ConVarR = cvar
self:UpdateDefaultColor()
end
function PANEL:SetConVarG( cvar )
self.m_ConVarG = cvar
self:UpdateDefaultColor()
end
function PANEL:SetConVarB( cvar )
self.m_ConVarB = cvar
self:UpdateDefaultColor()
end
function PANEL:SetConVarA( cvar )
self.m_ConVarA = cvar
self:SetAlphaBar( cvar != nil )
self:UpdateDefaultColor()
end
function PANEL:UpdateDefaultColor()
local function GetConVarDefault( str )
if ( str and GetConVar( str ) ) then return tonumber( GetConVar( str ):GetDefault() ) end
return 255
end
local defRGB = Color(
GetConVarDefault( self.m_ConVarR ),
GetConVarDefault( self.m_ConVarG ),
GetConVarDefault( self.m_ConVarB ),
GetConVarDefault( self.m_ConVarA )
)
self.HSV:SetDefaultColor( defRGB )
-- Allow immediate read of convar values
self.NextConVarCheck = 0
end
function PANEL:PerformLayout( w, h )
local hue, s, v = ColorToHSV( self.HSV:GetBaseRGB() )
self.RGB.LastY = ( 1 - hue / 360 ) * self.RGB:GetTall()
end
function PANEL:Paint()
-- Invisible background!
end
function PANEL:SetColor( color )
local hue, s, v = ColorToHSV( color )
self.RGB.LastY = ( 1 - hue / 360 ) * self.RGB:GetTall()
self.HSV:SetColor( color )
self:UpdateColor( color )
end
function PANEL:SetVector( vec )
self:SetColor( Color( vec.x * 255, vec.y * 255, vec.z * 255, 255 ) )
end
function PANEL:SetBaseColor( color )
self.HSV:SetBaseRGB( color )
self.HSV:TranslateValues()
end
function PANEL:UpdateConVar( strName, strKey, color )
if ( !strName ) then return end
local col = color[ strKey ]
RunConsoleCommand( strName, tostring( col ) )
self[ "ConVarOld" .. strName ] = col
end
function PANEL:UpdateConVars( color )
self.NextConVarCheck = SysTime() + 0.2
self:UpdateConVar( self.m_ConVarR, 'r', color )
self:UpdateConVar( self.m_ConVarG, 'g', color )
self:UpdateConVar( self.m_ConVarB, 'b', color )
self:UpdateConVar( self.m_ConVarA, 'a', color )
end
function PANEL:UpdateColor( color )
self.Alpha:SetBarColor( ColorAlpha( color, 255 ) )
self.Alpha:SetValue( color.a / 255 )
if ( color.r != self.txtR:GetValue() ) then
self.txtR.notuserchange = true
self.txtR:SetValue( color.r )
self.txtR.notuserchange = nil
end
if ( color.g != self.txtG:GetValue() ) then
self.txtG.notuserchange = true
self.txtG:SetValue( color.g )
self.txtG.notuserchange = nil
end
if ( color.b != self.txtB:GetValue() ) then
self.txtB.notuserchange = true
self.txtB:SetValue( color.b )
self.txtB.notuserchange = nil
end
if ( color.a != self.txtA:GetValue() ) then
self.txtA.notuserchange = true
self.txtA:SetValue( color.a )
self.txtA.notuserchange = nil
end
self:UpdateConVars( color )
self:ValueChanged( color )
self.m_Color = color
end
function PANEL:ValueChanged( color )
-- Override
end
function PANEL:GetColor()
self.m_Color.a = 255
if ( self.Alpha:IsVisible() ) then
self.m_Color.a = math.floor( self.Alpha:GetValue() * 255 )
end
return self.m_Color
end
function PANEL:GetVector()
local col = self:GetColor()
return Vector( col.r / 255, col.g / 255, col.b / 255 )
end
function PANEL:Think()
self:ConVarThink()
end
function PANEL:ConVarThink()
-- Don't update the convars while we're changing them!
if ( input.IsMouseDown( MOUSE_LEFT ) ) then return end
if ( self.NextConVarCheck > SysTime() ) then return end
local r, changed_r = self:DoConVarThink( self.m_ConVarR )
local g, changed_g = self:DoConVarThink( self.m_ConVarG )
local b, changed_b = self:DoConVarThink( self.m_ConVarB )
local a, changed_a = 255, false
if ( self.m_ConVarA ) then
a, changed_a = self:DoConVarThink( self.m_ConVarA )
end
if ( changed_r or changed_g or changed_b or changed_a ) then
self:SetColor( Color( r, g, b, a ) )
end
end
function PANEL:DoConVarThink( convar )
if ( !convar ) then return 255, false end
local fValue = GetConVarNumber( convar )
local fOldValue = self[ "ConVarOld" .. convar ]
if ( fOldValue and fValue == fOldValue ) then return fOldValue, false end
self[ "ConVarOld" .. convar ] = fValue
return fValue, true
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetSize( 256, 256 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DColorMixer", "", PANEL, "DPanel" )

255
lua/vgui/dcolorpalette.lua Normal file
View File

@@ -0,0 +1,255 @@
--[[
| 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 = {}
local color_Error = Color( 255, 0, 255 )
AccessorFunc( PANEL, "m_ConVarR", "ConVarR" )
AccessorFunc( PANEL, "m_ConVarG", "ConVarG" )
AccessorFunc( PANEL, "m_ConVarB", "ConVarB" )
AccessorFunc( PANEL, "m_ConVarA", "ConVarA" )
AccessorFunc( PANEL, "m_buttonsize", "ButtonSize", FORCE_NUMBER )
AccessorFunc( PANEL, "m_NumRows", "NumRows", FORCE_NUMBER )
local function CreateColorTable( num_rows )
local rows = num_rows or 8
local index = 0
local ColorTable = {}
for i = 0, rows * 2 - 1 do -- HSV
local col = math.Round( math.min( i * ( 360 / ( rows * 2 ) ), 359 ) )
index = index + 1
ColorTable[ index ] = HSVToColor( 360 - col, 1, 1 )
end
for i = 0, rows - 1 do -- HSV dark
local col = math.Round( math.min( i * ( 360 / rows ), 359 ) )
index = index + 1
ColorTable[ index ] = HSVToColor( 360 - col, 1, 0.5 )
end
for i = 0, rows - 1 do -- HSV grey
local col = math.Round( math.min( i * ( 360 / rows ), 359 ) )
index = index + 1
ColorTable[ index ] = HSVToColor( 360 - col, 0.5, 0.5 )
end
for i = 0, rows - 1 do -- HSV bright
local col = math.min( i * ( 360 / rows ), 359 )
index = index + 1
ColorTable[ index ] = HSVToColor( 360 - col, 0.5, 1 )
end
for i = 0, rows - 1 do -- Greyscale
local white = 255 - math.Round( math.min( i * ( 256 / ( rows - 1 ) ), 255 ) )
index = index + 1
ColorTable[ index ] = Color( white, white, white )
end
return ColorTable
end
local function AddButton( panel, color, size, id )
local button = vgui.Create( "DColorButton", panel )
button:SetSize( size or 10, size or 10 )
button:SetID( id )
--
-- If the cookie value exists, then use it
--
local col_saved = panel:GetCookie( "col." .. id, nil )
if ( col_saved != nil ) then
color = col_saved:ToColor()
end
button:SetColor( color or color_Error )
button.DoClick = function( self )
local col = self:GetColor() or color_Error
panel:OnValueChanged( col )
panel:UpdateConVars( col )
panel:DoClick( col, button )
end
button.DoRightClick = function( self )
panel:OnRightClickButton( self )
end
return button
end
-- This stuff could be better
g_ColorPalettePanels = g_ColorPalettePanels or {}
function PANEL:Init()
self:SetSize( 80, 120 )
self:SetNumRows( 8 )
self:Reset()
self:SetCookieName( "palette" )
self:SetButtonSize( 10 )
table.insert( g_ColorPalettePanels, self )
end
-- This stuff could be better
function PANEL:NetworkColorChange()
for id, pnl in pairs( g_ColorPalettePanels ) do
if ( !IsValid( pnl ) ) then table.remove( g_ColorPalettePanels, id ) end
end
for id, pnl in pairs( g_ColorPalettePanels ) do
if ( !IsValid( pnl ) or pnl == self ) then continue end
if ( pnl:GetNumRows() != self:GetNumRows() or pnl:GetCookieName() != self:GetCookieName() ) then continue end
local tab = {}
for pid, p in ipairs( self:GetChildren() ) do
tab[ p:GetID() ] = p:GetColor()
end
pnl:SetColorButtons( tab )
end
end
function PANEL:DoClick( color, button )
-- Override
end
function PANEL:Reset()
self:SetColorButtons( CreateColorTable( self:GetNumRows() ) )
end
function PANEL:ResetSavedColors()
local tab = CreateColorTable( self:GetNumRows() )
for i, color in pairs( tab ) do
local id = tonumber( i )
if ( !id ) then break end
self:SetCookie( "col." .. id, nil )
end
self:SetColorButtons( tab )
self:NetworkColorChange()
end
function PANEL:PaintOver( w, h )
surface.SetDrawColor( 0, 0, 0, 200 )
local childW = 0
for id, child in ipairs( self:GetChildren() ) do
if ( childW + child:GetWide() > w ) then break end
childW = childW + child:GetWide()
end
surface.DrawOutlinedRect( 0, 0, childW, h )
end
function PANEL:SetColorButtons( tab )
self:Clear()
for i, color in pairs( tab or {} ) do
local id = tonumber( i )
if ( !id ) then break end
AddButton( self, color, self:GetButtonSize(), i )
end
self:InvalidateLayout()
end
function PANEL:SetButtonSize( val )
self.m_buttonsize = math.floor( val )
for k, v in ipairs( self:GetChildren() ) do
v:SetSize( self:GetButtonSize(), self:GetButtonSize() )
end
self:InvalidateLayout()
end
function PANEL:UpdateConVar( strName, strKey, color )
if ( !strName ) then return end
RunConsoleCommand( strName, tostring( color[ strKey ] ) )
end
function PANEL:UpdateConVars( color )
self:UpdateConVar( self:GetConVarR(), "r", color )
self:UpdateConVar( self:GetConVarG(), "g", color )
self:UpdateConVar( self:GetConVarB(), "b", color )
self:UpdateConVar( self:GetConVarA(), "a", color )
end
function PANEL:SaveColor( btn, color )
-- TODO: If something uses different palette size, consider that a separate palette?
-- ( i.e. for each m_NumRows value, save to a different cookie prefix/suffix? )
-- Avoid unintended color changing.
color = table.Copy( color or color_Error )
btn:SetColor( color )
self:SetCookie( "col." .. btn:GetID(), string.FromColor( color ) )
self:NetworkColorChange()
end
function PANEL:SetColor( newcol )
-- TODO: This should mark this colour as selected..
end
function PANEL:OnValueChanged( newcol )
-- For override
end
function PANEL:OnRightClickButton( btn )
-- For override
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetSize( 160, 256 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DColorPalette", "", PANEL, "DIconLayout" )

95
lua/vgui/dcolumnsheet.lua Normal file
View File

@@ -0,0 +1,95 @@
--[[
| 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, "ActiveButton", "ActiveButton" )
function PANEL:Init()
self.Navigation = vgui.Create( "DScrollPanel", self )
self.Navigation:Dock( LEFT )
self.Navigation:SetWidth( 100 )
self.Navigation:DockMargin( 10, 10, 10, 0 )
self.Content = vgui.Create( "Panel", self )
self.Content:Dock( FILL )
self.Items = {}
end
function PANEL:UseButtonOnlyStyle()
self.ButtonOnly = true
end
function PANEL:AddSheet( label, panel, material )
if ( !IsValid( panel ) ) then return end
local Sheet = {}
if ( self.ButtonOnly ) then
Sheet.Button = vgui.Create( "DImageButton", self.Navigation )
else
Sheet.Button = vgui.Create( "DButton", self.Navigation )
end
Sheet.Button:SetImage( material )
Sheet.Button.Target = panel
Sheet.Button:Dock( TOP )
Sheet.Button:SetText( label )
Sheet.Button:DockMargin( 0, 1, 0, 0 )
Sheet.Button.DoClick = function()
self:SetActiveButton( Sheet.Button )
end
Sheet.Panel = panel
Sheet.Panel:SetParent( self.Content )
Sheet.Panel:SetVisible( false )
if ( self.ButtonOnly ) then
Sheet.Button:SizeToContents()
--Sheet.Button:SetColor( Color( 150, 150, 150, 100 ) )
end
table.insert( self.Items, Sheet )
if ( !IsValid( self.ActiveButton ) ) then
self:SetActiveButton( Sheet.Button )
end
return Sheet
end
function PANEL:SetActiveButton( active )
if ( self.ActiveButton == active ) then return end
if ( self.ActiveButton and self.ActiveButton.Target ) then
self.ActiveButton.Target:SetVisible( false )
self.ActiveButton:SetSelected( false )
self.ActiveButton:SetToggle( false )
--self.ActiveButton:SetColor( Color( 150, 150, 150, 100 ) )
end
self.ActiveButton = active
active.Target:SetVisible( true )
active:SetSelected( true )
active:SetToggle( true )
--active:SetColor( color_white )
self.Content:InvalidateLayout()
end
derma.DefineControl( "DColumnSheet", "", PANEL, "Panel" )

305
lua/vgui/dcombobox.lua Normal file
View File

@@ -0,0 +1,305 @@
--[[
| 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 = {}
Derma_Hook( PANEL, "Paint", "Paint", "ComboBox" )
Derma_Install_Convar_Functions( PANEL )
AccessorFunc( PANEL, "m_bDoSort", "SortItems", FORCE_BOOL )
function PANEL:Init()
-- Create button
self.DropButton = vgui.Create( "DPanel", self )
self.DropButton.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ComboDownArrow", panel, w, h ) end
self.DropButton:SetMouseInputEnabled( false )
self.DropButton.ComboBox = self
-- Setup internals
self:SetTall( 22 )
self:Clear()
self:SetContentAlignment( 4 )
self:SetTextInset( 8, 0 )
self:SetIsMenu( true )
self:SetSortItems( true )
end
function PANEL:Clear()
self:SetText( "" )
self.Choices = {}
self.Data = {}
self.ChoiceIcons = {}
self.Spacers = {}
self.selected = nil
self:CloseMenu()
end
function PANEL:GetOptionText( index )
return self.Choices[ index ]
end
function PANEL:GetOptionData( index )
return self.Data[ index ]
end
function PANEL:GetOptionTextByData( data )
for id, dat in pairs( self.Data ) do
if ( dat == data ) then
return self:GetOptionText( id )
end
end
-- Try interpreting it as a number
for id, dat in pairs( self.Data ) do
if ( dat == tonumber( data ) ) then
return self:GetOptionText( id )
end
end
-- In case we fail
return data
end
function PANEL:PerformLayout( w, h )
self.DropButton:SetSize( 15, 15 )
self.DropButton:AlignRight( 4 )
self.DropButton:CenterVertical()
-- Make sure the text color is updated
DButton.PerformLayout( self, w, h )
end
function PANEL:ChooseOption( value, index )
self:CloseMenu()
self:SetText( value )
-- This should really be the here, but it is too late now and convar
-- changes are handled differently by different child elements
-- self:ConVarChanged( self.Data[ index ] )
self.selected = index
self:OnSelect( index, value, self.Data[ index ] )
end
function PANEL:ChooseOptionID( index )
local value = self:GetOptionText( index )
self:ChooseOption( value, index )
end
function PANEL:GetSelectedID()
return self.selected
end
function PANEL:GetSelected()
if ( !self.selected ) then return end
return self:GetOptionText( self.selected ), self:GetOptionData( self.selected )
end
function PANEL:OnSelect( index, value, data )
-- For override
end
function PANEL:OnMenuOpened( menu )
-- For override
end
function PANEL:AddSpacer()
self.Spacers[ #self.Choices ] = true
end
function PANEL:AddChoice( value, data, select, icon )
local index = table.insert( self.Choices, value )
if ( data ) then
self.Data[ index ] = data
end
if ( icon ) then
self.ChoiceIcons[ index ] = icon
end
if ( select ) then
self:ChooseOption( value, index )
end
return index
end
function PANEL:RemoveChoice( index )
if ( !isnumber( index ) ) then return end
local text = table.remove( self.Choices, index )
local data = table.remove( self.Data, index )
return text, data
end
function PANEL:IsMenuOpen()
return IsValid( self.Menu ) && self.Menu:IsVisible()
end
function PANEL:OpenMenu( pControlOpener )
if ( pControlOpener && pControlOpener == self.TextEntry ) then
return
end
-- Don't do anything if there aren't any options..
if ( #self.Choices == 0 ) then return end
-- If the menu still exists and hasn't been deleted
-- then just close it and don't open a new one.
self:CloseMenu()
-- If we have a modal parent at some level, we gotta parent to
-- that or our menu items are not gonna be selectable
local parent = self
while ( IsValid( parent ) && !parent:IsModal() ) do
parent = parent:GetParent()
end
if ( !IsValid( parent ) ) then parent = self end
self.Menu = DermaMenu( false, parent )
if ( self:GetSortItems() ) then
local sorted = {}
for k, v in pairs( self.Choices ) do
local val = tostring( v ) --tonumber( v ) || v -- This would make nicer number sorting, but SortedPairsByMemberValue doesn't seem to like number-string mixing
if ( string.len( val ) > 1 && !tonumber( val ) && val:StartsWith( "#" ) ) then val = language.GetPhrase( val:sub( 2 ) ) end
table.insert( sorted, { id = k, data = v, label = val } )
end
for k, v in SortedPairsByMemberValue( sorted, "label" ) do
local option = self.Menu:AddOption( v.data, function() self:ChooseOption( v.data, v.id ) end )
if ( self.ChoiceIcons[ v.id ] ) then
option:SetIcon( self.ChoiceIcons[ v.id ] )
end
if ( self.Spacers[ v.id ] ) then
self.Menu:AddSpacer()
end
end
else
for k, v in pairs( self.Choices ) do
local option = self.Menu:AddOption( v, function() self:ChooseOption( v, k ) end )
if ( self.ChoiceIcons[ k ] ) then
option:SetIcon( self.ChoiceIcons[ k ] )
end
if ( self.Spacers[ k ] ) then
self.Menu:AddSpacer()
end
end
end
local x, y = self:LocalToScreen( 0, self:GetTall() )
self.Menu:SetMinimumWidth( self:GetWide() )
self.Menu:Open( x, y, false, self )
self:OnMenuOpened( self.Menu )
end
function PANEL:CloseMenu()
if ( IsValid( self.Menu ) ) then
self.Menu:Remove()
end
self.Menu = nil
end
-- This really should use a convar change hook
function PANEL:CheckConVarChanges()
if ( !self.m_strConVar ) then return end
local strValue = GetConVarString( self.m_strConVar )
if ( self.m_strConVarValue == strValue ) then return end
self.m_strConVarValue = strValue
self:SetValue( self:GetOptionTextByData( self.m_strConVarValue ) )
end
function PANEL:Think()
self:CheckConVarChanges()
end
function PANEL:SetValue( strValue )
self:SetText( strValue )
end
function PANEL:DoClick()
if ( self:IsMenuOpen() ) then
return self:CloseMenu()
end
self:OpenMenu()
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:AddChoice( "Some Choice" )
ctrl:AddChoice( "Another Choice", "myData" )
ctrl:AddChoice( "Default Choice", "myData2", true )
ctrl:AddChoice( "Icon Choice", "myData3", false, "icon16/star.png" )
ctrl:SetWide( 150 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DComboBox", "", PANEL, "DButton" )

180
lua/vgui/ddragbase.lua Normal file
View File

@@ -0,0 +1,180 @@
--[[
| 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_DNDName", "DnD" )
AccessorFunc( PANEL, "m_bLiveDrag", "UseLiveDrag" )
AccessorFunc( PANEL, "m_bReadOnly", "ReadOnly" )
function PANEL:Init()
self:SetPaintBackgroundEnabled( false )
self:SetPaintBorderEnabled( false )
self:SetMouseInputEnabled( true )
self:SetPaintBackground( false )
self:SetReadOnly( false )
self:SetDropPos( "5" )
end
--
-- Determines where we can drop stuff - relative to the other children
-- Param is a string of numpad numbers, ie "852" is top middle bottom
--
function PANEL:SetDropPos( strPos )
self.bDropLeft = string.find( strPos, "4" )
self.bDropCenter = string.find( strPos, "5" )
self.bDropRight = string.find( strPos, "6" )
self.bDropTop = string.find( strPos, "8" )
self.bDropBottom = string.find( strPos, "2" )
end
function PANEL:MakeDroppable( name, bAllowCopy )
self:SetDnD( name )
if ( bAllowCopy ) then
self:Receiver( name, self.DropAction_Copy, { copy = "#spawnmenu.menu.copy_dnd", move = "#spawnmenu.menu.move" } )
else
self:Receiver( name, self.DropAction_Normal )
end
end
-- Backwards compatibility
function PANEL:DropAction_Copy( Drops, bDoDrop, Command, x, y )
self:DropAction_Normal( Drops, bDoDrop, Command, x, y )
end
function PANEL:DropAction_Simple( Drops, bDoDrop, Command, x, y )
self:SetDropTarget( 0, 0, self:GetWide(), 2 )
if ( bDoDrop ) then
for k, v in pairs( Drops ) do
v = v:OnDrop( self )
v:SetParent( self )
end
self:OnModified()
end
end
function PANEL:DropAction_Normal( Drops, bDoDrop, Command, x, y )
local closest = self:GetClosestChild( x, y )
if ( !IsValid( closest ) ) then
return self:DropAction_Simple( Drops, bDoDrop, Command, x, y )
end
-- This panel is only meant to be copied from, not edited!
if ( self:GetReadOnly() ) then return end
local h = closest:GetTall()
local w = closest:GetWide()
local disty = y - ( closest.y + h * 0.5 )
local distx = x - ( closest.x + w * 0.5 )
local drop = 0
if ( self.bDropCenter ) then drop = 5 end
if ( disty < 0 && self.bDropTop && ( drop == 0 || math.abs( disty ) > h * 0.1 ) ) then drop = 8 end
if ( disty >= 0 && self.bDropBottom && ( drop == 0 || math.abs( disty ) > h * 0.1 ) ) then drop = 2 end
if ( distx < 0 && self.bDropLeft && ( drop == 0 || math.abs( distx ) > w * 0.1 ) ) then drop = 4 end
if ( distx >= 0 && self.bDropRight && ( drop == 0 || math.abs( distx ) > w * 0.1 ) ) then drop = 6 end
self:UpdateDropTarget( drop, closest )
if ( table.HasValue( Drops, closest ) ) then return end
if ( !bDoDrop && !self:GetUseLiveDrag() ) then return end
-- This keeps the drop order the same,
-- whether we add it before an object or after
if ( drop == 6 || drop == 2 ) then
Drops = table.Reverse( Drops )
end
for k, v in pairs( Drops ) do
-- Don't drop one of our parents onto us
-- because we'll be sucked into a vortex
if ( v:IsOurChild( self ) ) then continue end
-- Copy the panel if we are told to from the DermaMenu(), or if we are moving from a read only panel to a not read only one.
if ( ( Command && Command == "copy" || ( IsValid( v:GetParent() ) && v:GetParent().GetReadOnly && v:GetParent():GetReadOnly() && v:GetParent():GetReadOnly() != self:GetReadOnly() ) ) && v.Copy ) then v = v:Copy() end
v = v:OnDrop( self )
if ( drop == 5 ) then
closest:DroppedOn( v )
end
if ( drop == 8 || drop == 4 ) then
v:SetParent( self )
v:MoveToBefore( closest )
end
if ( drop == 2 || drop == 6 ) then
v:SetParent( self )
v:MoveToAfter( closest )
end
end
self:OnModified()
end
function PANEL:OnModified()
-- For override
end
function PANEL:UpdateDropTarget( drop, pnl )
if ( drop == 5 ) then
return self:SetDropTarget( pnl.x, pnl.y, pnl:GetWide(), pnl:GetTall() )
end
if ( drop == 8 ) then
return self:SetDropTarget( pnl.x, pnl.y - 2, pnl:GetWide(), 4 )
end
if ( drop == 2 ) then
return self:SetDropTarget( pnl.x, pnl.y + pnl:GetTall() - 2, pnl:GetWide(), 4 )
end
if ( drop == 4 ) then
return self:SetDropTarget( pnl.x - 2, pnl.y - 2, 4, pnl:GetTall() )
end
if ( drop == 6 ) then
return self:SetDropTarget( pnl.x + pnl:GetWide() - 2, pnl.y, 4, pnl:GetTall() )
end
-- Unhandled!
--self:ClearDropTarget()
end
derma.DefineControl( "DDragBase", "", PANEL, "DPanel" )

88
lua/vgui/ddrawer.lua Normal file
View File

@@ -0,0 +1,88 @@
--[[
| 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_iOpenSize", "OpenSize" )
AccessorFunc( PANEL, "m_fOpenTime", "OpenTime" )
function PANEL:Init()
self.m_bOpened = false
self:SetOpenSize( 100 )
self:SetOpenTime( 0.3 )
self:SetPaintBackground( false )
self:SetSize( 0, 0 )
self.ToggleButton = vgui.Create( "DButton", self:GetParent() )
self.ToggleButton:SetSize( 16, 16 )
self.ToggleButton:SetText( "::" )
self.ToggleButton.DoClick = function()
self:Toggle()
end
self.ToggleButton.Think = function()
self.ToggleButton:CenterHorizontal()
self.ToggleButton.y = self.y - 8
end
end
function PANEL:OnRemove()
self.ToggleButton:Remove()
end
function PANEL:Think()
local w, h = self:GetParent():GetSize()
self:SetPos( 0, h - self:GetTall() )
self:SetWide( w )
end
function PANEL:Toggle()
if ( self.m_bOpened ) then
self:Close()
else
self:Open()
end
end
function PANEL:Open()
if ( self.m_bOpened == true ) then return end
self.m_bOpened = true
self:SizeTo( self:GetWide(), self.m_iOpenSize, self.m_fOpenTime )
self.ToggleButton:MoveToFront()
end
function PANEL:Close()
if ( self.m_bOpened == false ) then return end
self.m_bOpened = false
self:SizeTo( self:GetWide(), 0, self.m_fOpenTime )
self.ToggleButton:MoveToFront()
end
derma.DefineControl( "DDrawer", "", PANEL, "DPanel" )

View File

@@ -0,0 +1,138 @@
--[[
| 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 = {}
function PANEL:Init()
-- Nothing :)
end
--
-- Sets the entity to edit.
-- This can be called any time, even when another entity has been set.
--
function PANEL:SetEntity( entity )
if ( self.m_Entity == entity ) then return end
self.m_Entity = entity
self:RebuildControls()
end
--
-- Clears and rebuilds the controls. Should only really be called internally.
--
function PANEL:RebuildControls()
--
-- we're rebuilding - so clear all the old controls
--
self:Clear()
--
-- It's kewl to return here - because it will leave an empty property sheet.
--
if ( !IsValid( self.m_Entity ) ) then return end
if ( !isfunction( self.m_Entity.GetEditingData ) ) then return end
--
-- Call EditVariable for each entry in the entity's EditingData
--
local editor = self.m_Entity:GetEditingData()
local i = 1000
for name, edit in pairs( editor ) do
if ( edit.order == nil ) then edit.order = i end
i = i + 1
end
for name, edit in SortedPairsByMemberValue( editor, "order" ) do
self:EditVariable( name, edit )
end
end
--
-- Called internally. Adds an entity variable to watch.
--
function PANEL:EditVariable( varname, editdata )
if ( !istable( editdata ) ) then return end
if ( !isstring( editdata.type ) ) then return end
--
-- Create a property row in the specified category.
--
local row = self:CreateRow( editdata.category or "#entedit.general", editdata.title or varname )
--
-- This is where the real business is done. Setup creates the specific controls for
-- the 'type' (eg, Float, Boolean). If the type isn't found it reverts to a generic textbox.
--
row:Setup( editdata.type, editdata )
--
-- These functions need to be implemented for each row. This is how it
-- gets and sets the data from the entity. DataUpdate is called peridocailly
-- but only when it's not being edited.
--
row.DataUpdate = function( _ )
if ( !IsValid( self.m_Entity ) ) then self:EntityLost() return end
row:SetValue( self.m_Entity:GetNetworkKeyValue( varname ) )
end
--
-- This is called when the data has changed as a result of user input.
-- We use it to edit the value on the entity itself.
--
row.DataChanged = function( _, val )
if ( !IsValid( self.m_Entity ) ) then self:EntityLost() return end
self.m_Entity:EditValue( varname, tostring( val ) )
end
end
--
-- Called when we were editing an entity and then it became invalid (probably removed)
--
function PANEL:EntityLost()
self:Clear()
self:OnEntityLost()
end
function PANEL:OnEntityLost()
-- For override
end
--
-- Auto-refreshing - these functions are just for the benefit
-- of development. So that when this control gets auto-reloaded
-- due to editing - we can rebuild things using the new function(s).
--
PANEL.AllowAutoRefresh = true
function PANEL:PreAutoRefresh()
end
function PANEL:PostAutoRefresh()
self:RebuildControls()
end
derma.DefineControl( "DEntityProperties", "", PANEL, "DProperties" )

View File

@@ -0,0 +1,28 @@
--[[
| 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_bExpanded", "Expanded", FORCE_BOOL )
Derma_Hook( PANEL, "Paint", "Paint", "ExpandButton" )
function PANEL:Init()
self:SetSize( 15, 15 )
self:SetText( "" )
end
-- No example for this control
function PANEL:GenerateExample( class, tabs, w, h )
end
derma.DefineControl( "DExpandButton", "", PANEL, "DButton" )

337
lua/vgui/dfilebrowser.lua Normal file
View File

@@ -0,0 +1,337 @@
--[[
| 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_strName", "Name" )
AccessorFunc( PANEL, "m_strPath", "Path" )
AccessorFunc( PANEL, "m_strFilter", "FileTypes" )
AccessorFunc( PANEL, "m_strBaseFolder", "BaseFolder" )
AccessorFunc( PANEL, "m_strCurrentFolder", "CurrentFolder" )
AccessorFunc( PANEL, "m_strSearch", "Search" )
AccessorFunc( PANEL, "m_bModels", "Models" )
AccessorFunc( PANEL, "m_bOpen", "Open" )
function PANEL:Init()
self:SetPath( "GAME" )
self.Divider = self:Add( "DHorizontalDivider" )
self.Divider:Dock( FILL )
self.Divider:SetLeftWidth( 160 )
self.Divider:SetDividerWidth( 4 )
self.Divider:SetLeftMin( 100 )
self.Divider:SetRightMin( 100 )
self.Tree = self.Divider:Add( "DTree" )
self.Divider:SetLeft( self.Tree )
self.Tree.DoClick = function( _, node )
local folder = node:GetFolder()
if ( !folder ) then return end
self:SetCurrentFolder( folder )
end
end
function PANEL:SetName( strName )
if ( strName ) then
self.m_strName = tostring( strName )
else
self.m_strName = nil
end
if ( !self.bSetup ) then return end
self:SetupTree()
end
function PANEL:SetBaseFolder( strBase )
self.m_strBaseFolder = tostring( strBase )
if ( !self.bSetup ) then return end
self:SetupTree()
end
function PANEL:SetPath( strPath )
self.m_strPath = tostring( strPath )
if ( !self.bSetup ) then return end
self:SetupTree()
end
function PANEL:SetSearch( strSearch )
if ( !strSearch || strSearch == "" ) then
strSearch = "*"
end
self.m_strSearch = tostring( strSearch )
if ( !self.bSetup ) then return end
self:SetupTree()
end
function PANEL:SetFileTypes( strTypes )
self.m_strFilter = tostring( strTypes || "*.*" )
if ( !self.bSetup ) then return end
if ( self.m_strCurrentFolder ) then
self:ShowFolder( self.m_strCurrentFolder )
end
end
function PANEL:SetModels( bUseModels )
self.m_bModels = tobool( bUseModels )
if ( !self.bSetup ) then return end
self:SetupFiles()
if ( self.m_strCurrentFolder ) then
self:ShowFolder( self.m_strCurrentFolder )
end
end
function PANEL:SetCurrentFolder( strDir )
strDir = tostring( strDir )
strDir = string.Trim( strDir, "/" )
if ( self.m_strBaseFolder && !string.StartsWith( strDir, self.m_strBaseFolder ) ) then
strDir = string.Trim( self.m_strBaseFolder, "/" ) .. "/" .. string.Trim( strDir, "/" )
end
self.m_strCurrentFolder = strDir
if ( !self.bSetup ) then return end
self:ShowFolder( strDir )
end
function PANEL:SetOpen( bOpen, bAnim )
bOpen = tobool( bOpen )
self.m_bOpen = bOpen
if ( !self.bSetup ) then return end
self.FolderNode:SetExpanded( bOpen, !bAnim )
self.m_bOpen = bOpen
self:SetCookie( "Open", bOpen && "1" || "0" )
end
function PANEL:Paint( w, h )
DPanel.Paint( self, w, h )
if ( !self.bSetup ) then
self.bSetup = self:Setup()
end
end
function PANEL:SetupTree()
local name = self.m_strName
if ( !name ) then name = string.Trim( string.match( self.m_strBaseFolder, "/.+$" ) || self.m_strBaseFolder, "/" ) end
local children = self.Tree.RootNode.ChildNodes
if ( IsValid( children ) ) then
children:Clear()
end
self.FolderNode = self.Tree.RootNode:AddFolder( name, self.m_strBaseFolder, self.m_strPath, false, self.m_strSearch )
self.Tree.RootNode.ChildExpanded = function( node, bExpand )
DTree_Node.ChildExpanded( node, bExpand )
self.m_bOpen = tobool( self.FolderNode.m_bExpanded )
self:SetCookie( "Open", self.m_bOpen && "1" || "0" )
end
self.FolderNode:SetExpanded( self.m_bOpen, true )
self:SetCookie( "Open", self.m_bOpen && "1" || "0" )
self:ShowFolder()
return true
end
function PANEL:SetupFiles()
if ( IsValid( self.Files ) ) then self.Files:Remove() end
if ( self.m_bModels ) then
self.Files = self.Divider:Add( "DIconBrowser" )
self.Files:SetManual( true )
self.Files:SetBackgroundColor( Color( 234, 234, 234 ) )
else
self.Files = self.Divider:Add( "DListView" )
self.Files:SetMultiSelect( false )
self.FileHeader = self.Files:AddColumn( "Files" ).Header
self.Files.DoDoubleClick = function( pnl, _, line )
self:OnDoubleClick( string.Trim( self:GetCurrentFolder() .. "/" .. line:GetColumnText( 1 ), "/" ), line )
end
self.Files.OnRowSelected = function( pnl, _, line )
self:OnSelect( string.Trim( self:GetCurrentFolder() .. "/" .. line:GetColumnText( 1 ), "/" ), line )
end
self.Files.OnRowRightClick = function( pnl, _, line )
self:OnRightClick( string.Trim( self:GetCurrentFolder() .. "/" .. line:GetColumnText( 1 ), "/" ), line )
end
end
self.Divider:SetRight( self.Files )
if ( self.m_strCurrentFolder && self.m_strCurrentFolder != "" ) then
self:ShowFolder( self.m_strCurrentFolder )
end
return true
end
function PANEL:Setup()
if ( !self.m_strBaseFolder ) then return false end
return self:SetupTree() && self:SetupFiles()
end
function PANEL:ShowFolder( path )
if ( !IsValid( self.Files ) ) then return end
self.Files:Clear()
if ( IsValid( self.FileHeader ) ) then
self.FileHeader:SetText( path || "Files" )
end
if ( !path ) then return end
local filters = self.m_strFilter
if ( !filters || filters == "" ) then
filters = "*.*"
end
for _, filter in ipairs( string.Explode( " ", filters ) ) do
local files = file.Find( string.Trim( path .. "/" .. ( filter || "*.*" ), "/" ), self.m_strPath )
if ( !istable( files ) ) then continue end
for _, v in ipairs( files ) do
if ( self.m_bModels ) then
local icon = self.Files:Add( "SpawnIcon" )
icon:SetModel( path .. "/" .. v )
icon.DoClick = function( pnl )
if ( pnl.LastClickTime && SysTime() - pnl.LastClickTime < 0.3 ) then
self:OnDoubleClick( path .. "/" .. v, icon )
else
self:OnSelect( path .. "/" .. v, icon )
end
pnl.LastClickTime = SysTime()
end
icon.DoRightClick = function()
self:OnRightClick( path .. "/" .. v, icon )
end
else
self.Files:AddLine( v )
end
end
end
end
function PANEL:SortFiles( desc )
if ( !self:GetModels() ) then
self.Files:SortByColumn( 1, tobool( desc ) )
end
end
function PANEL:GetFolderNode()
return self.FolderNode
end
function PANEL:Clear()
DPanel.Clear( self )
self.m_strBaseFolder, self.m_strCurrentFolder, self.m_strFilter, self.m_strName, self.m_strSearch, self.Divider.m_pRight = nil
self.m_bOpen, self.m_bModels, self.m_strPath = false, false, "GAME"
self.bSetup = nil
self:Init()
end
function PANEL:LoadCookies()
self:SetOpen( self:GetCookieNumber( "Open" ), true )
end
function PANEL:OnSelect( path, pnl )
-- For override
end
function PANEL:OnDoubleClick( path, pnl )
-- For override
end
function PANEL:OnRightClick( path, pnl )
-- For override
end
function PANEL:GenerateExample( class, sheet, w, h )
local browser = vgui.Create( class )
browser:Dock( FILL )
browser:DockMargin( 5, 0, 5, 5 )
browser:SetPath( "GAME" ) -- The access path i.e. GAME, LUA, DATA etc.
browser:SetBaseFolder( "data" ) -- The root folder
browser:SetOpen( true ) -- Open the tree to show sub-folders
function browser:OnSelect( path, pnl ) -- Called when a file is clicked
-- Do something
end
sheet:AddSheet( class, browser, nil, true, true )
end
derma.DefineControl( "DFileBrowser", "A tree and list-based file browser", PANEL, "DPanel" )

314
lua/vgui/dform.lua Normal file
View File

@@ -0,0 +1,314 @@
--[[
| 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 = {}
DEFINE_BASECLASS( "DCollapsibleCategory" )
AccessorFunc( PANEL, "m_bSizeToContents", "AutoSize", FORCE_BOOL )
AccessorFunc( PANEL, "m_iSpacing", "Spacing" )
AccessorFunc( PANEL, "m_Padding", "Padding" )
function PANEL:Init()
self.Items = {}
self:SetSpacing( 4 )
self:SetPadding( 10 )
self:SetPaintBackground( true )
self:SetMouseInputEnabled( true )
self:SetKeyboardInputEnabled( true )
end
function PANEL:SetName( name )
self:SetLabel( name )
end
function PANEL:Clear()
for k, v in pairs( self.Items ) do
if ( IsValid( v ) ) then v:Remove() end
end
self.Items = {}
end
function PANEL:AddItem( left, right )
self:InvalidateLayout()
local Panel = vgui.Create( "DSizeToContents", self )
--Panel.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "CategoryButton", panel, w, h ) end
Panel:SetSizeX( false )
Panel:Dock( TOP )
Panel:DockPadding( 10, 10, 10, 0 )
Panel:InvalidateLayout()
if ( IsValid( right ) ) then
left:SetParent( Panel )
left:Dock( LEFT )
left:InvalidateLayout( true )
left:SetSize( 100, 20 )
right:SetParent( Panel )
right:SetPos( 110, 0 )
right:InvalidateLayout( true )
elseif ( IsValid( left ) ) then
left:SetParent( Panel )
left:Dock( TOP )
end
table.insert( self.Items, Panel )
end
function PANEL:TextEntry( strLabel, strConVar )
local left = vgui.Create( "DLabel", self )
left:SetText( strLabel )
left:SetDark( true )
local right = vgui.Create( "DTextEntry", self )
right:SetConVar( strConVar )
right:Dock( TOP )
self:AddItem( left, right )
return right, left
end
function PANEL:PropSelect( label, convar, models, height )
local props = vgui.Create( "PropSelect", self )
props:SetConVar( convar or "" )
props.Label:SetText( label or "" )
props.Height = height or 2
local firstKey, firstVal = next( models )
if ( firstVal.model == nil ) then
-- Lowercase model names for sorting purposes
local models_lower = table.LowerKeyNames( models )
-- list.Get where key is the model and value is the cvars to set when that model is selected
for k, v in SortedPairs( models_lower ) do
props:AddModel( k, v )
end
else
local tmp = {} -- HACK: Order by skin too
for k, v in SortedPairsByMemberValue( models, "model" ) do
tmp[ k ] = v.model:lower() .. ( v.skin or 0 )
end
for k, v in SortedPairsByValue( tmp ) do
v = models[ k ]
local icon = props:AddModelEx( k, v.model, v.skin or 0 )
if ( v.tooltip ) then icon:SetTooltip( v.tooltip ) end
end
end
props:InvalidateLayout( true )
self:AddPanel( props )
return props
end
function PANEL:ComboBox( strLabel, strConVar )
local left = vgui.Create( "DLabel", self )
left:SetText( strLabel )
left:SetDark( true )
local right = vgui.Create( "DComboBox", self )
right:SetConVar( strConVar )
right:Dock( FILL )
function right:OnSelect( index, value, data )
if ( !self.m_strConVar ) then return end
RunConsoleCommand( self.m_strConVar, tostring( data or value ) )
end
self:AddItem( left, right )
return right, left
end
function PANEL:NumberWang( strLabel, strConVar, numMin, numMax, numDecimals )
local left = vgui.Create( "DLabel", self )
left:SetText( strLabel )
left:SetDark( true )
local right = vgui.Create( "DNumberWang", self )
right:SetMinMax( numMin, numMax )
if ( numDecimals != nil ) then right:SetDecimals( numDecimals ) end
right:SetConVar( strConVar )
right:SizeToContents()
self:AddItem( left, right )
return right, left
end
function PANEL:NumSlider( strLabel, strConVar, numMin, numMax, numDecimals )
local left = vgui.Create( "DNumSlider", self )
left:SetText( strLabel )
left:SetMinMax( numMin, numMax )
left:SetDark( true )
if ( numDecimals != nil ) then left:SetDecimals( numDecimals ) end
left:SetConVar( strConVar )
left:SizeToContents()
self:AddItem( left, nil )
return left
end
function PANEL:CheckBox( strLabel, strConVar )
local left = vgui.Create( "DCheckBoxLabel", self )
left:SetText( strLabel )
left:SetDark( true )
left:SetConVar( strConVar )
self:AddItem( left, nil )
return left
end
function PANEL:Help( strHelp )
local left = vgui.Create( "DLabel", self )
left:SetDark( true )
left:SetWrap( true )
left:SetTextInset( 0, 0 )
left:SetText( strHelp )
left:SetContentAlignment( 7 )
left:SetAutoStretchVertical( true )
left:DockMargin( 8, 0, 8, 8 )
self:AddItem( left, nil )
left:InvalidateLayout( true )
return left
end
function PANEL:ControlHelp( strHelp )
local Panel = vgui.Create( "DSizeToContents", self )
Panel:SetSizeX( false )
Panel:Dock( TOP )
Panel:InvalidateLayout()
local left = vgui.Create( "DLabel", Panel )
left:SetDark( true )
left:SetWrap( true )
left:SetTextInset( 0, 0 )
left:SetText( strHelp )
left:SetContentAlignment( 5 )
left:SetAutoStretchVertical( true )
left:DockMargin( 32, 0, 32, 8 )
left:Dock( TOP )
left:SetTextColor( self:GetSkin().Colours.Tree.Hover )
table.insert( self.Items, Panel )
return left
end
--[[---------------------------------------------------------
Note: If you're running a console command like "maxplayers 10" you
need to add the "10" to the arguments, like so
Button( "LabelName", "maxplayers", "10" )
-----------------------------------------------------------]]
function PANEL:Button( strName, strConCommand, ... --[[ console command args!! --]] )
local left = vgui.Create( "DButton", self )
if ( strConCommand ) then
left:SetConsoleCommand( strConCommand, ... )
end
left:SetText( strName )
self:AddItem( left, nil )
return left
end
function PANEL:PanelSelect()
local left = vgui.Create( "DPanelSelect", self )
self:AddItem( left, nil )
return left
end
function PANEL:ListBox( strLabel )
local left = nil
if ( strLabel ) then
left = vgui.Create( "DLabel", self )
left:SetText( strLabel )
self:AddItem( left )
left:SetDark( true )
end
local right = vgui.Create( "DListBox", self )
--right:SetConVar( strConVar )
right.Stretch = true
self:AddItem( right )
return right, left
end
function PANEL:Rebuild()
end
-- No example for this control
function PANEL:GenerateExample( class, tabs, w, h )
end
derma.DefineControl( "DForm", "A panel with quick methods to create basic user inputs.", PANEL, "DCollapsibleCategory" )

270
lua/vgui/dframe.lua Normal file
View File

@@ -0,0 +1,270 @@
--[[
| 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_bIsMenuComponent", "IsMenu", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDraggable", "Draggable", FORCE_BOOL )
AccessorFunc( PANEL, "m_bSizable", "Sizable", FORCE_BOOL )
AccessorFunc( PANEL, "m_bScreenLock", "ScreenLock", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDeleteOnClose", "DeleteOnClose", FORCE_BOOL )
AccessorFunc( PANEL, "m_bPaintShadow", "PaintShadow", FORCE_BOOL )
AccessorFunc( PANEL, "m_iMinWidth", "MinWidth", FORCE_NUMBER )
AccessorFunc( PANEL, "m_iMinHeight", "MinHeight", FORCE_NUMBER )
AccessorFunc( PANEL, "m_bBackgroundBlur", "BackgroundBlur", FORCE_BOOL )
function PANEL:Init()
self:SetFocusTopLevel( true )
--self:SetCursor( "sizeall" )
self:SetPaintShadow( true )
self.btnClose = vgui.Create( "DButton", self )
self.btnClose:SetText( "" )
self.btnClose.DoClick = function ( button ) self:Close() end
self.btnClose.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "WindowCloseButton", panel, w, h ) end
self.btnMaxim = vgui.Create( "DButton", self )
self.btnMaxim:SetText( "" )
self.btnMaxim.DoClick = function ( button ) self:Close() end
self.btnMaxim.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "WindowMaximizeButton", panel, w, h ) end
self.btnMaxim:SetEnabled( false )
self.btnMinim = vgui.Create( "DButton", self )
self.btnMinim:SetText( "" )
self.btnMinim.DoClick = function ( button ) self:Close() end
self.btnMinim.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "WindowMinimizeButton", panel, w, h ) end
self.btnMinim:SetEnabled( false )
self.lblTitle = vgui.Create( "DLabel", self )
self.lblTitle.UpdateColours = function( label, skin )
if ( self:IsActive() ) then return label:SetTextStyleColor( skin.Colours.Window.TitleActive ) end
return label:SetTextStyleColor( skin.Colours.Window.TitleInactive )
end
self:SetDraggable( true )
self:SetSizable( false )
self:SetScreenLock( false )
self:SetDeleteOnClose( true )
self:SetTitle( "Window" )
self:SetMinWidth( 50 )
self:SetMinHeight( 50 )
-- This turns off the engine drawing
self:SetPaintBackgroundEnabled( false )
self:SetPaintBorderEnabled( false )
self.m_fCreateTime = SysTime()
self:DockPadding( 5, 24 + 5, 5, 5 )
end
function PANEL:ShowCloseButton( bShow )
self.btnClose:SetVisible( bShow )
self.btnMaxim:SetVisible( bShow )
self.btnMinim:SetVisible( bShow )
end
function PANEL:GetTitle()
return self.lblTitle:GetText()
end
function PANEL:SetTitle( strTitle )
self.lblTitle:SetText( strTitle )
end
function PANEL:Close()
self:SetVisible( false )
if ( self:GetDeleteOnClose() ) then
self:Remove()
end
self:OnClose()
end
function PANEL:OnClose()
end
function PANEL:Center()
self:InvalidateLayout( true )
self:CenterVertical()
self:CenterHorizontal()
end
function PANEL:IsActive()
if ( self:HasFocus() ) then return true end
if ( vgui.FocusedHasParent( self ) ) then return true end
return false
end
function PANEL:SetIcon( str )
if ( !str && IsValid( self.imgIcon ) ) then
return self.imgIcon:Remove() -- We are instructed to get rid of the icon, do it and bail.
end
if ( !IsValid( self.imgIcon ) ) then
self.imgIcon = vgui.Create( "DImage", self )
end
if ( IsValid( self.imgIcon ) ) then
self.imgIcon:SetMaterial( Material( str ) )
end
end
function PANEL:Think()
local mousex = math.Clamp( gui.MouseX(), 1, ScrW() - 1 )
local mousey = math.Clamp( gui.MouseY(), 1, ScrH() - 1 )
if ( self.Dragging ) then
local x = mousex - self.Dragging[1]
local y = mousey - self.Dragging[2]
-- Lock to screen bounds if screenlock is enabled
if ( self:GetScreenLock() ) then
x = math.Clamp( x, 0, ScrW() - self:GetWide() )
y = math.Clamp( y, 0, ScrH() - self:GetTall() )
end
self:SetPos( x, y )
end
if ( self.Sizing ) then
local x = mousex - self.Sizing[1]
local y = mousey - self.Sizing[2]
local px, py = self:GetPos()
if ( x < self.m_iMinWidth ) then x = self.m_iMinWidth elseif ( x > ScrW() - px && self:GetScreenLock() ) then x = ScrW() - px end
if ( y < self.m_iMinHeight ) then y = self.m_iMinHeight elseif ( y > ScrH() - py && self:GetScreenLock() ) then y = ScrH() - py end
self:SetSize( x, y )
self:SetCursor( "sizenwse" )
return
end
local screenX, screenY = self:LocalToScreen( 0, 0 )
if ( self.Hovered && self.m_bSizable && mousex > ( screenX + self:GetWide() - 20 ) && mousey > ( screenY + self:GetTall() - 20 ) ) then
self:SetCursor( "sizenwse" )
return
end
if ( self.Hovered && self:GetDraggable() && mousey < ( screenY + 24 ) ) then
self:SetCursor( "sizeall" )
return
end
self:SetCursor( "arrow" )
-- Don't allow the frame to go higher than 0
if ( self.y < 0 ) then
self:SetPos( self.x, 0 )
end
end
function PANEL:Paint( w, h )
if ( self.m_bBackgroundBlur ) then
Derma_DrawBackgroundBlur( self, self.m_fCreateTime )
end
derma.SkinHook( "Paint", "Frame", self, w, h )
return true
end
function PANEL:OnMousePressed()
local screenX, screenY = self:LocalToScreen( 0, 0 )
if ( self.m_bSizable && gui.MouseX() > ( screenX + self:GetWide() - 20 ) && gui.MouseY() > ( screenY + self:GetTall() - 20 ) ) then
self.Sizing = { gui.MouseX() - self:GetWide(), gui.MouseY() - self:GetTall() }
self:MouseCapture( true )
return
end
if ( self:GetDraggable() && gui.MouseY() < ( screenY + 24 ) ) then
self.Dragging = { gui.MouseX() - self.x, gui.MouseY() - self.y }
self:MouseCapture( true )
return
end
end
function PANEL:OnMouseReleased()
self.Dragging = nil
self.Sizing = nil
self:MouseCapture( false )
end
function PANEL:PerformLayout()
local titlePush = 0
if ( IsValid( self.imgIcon ) ) then
self.imgIcon:SetPos( 5, 5 )
self.imgIcon:SetSize( 16, 16 )
titlePush = 16
end
self.btnClose:SetPos( self:GetWide() - 31 - 4, 0 )
self.btnClose:SetSize( 31, 24 )
self.btnMaxim:SetPos( self:GetWide() - 31 * 2 - 4, 0 )
self.btnMaxim:SetSize( 31, 24 )
self.btnMinim:SetPos( self:GetWide() - 31 * 3 - 4, 0 )
self.btnMinim:SetSize( 31, 24 )
self.lblTitle:SetPos( 8 + titlePush, 2 )
self.lblTitle:SetSize( self:GetWide() - 25 - titlePush, 20 )
end
derma.DefineControl( "DFrame", "A simple window", PANEL, "EditablePanel" )

132
lua/vgui/dgrid.lua Normal file
View File

@@ -0,0 +1,132 @@
--[[
| 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_iCols", "Cols" )
AccessorFunc( PANEL, "m_iColWide", "ColWide" )
AccessorFunc( PANEL, "m_iRowHeight", "RowHeight" )
function PANEL:Init()
self.Items = {}
self:SetCols( 4 )
self:SetColWide( 32 )
self:SetRowHeight( 32 )
self:SetMouseInputEnabled( true )
end
function PANEL:GetItems()
-- Should we return a copy of this to stop
-- people messing with it?
return self.Items
end
function PANEL:AddItem( item )
if ( !IsValid( item ) ) then return end
item:SetVisible( true )
item:SetParent( self )
table.insert( self.Items, item )
self:InvalidateLayout()
end
function PANEL:RemoveItem( item, bDontDelete )
for k, panel in pairs( self.Items ) do
if ( panel == item ) then
table.remove( self.Items, k )
if ( !bDontDelete ) then
panel:Remove()
end
self:InvalidateLayout()
end
end
end
function PANEL:PerformLayout()
local i = 0
self.m_iCols = math.floor( self.m_iCols )
self.m_iRowHeight = math.floor( self.m_iRowHeight )
self.m_iColWide = math.floor( self.m_iColWide )
for k, panel in pairs( self.Items ) do
if ( !panel:IsVisible() ) then continue end
local x = ( i % self.m_iCols ) * self.m_iColWide
local y = math.floor( i / self.m_iCols ) * self.m_iRowHeight
panel:SetPos( x, y )
i = i + 1
end
self:SetWide( self.m_iColWide * self.m_iCols )
self:SetTall( math.ceil( i / self.m_iCols ) * self.m_iRowHeight )
end
function PANEL:SortByMember( key, desc )
if ( desc == nil ) then
desc = true
end
table.sort( self.Items, function( a, b )
if ( desc ) then
local ta = a
local tb = b
a = tb
b = ta
end
if ( a[ key ] == nil ) then return false end
if ( b[ key ] == nil ) then return true end
return a[ key ] > b[ key ]
end )
end
function PANEL:Clear()
for k, panel in ipairs( self:GetChildren() ) do
panel:Remove()
end
self.Items = {}
end
derma.DefineControl( "DGrid", "A really simple grid layout panel", PANEL, "Panel" )

View File

@@ -0,0 +1,188 @@
--[[
| 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 = {}
function PANEL:Init()
self:SetCursor( "sizewe" )
self:SetPaintBackground( false )
end
function PANEL:OnMousePressed( mcode )
if ( mcode == MOUSE_LEFT ) then
self:GetParent():StartGrab()
end
end
derma.DefineControl( "DHorizontalDividerBar", "", PANEL, "DPanel" )
local PANEL = {}
AccessorFunc( PANEL, "m_pLeft", "Left" )
AccessorFunc( PANEL, "m_pRight", "Right" )
AccessorFunc( PANEL, "m_pMiddle", "Middle" )
AccessorFunc( PANEL, "m_iDividerWidth", "DividerWidth" )
AccessorFunc( PANEL, "m_iLeftWidth", "LeftWidth" )
AccessorFunc( PANEL, "m_bDragging", "Dragging", FORCE_BOOL )
AccessorFunc( PANEL, "m_iLeftWidthMin", "LeftMin" )
AccessorFunc( PANEL, "m_iRightWidthMin", "RightMin" )
AccessorFunc( PANEL, "m_iHoldPos", "HoldPos" )
function PANEL:Init()
self:SetDividerWidth( 8 )
self:SetLeftWidth( 100 )
self:SetLeftMin( 50 )
self:SetRightMin( 50 )
self:SetPaintBackground( false )
self.m_DragBar = vgui.Create( "DHorizontalDividerBar", self )
self._OldCookieW = 0
end
function PANEL:LoadCookies()
self:SetLeftWidth( self:GetCookieNumber( "LeftWidth", self:GetLeftWidth() ) )
self._OldCookieW = self:GetCookieNumber( "LeftWidth", self:GetLeftWidth() )
end
function PANEL:SetLeft( pnl )
self.m_pLeft = pnl
if ( IsValid( self.m_pLeft ) ) then
self.m_pLeft:SetParent( self )
end
end
function PANEL:SetMiddle( Middle )
self.m_pMiddle = Middle
if ( IsValid( self.m_pMiddle ) ) then
self.m_pMiddle:SetParent( self.m_DragBar )
end
end
function PANEL:SetRight( pnl )
self.m_pRight = pnl
if ( IsValid( self.m_pRight ) ) then
self.m_pRight:SetParent( self )
end
end
function PANEL:PerformLayout()
self:SetLeftWidth( math.Clamp( self:GetLeftWidth(), self:GetLeftMin(), math.max( self:GetWide() - self:GetRightMin() - self:GetDividerWidth(), self:GetLeftMin() ) ) )
if ( IsValid( self.m_pLeft ) ) then
self.m_pLeft:StretchToParent( 0, 0, nil, 0 )
self.m_pLeft:SetWide( self:GetLeftWidth() )
self.m_pLeft:InvalidateLayout()
end
self.m_DragBar:SetPos( self:GetLeftWidth(), 0 )
self.m_DragBar:SetSize( self:GetDividerWidth(), self:GetTall() )
self.m_DragBar:SetZPos( -1 )
if ( IsValid( self.m_pRight ) ) then
self.m_pRight:StretchToParent( self:GetLeftWidth() + self.m_DragBar:GetWide(), 0, 0, 0 )
self.m_pRight:InvalidateLayout()
end
if ( IsValid( self.m_pMiddle ) ) then
self.m_pMiddle:StretchToParent( 0, 0, 0, 0 )
self.m_pMiddle:InvalidateLayout()
end
end
function PANEL:OnCursorMoved( x, y )
if ( !self:GetDragging() ) then return end
local oldLeftWidth = self:GetLeftWidth()
x = math.Clamp( x - self:GetHoldPos(), self:GetLeftMin(), self:GetWide() - self:GetRightMin() - self:GetDividerWidth() )
self:SetLeftWidth( x )
if ( oldLeftWidth != x ) then self:InvalidateLayout() end
end
function PANEL:Think()
-- If 2 or more panels use the same cookie name, make every panel resize automatically to the same size
if ( self._OldCookieW != self:GetCookieNumber( "LeftWidth", self:GetLeftWidth() ) && !self:GetDragging() ) then
self:LoadCookies()
self:InvalidateLayout()
end
end
function PANEL:StartGrab()
self:SetCursor( "sizewe" )
local x, y = self.m_DragBar:CursorPos()
self:SetHoldPos( x )
self:SetDragging( true )
self:MouseCapture( true )
end
function PANEL:OnMouseReleased( mcode )
if ( mcode == MOUSE_LEFT ) then
self:SetCursor( "none" )
self:SetDragging( false )
self:MouseCapture( false )
self:SetCookie( "LeftWidth", self:GetLeftWidth() )
end
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetSize( 256, 256 )
ctrl:SetLeft( vgui.Create( "DButton" ) )
ctrl:SetRight( vgui.Create( "DButton" ) )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DHorizontalDivider", "", PANEL, "DPanel" )

View File

@@ -0,0 +1,227 @@
--[[
| 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" )

266
lua/vgui/dhscrollbar.lua Normal file
View File

@@ -0,0 +1,266 @@
--[[
| 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_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( s ) s: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( s ) s: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: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 OnHScroll function use that, if
-- not then invalidate layout (which can be pretty slow)
local func = self:GetParent().OnHScroll
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", "HScrollBar", self, 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( lx, ly )
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 BtnWidth = self:GetTall()
if ( self:GetHideButtons() ) then BtnWidth = 0 end
local TrackSize = self:GetWide() - BtnWidth * 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 Tall = self:GetTall()
local BtnWidth = Tall
if ( self:GetHideButtons() ) then BtnWidth = 0 end
local Scroll = self:GetScroll() / self.CanvasSize
local BarSize = math.max( self:BarScale() * ( self:GetWide() - ( BtnWidth * 2 ) ), 10 )
local Track = self:GetWide() - ( BtnWidth * 2 ) - BarSize
Track = Track + 1
Scroll = Scroll * Track
self.btnGrip:SetPos( BtnWidth + Scroll, 0 )
self.btnGrip:SetSize( BarSize, Tall )
if ( BtnWidth > 0 ) then
self.btnLeft:SetPos( 0, 0 )
self.btnLeft:SetSize( BtnWidth, Tall )
self.btnRight:SetPos( self:GetWide() - BtnWidth, 0 )
self.btnRight:SetSize( BtnWidth, Tall )
self.btnLeft:SetVisible( true )
self.btnRight:SetVisible( true )
else
self.btnLeft:SetVisible( false )
self.btnRight:SetVisible( false )
self.btnRight:SetSize( BtnWidth, Tall )
self.btnLeft:SetSize( BtnWidth, Tall )
end
end
derma.DefineControl( "DHScrollBar", "A Horizontal Scrollbar", PANEL, "Panel" )

194
lua/vgui/dhtml.lua Normal file
View File

@@ -0,0 +1,194 @@
--[[
| 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_bScrollbars", "Scrollbars", FORCE_BOOL )
AccessorFunc( PANEL, "m_bAllowLua", "AllowLua", FORCE_BOOL )
function PANEL:Init()
self:SetScrollbars( true )
self:SetAllowLua( false )
self.JS = {}
self.Callbacks = {}
--
-- Implement a console.log - because awesomium doesn't provide it for us anymore.
--
self:AddFunction( "console", "log", function( param ) self:ConsoleMessage( param ) end )
end
function PANEL:Think()
if ( self.JS && !self:IsLoading() ) then
for k, v in pairs( self.JS ) do
self:RunJavascript( v )
end
self.JS = nil
end
end
function PANEL:Paint()
if ( self:IsLoading() ) then
return true
end
end
function PANEL:QueueJavascript( js )
--
-- Can skip using the queue if there's nothing else in it
--
if ( !self.JS && !self:IsLoading() ) then
return self:RunJavascript( js )
end
self.JS = self.JS or {}
table.insert( self.JS, js )
self:Think()
end
function PANEL:Call( js )
self:QueueJavascript( js )
end
function PANEL:ConsoleMessage( msg, file, line )
if ( !isstring( msg ) ) then msg = "*js variable*" end
--
-- Handle error messages
--
if ( isstring( file ) && isnumber( line ) ) then
if ( #file > 64 ) then
file = string.sub( file, 1, 64 ) .. "..."
end
MsgC( Color( 255, 160, 255 ), "[HTML] " )
MsgC( Color( 255, 255, 255 ), file, ":", line, ": ", msg, "\n" )
return
end
--
-- Handle Lua execution
--
if ( self.m_bAllowLua && msg:StartsWith( "RUNLUA:" ) ) then
local strLua = msg:sub( 8 )
SELF = self
RunString( strLua )
SELF = nil
return
end
--
-- Plain ol' console.log
--
MsgC( Color( 255, 160, 255 ), "[HTML] " )
MsgC( Color( 255, 255, 255 ), msg, "\n" )
end
--
-- Called by the engine when a callback function is called
--
function PANEL:OnCallback( obj, func, args )
--
-- Use AddFunction to add functions to this.
--
local f = self.Callbacks[ obj .. "." .. func ]
if ( f ) then
return f( unpack( args ) )
end
end
--
-- Add a function to Javascript
--
function PANEL:AddFunction( obj, funcname, func )
--
-- Create the `object` if it doesn't exist
--
if ( !self.Callbacks[ obj ] ) then
self:NewObject( obj )
self.Callbacks[ obj ] = true
end
--
-- This creates the function in javascript (which redirects to c++ which calls OnCallback here)
--
self:NewObjectCallback( obj, funcname )
--
-- Store the function so OnCallback can find it and call it
--
self.Callbacks[ obj .. "." .. funcname ] = func
end
--
-- Called when this panel begins loading a page
--
function PANEL:OnBeginLoadingDocument( url )
end
--
-- Called when this panel successfully loads a page
--
function PANEL:OnFinishLoadingDocument( url )
end
--
-- Called when this panel's DOM has been set up. You can run JavaScript in here
--
function PANEL:OnDocumentReady( url )
end
--
-- Called when a this panel tries to open a child (such as a popup or new tab)
--
function PANEL:OnChildViewCreated( sourceURL, targetURL, isPopup )
end
--
-- Called when the title of the loaded document has changed
--
function PANEL:OnChangeTitle( title )
end
--
-- Called when the target URL of the frame has changed, this happens when you hover over a link
--
function PANEL:OnChangeTargetURL( url )
end
derma.DefineControl( "DHTML", "A shape", PANEL, "Awesomium" )

196
lua/vgui/dhtmlcontrols.lua Normal file
View File

@@ -0,0 +1,196 @@
--[[
| 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 = {}
function PANEL:Init()
local ButtonSize = 32
local Margins = 2
local Spacing = 0
self.BackButton = vgui.Create( "DImageButton", self )
self.BackButton:SetSize( ButtonSize, ButtonSize )
self.BackButton:SetImage( "gui/HTML/back" )
self.BackButton:Dock( LEFT )
self.BackButton:DockMargin( Spacing * 3, Margins, Spacing, Margins )
self.BackButton.DoClick = function()
self.BackButton:SetEnabled( false )
self.Cur = self.Cur - 1
self.Navigating = true
self.HTML:GoBack()
end
self.ForwardButton = vgui.Create( "DImageButton", self )
self.ForwardButton:SetSize( ButtonSize, ButtonSize )
self.ForwardButton:SetImage( "gui/HTML/forward" )
self.ForwardButton:Dock( LEFT )
self.ForwardButton:DockMargin( Spacing, Margins, Spacing, Margins )
self.ForwardButton.DoClick = function()
self.ForwardButton:SetEnabled( false )
self.Cur = self.Cur + 1
self.Navigating = true
self.HTML:GoForward()
end
self.RefreshButton = vgui.Create( "DImageButton", self )
self.RefreshButton:SetSize( ButtonSize, ButtonSize )
self.RefreshButton:SetImage( "gui/HTML/refresh" )
self.RefreshButton:Dock( LEFT )
self.RefreshButton:DockMargin( Spacing, Margins, Spacing, Margins )
self.RefreshButton.DoClick = function() self.HTML:Refresh() end
self.HomeButton = vgui.Create( "DImageButton", self )
self.HomeButton:SetSize( ButtonSize, ButtonSize )
self.HomeButton:SetImage( "gui/HTML/home" )
self.HomeButton:Dock( LEFT )
self.HomeButton:DockMargin( Spacing, Margins, Spacing * 3, Margins )
self.HomeButton.DoClick = function()
if ( self.HTML.URL == self.HomeURL ) then return end
self.HTML:StopLoading()
self.HTML:OpenURL( self.HomeURL )
end
self.StopButton = vgui.Create( "DImageButton", self )
self.StopButton:SetSize( ButtonSize, ButtonSize )
self.StopButton:SetImage( "gui/HTML/stop" )
self.StopButton:Dock( RIGHT )
self.StopButton:DockMargin( Spacing * 3, Margins, Spacing * 3, Margins )
self.StopButton.DoClick = function() self.HTML:Stop() end
self.AddressBar = vgui.Create( "DTextEntry", self )
self.AddressBar:Dock( FILL )
self.AddressBar:DockMargin( Spacing, Margins * 3, Margins * 3, Margins * 3 )
self.AddressBar.OnEnter = function()
self.HTML:StopLoading()
self.HTML:OpenURL( self.AddressBar:GetValue() )
end
self:SetHeight( ButtonSize + Margins * 2 )
self.History = {}
self.Cur = 1
-- This is the default look, feel free to change it on your created control :)
self:SetButtonColor( Color( 250, 250, 250, 200 ) )
self.BorderSize = 4
self.BackgroundColor = Color( 40, 40, 40, 255 )
self.HomeURL = "http://www.google.com"
end
function PANEL:SetHTML( html )
self.HTML = html
if ( html.URL ) then
self.HomeURL = self.HTML.URL
end
self.AddressBar:SetText( self.HomeURL )
self:UpdateHistory( self.HomeURL )
local OldFunc = self.HTML.OnBeginLoadingDocument
self.HTML.OnBeginLoadingDocument = function( panel, url )
self.AddressBar:SetText( url )
self:StartedLoading()
if ( OldFunc ) then
OldFunc( panel, url )
end
self:UpdateHistory( url )
end
local OldFunc2 = self.HTML.OnFinishLoadingDocument
self.HTML.OnFinishLoadingDocument = function( panel, url )
self:FinishedLoading()
if ( OldFunc2 ) then
OldFunc2( panel, url )
end
end
end
function PANEL:UpdateHistory( url )
self.Cur = math.Clamp( self.Cur, 1, table.Count( self.History ) )
if ( self.Navigating ) then
self.Navigating = false
self:UpdateNavButtonStatus()
return
end
-- Check if we refreshed or hooked into the panel just after creation.
if ( self.History[ self.Cur ] == url ) then return end
-- We were back in the history queue, but now we're navigating
-- So clear the front out so we can re-write history!!
if ( self.Cur < table.Count( self.History ) ) then
for i = self.Cur + 1, table.Count( self.History ) do
self.History[i] = nil
end
end
self.Cur = table.insert( self.History, url )
self:UpdateNavButtonStatus()
end
function PANEL:FinishedLoading()
self.StopButton:SetEnabled( false )
self.RefreshButton:SetEnabled( true )
end
function PANEL:StartedLoading()
self.StopButton:SetEnabled( true )
self.RefreshButton:SetEnabled( false )
end
function PANEL:UpdateNavButtonStatus()
self.ForwardButton:SetEnabled( self.Cur < table.Count( self.History ) )
self.BackButton:SetEnabled( self.Cur != 1 )
end
function PANEL:SetButtonColor( col )
self.BackButton:SetColor( col )
self.ForwardButton:SetColor( col )
self.RefreshButton:SetColor( col )
self.HomeButton:SetColor( col )
self.StopButton:SetColor( col )
end
function PANEL:Paint()
draw.RoundedBoxEx( self.BorderSize, 0, 0, self:GetWide(), self:GetTall(), self.BackgroundColor, true, true, false, false )
end
derma.DefineControl( "DHTMLControls", "", PANEL, "Panel" )

169
lua/vgui/diconbrowser.lua Normal file
View File

@@ -0,0 +1,169 @@
--[[
| 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_strSelectedIcon", "SelectedIcon" )
AccessorFunc( PANEL, "m_bManual", "Manual" )
function PANEL:SelectIcon( name )
self.m_strSelectedIcon = name
for k, v in ipairs( self.IconLayout:GetChildren() ) do
if ( v:GetImage() == name ) then
self.m_pSelectedIcon = v
end
end
end
function PANEL:ScrollToSelected()
if ( !IsValid( self.m_pSelectedIcon ) ) then return end
self:ScrollToChild( self.m_pSelectedIcon )
end
function PANEL:Init()
self.m_strSelectedIcon = ""
self.IconLayout = self:GetCanvas():Add( "DIconLayout" )
self.IconLayout:SetSpaceX( 0 )
self.IconLayout:SetSpaceY( 0 )
self.IconLayout:SetBorder( 4 )
self.IconLayout:Dock( TOP )
self:SetPaintBackground( true )
end
local local_IconList = nil
local local_IconList_Split = 0
local local_IconList_FlagSplit = 0
function PANEL:Fill()
self.Filled = true
if ( self.m_bManual ) then return end
if ( !local_IconList ) then
local_IconList = file.Find( "materials/icon16/*.png", "MOD" )
local_IconList_Split = #local_IconList
table.Add( local_IconList, file.Find( "materials/flags16/*.png", "MOD" ) )
local_IconList_FlagSplit = #local_IconList
table.Add( local_IconList, file.Find( "materials/games/16/*.png", "MOD" ) )
end
for k, v in SortedPairs( local_IconList ) do
timer.Simple( k * 0.001, function()
if ( !IsValid( self ) ) then return end
if ( !IsValid( self.IconLayout ) ) then return end
local btn = self.IconLayout:Add( "DImageButton" )
btn.FilterText = string.lower( v )
if ( k > local_IconList_Split and k > local_IconList_FlagSplit ) then
btn:SetOnViewMaterial( "games/16/" .. v )
elseif (k > local_IconList_Split ) then
btn:SetOnViewMaterial( "flags16/" .. v )
else
btn:SetOnViewMaterial( "icon16/" .. v )
end
btn:SetTooltip( btn:GetImage() )
btn:SetSize( 22, 22 )
btn:SetPos( -22, -22 )
btn:SetStretchToFit( false )
btn.DoClick = function()
self.m_pSelectedIcon = btn
self.m_strSelectedIcon = btn:GetImage()
self:OnChangeInternal()
end
btn.Paint = function( pnl, w, h )
if ( self.m_pSelectedIcon != pnl ) then return end
derma.SkinHook( "Paint", "Selection", pnl, w, h )
end
if ( !self.m_pSelectedIcon || self.m_strSelectedIcon == btn:GetImage() ) then
self.m_pSelectedIcon = btn
--self:ScrollToChild( btn )
end
self.IconLayout:Layout()
end )
end
end
function PANEL:FilterByText( text )
local text_lwr = string.lower( text )
for k, v in ipairs( self.IconLayout:GetChildren() ) do
v:SetVisible( v.FilterText:find( text_lwr ) != nil )
end
self.IconLayout:Layout()
end
function PANEL:Paint( w, h )
if ( !self.Filled ) then self:Fill() end
derma.SkinHook( "Paint", "Tree", self, w, h )
end
function PANEL:OnChangeInternal()
self:OnChange()
end
function PANEL:Clear()
self.IconLayout:Clear()
end
function PANEL:Add( name )
return self.IconLayout:Add( name )
end
function PANEL:OnChange()
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetSize( 300, 300 )
ctrl:SelectIcon( "icon16/heart.png" )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DIconBrowser", "", PANEL, "DScrollPanel" )

214
lua/vgui/diconlayout.lua Normal file
View File

@@ -0,0 +1,214 @@
--[[
| 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_iLayoutDir", "LayoutDir" )
AccessorFunc( PANEL, "m_bStretchW", "StretchWidth", FORCE_BOOL )
AccessorFunc( PANEL, "m_bStretchH", "StretchHeight", FORCE_BOOL )
function PANEL:Init()
self:SetDropPos( "46" )
self:SetSpaceX( 0 )
self:SetSpaceY( 0 )
self:SetBorder( 0 )
self:SetLayoutDir( TOP )
self:SetStretchWidth( false )
self:SetStretchHeight( true )
self.LastW = 0
self.LastH = 0
end
function PANEL:Layout()
self.LastW = 0
self.LastH = 0
self:InvalidateLayout()
end
function PANEL:LayoutIcons_TOP()
local x = self.m_iBorder
local y = self.m_iBorder
local RowHeight = 0
local MaxWidth = self:GetWide() - self.m_iBorder
for k, v in ipairs( self:GetChildren() ) do
if ( !v:IsVisible() ) then continue end
local w, h = v:GetSize()
if ( x + w > MaxWidth || ( v.OwnLine && x > self.m_iBorder ) ) then
x = self.m_iBorder
y = y + RowHeight + self.m_iSpaceY
RowHeight = 0
end
v:SetPos( x, y )
x = x + v:GetWide() + self.m_iSpaceX
RowHeight = math.max( RowHeight, v:GetTall() )
-- Start a new line if this panel is meant to be on its own line
if ( v.OwnLine ) then
x = MaxWidth + 1
end
end
end
function PANEL:LayoutIcons_LEFT()
local x = self.m_iBorder
local y = self.m_iBorder
local RowWidth = 0
local MaxHeight = self:GetTall() - self.m_iBorder
for k, v in ipairs( self:GetChildren() ) do
if ( !v:IsVisible() ) then continue end
local w, h = v:GetSize()
if ( y + h > MaxHeight || ( v.OwnLine && y > self.m_iBorder ) ) then
y = self.m_iBorder
x = x + RowWidth + self.m_iSpaceX
RowWidth = 0
end
v:SetPos( x, y )
y = y + v:GetTall() + self.m_iSpaceY
RowWidth = math.max( RowWidth, v:GetWide() )
-- Start a new line if this panel is meant to be on its own line
if ( v.OwnLine ) then
y = MaxHeight + 1
end
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
if ( self.m_iLayoutDir == LEFT ) then self:LayoutIcons_LEFT() end
if ( self.m_iLayoutDir == TOP ) then self:LayoutIcons_TOP() end
end
self:SizeToChildren( self:GetStretchWidth(), self:GetStretchHeight() )
end
function PANEL:OnModified()
-- Override me
end
function PANEL:OnChildRemoved()
self:Layout()
end
function PANEL:OnChildAdded( child )
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( "DIconLayout", self:GetParent() )
copy:CopyBase( self )
copy:SetSortable( self:GetSortable() )
copy:SetDnD( self:GetDnD() )
copy:SetSpaceX( self:GetSpaceX() )
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:SetSize( 200, 200 )
pnl:SetUseLiveDrag( true )
pnl:SetSelectionCanvas( true )
pnl:SetSpaceX( 4 )
pnl:SetSpaceY( 4 )
for i = 1, 32 do
local btn = pnl:Add( "DButton" )
btn:SetSize( 32, 32 )
btn:SetText( i )
end
PropertySheet:AddSheet( ClassName, pnl, nil, true, true )
end
derma.DefineControl( "DIconLayout", "", PANEL, "DDragBase" )

241
lua/vgui/dimage.lua Normal file
View File

@@ -0,0 +1,241 @@
--[[
| 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_Material", "Material" )
AccessorFunc( PANEL, "m_Color", "ImageColor" )
AccessorFunc( PANEL, "m_bKeepAspect", "KeepAspect" )
AccessorFunc( PANEL, "m_strMatName", "MatName" )
AccessorFunc( PANEL, "m_strMatNameFailsafe", "FailsafeMatName" )
function PANEL:Init()
self:SetImageColor( color_white )
self:SetMouseInputEnabled( false )
self:SetKeyboardInputEnabled( false )
self:SetKeepAspect( false )
self.ImageName = ""
self.ActualWidth = 10
self.ActualHeight = 10
end
function PANEL:SetOnViewMaterial( MatName, MatNameBackup )
self:SetMatName( MatName )
self:SetFailsafeMatName( MatNameBackup )
self.ImageName = MatName
end
function PANEL:Unloaded()
return self.m_strMatName != nil
end
function PANEL:LoadMaterial()
if ( !self:Unloaded() ) then return end
self:DoLoadMaterial()
self:SetMatName( nil )
end
function PANEL:DoLoadMaterial()
local mat = Material( self:GetMatName() )
self:SetMaterial( mat )
if ( self.m_Material:IsError() && self:GetFailsafeMatName() ) then
self:SetMaterial( Material( self:GetFailsafeMatName() ) )
end
self:FixVertexLitMaterial()
--
-- This isn't ideal, but it will probably help you out of a jam
-- in cases where you position the image according to the texture
-- size and you want to load on view - instead of on load.
--
self:InvalidateParent()
end
function PANEL:SetMaterial( Mat )
-- Everybody makes mistakes,
-- that's why they put erasers on pencils.
if ( isstring( Mat ) ) then
self:SetImage( Mat )
return
end
self.m_Material = Mat
if ( !self.m_Material ) then return end
local Texture = self.m_Material:GetTexture( "$basetexture" )
if ( Texture ) then
self.ActualWidth = Texture:Width()
self.ActualHeight = Texture:Height()
else
self.ActualWidth = self.m_Material:Width()
self.ActualHeight = self.m_Material:Height()
end
end
function PANEL:SetImage( strImage, strBackup )
if ( strBackup && !file.Exists( "materials/" .. strImage .. ".vmt", "GAME" ) && !file.Exists( "materials/" .. strImage, "GAME" ) ) then
strImage = strBackup
end
self.ImageName = strImage
local Mat = Material( strImage )
self:SetMaterial( Mat )
self:FixVertexLitMaterial()
end
function PANEL:GetImage()
return self.ImageName
end
function PANEL:FixVertexLitMaterial()
--
-- If it's a vertexlitgeneric material we need to change it to be
-- UnlitGeneric so it doesn't go dark when we enter a dark room
-- and flicker all about
--
local Mat = self:GetMaterial()
local strImage = Mat:GetName()
if ( string.find( Mat:GetShader(), "VertexLitGeneric" ) or string.find( Mat:GetShader(), "Cable" ) ) then
local t = Mat:GetString( "$basetexture" )
if ( t ) then
local params = {}
params[ "$basetexture" ] = t
params[ "$vertexcolor" ] = 1
params[ "$vertexalpha" ] = 1
Mat = CreateMaterial( strImage .. "_DImage", "UnlitGeneric", params )
end
end
self:SetMaterial( Mat )
end
function PANEL:SizeToContents()
self:SetSize( self.ActualWidth, self.ActualHeight )
end
function PANEL:Paint()
self:PaintAt( 0, 0, self:GetWide(), self:GetTall() )
end
function PANEL:PaintAt( x, y, dw, dh )
dw, dh = dw or self:GetWide(), dh or self:GetTall()
self:LoadMaterial()
if ( !self.m_Material ) then return true end
surface.SetMaterial( self.m_Material )
surface.SetDrawColor( self.m_Color.r, self.m_Color.g, self.m_Color.b, self.m_Color.a )
if ( self:GetKeepAspect() ) then
local w = self.ActualWidth
local h = self.ActualHeight
-- Image is bigger than panel, shrink to suitable size
if ( w > dw && h > dh ) then
if ( w > dw ) then
local diff = dw / w
w = w * diff
h = h * diff
end
if ( h > dh ) then
local diff = dh / h
w = w * diff
h = h * diff
end
end
if ( w < dw ) then
local diff = dw / w
w = w * diff
h = h * diff
end
if ( h < dh ) then
local diff = dh / h
w = w * diff
h = h * diff
end
local OffX = ( dw - w ) * 0.5
local OffY = ( dh - h ) * 0.5
surface.DrawTexturedRect( OffX + x, OffY + y, w, h )
return true
end
surface.DrawTexturedRect( x, y, dw, dh )
return true
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetImage( "brick/brick_model" )
ctrl:SetSize( 200, 200 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DImage", "A simple image", PANEL, "DPanel" )

168
lua/vgui/dimagebutton.lua Normal file
View File

@@ -0,0 +1,168 @@
--[[
| 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_bStretchToFit", "StretchToFit" )
AccessorFunc( PANEL, "m_bDepressImage", "DepressImage" )
function PANEL:Init()
self:SetPaintBackground( false )
self:SetDrawBorder( false )
self:SetStretchToFit( true )
self:SetDepressImage( true )
self:SetCursor( "hand" )
self.m_Image = vgui.Create( "DImage", self )
self:SetText( "" )
self:SetColor( color_white )
end
--
-- SetImageVisible
-- Hide the button's image
--
function PANEL:SetImageVisible( bBool )
self.m_Image:SetVisible( bBool )
end
function PANEL:SetImage( strImage, strBackup )
self.m_Image:SetImage( strImage, strBackup )
end
PANEL.SetIcon = PANEL.SetImage
function PANEL:SetColor( col )
self.m_Image:SetImageColor( col )
self.ImageColor = col
end
function PANEL:GetImage()
return self.m_Image:GetImage()
end
function PANEL:SetKeepAspect( bKeep )
self.m_Image:SetKeepAspect( bKeep )
end
-- SetMaterial should replace SetImage for cached materials
function PANEL:SetMaterial( Mat )
self.m_Image:SetMaterial( Mat )
end
function PANEL:SizeToContents()
self.m_Image:SizeToContents()
self:SetSize( self.m_Image:GetWide(), self.m_Image:GetTall() )
end
function PANEL:DepressImage()
if ( !self.m_bDepressImage ) then return end
self.m_bImageDepressed = true
if ( self.m_bStretchToFit ) then
self.m_Image:SetPos( 2, 2 )
self.m_Image:SetSize( self:GetWide() - 4, self:GetTall() - 4 )
else
self.m_Image:SizeToContents()
self.m_Image:SetSize( self.m_Image:GetWide() * 0.8, self.m_Image:GetTall() * 0.8 )
self.m_Image:Center()
end
end
function PANEL:OnMousePressed( mousecode )
DButton.OnMousePressed( self, mousecode )
self:DepressImage()
end
function PANEL:OnMouseReleased( mousecode )
DButton.OnMouseReleased( self, mousecode )
self.m_bImageDepressed = nil
self:InvalidateLayout()
end
function PANEL:PerformLayout()
if ( self.m_bDepressImage && self.m_bImageDepressed ) then
self:DepressImage()
elseif ( self.m_bStretchToFit ) then
self.m_Image:SetPos( 0, 0 )
self.m_Image:SetSize( self:GetSize() )
else
self.m_Image:SizeToContents()
self.m_Image:Center()
end
end
function PANEL:SetDisabled( bDisabled )
DButton.SetDisabled( self, bDisabled )
if ( bDisabled ) then
self.m_Image:SetAlpha( self.ImageColor.a * 0.4 )
else
self.m_Image:SetAlpha( self.ImageColor.a )
end
end
function PANEL:SetOnViewMaterial( MatName, Backup )
self.m_Image:SetOnViewMaterial( MatName, Backup )
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetImage( "gui/dupe_bg.png" )
ctrl:SetSize( 200, 200 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DImageButton", "A button which uses an image instead of text", PANEL, "DButton" )

38
lua/vgui/dkillicon.lua Normal file
View File

@@ -0,0 +1,38 @@
--[[
| 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_Name", "Name" )
function PANEL:Init()
self.m_Name = ""
self.m_fOffset = 0
self:NoClipping( true )
end
function PANEL:SizeToContents()
local w, h = killicon.GetSize( self.m_Name )
self.m_fOffset = h * 0.1
self:SetSize( w, 5 )
end
function PANEL:Paint()
killicon.Draw( self:GetWide() * 0.5, self.m_fOffset, self.m_Name, 255 )
end
derma.DefineControl( "DKillIcon", "A kill icon", PANEL, "Panel" )

325
lua/vgui/dlabel.lua Normal file
View File

@@ -0,0 +1,325 @@
--[[
| 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_colText", "TextColor" )
AccessorFunc( PANEL, "m_colTextStyle", "TextStyleColor" )
AccessorFunc( PANEL, "m_FontName", "Font" )
AccessorFunc( PANEL, "m_bDoubleClicking", "DoubleClickingEnabled", FORCE_BOOL )
AccessorFunc( PANEL, "m_bAutoStretchVertical", "AutoStretchVertical", FORCE_BOOL )
AccessorFunc( PANEL, "m_bIsMenuComponent", "IsMenu", FORCE_BOOL )
AccessorFunc( PANEL, "m_bBackground", "PaintBackground", FORCE_BOOL )
AccessorFunc( PANEL, "m_bBackground", "DrawBackground", FORCE_BOOL ) -- deprecated, see line above
AccessorFunc( PANEL, "m_bDisabled", "Disabled", FORCE_BOOL ) -- deprecated, use SetEnabled/IsEnabled isntead
AccessorFunc( PANEL, "m_bIsToggle", "IsToggle", FORCE_BOOL )
AccessorFunc( PANEL, "m_bToggle", "Toggle", FORCE_BOOL )
AccessorFunc( PANEL, "m_bBright", "Bright", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDark", "Dark", FORCE_BOOL )
AccessorFunc( PANEL, "m_bHighlight", "Highlight", FORCE_BOOL )
function PANEL:Init()
self:SetIsToggle( false )
self:SetToggle( false )
self:SetEnabled( true )
self:SetMouseInputEnabled( false )
self:SetKeyboardInputEnabled( false )
self:SetDoubleClickingEnabled( true )
-- Nicer default height
self:SetTall( 20 )
-- This turns off the engine drawing
self:SetPaintBackgroundEnabled( false )
self:SetPaintBorderEnabled( false )
self:SetFont( "DermaDefault" )
end
function PANEL:SetFont( strFont )
self.m_FontName = strFont
self:SetFontInternal( self.m_FontName )
self:ApplySchemeSettings()
end
function PANEL:SetTextColor( clr )
self.m_colText = clr
self:UpdateFGColor()
end
PANEL.SetColor = PANEL.SetTextColor
function PANEL:GetColor()
return self.m_colText || self.m_colTextStyle
end
function PANEL:UpdateFGColor()
local col = self:GetTextStyleColor()
if ( self:GetTextColor() ) then col = self:GetTextColor() end
if ( !col ) then return end
self:SetFGColor( col.r, col.g, col.b, col.a )
end
function PANEL:Toggle()
if ( !self:GetIsToggle() ) then return end
self:SetToggle( !self:GetToggle() )
self:OnToggled( self:GetToggle() )
end
function PANEL:SetDisabled( bDisabled )
self.m_bDisabled = bDisabled
self:InvalidateLayout()
end
function PANEL:SetEnabled( bEnabled )
self:SetDisabled( !bEnabled )
end
function PANEL:IsEnabled()
return !self:GetDisabled()
end
function PANEL:SetDark( bDark )
self.m_bDark = bDark
if ( bDark ) then self.m_bBright = false end
end
function PANEL:SetBright( bBright )
self.m_bBright = bBright
if ( bBright ) then self.m_bDark = false end
end
function PANEL:UpdateColours( skin )
local gray = Color( 128, 128, 128, 128 )
local frac = 0
if ( !self:IsEnabled() ) then frac = 0.75 end
if ( self:GetHighlight() ) then return self:SetTextStyleColor( skin.Colours.Label.Highlight:Lerp( gray, frac ) ) end
if ( self:GetBright() ) then return self:SetTextStyleColor( skin.Colours.Label.Bright:Lerp( gray, frac ) ) end
if ( self:GetDark() ) then return self:SetTextStyleColor( skin.Colours.Label.Dark:Lerp( gray, frac ) ) end
return self:SetTextStyleColor( skin.Colours.Label.Default:Lerp( gray, frac ) )
end
function PANEL:ApplySchemeSettings()
self:UpdateColours( self:GetSkin() )
self:UpdateFGColor()
end
function PANEL:Think()
if ( self:GetAutoStretchVertical() ) then
self:SizeToContentsY()
end
end
function PANEL:PerformLayout()
self:ApplySchemeSettings()
end
function PANEL:OnCursorEntered()
self:InvalidateLayout( true )
end
function PANEL:OnCursorExited()
self:InvalidateLayout( true )
end
function PANEL:OnMousePressed( mousecode )
if ( !self:IsEnabled() ) then return end
if ( mousecode == MOUSE_LEFT && !dragndrop.IsDragging() && self.m_bDoubleClicking ) then
if ( self.LastClickTime && SysTime() - self.LastClickTime < 0.2 ) then
self:DoDoubleClickInternal()
self:DoDoubleClick()
return
end
self.LastClickTime = SysTime()
end
-- Do not do selections if playing is spawning things while moving
local isPlyMoving = LocalPlayer && IsValid( LocalPlayer() ) && ( LocalPlayer():KeyDown( IN_FORWARD ) || LocalPlayer():KeyDown( IN_BACK ) || LocalPlayer():KeyDown( IN_MOVELEFT ) || LocalPlayer():KeyDown( IN_MOVERIGHT ) )
-- If we're selectable and have shift held down then go up
-- the parent until we find a selection canvas and start box selection
if ( self:IsSelectable() && mousecode == MOUSE_LEFT && ( input.IsShiftDown() || input.IsControlDown() ) && !isPlyMoving ) then
return self:StartBoxSelection()
end
self:MouseCapture( true )
self.Depressed = true
self:OnDepressed()
self:InvalidateLayout( true )
--
-- Tell DragNDrop that we're down, and might start getting dragged!
--
self:DragMousePress( mousecode )
end
function PANEL:OnMouseReleased( mousecode )
self:MouseCapture( false )
if ( !self:IsEnabled() ) then return end
if ( !self.Depressed && dragndrop.m_DraggingMain != self ) then return end
if ( self.Depressed ) then
self.Depressed = nil
self:OnReleased()
self:InvalidateLayout( true )
end
--
-- If we were being dragged then don't do the default behaviour!
--
if ( self:DragMouseRelease( mousecode ) ) then
return
end
if ( self:IsSelectable() && mousecode == MOUSE_LEFT ) then
local canvas = self:GetSelectionCanvas()
if ( canvas ) then
canvas:UnselectAll()
end
end
if ( !self.Hovered ) then return end
--
-- For the purposes of these callbacks we want to
-- keep depressed true. This helps us out in controls
-- like the checkbox in the properties dialog. Because
-- the properties dialog will only manually change the value
-- if IsEditing() is true - and the only way to work out if
-- a label/button based control is editing is when it's depressed.
--
self.Depressed = true
if ( mousecode == MOUSE_RIGHT ) then
self:DoRightClick()
end
if ( mousecode == MOUSE_LEFT ) then
self:DoClickInternal()
self:DoClick()
end
if ( mousecode == MOUSE_MIDDLE ) then
self:DoMiddleClick()
end
self.Depressed = nil
end
function PANEL:OnReleased()
end
function PANEL:OnDepressed()
end
function PANEL:OnToggled( bool )
end
function PANEL:DoClick()
self:Toggle()
end
function PANEL:DoRightClick()
end
function PANEL:DoMiddleClick()
end
function PANEL:DoClickInternal()
end
function PANEL:DoDoubleClick()
end
function PANEL:DoDoubleClickInternal()
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetText( "This is a label example." )
ctrl:SizeToContents()
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DLabel", "A Label", PANEL, "Label" )
-- Convenience Function
function Label( strText, parent )
local lbl = vgui.Create( "DLabel", parent )
lbl:SetText( strText )
return lbl
end

View File

@@ -0,0 +1,98 @@
--[[
| 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_bStretch", "AutoStretch", FORCE_BOOL )
function PANEL:Init()
self:SetAutoStretch( false )
end
function PANEL:SizeToContents()
local w, h = self:GetContentSize()
self:SetSize( w + 16, h ) -- Add a bit more room so it looks nice as a textbox :)
end
function PANEL:GetContentSize()
local w, h = DLabel.GetContentSize( self )
-- Expand the label to fit our text
if ( self:IsEditing() && self:GetAutoStretch() ) then
surface.SetFont( self:GetFont() )
w, h = surface.GetTextSize( self._TextEdit:GetText() )
end
return w, h
end
function PANEL:DoDoubleClick()
if ( !self:IsEnabled() ) then return end
local TextEdit = vgui.Create( "DTextEntry", self )
TextEdit:Dock( FILL )
TextEdit:SetText( self:GetText() )
TextEdit:SetFont( self:GetFont() )
TextEdit.OnTextChanged = function()
self:SizeToContents()
end
TextEdit.OnEnter = function()
local text = self:OnLabelTextChanged( TextEdit:GetText() ) or TextEdit:GetText()
if ( text:byte() == 35 ) then text = "#" .. text end -- Hack!
self:SetText( text )
hook.Run( "OnTextEntryLoseFocus", TextEdit )
TextEdit:Remove()
end
TextEdit.OnLoseFocus = function()
hook.Run( "OnTextEntryLoseFocus", TextEdit )
TextEdit:Remove()
end
TextEdit:RequestFocus()
TextEdit:OnGetFocus() -- Because the keyboard input might not be enabled yet! (spawnmenu)
TextEdit:SelectAllText( true )
self._TextEdit = TextEdit
end
function PANEL:IsEditing()
if ( !IsValid( self._TextEdit ) ) then return false end
return self._TextEdit:IsEditing()
end
function PANEL:OnLabelTextChanged( text )
return text
end
derma.DefineControl( "DLabelEditable", "A Label", PANEL, "DLabel" )

73
lua/vgui/dlabelurl.lua Normal file
View File

@@ -0,0 +1,73 @@
--[[
| 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_colText", "TextColor" )
AccessorFunc( PANEL, "m_colTextStyle", "TextStyleColor" )
AccessorFunc( PANEL, "m_bAutoStretchVertical", "AutoStretchVertical" )
function PANEL:Init()
self:SetTextStyleColor( Color( 0, 0, 255 ) )
-- Nicer default height
self:SetTall( 20 )
-- This turns off the engine drawing
self:SetPaintBackgroundEnabled( false )
self:SetPaintBorderEnabled( false )
end
function PANEL:ApplySchemeSettings()
self:UpdateFGColor()
end
function PANEL:SetTextColor( clr )
self.m_colText = clr
self:UpdateFGColor()
end
PANEL.SetColor = PANEL.SetTextColor
function PANEL:GetColor()
return self.m_colText or self.m_colTextStyle
end
function PANEL:OnCursorEntered()
self:SetTextStyleColor( Color( 0, 50, 255 ) )
self:UpdateFGColor()
end
function PANEL:OnCursorExited()
self:SetTextStyleColor( Color( 0, 0, 255 ) )
self:UpdateFGColor()
end
function PANEL:UpdateFGColor()
local col = self:GetColor()
self:SetFGColor( col.r, col.g, col.b, col.a )
end
derma.DefineControl( "DLabelURL", "A Label", PANEL, "URLLabel" )

205
lua/vgui/dlistbox.lua Normal file
View File

@@ -0,0 +1,205 @@
--[[
| 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_pMother", "Mother" )
function PANEL:Init()
self:SetMouseInputEnabled( true )
self:SetTextInset( 5, 0 )
self:SetTall( 19 )
self:SetDark( true )
end
function PANEL:OnMousePressed( mcode )
if ( mcode == MOUSE_LEFT ) then
self:Select( true )
end
self:SetTextColor( color_black )
end
function PANEL:Paint( w, h )
if ( self:IsSelected() ) then
draw.RoundedBox( 0, 0, 0, w, h, Color( 0, 128, 255, 200 ) )
elseif ( self.Hovered ) then
draw.RoundedBox( 0, 0, 0, w, h, Color( 0, 128, 255, 128 ) )
end
end
function PANEL:OnCursorMoved( x, y )
if ( input.IsMouseDown( MOUSE_LEFT ) ) then
self:Select( false )
end
end
function PANEL:Select( bOnlyMe )
self.m_pMother:SelectItem( self, bOnlyMe )
self:DoClick()
end
function PANEL:DoClick()
-- For override
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
end
derma.DefineControl( "DListBoxItem", "", PANEL, "DLabel" )
--[[---------------------------------------------------------
DListBox
-----------------------------------------------------------]]
local PANEL = {}
AccessorFunc( PANEL, "m_bSelectMultiple", "Multiple", FORCE_BOOL )
AccessorFunc( PANEL, "SelectedItems", "SelectedItems" ) -- All selected in a table
Derma_Hook( PANEL, "Paint", "Paint", "ListBox" )
function PANEL:Init()
self:SetMultiple( true )
self:EnableHorizontal( false )
self:EnableVerticalScrollbar()
self:SetPadding( 1 )
self.m_bSelectionCanvas = true
self.SelectedItems = {}
end
function PANEL:Clear()
self.SelectedItems = {}
DPanelList.Clear( self, true )
end
function PANEL:AddItem( strLabel )
local item = vgui.Create( "DListBoxItem", self )
item:SetMother( self )
item:SetText( strLabel )
DPanelList.AddItem( self, item )
return item
end
function PANEL:Rebuild()
local Offset = 0
local x, y = self.Padding, self.Padding
for k, panel in pairs( self.Items ) do
local w = panel:GetWide()
local h = panel:GetTall()
panel:SetPos( self.Padding, y )
panel:SetWide( self:GetCanvas():GetWide() - self.Padding * 2 )
x = x + w + self.Spacing
y = y + h + self.Spacing
Offset = y + h + self.Spacing
end
self:GetCanvas():SetTall( Offset + (self.Padding * 2) - self.Spacing )
end
function PANEL:SelectItem( item, onlyme )
if ( !onlyme && item:IsSelected() ) then return end
-- Unselect old items
if ( onlyme || !self.m_bSelectMultiple ) then
for k, v in pairs( self.SelectedItems ) do
v:SetSelected( false )
end
self.SelectedItems = {}
self.m_pSelected = nil
end
if ( self.OnSelect ) then self:OnSelect( item ) end
self.m_pSelected = item
item:SetSelected( true )
table.insert( self.SelectedItems, item )
end
function PANEL:SelectByName( strName )
for k, panel in pairs( self.Items ) do
if ( panel:GetValue() == strName ) then
self:SelectItem( panel, true )
return end
end
end
function PANEL:GetSelectedValues()
local items = self:GetSelectedItems()
if ( #items > 1 ) then
local ret = {}
for _, v in pairs( items ) do table.insert( ret, v:GetValue() ) end
return ret
elseif ( #items == 1 ) then
return items[1]:GetValue()
end
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:AddItem( "Bread" )
ctrl:AddItem( "Carrots" )
ctrl:AddItem( "Toilet Paper" )
ctrl:AddItem( "Air Freshner" )
ctrl:AddItem( "Shovel" )
ctrl:SetSize( 100, 300 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DListBox", "", PANEL, "DPanelList" )

78
lua/vgui/dlistlayout.lua Normal file
View File

@@ -0,0 +1,78 @@
--[[
| 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 = {}
function PANEL:Init()
self:SetDropPos( "82" )
end
function PANEL:OnModified()
-- Override me
end
function PANEL:OnChildRemoved()
self:InvalidateLayout()
end
function PANEL:PerformLayout()
self:SizeToChildren( false, true )
end
function PANEL:OnChildAdded( child )
child:Dock( TOP )
local dn = self:GetDnD()
if ( dn ) then
child:Droppable( self:GetDnD() )
end
if ( self:IsSelectionCanvas() ) then
child:SetSelectable( true )
end
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local pnl = vgui.Create( ClassName )
pnl:MakeDroppable( "ExampleDraggable", false )
pnl:SetSize( 200, 200 )
for i = 1, 5 do
local btn = pnl:Add( "DButton" )
btn:SetText( "Button " .. i )
end
for i = 1, 5 do
local btn = pnl:Add( "DLabel" )
btn:SetText( "Label " .. i )
btn:SetMouseInputEnabled( true )
end
PropertySheet:AddSheet( ClassName, pnl, nil, true, true )
end
derma.DefineControl( "DListLayout", "", PANEL, "DDragBase" )

605
lua/vgui/dlistview.lua Normal file
View File

@@ -0,0 +1,605 @@
--[[
| 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_bDirty", "Dirty", FORCE_BOOL )
AccessorFunc( PANEL, "m_bSortable", "Sortable", FORCE_BOOL )
AccessorFunc( PANEL, "m_iHeaderHeight", "HeaderHeight" )
AccessorFunc( PANEL, "m_iDataHeight", "DataHeight" )
AccessorFunc( PANEL, "m_bMultiSelect", "MultiSelect" )
AccessorFunc( PANEL, "m_bHideHeaders", "HideHeaders" )
Derma_Hook( PANEL, "Paint", "Paint", "ListView" )
function PANEL:Init()
self:SetSortable( true )
self:SetMouseInputEnabled( true )
self:SetMultiSelect( true )
self:SetHideHeaders( false )
self:SetPaintBackground( true )
self:SetHeaderHeight( 16 )
self:SetDataHeight( 17 )
self.Columns = {}
self.Lines = {}
self.Sorted = {}
self:SetDirty( true )
self.pnlCanvas = vgui.Create( "Panel", self )
self.VBar = vgui.Create( "DVScrollBar", self )
self.VBar:SetZPos( 20 )
end
function PANEL:DisableScrollbar()
if ( IsValid( self.VBar ) ) then
self.VBar:Remove()
end
self.VBar = nil
end
function PANEL:GetLines()
return self.Lines
end
function PANEL:GetInnerTall()
return self:GetCanvas():GetTall()
end
function PANEL:GetCanvas()
return self.pnlCanvas
end
function PANEL:AddColumn( strName, iPosition )
if ( iPosition ) then
if ( iPosition <= 0 ) then
ErrorNoHaltWithStack( "Attempted to insert column at invalid position ", iPosition )
return
end
if ( IsValid( self.Columns[ iPosition ] ) ) then
ErrorNoHaltWithStack( "Attempted to insert duplicate column." )
return
end
end
local pColumn = nil
if ( self.m_bSortable ) then
pColumn = vgui.Create( "DListView_Column", self )
else
pColumn = vgui.Create( "DListView_ColumnPlain", self )
end
pColumn:SetName( strName )
pColumn:SetZPos( 10 )
if ( iPosition ) then
table.insert( self.Columns, iPosition, pColumn )
local i = 1
for id, pnl in pairs( self.Columns ) do
pnl:SetColumnID( i )
i = i + 1
end
else
local ID = table.insert( self.Columns, pColumn )
pColumn:SetColumnID( ID )
end
self:InvalidateLayout()
return pColumn
end
function PANEL:RemoveLine( LineID )
local Line = self:GetLine( LineID )
local SelectedID = self:GetSortedID( LineID )
self.Lines[ LineID ] = nil
table.remove( self.Sorted, SelectedID )
self:SetDirty( true )
self:InvalidateLayout()
Line:Remove()
end
function PANEL:ColumnWidth( i )
local ctrl = self.Columns[ i ]
if ( !ctrl ) then return 0 end
return ctrl:GetWide()
end
function PANEL:FixColumnsLayout()
local NumColumns = table.Count( self.Columns )
if ( NumColumns == 0 ) then return end
local AllWidth = 0
for k, Column in pairs( self.Columns ) do
AllWidth = AllWidth + math.ceil( Column:GetWide() )
end
local ChangeRequired = self.pnlCanvas:GetWide() - AllWidth
local ChangePerColumn = math.floor( ChangeRequired / NumColumns )
local Remainder = ChangeRequired - ( ChangePerColumn * NumColumns )
for k, Column in pairs( self.Columns ) do
local TargetWidth = math.ceil( Column:GetWide() ) + ChangePerColumn
Remainder = Remainder + ( TargetWidth - Column:SetWidth( TargetWidth ) )
end
local TotalMaxWidth = 0
-- If there's a remainder, try to palm it off on the other panels, equally
while ( Remainder != 0 ) do
local PerPanel = math.floor( Remainder / NumColumns )
for k, Column in pairs( self.Columns ) do
Remainder = math.Approach( Remainder, 0, PerPanel )
local TargetWidth = math.ceil( Column:GetWide() ) + PerPanel
Remainder = Remainder + ( TargetWidth - Column:SetWidth( TargetWidth ) )
if ( Remainder == 0 ) then break end
TotalMaxWidth = TotalMaxWidth + math.ceil( Column:GetMaxWidth() )
end
-- Total max width of all the columns is less than the width of the DListView, abort!
if ( TotalMaxWidth < self.pnlCanvas:GetWide() ) then break end
Remainder = math.Approach( Remainder, 0, 1 )
end
-- Set the positions of the resized columns
local x = 0
for k, Column in pairs( self.Columns ) do
Column.x = x
x = x + math.ceil( Column:GetWide() )
Column:SetTall( math.ceil( self:GetHeaderHeight() ) )
Column:SetVisible( !self:GetHideHeaders() )
end
end
function PANEL:PerformLayout()
-- Do Scrollbar
local Wide = self:GetWide()
local YPos = 0
if ( IsValid( self.VBar ) ) then
self.VBar:SetPos( self:GetWide() - 16, 0 )
self.VBar:SetSize( 16, self:GetTall() )
self.VBar:SetUp( self.VBar:GetTall() - self:GetHeaderHeight(), self.pnlCanvas:GetTall() )
YPos = self.VBar:GetOffset()
if ( self.VBar.Enabled ) then Wide = Wide - 16 end
end
if ( self.m_bHideHeaders ) then
self.pnlCanvas:SetPos( 0, YPos )
else
self.pnlCanvas:SetPos( 0, YPos + self:GetHeaderHeight() )
end
self.pnlCanvas:SetSize( Wide, self.pnlCanvas:GetTall() )
self:FixColumnsLayout()
--
-- If the data is dirty, re-layout
--
if ( self:GetDirty() ) then
self:SetDirty( false )
local y = self:DataLayout()
self.pnlCanvas:SetTall( y )
-- Layout again, since stuff has changed..
self:InvalidateLayout( true )
end
end
function PANEL:OnScrollbarAppear()
self:SetDirty( true )
self:InvalidateLayout()
end
function PANEL:OnRequestResize( SizingColumn, iSize )
-- Find the column to the right of this one
local Passed = false
local RightColumn = nil
for k, Column in pairs( self.Columns ) do
if ( Passed ) then
RightColumn = Column
break
end
if ( SizingColumn == Column ) then Passed = true end
end
-- Alter the size of the column on the right too, slightly
if ( RightColumn ) then
local SizeChange = SizingColumn:GetWide() - iSize
RightColumn:SetWide( RightColumn:GetWide() + SizeChange )
end
SizingColumn:SetWide( iSize )
self:SetDirty( true )
-- Invalidating will munge all the columns about and make it right
self:InvalidateLayout()
end
function PANEL:DataLayout()
local y = 0
local h = self.m_iDataHeight
local alt = false
for k, Line in ipairs( self.Sorted ) do
if ( !Line:IsVisible() ) then continue end
Line:SetPos( 1, y )
Line:SetSize( self:GetWide() - 2, h )
Line:DataLayout( self )
Line:SetAltLine( alt )
alt = !alt
y = y + Line:GetTall()
end
return y
end
function PANEL:AddLine( ... )
self:SetDirty( true )
self:InvalidateLayout()
local Line = vgui.Create( "DListView_Line", self.pnlCanvas )
local ID = table.insert( self.Lines, Line )
Line:SetListView( self )
Line:SetID( ID )
-- This assures that there will be an entry for every column
for k, v in pairs( self.Columns ) do
Line:SetColumnText( k, "" )
end
for k, v in pairs( {...} ) do
Line:SetColumnText( k, v )
end
-- Make appear at the bottom of the sorted list
local SortID = table.insert( self.Sorted, Line )
if ( SortID % 2 == 1 ) then
Line:SetAltLine( true )
end
return Line
end
function PANEL:OnMouseWheeled( dlta )
if ( !IsValid( self.VBar ) ) then return end
return self.VBar:OnMouseWheeled( dlta )
end
function PANEL:ClearSelection( dlta )
for k, Line in pairs( self.Lines ) do
Line:SetSelected( false )
end
end
function PANEL:GetSelectedLine()
for k, Line in pairs( self.Lines ) do
if ( Line:IsSelected() ) then return k, Line end
end
end
function PANEL:GetLine( id )
return self.Lines[ id ]
end
function PANEL:GetSortedID( line )
for k, v in pairs( self.Sorted ) do
if ( v:GetID() == line ) then return k end
end
end
function PANEL:OnClickLine( Line, bClear )
local bMultiSelect = self:GetMultiSelect()
if ( !bMultiSelect && !bClear ) then return end
--
-- Control, multi select
--
if ( bMultiSelect && input.IsKeyDown( KEY_LCONTROL ) ) then
bClear = false
end
--
-- Shift block select
--
if ( bMultiSelect && input.IsKeyDown( KEY_LSHIFT ) ) then
local Selected = self:GetSortedID( self:GetSelectedLine() )
if ( Selected ) then
local LineID = self:GetSortedID( Line:GetID() )
local First = math.min( Selected, LineID )
local Last = math.max( Selected, LineID )
-- Fire off OnRowSelected for each non selected row
for id = First, Last do
local line = self.Sorted[ id ]
if ( !line:IsLineSelected() ) then self:OnRowSelected( line:GetID(), line ) end
line:SetSelected( true )
end
-- Clear the selection and select only the required rows
if ( bClear ) then self:ClearSelection() end
for id = First, Last do
local line = self.Sorted[ id ]
line:SetSelected( true )
end
return
end
end
--
-- Check for double click
--
if ( Line:IsSelected() && Line.m_fClickTime && ( !bMultiSelect || bClear ) ) then
local fTimeDistance = SysTime() - Line.m_fClickTime
if ( fTimeDistance < 0.3 ) then
self:DoDoubleClick( Line:GetID(), Line )
return
end
end
--
-- If it's a new mouse click, or this isn't
-- multiselect we clear the selection
--
if ( !bMultiSelect || bClear ) then
self:ClearSelection()
end
if ( Line:IsSelected() ) then return end
Line:SetSelected( true )
Line.m_fClickTime = SysTime()
self:OnRowSelected( Line:GetID(), Line )
end
function PANEL:SortByColumns( c1, d1, c2, d2, c3, d3, c4, d4 )
table.sort( self.Sorted, function( a, b )
if ( !IsValid( a ) ) then return true end
if ( !IsValid( b ) ) then return false end
if ( c1 && a:GetColumnText( c1 ) != b:GetColumnText( c1 ) ) then
if ( d1 ) then a, b = b, a end
return a:GetColumnText( c1 ) < b:GetColumnText( c1 )
end
if ( c2 && a:GetColumnText( c2 ) != b:GetColumnText( c2 ) ) then
if ( d2 ) then a, b = b, a end
return a:GetColumnText( c2 ) < b:GetColumnText( c2 )
end
if ( c3 && a:GetColumnText( c3 ) != b:GetColumnText( c3 ) ) then
if ( d3 ) then a, b = b, a end
return a:GetColumnText( c3 ) < b:GetColumnText( c3 )
end
if ( c4 && a:GetColumnText( c4 ) != b:GetColumnText( c4 ) ) then
if ( d4 ) then a, b = b, a end
return a:GetColumnText( c4 ) < b:GetColumnText( c4 )
end
return true
end )
self:SetDirty( true )
self:InvalidateLayout()
end
function PANEL:SortByColumn( ColumnID, Desc )
table.sort( self.Sorted, function( a, b )
if ( Desc ) then
a, b = b, a
end
local aval = a:GetSortValue( ColumnID ) || a:GetColumnText( ColumnID )
local bval = b:GetSortValue( ColumnID ) || b:GetColumnText( ColumnID )
-- Maintain nicer sorting for numbers
if ( isnumber( aval ) && isnumber( bval ) ) then return aval < bval end
return tostring( aval ) < tostring( bval )
end )
self:SetDirty( true )
self:InvalidateLayout()
end
function PANEL:SelectItem( Item )
if ( !Item ) then return end
Item:SetSelected( true )
self:OnRowSelected( Item:GetID(), Item )
end
function PANEL:SelectFirstItem()
self:ClearSelection()
self:SelectItem( self.Sorted[ 1 ] )
end
function PANEL:DoDoubleClick( LineID, Line )
-- For Override
end
function PANEL:OnRowSelected( LineID, Line )
-- For Override
end
function PANEL:OnRowRightClick( LineID, Line )
-- For Override
end
function PANEL:Clear()
for k, v in pairs( self.Lines ) do
v:Remove()
end
self.Lines = {}
self.Sorted = {}
self:SetDirty( true )
end
function PANEL:GetSelected()
local ret = {}
for k, v in pairs( self.Lines ) do
if ( v:IsLineSelected() ) then
table.insert( ret, v )
end
end
return ret
end
function PANEL:SizeToContents()
self:SetHeight( self.pnlCanvas:GetTall() + self:GetHeaderHeight() )
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:AddColumn( "Address" )
local Col2 = ctrl:AddColumn( "Port" )
Col2:SetFixedWidth( 30 )
for i = 1, 128 do
ctrl:AddLine( "192.168.0." .. i, "80" )
end
ctrl:SetSize( 300, 200 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DListView", "Data View", PANEL, "DPanel" )

View File

@@ -0,0 +1,170 @@
--[[
| 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 = {}
Derma_Hook( PANEL, "Paint", "Paint", "ListViewHeaderLabel" )
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "ListViewHeaderLabel" )
Derma_Hook( PANEL, "PerformLayout", "Layout", "ListViewHeaderLabel" )
function PANEL:Init()
end
-- No example for this control. Why do we have this control?
function PANEL:GenerateExample( class, tabs, w, h )
end
derma.DefineControl( "DListViewHeaderLabel", "", PANEL, "DLabel" )
--[[---------------------------------------------------------
DListView_DraggerBar
-----------------------------------------------------------]]
local PANEL = {}
function PANEL:Init()
self:SetCursor( "sizewe" )
end
function PANEL:Paint()
return true
end
function PANEL:OnCursorMoved()
if ( self.Depressed ) then
local x, y = self:GetParent():CursorPos()
self:GetParent():ResizeColumn( x )
end
end
-- No example for this control
function PANEL:GenerateExample( class, tabs, w, h )
end
derma.DefineControl( "DListView_DraggerBar", "", PANEL, "DButton" )
--[[---------------------------------------------------------
DListView_Column
-----------------------------------------------------------]]
local PANEL = {}
AccessorFunc( PANEL, "m_iMinWidth", "MinWidth" )
AccessorFunc( PANEL, "m_iMaxWidth", "MaxWidth" )
AccessorFunc( PANEL, "m_iTextAlign", "TextAlign" )
AccessorFunc( PANEL, "m_bFixedWidth", "FixedWidth" )
AccessorFunc( PANEL, "m_bDesc", "Descending" )
AccessorFunc( PANEL, "m_iColumnID", "ColumnID" )
Derma_Hook( PANEL, "Paint", "Paint", "ListViewColumn" )
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "ListViewColumn" )
Derma_Hook( PANEL, "PerformLayout", "Layout", "ListViewColumn" )
function PANEL:Init()
self.Header = vgui.Create( "DButton", self )
self.Header.DoClick = function() self:DoClick() end
self.Header.DoRightClick = function() self:DoRightClick() end
self.DraggerBar = vgui.Create( "DListView_DraggerBar", self )
self:SetMinWidth( 10 )
self:SetMaxWidth( 19200 )
end
function PANEL:SetFixedWidth( iSize )
self:SetMinWidth( iSize )
self:SetMaxWidth( iSize )
self:SetWide( iSize )
end
function PANEL:DoClick()
self:GetParent():SortByColumn( self:GetColumnID(), self:GetDescending() )
self:SetDescending( !self:GetDescending() )
end
function PANEL:DoRightClick()
end
function PANEL:SetName( strName )
self.Header:SetText( strName )
end
function PANEL:Paint()
return true
end
function PANEL:PerformLayout()
if ( self:GetTextAlign() ) then
self.Header:SetContentAlignment( self:GetTextAlign() )
end
self.Header:SetPos( 0, 0 )
self.Header:SetSize( self:GetWide(), self:GetParent():GetHeaderHeight() )
self.DraggerBar:SetWide( 4 )
self.DraggerBar:StretchToParent( nil, 0, nil, 0 )
self.DraggerBar:AlignRight()
end
function PANEL:ResizeColumn( iSize )
self:GetParent():OnRequestResize( self, iSize )
end
function PANEL:SetWidth( iSize )
iSize = math.Clamp( iSize, self:GetMinWidth(), math.max( self:GetMaxWidth(), 0 ) )
iSize = math.ceil( iSize )
-- If the column changes size we need to lay the data out too
if ( iSize != math.ceil( self:GetWide() ) ) then
self:GetParent():SetDirty( true )
end
self:SetWide( iSize )
return iSize
end
derma.DefineControl( "DListView_Column", "Sortable DListView Column", PANEL, "Panel" )
--[[---------------------------------------------------------
DListView_ColumnPlain
-----------------------------------------------------------]]
local PANEL = {}
function PANEL:DoClick()
end
derma.DefineControl( "DListView_ColumnPlain", "Non sortable DListView Column", PANEL, "DListView_Column" )

195
lua/vgui/dlistview_line.lua Normal file
View File

@@ -0,0 +1,195 @@
--[[
| 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 = {}
function PANEL:Init()
self:SetTextInset( 5, 0 )
end
function PANEL:UpdateColours( skin )
if ( self:GetParent():IsLineSelected() ) then return self:SetTextStyleColor( skin.Colours.Label.Bright ) end
return self:SetTextStyleColor( skin.Colours.Label.Dark )
end
function PANEL:GenerateExample()
-- Do nothing!
end
derma.DefineControl( "DListViewLabel", "", PANEL, "DLabel" )
--[[---------------------------------------------------------
DListView_Line
-----------------------------------------------------------]]
local PANEL = {}
Derma_Hook( PANEL, "Paint", "Paint", "ListViewLine" )
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "ListViewLine" )
Derma_Hook( PANEL, "PerformLayout", "Layout", "ListViewLine" )
AccessorFunc( PANEL, "m_iID", "ID" )
AccessorFunc( PANEL, "m_pListView", "ListView" )
AccessorFunc( PANEL, "m_bAlt", "AltLine" )
function PANEL:Init()
self:SetSelectable( true )
self:SetMouseInputEnabled( true )
self.Columns = {}
self.Data = {}
end
function PANEL:OnSelect()
-- For override
end
function PANEL:OnRightClick()
-- For override
end
function PANEL:OnMousePressed( mcode )
if ( mcode == MOUSE_RIGHT ) then
-- This is probably the expected behaviour..
if ( !self:IsLineSelected() ) then
self:GetListView():OnClickLine( self, true )
self:OnSelect()
end
self:GetListView():OnRowRightClick( self:GetID(), self )
self:OnRightClick()
return
end
self:GetListView():OnClickLine( self, true )
self:OnSelect()
end
function PANEL:OnCursorMoved()
if ( input.IsMouseDown( MOUSE_LEFT ) ) then
self:GetListView():OnClickLine( self )
end
end
function PANEL:SetSelected( b )
self.m_bSelected = b
-- Update colors of the lines
for id, column in pairs( self.Columns ) do
column:ApplySchemeSettings()
end
end
function PANEL:IsLineSelected()
return self.m_bSelected
end
function PANEL:SetColumnText( i, strText )
if ( type( strText ) == "Panel" ) then
if ( IsValid( self.Columns[ i ] ) ) then self.Columns[ i ]:Remove() end
strText:SetParent( self )
self.Columns[ i ] = strText
self.Columns[ i ].Value = strText
return
end
if ( !IsValid( self.Columns[ i ] ) ) then
self.Columns[ i ] = vgui.Create( "DListViewLabel", self )
self.Columns[ i ]:SetMouseInputEnabled( false )
end
self.Columns[ i ]:SetText( tostring( strText ) )
self.Columns[ i ].Value = strText
return self.Columns[ i ]
end
PANEL.SetValue = PANEL.SetColumnText
function PANEL:GetColumnText( i )
if ( !self.Columns[ i ] ) then return "" end
return self.Columns[ i ].Value
end
PANEL.GetValue = PANEL.GetColumnText
--[[---------------------------------------------------------
Allows you to store data per column
Used in the SortByColumn function for incase you want to
sort with something else than the text
-----------------------------------------------------------]]
function PANEL:SetSortValue( i, data )
self.Data[ i ] = data
end
function PANEL:GetSortValue( i )
return self.Data[ i ]
end
function PANEL:DataLayout( ListView )
self:ApplySchemeSettings()
local height = self:GetTall()
local x = 0
for k, Column in pairs( self.Columns ) do
local w = ListView:ColumnWidth( k )
Column:SetPos( x, 0 )
Column:SetSize( w, height )
x = x + w
end
end
derma.DefineControl( "DListViewLine", "A line from the List View", PANEL, "Panel" )
derma.DefineControl( "DListView_Line", "A line from the List View", PANEL, "Panel" )

321
lua/vgui/dmenu.lua Normal file
View File

@@ -0,0 +1,321 @@
--[[
| 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_bBorder", "DrawBorder" )
AccessorFunc( PANEL, "m_bDeleteSelf", "DeleteSelf" )
AccessorFunc( PANEL, "m_iMinimumWidth", "MinimumWidth" )
AccessorFunc( PANEL, "m_bDrawColumn", "DrawColumn" )
AccessorFunc( PANEL, "m_iMaxHeight", "MaxHeight" )
AccessorFunc( PANEL, "m_pOpenSubMenu", "OpenSubMenu" )
function PANEL:Init()
self:SetIsMenu( true )
self:SetDrawBorder( true )
self:SetPaintBackground( true )
self:SetMinimumWidth( 100 )
self:SetDrawOnTop( true )
self:SetMaxHeight( ScrH() * 0.9 )
self:SetDeleteSelf( true )
self:SetPadding( 0 )
-- Automatically remove this panel when menus are to be closed
RegisterDermaMenuForClose( self )
end
function PANEL:AddPanel( pnl )
self:AddItem( pnl )
pnl.ParentMenu = self
end
function PANEL:AddOption( strText, funcFunction )
local pnl = vgui.Create( "DMenuOption", self )
pnl:SetMenu( self )
pnl:SetText( strText )
if ( funcFunction ) then pnl.DoClick = funcFunction end
self:AddPanel( pnl )
return pnl
end
function PANEL:AddCVar( strText, convar, on, off, funcFunction )
local pnl = vgui.Create( "DMenuOptionCVar", self )
pnl:SetMenu( self )
pnl:SetText( strText )
if ( funcFunction ) then pnl.DoClick = funcFunction end
pnl:SetConVar( convar )
pnl:SetValueOn( on )
pnl:SetValueOff( off )
self:AddPanel( pnl )
return pnl
end
function PANEL:AddSpacer()
local pnl = vgui.Create( "DPanel", self )
pnl.Paint = function( p, w, h )
derma.SkinHook( "Paint", "MenuSpacer", p, w, h )
end
pnl:SetTall( 1 )
self:AddPanel( pnl )
return pnl
end
function PANEL:AddSubMenu( strText, funcFunction )
local pnl = vgui.Create( "DMenuOption", self )
local SubMenu = pnl:AddSubMenu()
pnl:SetText( strText )
if ( funcFunction ) then pnl.DoClick = funcFunction end
self:AddPanel( pnl )
return SubMenu, pnl
end
function PANEL:Hide()
local openmenu = self:GetOpenSubMenu()
if ( openmenu ) then
openmenu:Hide()
end
self:SetVisible( false )
self:SetOpenSubMenu( nil )
end
function PANEL:OpenSubMenu( item, menu )
-- Do we already have a menu open?
local openmenu = self:GetOpenSubMenu()
if ( IsValid( openmenu ) && openmenu:IsVisible() ) then
-- Don't open it again!
if ( menu && openmenu == menu ) then return end
-- Close it!
self:CloseSubMenu( openmenu )
end
if ( !IsValid( menu ) ) then return end
local x, y = item:LocalToScreen( self:GetWide(), 0 )
menu:Open( x - 3, y, false, item )
self:SetOpenSubMenu( menu )
end
function PANEL:CloseSubMenu( menu )
menu:Hide()
self:SetOpenSubMenu( nil )
end
function PANEL:Paint( w, h )
if ( !self:GetPaintBackground() ) then return end
derma.SkinHook( "Paint", "Menu", self, w, h )
return true
end
function PANEL:ChildCount()
return #self:GetCanvas():GetChildren()
end
function PANEL:GetChild( num )
return self:GetCanvas():GetChildren()[ num ]
end
function PANEL:PerformLayout( w, h )
local minW = self:GetMinimumWidth()
-- Find the widest one
for k, pnl in ipairs( self:GetCanvas():GetChildren() ) do
pnl:InvalidateLayout( true )
minW = math.max( minW, pnl:GetWide() )
end
self:SetWide( minW )
local y = 0 -- for padding
for k, pnl in ipairs( self:GetCanvas():GetChildren() ) do
pnl:SetWide( minW )
pnl:SetPos( 0, y )
pnl:InvalidateLayout( true )
y = y + pnl:GetTall()
end
y = math.min( y, self:GetMaxHeight() )
self:SetTall( y )
derma.SkinHook( "Layout", "Menu", self )
DScrollPanel.PerformLayout( self, minW, h )
end
--[[---------------------------------------------------------
Open - Opens the menu.
x and y are optional, if they're not provided the menu
will appear at the cursor.
-----------------------------------------------------------]]
function PANEL:Open( x, y, skipanimation, ownerpanel )
RegisterDermaMenuForClose( self )
local maunal = x && y
x = x or gui.MouseX()
y = y or gui.MouseY()
local OwnerHeight = 0
local OwnerWidth = 0
if ( ownerpanel ) then
OwnerWidth, OwnerHeight = ownerpanel:GetSize()
end
self:InvalidateLayout( true )
local w = self:GetWide()
local h = self:GetTall()
self:SetSize( w, h )
if ( y + h > ScrH() ) then y = ( ( maunal && ScrH() ) or ( y + OwnerHeight ) ) - h end
if ( x + w > ScrW() ) then x = ( ( maunal && ScrW() ) or x ) - w end
if ( y < 1 ) then y = 1 end
if ( x < 1 ) then x = 1 end
local p = self:GetParent()
if ( IsValid( p ) && p:IsModal() ) then
-- Can't popup while we are parented to a modal panel
-- We will end up behind the modal panel in that case
x, y = p:ScreenToLocal( x, y )
-- We have to reclamp the values
if ( y + h > p:GetTall() ) then y = p:GetTall() - h end
if ( x + w > p:GetWide() ) then x = p:GetWide() - w end
if ( y < 1 ) then y = 1 end
if ( x < 1 ) then x = 1 end
self:SetPos( x, y )
else
self:SetPos( x, y )
-- Popup!
self:MakePopup()
end
-- Make sure it's visible!
self:SetVisible( true )
-- Keep the mouse active while the menu is visible.
self:SetKeyboardInputEnabled( false )
end
--
-- Called by DMenuOption
--
function PANEL:OptionSelectedInternal( option )
self:OptionSelected( option, option:GetText() )
end
function PANEL:OptionSelected( option, text )
-- For override
end
function PANEL:ClearHighlights()
for k, pnl in ipairs( self:GetCanvas():GetChildren() ) do
pnl.Highlight = nil
end
end
function PANEL:HighlightItem( item )
for k, pnl in ipairs( self:GetCanvas():GetChildren() ) do
if ( pnl == item ) then
pnl.Highlight = true
end
end
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local MenuItemSelected = function()
Derma_Message( "Choosing a menu item worked!" )
end
local ctrl = vgui.Create( "Button" )
ctrl:SetText( "Test Me!" )
ctrl.DoClick = function()
local menu = DermaMenu()
menu:AddOption( "Option One", MenuItemSelected )
menu:AddOption( "Option 2", MenuItemSelected )
local submenu = menu:AddSubMenu( "Option Free" )
submenu:AddOption( "Submenu 1", MenuItemSelected )
submenu:AddOption( "Submenu 2", MenuItemSelected )
menu:AddOption( "Option For", MenuItemSelected )
menu:Open()
end
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DMenu", "A Menu", PANEL, "DScrollPanel" )

119
lua/vgui/dmenubar.lua Normal file
View File

@@ -0,0 +1,119 @@
--[[
| 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_bBackground", "PaintBackground", FORCE_BOOL )
AccessorFunc( PANEL, "m_bBackground", "DrawBackground", FORCE_BOOL ) -- deprecated
AccessorFunc( PANEL, "m_bIsMenuComponent", "IsMenu", FORCE_BOOL )
Derma_Hook( PANEL, "Paint", "Paint", "MenuBar" )
function PANEL:Init()
self:Dock( TOP )
self:SetTall( 24 )
self.Menus = {}
end
function PANEL:GetOpenMenu()
for k, v in pairs( self.Menus ) do
if ( v:IsVisible() ) then return v end
end
return nil
end
function PANEL:AddOrGetMenu( label )
if ( self.Menus[ label ] ) then return self.Menus[ label ] end
return self:AddMenu( label )
end
function PANEL:AddMenu( label )
local m = DermaMenu()
m:SetDeleteSelf( false )
m:SetDrawColumn( true )
m:Hide()
self.Menus[ label ] = m
local b = self:Add( "DButton" )
b:SetText( label )
b:Dock( LEFT )
b:DockMargin( 5, 0, 0, 0 )
b:SetIsMenu( true )
b:SetPaintBackground( false )
b:SizeToContentsX( 16 )
b.DoClick = function()
if ( m:IsVisible() ) then
m:Hide()
return
end
local x, y = b:LocalToScreen( 0, 0 )
m:Open( x, y + b:GetTall(), false, b )
end
b.OnCursorEntered = function()
local opened = self:GetOpenMenu()
if ( !IsValid( opened ) || opened == m ) then return end
opened:Hide()
b:DoClick()
end
return m
end
function PANEL:OnRemove()
for id, pnl in pairs( self.Menus ) do
pnl:Remove()
end
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local pnl = vgui.Create( "Panel" )
pnl:Dock( FILL )
pnl:DockMargin( 2, 22, 2, 2 )
local ctrl = pnl:Add( ClassName )
local m = ctrl:AddMenu( "File" )
m:AddOption( "New", function() MsgN( "Chose New" ) end )
m:AddOption( "File", function() MsgN( "Chose File" ) end )
m:AddOption( "Exit", function() MsgN( "Chose Exit" ) end )
local m2 = ctrl:AddMenu( "Edit" )
m2:AddOption( "Copy", function() MsgN( "Chose Copy" ) end )
m2:AddOption( "Paste", function() MsgN( "Chose Paste" ) end )
m2:AddOption( "Blah", function() MsgN( "Chose Blah" ) end )
local sub = m:AddSubMenu( "Sub Menu" )
sub:SetDeleteSelf( false )
for i = 0, 5 do
sub:AddOption( "Option " .. i, function() MsgN( "Chose sub menu option " .. i ) end )
end
PropertySheet:AddSheet( ClassName, pnl, nil, true, true )
end
derma.DefineControl( "DMenuBar", "", PANEL, "DPanel" )

174
lua/vgui/dmenuoption.lua Normal file
View File

@@ -0,0 +1,174 @@
--[[
| 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_pMenu", "Menu" )
AccessorFunc( PANEL, "m_bChecked", "Checked" )
AccessorFunc( PANEL, "m_bCheckable", "IsCheckable" )
AccessorFunc( PANEL, "m_bRadio", "Radio" )
function PANEL:Init()
self:SetContentAlignment( 4 )
self:SetTextInset( 32, 0 ) -- Room for icon on left
self:SetChecked( false )
end
function PANEL:SetSubMenu( menu )
self.SubMenu = menu
if ( !IsValid( self.SubMenuArrow ) ) then
self.SubMenuArrow = vgui.Create( "DPanel", self )
self.SubMenuArrow.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "MenuRightArrow", panel, w, h ) end
end
end
function PANEL:AddSubMenu()
local SubMenu = DermaMenu( true, self )
SubMenu:SetVisible( false )
SubMenu:SetParent( self )
self:SetSubMenu( SubMenu )
return SubMenu
end
function PANEL:OnCursorEntered()
if ( IsValid( self.ParentMenu ) ) then
self.ParentMenu:OpenSubMenu( self, self.SubMenu )
return
end
self:GetParent():OpenSubMenu( self, self.SubMenu )
end
function PANEL:OnCursorExited()
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "MenuOption", self, w, h )
--
-- Draw the button text
--
return false
end
function PANEL:OnMousePressed( mousecode )
self.m_MenuClicking = true
DButton.OnMousePressed( self, mousecode )
end
function PANEL:OnMouseReleased( mousecode )
DButton.OnMouseReleased( self, mousecode )
if ( self.m_MenuClicking && mousecode == MOUSE_LEFT ) then
self.m_MenuClicking = false
CloseDermaMenus()
end
end
function PANEL:DoRightClick()
if ( self:GetIsCheckable() ) then
self:ToggleCheck()
end
end
function PANEL:DoClickInternal()
if ( self:GetIsCheckable() ) then
self:ToggleCheck()
end
if ( self.m_pMenu ) then
self.m_pMenu:OptionSelectedInternal( self )
end
end
function PANEL:ToggleCheck()
if ( self:GetRadio() ) then
if ( self:GetChecked() ) then return end
local menu = self:GetMenu():GetCanvas()
for k, pnl in pairs( menu:GetChildren() ) do
pnl:SetChecked( false )
end
end
self:SetChecked( !self:GetChecked() )
end
function PANEL:SetChecked( b )
if ( self:GetChecked() != b ) then
self:OnChecked( b )
end
self.m_bChecked = b
end
function PANEL:OnChecked( b )
end
function PANEL:PerformLayout( w, h )
self:SizeToContents()
self:SetWide( self:GetWide() + 30 )
w = math.max( self:GetParent():GetWide(), self:GetWide() )
self:SetSize( w, 22 )
if ( IsValid( self.SubMenuArrow ) ) then
self.SubMenuArrow:SetSize( 15, 15 )
self.SubMenuArrow:CenterVertical()
self.SubMenuArrow:AlignRight( 4 )
end
DButton.PerformLayout( self, w, h )
end
function PANEL:GenerateExample()
-- Do nothing!
end
derma.DefineControl( "DMenuOption", "Menu Option Line", PANEL, "DButton" )

View File

@@ -0,0 +1,57 @@
--[[
| 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 = {}
DEFINE_BASECLASS( "DMenuOption" )
AccessorFunc( PANEL, "m_strConVar", "ConVar" )
AccessorFunc( PANEL, "m_strValueOn", "ValueOn" )
AccessorFunc( PANEL, "m_strValueOff", "ValueOff" )
function PANEL:Init()
self:SetChecked( false )
self:SetIsCheckable( true )
self:SetValueOn( "1" )
self:SetValueOff( "0" )
self._NextThink = 0
end
function PANEL:Think()
if ( !self.m_strConVar ) then return end
if ( self._NextThink > RealTime() ) then return end
local strValue = GetConVarString( self.m_strConVar )
self:SetChecked( strValue == self.m_strValueOn )
end
function PANEL:OnChecked( b )
if ( !self.m_strConVar ) then return end
-- Give time for the cvar to update
self._NextThink = RealTime() + 0.1
if ( b ) then
RunConsoleCommand( self.m_strConVar, self.m_strValueOn )
else
RunConsoleCommand( self.m_strConVar, self.m_strValueOff )
end
end
derma.DefineControl( "DMenuOptionCVar", "", PANEL, "DMenuOption" )

209
lua/vgui/dmodelpanel.lua Normal file
View File

@@ -0,0 +1,209 @@
--[[
| 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_fAnimSpeed", "AnimSpeed" )
AccessorFunc( PANEL, "Entity", "Entity" )
AccessorFunc( PANEL, "vCamPos", "CamPos" )
AccessorFunc( PANEL, "fFOV", "FOV" )
AccessorFunc( PANEL, "vLookatPos", "LookAt" )
AccessorFunc( PANEL, "aLookAngle", "LookAng" )
AccessorFunc( PANEL, "colAmbientLight", "AmbientLight" )
AccessorFunc( PANEL, "colColor", "Color" )
AccessorFunc( PANEL, "bAnimated", "Animated" )
function PANEL:Init()
self.Entity = nil
self.LastPaint = 0
self.DirectionalLight = {}
self.FarZ = 4096
self:SetCamPos( Vector( 50, 50, 50 ) )
self:SetLookAt( Vector( 0, 0, 40 ) )
self:SetFOV( 70 )
self:SetText( "" )
self:SetAnimSpeed( 0.5 )
self:SetAnimated( false )
self:SetAmbientLight( Color( 50, 50, 50 ) )
self:SetDirectionalLight( BOX_TOP, Color( 255, 255, 255 ) )
self:SetDirectionalLight( BOX_FRONT, Color( 255, 255, 255 ) )
self:SetColor( color_white )
end
function PANEL:SetDirectionalLight( iDirection, color )
self.DirectionalLight[ iDirection ] = color
end
function PANEL:SetModel( strModelName )
-- Note - there's no real need to delete the old
-- entity, it will get garbage collected, but this is nicer.
if ( IsValid( self.Entity ) ) then
self.Entity:Remove()
self.Entity = nil
end
-- Note: Not in menu dll
if ( !ClientsideModel ) then return end
self.Entity = ClientsideModel( strModelName, RENDERGROUP_OTHER )
if ( !IsValid( self.Entity ) ) then return end
self.Entity:SetNoDraw( true )
self.Entity:SetIK( false )
-- Try to find a nice sequence to play
local iSeq = self.Entity:LookupSequence( "walk_all" )
if ( iSeq <= 0 ) then iSeq = self.Entity:LookupSequence( "WalkUnarmed_all" ) end
if ( iSeq <= 0 ) then iSeq = self.Entity:LookupSequence( "walk_all_moderate" ) end
if ( iSeq > 0 ) then self.Entity:ResetSequence( iSeq ) end
end
function PANEL:GetModel()
if ( !IsValid( self.Entity ) ) then return end
return self.Entity:GetModel()
end
function PANEL:DrawModel()
local curparent = self
local leftx, topy = self:LocalToScreen( 0, 0 )
local rightx, bottomy = self:LocalToScreen( self:GetWide(), self:GetTall() )
while ( curparent:GetParent() != nil ) do
curparent = curparent:GetParent()
local x1, y1 = curparent:LocalToScreen( 0, 0 )
local x2, y2 = curparent:LocalToScreen( curparent:GetWide(), curparent:GetTall() )
leftx = math.max( leftx, x1 )
topy = math.max( topy, y1 )
rightx = math.min( rightx, x2 )
bottomy = math.min( bottomy, y2 )
previous = curparent
end
render.ClearDepth( false )
render.SetScissorRect( leftx, topy, rightx, bottomy, true )
local ret = self:PreDrawModel( self.Entity )
if ( ret != false ) then
self.Entity:DrawModel()
self:PostDrawModel( self.Entity )
end
render.SetScissorRect( 0, 0, 0, 0, false )
end
function PANEL:PreDrawModel( ent )
return true
end
function PANEL:PostDrawModel( ent )
end
function PANEL:Paint( w, h )
if ( !IsValid( self.Entity ) ) then return end
local x, y = self:LocalToScreen( 0, 0 )
self:LayoutEntity( self.Entity )
local ang = self.aLookAngle
if ( !ang ) then
ang = ( self.vLookatPos - self.vCamPos ):Angle()
end
cam.Start3D( self.vCamPos, ang, self.fFOV, x, y, w, h, 5, self.FarZ )
render.SuppressEngineLighting( true )
render.SetLightingOrigin( self.Entity:GetPos() )
render.ResetModelLighting( self.colAmbientLight.r / 255, self.colAmbientLight.g / 255, self.colAmbientLight.b / 255 )
render.SetColorModulation( self.colColor.r / 255, self.colColor.g / 255, self.colColor.b / 255 )
render.SetBlend( ( self:GetAlpha() / 255 ) * ( self.colColor.a / 255 ) ) -- * surface.GetAlphaMultiplier()
for i = 0, 6 do
local col = self.DirectionalLight[ i ]
if ( col ) then
render.SetModelLighting( i, col.r / 255, col.g / 255, col.b / 255 )
end
end
self:DrawModel()
render.SuppressEngineLighting( false )
cam.End3D()
self.LastPaint = RealTime()
end
function PANEL:RunAnimation()
self.Entity:FrameAdvance( --[[( RealTime() - self.LastPaint ) * self.m_fAnimSpeed]] )
end
function PANEL:StartScene( name )
if ( IsValid( self.Scene ) ) then
self.Scene:Remove()
end
self.Scene = ClientsideScene( name, self.Entity )
end
function PANEL:LayoutEntity( Entity )
--
-- This function is to be overriden
--
if ( self.bAnimated ) then
self:RunAnimation()
end
Entity:SetAngles( Angle( 0, RealTime() * 10 % 360, 0 ) )
end
function PANEL:OnRemove()
if ( IsValid( self.Entity ) ) then
self.Entity:Remove()
end
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetSize( 300, 300 )
ctrl:SetModel( "models/props_junk/PlasticCrate01a.mdl" )
ctrl:GetEntity():SetSkin( 2 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DModelPanel", "A panel containing a model", PANEL, "DButton" )

61
lua/vgui/dmodelselect.lua Normal file
View File

@@ -0,0 +1,61 @@
--[[
| 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 = {}
function PANEL:Init()
self:EnableVerticalScrollbar()
self:SetHeight( 2 )
end
function PANEL:SetHeight( numHeight )
self:SetTall( 66 * ( numHeight or 2 ) + 2 )
end
function PANEL:SetModelList( modelList, conVar, dontSort, dontCallListConVars )
for model, v in pairs( modelList ) do
local icon = vgui.Create( "SpawnIcon" )
icon:SetModel( model )
icon:SetSize( 64, 64 )
icon:SetTooltip( model )
icon.Model = model
icon.ConVars = v
local convars = {}
-- some model lists, like from wheels, have extra convars in the ModelList
-- we'll need to add those too
if ( !dontCallListConVars && istable( v ) ) then
table.Merge( convars, v ) -- copy them in to new list
end
-- make strConVar optional so we can have everything in the ModelList instead, if we want to
if ( conVar ) then
convars[ conVar ] = model
end
self:AddPanel( icon, convars )
end
if ( !dontSort ) then
self:SortByMember( "Model", false )
end
end
derma.DefineControl( "DModelSelect", "", PANEL, "DPanelSelect" )

View File

@@ -0,0 +1,41 @@
--[[
| 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 = {}
function PANEL:Init()
self.ModelPanels = {}
self:SetHeight( 2 )
end
function PANEL:SetHeight( numHeight )
self:SetTall( 66 * ( numHeight or 2 ) + 26 )
end
function PANEL:AddModelList( name, modelList, conVar, dontSort, dontCallListConVars )
local ModelSelect = vgui.Create( "DModelSelect", self )
ModelSelect:SetModelList( modelList, conVar, dontSort, dontCallListConVars )
self:AddSheet( name, ModelSelect )
self.ModelPanels[ name ] = ModelSelect
return ModelSelect
end
derma.DefineControl( "DModelSelectMulti", "", PANEL, "DPropertySheet" )

132
lua/vgui/dnotify.lua Normal file
View File

@@ -0,0 +1,132 @@
--[[
| 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, "Spacing", "Spacing" )
AccessorFunc( PANEL, "Alignment", "Alignment" )
AccessorFunc( PANEL, "m_fLifeLength", "Life" )
function PANEL:Init()
self.Items = {}
self:SetSpacing( 4 )
self:SetAlignment( 7 )
self:SetLife( 5 )
-- This turns off the engine drawing
self:SetPaintBackgroundEnabled( false )
self:SetPaintBorderEnabled( false )
end
function PANEL:GetItems()
return self.Items
end
function PANEL:AddItem( item, LifeLength )
if ( !IsValid( item ) ) then return end
LifeLength = LifeLength || self.m_fLifeLength
item:SetVisible( true )
item:SetParent( self )
table.insert( self.Items, item )
item:SetAlpha( 1 )
item:SetTerm( LifeLength )
item:AlphaTo( 0, 0.3, LifeLength - 0.3 )
self:Shuffle()
end
function PANEL:Think()
local bChange = false
for k, panel in pairs( self.Items ) do
if ( !IsValid( panel ) ) then
self.Items[ k ] = false
bChange = true
end
end
if ( bChange ) then
self:Shuffle()
end
end
function PANEL:Shuffle()
local y = 0
if ( self.Alignment == 1 || self.Alignment == 3 ) then
y = self:GetTall()
end
local Count = 0
for k, panel in pairs( self.Items ) do
if ( IsValid( panel ) ) then
local x = 0
if ( self.Alignment == 8 || self.Alignment == 2 ) then
x = (self:GetWide() + panel:GetWide()) / 2
elseif ( self.Alignment == 9 || self.Alignment == 3 ) then
x = self:GetWide() - panel:GetWide()
end
if ( self.Alignment == 1 || self.Alignment == 3 ) then
y = y - panel:GetTall()
end
if ( panel.bHasEntered ) then
panel:SetPos( x, y )
else
panel:SetPos( x, y )
panel:LerpPositions( 1, true )
panel:AlphaTo( 255, 0.3 )
panel.bHasEntered = true
end
if ( self.Alignment == 1 || self.Alignment == 3 ) then
y = y - self.Spacing
else
y = y + panel:GetTall() + self.Spacing
end
Count = Count + 1
end
end
-- By only removing them when the list is empty
-- we keep the order.
if ( Count == 0 && #self.Items > 0 ) then
self.Items = {}
end
end
function PANEL:PerformLayout()
end
derma.DefineControl( "DNotify", "", PANEL, "Panel" )

381
lua/vgui/dnumberscratch.lua Normal file
View File

@@ -0,0 +1,381 @@
--[[
| 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/
--]]
DEFINE_BASECLASS( "DImageButton" )
local g_Active = nil
local PANEL = {}
AccessorFunc( PANEL, "m_numMin", "Min" )
AccessorFunc( PANEL, "m_numMax", "Max" )
AccessorFunc( PANEL, "m_Zoom", "Zoom" )
AccessorFunc( PANEL, "m_fFloatValue", "FloatValue" )
AccessorFunc( PANEL, "m_bActive", "Active" )
AccessorFunc( PANEL, "m_iDecimals", "Decimals" )
AccessorFunc( PANEL, "m_bDrawScreen", "ShouldDrawScreen" )
Derma_Install_Convar_Functions( PANEL )
function PANEL:Init()
self:SetMin( 0 )
self:SetMax( 10 )
self:SetZoom( 0 )
self:SetDecimals( 2 )
self:SetFloatValue( 1.5 )
self:SetShouldDrawScreen( false )
self.MouseX = 0
self.MouseY = 0
self.UnderMaterial = Material( "gui/numberscratch_under.png" )
self.CoverMaterial = Material( "gui/numberscratch_cover.png" )
self:SetImage( "icon16/scratchnumber.png" )
self:SetStretchToFit( false )
self:SetSize( 16, 16 )
self:SetCursor( "sizewe" )
end
function PANEL:SetValue( val )
local val = tonumber( val )
if ( val == nil ) then return end
if ( val == self:GetFloatValue() ) then return end
self:SetFloatValue( val )
self:OnValueChanged( val )
self:UpdateConVar()
end
function PANEL:SetFraction( fFraction )
self:SetFloatValue( self:GetMin() + ( fFraction * self:GetRange() ) )
end
function PANEL:GetFraction()
return ( self:GetFloatValue() - self:GetMin() ) / self:GetRange()
end
function PANEL:GetDecimals()
return self.m_iDecimals or 0
end
function PANEL:GetRange()
return self:GetMax() - self:GetMin()
end
function PANEL:IdealZoom()
return 400 / self:GetRange()
end
function PANEL:OnMousePressed( mousecode )
if ( !self:IsEnabled() ) then return end
if ( self:GetZoom() == 0 ) then self:SetZoom( self:IdealZoom() ) end
self:SetActive( true )
self:MouseCapture( true )
self:LockCursor()
-- Temporary fix for Linux
-- Something keeps snapping the cursor to the center of the screen when it is invisible
-- and we definitely don't want that, let's keep the cursor visible for now
if ( !system.IsLinux() ) then
self:SetCursor( "none" )
end
self:SetShouldDrawScreen( mousecode == MOUSE_LEFT )
g_Active = self
end
function PANEL:OnMouseReleased( mousecode )
g_Active = nil
self:SetActive( false )
self:MouseCapture( false )
self:SetCursor( "sizewe" )
end
function PANEL:LockCursor()
local x, y = self:LocalToScreen( math.floor( self:GetWide() * 0.5 ), math.floor( self:GetTall() * 0.5 ) )
input.SetCursorPos( x, y )
end
function PANEL:OnCursorMoved( x, y )
if ( !self:GetActive() ) then return end
x = x - math.floor( self:GetWide() * 0.5 )
y = y - math.floor( self:GetTall() * 0.5 )
local zoom = self:GetZoom()
local ControlScale = 100 / zoom
local maxzoom = 10 ^ ( 1 + self:GetDecimals() )
zoom = math.Clamp( zoom + ( ( y * -0.6 ) / ControlScale ), 0.01, maxzoom )
if ( !input.IsKeyDown( KEY_LSHIFT ) ) then self:SetZoom( zoom ) end
local oldValue = self:GetFloatValue()
local value = self:GetFloatValue()
value = math.Clamp( value + ( x * ControlScale * 0.002 ), self:GetMin(), self:GetMax() )
self:SetFloatValue( value )
self:LockCursor()
if ( oldValue != value ) then self:OnValueChanged( value ) end
self:UpdateConVar()
end
function PANEL:GetTextValue()
local iDecimals = self:GetDecimals()
if ( iDecimals == 0 ) then
return Format( "%i", self:GetFloatValue() )
end
return Format( "%." .. iDecimals .. "f", self:GetFloatValue() )
end
function PANEL:UpdateConVar()
self:ConVarChanged( self:GetTextValue() )
end
function PANEL:DrawNotches( level, x, y, w, h, range, value, min, max )
local size = level * self:GetZoom()
if ( size < 5 ) then return end
if ( size > w * 2 ) then return end
local alpha = 255
if ( size < 150 ) then alpha = alpha * ( ( size - 2 ) / 140 ) end
if ( size > ( w * 2 ) - 100 ) then alpha = alpha * ( 1 - ( ( size - ( w - 50 ) ) / 50 ) ) end
local halfw = w * 0.5
local span = math.ceil( w / size )
local realmid = x + w * 0.5 - ( value * self:GetZoom() )
local mid = x + w * 0.5 - math.fmod( value * self:GetZoom(), size )
local top = h * 0.4
local nh = h - top
local frame_min = math.floor( realmid + min * self:GetZoom() )
local frame_width = math.ceil( range * self:GetZoom() )
local targetW = math.min( w - math.max( 0, frame_min - x ), frame_width - math.max( 0, x - frame_min ) )
surface.SetDrawColor( 0, 0, 0, alpha )
surface.DrawRect( math.max( x, frame_min ), y + top, targetW, 2 )
surface.SetFont( "DermaDefault" )
for n = -span, span, 1 do
local nx = mid + n * size
if ( nx > x + w or nx < x ) then continue end
local dist = 1 - ( math.abs( halfw - nx + x ) / w )
local val = ( nx - realmid ) / self:GetZoom()
if ( val <= min + 0.001 ) then continue end
if ( val >= max - 0.001 ) then continue end
surface.SetDrawColor( 0, 0, 0, alpha * dist )
surface.SetTextColor( 0, 0, 0, alpha * dist )
surface.DrawRect( nx, y + top, 2, nh )
local tw, th = surface.GetTextSize( val )
surface.SetTextPos( nx - ( tw * 0.5 ), y + top - th )
surface.DrawText( val )
end
surface.SetDrawColor( 0, 0, 0, alpha )
surface.SetTextColor( 0, 0, 0, alpha )
--
-- Draw the last one.
--
local nx = realmid + max * self:GetZoom()
if ( nx < x + w ) then
surface.DrawRect( nx, y + top, 2, nh )
local val = max
local tw, th = surface.GetTextSize( val )
surface.SetTextPos( nx - ( tw * 0.5 ), y + top - th )
surface.DrawText( val )
end
--
-- Draw the first
--
local nx = realmid + min * self:GetZoom()
if ( nx > x ) then
surface.DrawRect( nx, y + top, 2, nh )
local val = min
local tw, th = surface.GetTextSize( val )
surface.SetTextPos( nx - ( tw * 0.5 ), y + top - th )
surface.DrawText( val )
end
end
function PANEL:Think()
if ( !self:GetActive() ) then
self:ConVarNumberThink()
end
end
function PANEL:IsEditing()
return self:GetActive()
end
function PANEL:DrawScreen( x, y, w, h )
if ( !self:GetShouldDrawScreen() ) then return end
local wasEnabled = DisableClipping( true )
--
-- Background
--
surface.SetMaterial( self.UnderMaterial )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.DrawTexturedRect( x, y, w, h )
local min = self:GetMin()
local max = self:GetMax()
local range = self:GetMax() - self:GetMin()
local value = self:GetFloatValue()
--
-- Background colour block
--
surface.SetDrawColor( 255, 250, 180, 100 )
local targetX = x + w * 0.5 - ( ( value - min ) * self:GetZoom() )
local targetW = range * self:GetZoom()
targetW = targetW - math.max( 0, x - targetX )
targetW = math.min( targetW, w - math.max( 0, targetX - x ) )
surface.DrawRect( math.max( targetX, x ) + 3, y + h * 0.4, targetW - 6, h * 0.6 )
for i = 1, 4 do
self:DrawNotches( 10 ^ i, x, y, w, h, range, value, min, max )
end
for i = 0, self:GetDecimals() do
self:DrawNotches( 1 / 10 ^ i, x, y, w, h, range, value, min, max )
end
--
-- Cover
--
surface.SetMaterial( self.CoverMaterial )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.DrawTexturedRect( x, y, w, h )
--
-- Text Value
--
surface.SetFont( "DermaLarge" )
local str = self:GetTextValue()
str = string.Comma( str )
local tw, th = surface.GetTextSize( str )
draw.RoundedBoxEx( 8, x + w * 0.5 - tw / 2 - 10, y + h - 43, tw + 20, 39, Color( 0, 186, 255, 255 ), true, true, false, false )
surface.SetTextColor( 255, 255, 255, 255 )
surface.SetTextPos( x + w * 0.5 - tw * 0.5, y + h - th - 6 )
surface.DrawText( str )
DisableClipping( wasEnabled )
end
function PANEL:PaintScratchWindow()
if ( !self:GetActive() ) then return end
if ( self:GetZoom() == 0 ) then self:SetZoom( self:IdealZoom() ) end
local w, h = 512, 256
local x, y = self:LocalToScreen( 0, 0 )
x = x + self:GetWide() * 0.5 - w * 0.5
y = y - 8 - h
if ( x + w + 32 > ScrW() ) then x = ScrW() - w - 32 end
if ( y + h + 32 > ScrH() ) then y = ScrH() - h - 32 end
if ( x < 32 ) then x = 32 end
if ( y < 32 ) then y = 32 end
if ( render ) then render.SetScissorRect( x, y, x + w, y + h, true ) end
self:DrawScreen( x, y, w, h )
if ( render ) then render.SetScissorRect( x, y, w, h, false ) end
end
--
-- For your pleasure.
--
function PANEL:OnValueChanged( value )
end
PANEL.AllowAutoRefresh = true
function PANEL:GenerateExample()
-- The concommand derma_controls currently runs in the menu realm
-- DNumberScratch uses the render library which is currently unavailable in this realm
-- Therefor we cannot generate an example without spitting errors
end
derma.DefineControl( "DNumberScratch", "", PANEL, "DImageButton" )
hook.Add( "DrawOverlay", "DrawNumberScratch", function()
if ( !IsValid( g_Active ) ) then return end
g_Active:PaintScratchWindow()
end )

262
lua/vgui/dnumberwang.lua Normal file
View File

@@ -0,0 +1,262 @@
--[[
| 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_numMin", "Min" )
AccessorFunc( PANEL, "m_numMax", "Max" )
AccessorFunc( PANEL, "m_iDecimals", "Decimals" ) -- The number of decimal places in the output
AccessorFunc( PANEL, "m_fFloatValue", "FloatValue" )
AccessorFunc( PANEL, "m_iInterval", "Interval" )
-- AnchorValue and UnAnchorValue functions are internally used for "drag-changing" the value
local function AnchorValue( wang, button, mcode )
button:OldOnMousePressed( mcode )
wang.mouseAnchor = gui.MouseY()
wang.valAnchor = wang:GetValue()
end
local function UnAnchorValue( wang, button, mcode )
button:OldOnMouseReleased( mcode )
wang.mouseAnchor = nil
wang.valAnchor = nil
end
function PANEL:Init()
self:SetDecimals( 2 )
self:SetTall( 20 )
self:SetMinMax( 0, 100 )
self:SetInterval( 1 )
self:SetUpdateOnType( true )
self:SetNumeric( true )
self.OnChange = function() self:OnValueChanged( self:GetValue() ) end
self.Up = vgui.Create( "DButton", self )
self.Up:SetText( "" )
self.Up.DoClick = function( button, mcode ) self:SetValue( self:GetValue() + self:GetInterval() ) end
self.Up.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "NumberUp", panel, w, h ) end
self.Up.OldOnMousePressed = self.Up.OnMousePressed
self.Up.OldOnMouseReleased = self.Up.OnMouseReleased
self.Up.OnMousePressed = function( button, mcode ) AnchorValue( self, button, mcode ) end
self.Up.OnMouseReleased = function( button, mcode ) UnAnchorValue( self, button, mcode ) end
self.Up.OnMouseWheeled = function( button, delta ) self:SetValue( self:GetValue() + delta ) end
self.Down = vgui.Create( "DButton", self )
self.Down:SetText( "" )
self.Down.DoClick = function( button, mcode ) self:SetValue( self:GetValue() - self:GetInterval() ) end
self.Down.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "NumberDown", panel, w, h ) end
self.Down.OldOnMousePressed = self.Down.OnMousePressed
self.Down.OldOnMouseReleased = self.Down.OnMouseReleased
self.Down.OnMousePressed = function( button, mcode ) AnchorValue( self, button, mcode ) end
self.Down.OnMouseReleased = function( button, mcode ) UnAnchorValue( self, button, mcode ) end
self.Down.OnMouseWheeled = function( button, delta ) self:SetValue( self:GetValue() + delta ) end
self:SetValue( 0 )
end
function PANEL:HideWang()
self.Up:Hide()
self.Down:Hide()
end
function PANEL:Think()
if ( self.mouseAnchor ) then
self:SetValue( self.valAnchor + self.mouseAnchor - gui.MouseY() )
end
end
function PANEL:SetDecimals( num )
self.m_iDecimals = num
self:SetValue( self:GetValue() )
end
function PANEL:SetMinMax( min, max )
self:SetMin( min )
self:SetMax( max )
end
function PANEL:SetMin( min )
self.m_numMin = tonumber( min )
end
function PANEL:SetMax( max )
self.m_numMax = tonumber( max )
end
function PANEL:GetFloatValue( max )
if ( !self.m_fFloatValue ) then self.m_fFloatValue = 0 end
return tonumber( self.m_fFloatValue ) or 0
end
function PANEL:SetValue( val )
if ( val == nil ) then return end
val = tonumber( val )
val = val or 0
if ( self.m_numMax != nil ) then
val = math.min( self.m_numMax, val )
end
if ( self.m_numMin != nil ) then
val = math.max( self.m_numMin, val )
end
local valText
if ( self.m_iDecimals == 0 ) then
valText = Format( "%i", val )
elseif ( val != 0 ) then
valText = Format( "%." .. self.m_iDecimals .. "f", val )
-- Trim trailing 0's and .'s 0 this gets rid of .00 etc
valText = string.TrimRight( valText, "0" )
valText = string.TrimRight( valText, "." )
else
valText = tostring( val )
end
local hasChanged = tonumber( val ) != tonumber( self:GetValue() )
--
-- Don't change the value while we're typing into it!
-- It causes confusion!
--
if ( !self:HasFocus() ) then
self:SetText( valText )
self:ConVarChanged( valText )
end
if ( hasChanged ) then
self:OnValueChanged( val )
end
end
local meta = FindMetaTable( "Panel" )
function PANEL:GetValue()
return tonumber( meta.GetValue( self ) ) or 0
end
function PANEL:PerformLayout()
local s = math.floor( self:GetTall() * 0.5 )
self.Up:SetSize( s, s - 1 )
self.Up:AlignRight( 3 )
self.Up:AlignTop( 0 )
self.Down:SetSize( s, s - 1 )
self.Down:AlignRight( 3 )
self.Down:AlignBottom( 2 )
end
function PANEL:SizeToContents()
-- Size based on the max number and max amount of decimals
local chars = 0
local min = math.Round( self:GetMin(), self:GetDecimals() )
local max = math.Round( self:GetMax(), self:GetDecimals() )
local minchars = string.len( "" .. min .. "" )
local maxchars = string.len( "" .. max .. "" )
chars = chars + math.max( minchars, maxchars )
if ( self:GetDecimals() && self:GetDecimals() > 0 ) then
chars = chars + 1 -- .
chars = chars + self:GetDecimals()
end
self:InvalidateLayout( true )
self:SetWide( chars * 6 + 10 + 5 + 5 )
self:InvalidateLayout()
end
function PANEL:GetFraction( val )
local Value = val or self:GetValue()
local Fraction = ( Value - self.m_numMin ) / ( self.m_numMax - self.m_numMin )
return Fraction
end
function PANEL:SetFraction( val )
local Fraction = self.m_numMin + ( (self.m_numMax - self.m_numMin) * val )
self:SetValue( Fraction )
end
function PANEL:OnValueChanged( val )
end
function PANEL:GetTextArea()
return self
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetDecimals( 0 )
ctrl:SetMinMax( 0, 255 )
ctrl:SetValue( 3 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DNumberWang", "Menu Option Line", PANEL, "DTextEntry" )

180
lua/vgui/dnumpad.lua Normal file
View File

@@ -0,0 +1,180 @@
--[[
| 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 KP_ENTER = 11
local KP_PERIOD = 10
local KP_PLUS = 12
local KP_MINUS = 13
local KP_STAR = 14
local KP_DIV = 15
local PANEL = {}
AccessorFunc( PANEL, "m_SelectedButton", "Selected" )
AccessorFunc( PANEL, "m_iSelectedNumber", "SelectedNumber" )
AccessorFunc( PANEL, "m_iPadding", "Padding" )
AccessorFunc( PANEL, "m_bButtonSize", "ButtonSize" )
AccessorFunc( PANEL, "m_bStickyKeys", "StickyKeys" ) -- Should keys stay selected when pressed? (like the spawn menu)
Derma_Install_Convar_Functions( PANEL )
function PANEL:Init()
self.Buttons = {}
for i = 0, 15 do
self.Buttons[ i ] = vgui.Create( "DButton", self )
self.Buttons[ i ]:SetText( i )
self.Buttons[ i ].DoClick = function( btn ) self:ButtonPressed( btn, i ) end
end
self.Buttons[KP_ENTER]:SetText( "" )
self.Buttons[KP_PERIOD]:SetText( "." )
self.Buttons[KP_PLUS]:SetText( "+" )
self.Buttons[KP_MINUS]:SetText( "-" )
self.Buttons[KP_STAR]:SetText( "*" )
self.Buttons[KP_DIV]:SetText( "/" )
self.Buttons[0]:SetContentAlignment( 4 )
self.Buttons[0]:SetTextInset( 6, 0 )
self:SetStickyKeys( true )
self:SetButtonSize( 17 )
self:SetPadding( 4 )
self:SetSelectedNumber( -1 )
end
function PANEL:ButtonPressed( btn, iNum )
-- Toggle off
if ( self.m_bStickyKeys && self.m_SelectedButton && self.m_SelectedButton == btn ) then
self.m_SelectedButton:SetSelected( false )
self:SetSelected( -1 )
return
end
self:SetSelected( iNum )
self:OnButtonPressed( iNum, btn )
end
function PANEL:SetSelected( iNum )
local btn = self.Buttons[ iNum ]
self:SetSelectedNumber( iNum )
self:ConVarChanged( iNum )
if ( self.m_SelectedButton ) then
self.m_SelectedButton:SetSelected( false )
end
self.m_SelectedButton = btn
if ( btn && self.m_bStickyKeys ) then
btn:SetSelected( true )
end
end
function PANEL:OnButtonPressed( iButtonNumber, pButton )
-- Override this.
end
function PANEL:PerformLayout()
local ButtonSize = self:GetButtonSize()
local Padding = self:GetPadding()
self:SetSize( ButtonSize * 4 + Padding * 2, ButtonSize * 5 + Padding * 2 )
self.Buttons[ 0 ]:SetSize( ButtonSize * 2, ButtonSize )
self.Buttons[ 0 ]:AlignBottom( Padding )
self.Buttons[ 0 ]:AlignLeft( Padding )
self.Buttons[KP_PERIOD]:CopyBounds( self.Buttons[0] )
self.Buttons[KP_PERIOD]:SetSize( ButtonSize, ButtonSize )
self.Buttons[KP_PERIOD]:MoveRightOf( self.Buttons[0] )
self.Buttons[1]:SetSize( ButtonSize, ButtonSize )
self.Buttons[1]:AlignLeft( Padding )
self.Buttons[1]:MoveAbove( self.Buttons[ 0 ] )
self.Buttons[2]:CopyBounds( self.Buttons[1] )
self.Buttons[2]:MoveRightOf( self.Buttons[1] )
self.Buttons[3]:CopyBounds( self.Buttons[2] )
self.Buttons[3]:MoveRightOf( self.Buttons[2] )
self.Buttons[KP_ENTER]:SetSize( ButtonSize, ButtonSize * 2 )
self.Buttons[KP_ENTER]:AlignBottom( Padding )
self.Buttons[KP_ENTER]:AlignRight( Padding )
self.Buttons[KP_PLUS]:CopyBounds( self.Buttons[KP_ENTER] )
self.Buttons[KP_PLUS]:MoveAbove( self.Buttons[KP_ENTER] )
self.Buttons[KP_MINUS]:CopyBounds( self.Buttons[KP_PLUS] )
self.Buttons[KP_MINUS]:SetSize( ButtonSize, ButtonSize )
self.Buttons[KP_MINUS]:MoveAbove( self.Buttons[KP_PLUS] )
self.Buttons[KP_STAR]:CopyBounds( self.Buttons[KP_MINUS] )
self.Buttons[KP_STAR]:MoveLeftOf( self.Buttons[KP_MINUS] )
self.Buttons[KP_DIV]:CopyBounds( self.Buttons[KP_STAR] )
self.Buttons[KP_DIV]:MoveLeftOf( self.Buttons[KP_STAR] )
self.Buttons[4]:CopyBounds( self.Buttons[1] )
self.Buttons[4]:MoveAbove( self.Buttons[1] )
self.Buttons[5]:CopyBounds( self.Buttons[4] )
self.Buttons[5]:MoveRightOf( self.Buttons[4] )
self.Buttons[6]:CopyBounds( self.Buttons[5] )
self.Buttons[6]:MoveRightOf( self.Buttons[5] )
self.Buttons[7]:CopyBounds( self.Buttons[4] )
self.Buttons[7]:MoveAbove( self.Buttons[4] )
self.Buttons[8]:CopyBounds( self.Buttons[7] )
self.Buttons[8]:MoveRightOf( self.Buttons[7] )
self.Buttons[9]:CopyBounds( self.Buttons[8] )
self.Buttons[9]:MoveRightOf( self.Buttons[8] )
end
function PANEL:Think()
self:ConVarNumberThink()
end
function PANEL:SetValue( iNumValue )
self:SetSelected( iNumValue )
end
function PANEL:GetValue()
return self:GetSelectedNumber()
end
derma.DefineControl( "DNumPad", "", PANEL, "DPanel" )

306
lua/vgui/dnumslider.lua Normal file
View File

@@ -0,0 +1,306 @@
--[[
| 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_fDefaultValue", "DefaultValue" )
function PANEL:Init()
self.TextArea = self:Add( "DTextEntry" )
self.TextArea:Dock( RIGHT )
self.TextArea:SetPaintBackground( false )
self.TextArea:SetWide( 45 )
self.TextArea:SetNumeric( true )
self.TextArea.OnChange = function( textarea, val ) self:SetValue( self.TextArea:GetText() ) end
-- Causes automatic clamp to min/max, disabled for now. TODO: Enforce this with a setter/getter?
--self.TextArea.OnEnter = function( textarea, val ) textarea:SetText( self.Scratch:GetTextValue() ) end -- Update the text
self.Slider = self:Add( "DSlider", self )
self.Slider:SetLockY( 0.5 )
self.Slider.TranslateValues = function( slider, x, y ) return self:TranslateSliderValues( x, y ) end
self.Slider:SetTrapInside( true )
self.Slider:Dock( FILL )
self.Slider:SetHeight( 16 )
self.Slider.ResetToDefaultValue = function( s )
self:ResetToDefaultValue()
end
Derma_Hook( self.Slider, "Paint", "Paint", "NumSlider" )
self.Label = vgui.Create ( "DLabel", self )
self.Label:Dock( LEFT )
self.Label:SetMouseInputEnabled( true )
self.Scratch = self.Label:Add( "DNumberScratch" )
self.Scratch:SetImageVisible( false )
self.Scratch:Dock( FILL )
self.Scratch.OnValueChanged = function() self:ValueChanged( self.Scratch:GetFloatValue() ) end
self:SetTall( 32 )
self:SetMin( 0 )
self:SetMax( 1 )
self:SetDecimals( 2 )
self:SetText( "" )
self:SetValue( 0.5 )
--
-- You really shouldn't be messing with the internals of these controls from outside..
-- .. but if you are, this might stop your code from fucking us both.
--
self.Wang = self.Scratch
end
function PANEL:SetMinMax( min, max )
self.Scratch:SetMin( tonumber( min ) )
self.Scratch:SetMax( tonumber( max ) )
self:UpdateNotches()
end
function PANEL:ApplySchemeSettings()
self.Label:ApplySchemeSettings()
-- Copy the color of the label to the slider notches and the text entry
local col = self.Label:GetTextStyleColor()
if ( self.Label:GetTextColor() ) then col = self.Label:GetTextColor() end
self.TextArea:SetTextColor( col )
local color = table.Copy( col )
color.a = 100 -- Fade it out a bit so it looks right
self.Slider:SetNotchColor( color )
end
function PANEL:SetDark( b )
self.Label:SetDark( b )
self:ApplySchemeSettings()
end
function PANEL:GetMin()
return self.Scratch:GetMin()
end
function PANEL:GetMax()
return self.Scratch:GetMax()
end
function PANEL:GetRange()
return self:GetMax() - self:GetMin()
end
function PANEL:ResetToDefaultValue()
if ( !self:GetDefaultValue() ) then return end
self:SetValue( self:GetDefaultValue() )
end
function PANEL:SetMin( min )
if ( !min ) then min = 0 end
self.Scratch:SetMin( tonumber( min ) )
self:UpdateNotches()
end
function PANEL:SetMax( max )
if ( !max ) then max = 0 end
self.Scratch:SetMax( tonumber( max ) )
self:UpdateNotches()
end
function PANEL:SetValue( val )
val = math.Clamp( tonumber( val ) || 0, self:GetMin(), self:GetMax() )
if ( self:GetValue() == val ) then return end
self.Scratch:SetValue( val ) -- This will also call ValueChanged
self:ValueChanged( self:GetValue() ) -- In most cases this will cause double execution of OnValueChanged
end
function PANEL:GetValue()
return self.Scratch:GetFloatValue()
end
function PANEL:SetDecimals( d )
self.Scratch:SetDecimals( d )
self:UpdateNotches()
self:ValueChanged( self:GetValue() ) -- Update the text
end
function PANEL:GetDecimals()
return self.Scratch:GetDecimals()
end
--
-- Are we currently changing the value?
--
function PANEL:IsEditing()
return self.Scratch:IsEditing() || self.TextArea:IsEditing() || self.Slider:IsEditing()
end
function PANEL:IsHovered()
return self.Scratch:IsHovered() || self.TextArea:IsHovered() || self.Slider:IsHovered() || vgui.GetHoveredPanel() == self
end
function PANEL:PerformLayout()
self.Label:SetWide( self:GetWide() / 2.4 )
end
function PANEL:SetConVar( cvar )
self.Scratch:SetConVar( cvar )
self.TextArea:SetConVar( cvar )
end
function PANEL:SetText( text )
self.Label:SetText( text )
end
function PANEL:GetText()
return self.Label:GetText()
end
function PANEL:ValueChanged( val )
val = math.Clamp( tonumber( val ) || 0, self:GetMin(), self:GetMax() )
if ( self.TextArea != vgui.GetKeyboardFocus() ) then
self.TextArea:SetValue( self.Scratch:GetTextValue() )
end
self.Slider:SetSlideX( self.Scratch:GetFraction() )
self:OnValueChanged( val )
self:SetCookie( "slider_val", val )
end
function PANEL:LoadCookies()
self:SetValue( self:GetCookie( "slider_val" ) )
end
function PANEL:OnValueChanged( val )
-- For override
end
function PANEL:TranslateSliderValues( x, y )
self:SetValue( self.Scratch:GetMin() + ( x * self.Scratch:GetRange() ) )
return self.Scratch:GetFraction(), y
end
function PANEL:GetTextArea()
return self.TextArea
end
function PANEL:UpdateNotches()
local range = self:GetRange()
self.Slider:SetNotches( nil )
if ( range < self:GetWide() / 4 ) then
return self.Slider:SetNotches( range )
else
self.Slider:SetNotches( self:GetWide() / 4 )
end
end
function PANEL:SetEnabled( b )
self.TextArea:SetEnabled( b )
self.Slider:SetEnabled( b )
self.Scratch:SetEnabled( b )
self.Label:SetEnabled( b )
FindMetaTable( "Panel" ).SetEnabled( self, b ) -- There has to be a better way!
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetWide( 200 )
ctrl:SetMin( 1 )
ctrl:SetMax( 10 )
ctrl:SetText( "Example Slider!" )
ctrl:SetDecimals( 0 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DNumSlider", "Menu Option Line", table.Copy( PANEL ), "Panel" )
-- No example for this fella
PANEL.GenerateExample = nil
function PANEL:PostMessage( name, _, val )
if ( name == "SetInteger" ) then
if ( val == "1" ) then
self:SetDecimals( 0 )
else
self:SetDecimals( 2 )
end
end
if ( name == "SetLower" ) then
self:SetMin( tonumber( val ) )
end
if ( name == "SetHigher" ) then
self:SetMax( tonumber( val ) )
end
if ( name == "SetValue" ) then
self:SetValue( tonumber( val ) )
end
end
function PANEL:PerformLayout()
self.Scratch:SetVisible( false )
self.Label:SetVisible( false )
self.Slider:StretchToParent( 0, 0, 0, 0 )
self.Slider:SetSlideX( self.Scratch:GetFraction() )
end
function PANEL:SetActionFunction( func )
self.OnValueChanged = function( pnl, val ) func( pnl, "SliderMoved", val, 0 ) end
end
-- Compat
derma.DefineControl( "Slider", "Backwards Compatibility", PANEL, "Panel" )

93
lua/vgui/dpanel.lua Normal file
View File

@@ -0,0 +1,93 @@
--[[
| 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_bBackground", "PaintBackground", FORCE_BOOL )
AccessorFunc( PANEL, "m_bBackground", "DrawBackground", FORCE_BOOL ) -- deprecated
AccessorFunc( PANEL, "m_bIsMenuComponent", "IsMenu", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDisableTabbing", "TabbingDisabled", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDisabled", "Disabled" )
AccessorFunc( PANEL, "m_bgColor", "BackgroundColor" )
Derma_Hook( PANEL, "Paint", "Paint", "Panel" )
Derma_Hook( PANEL, "ApplySchemeSettings", "Scheme", "Panel" )
Derma_Hook( PANEL, "PerformLayout", "Layout", "Panel" )
function PANEL:Init()
self:SetPaintBackground( true )
-- This turns off the engine drawing
self:SetPaintBackgroundEnabled( false )
self:SetPaintBorderEnabled( false )
end
function PANEL:SetDisabled( bDisabled )
self.m_bDisabled = bDisabled
if ( bDisabled ) then
self:SetAlpha( 75 )
self:SetMouseInputEnabled( false )
else
self:SetAlpha( 255 )
self:SetMouseInputEnabled( true )
end
end
function PANEL:SetEnabled( bEnabled )
self:SetDisabled( !bEnabled )
end
function PANEL:IsEnabled()
return !self:GetDisabled()
end
function PANEL:OnMousePressed( mousecode )
if ( self:IsSelectionCanvas() && !dragndrop.IsDragging() ) then
self:StartBoxSelection()
return
end
if ( self:IsDraggable() ) then
self:MouseCapture( true )
self:DragMousePress( mousecode )
end
end
function PANEL:OnMouseReleased( mousecode )
if ( self:EndBoxSelection() ) then return end
self:MouseCapture( false )
if ( self:DragMouseRelease( mousecode ) ) then
return
end
end
function PANEL:UpdateColours()
end
derma.DefineControl( "DPanel", "", PANEL, "Panel" )

438
lua/vgui/dpanellist.lua Normal file
View File

@@ -0,0 +1,438 @@
--[[
| 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_bSizeToContents", "AutoSize" )
AccessorFunc( PANEL, "m_bStretchHorizontally", "StretchHorizontally" )
AccessorFunc( PANEL, "m_bNoSizing", "NoSizing" )
AccessorFunc( PANEL, "m_bSortable", "Sortable" )
AccessorFunc( PANEL, "m_fAnimTime", "AnimTime" )
AccessorFunc( PANEL, "m_fAnimEase", "AnimEase" )
AccessorFunc( PANEL, "m_strDraggableName", "DraggableName" )
AccessorFunc( PANEL, "Spacing", "Spacing" )
AccessorFunc( PANEL, "Padding", "Padding" )
function PANEL:Init()
self:SetDraggableName( "GlobalDPanel" )
self.pnlCanvas = vgui.Create( "DPanel", self )
self.pnlCanvas:SetPaintBackground( false )
self.pnlCanvas.OnMousePressed = function( slf, code ) slf:GetParent():OnMousePressed( code ) end
self.pnlCanvas.OnChildRemoved = function() self:OnChildRemoved() end
self.pnlCanvas:SetMouseInputEnabled( true )
self.pnlCanvas.InvalidateLayout = function() self:InvalidateLayout() end
self.Items = {}
self.YOffset = 0
self.m_fAnimTime = 0
self.m_fAnimEase = -1 -- means ease in out
self.m_iBuilds = 0
self:SetSpacing( 0 )
self:SetPadding( 0 )
self:EnableHorizontal( false )
self:SetAutoSize( false )
self:SetPaintBackground( true )
self:SetNoSizing( false )
self:SetMouseInputEnabled( true )
-- This turns off the engine drawing
self:SetPaintBackgroundEnabled( false )
self:SetPaintBorderEnabled( false )
end
function PANEL:OnModified()
-- Override me
end
function PANEL:SizeToContents()
self:SetSize( self.pnlCanvas:GetSize() )
end
function PANEL:GetItems()
-- Should we return a copy of this to stop
-- people messing with it?
return self.Items
end
function PANEL:EnableHorizontal( bHoriz )
self.Horizontal = bHoriz
end
function PANEL:EnableVerticalScrollbar()
if ( self.VBar ) then return end
self.VBar = vgui.Create( "DVScrollBar", self )
end
function PANEL:GetCanvas()
return self.pnlCanvas
end
function PANEL:Clear( bDelete )
for k, panel in pairs( self.Items ) do
if ( !IsValid( panel ) ) then continue end
panel:SetVisible( false )
if ( bDelete ) then
panel:Remove()
end
end
self.Items = {}
end
function PANEL:AddItem( item, strLineState )
if ( !IsValid( item ) ) then return end
item:SetVisible( true )
item:SetParent( self:GetCanvas() )
item.m_strLineState = strLineState || item.m_strLineState
table.insert( self.Items, item )
--[[if ( self.m_bSortable ) then
local DragSlot = item:MakeDraggable( self:GetDraggableName(), self )
DragSlot.OnDrop = self.DropAction
end]]
item:SetSelectable( self.m_bSelectionCanvas )
self:InvalidateLayout()
end
function PANEL:InsertBefore( before, insert, strLineState )
table.RemoveByValue( self.Items, insert )
self:AddItem( insert, strLineState )
local key = table.KeyFromValue( self.Items, before )
if ( key ) then
table.RemoveByValue( self.Items, insert )
table.insert( self.Items, key, insert )
end
end
function PANEL:InsertAfter( before, insert, strLineState )
table.RemoveByValue( self.Items, insert )
self:AddItem( insert, strLineState )
local key = table.KeyFromValue( self.Items, before )
if ( key ) then
table.RemoveByValue( self.Items, insert )
table.insert( self.Items, key + 1, insert )
end
end
function PANEL:InsertAtTop( insert, strLineState )
table.RemoveByValue( self.Items, insert )
self:AddItem( insert, strLineState )
local key = 1
if ( key ) then
table.RemoveByValue( self.Items, insert )
table.insert( self.Items, key, insert )
end
end
function PANEL.DropAction( Slot, RcvSlot )
local PanelToMove = Slot.Panel
if ( dragndrop.m_MenuData == "copy" ) then
if ( PanelToMove.Copy ) then
PanelToMove = Slot.Panel:Copy()
PanelToMove.m_strLineState = Slot.Panel.m_strLineState
else
return
end
end
PanelToMove:SetPos( RcvSlot.Data.pnlCanvas:ScreenToLocal( gui.MouseX() - dragndrop.m_MouseLocalX, gui.MouseY() - dragndrop.m_MouseLocalY ) )
if ( dragndrop.DropPos == 4 || dragndrop.DropPos == 8 ) then
RcvSlot.Data:InsertBefore( RcvSlot.Panel, PanelToMove )
else
RcvSlot.Data:InsertAfter( RcvSlot.Panel, PanelToMove )
end
end
function PANEL:RemoveItem( item, bDontDelete )
for k, panel in pairs( self.Items ) do
if ( panel == item ) then
self.Items[ k ] = nil
if ( !bDontDelete ) then
panel:Remove()
end
self:InvalidateLayout()
end
end
end
function PANEL:CleanList()
for k, panel in pairs( self.Items ) do
if ( !IsValid( panel ) || panel:GetParent() != self.pnlCanvas ) then
self.Items[k] = nil
end
end
end
function PANEL:Rebuild()
local Offset = 0
self.m_iBuilds = self.m_iBuilds + 1
self:CleanList()
if ( self.Horizontal ) then
local x, y = self.Padding, self.Padding
for k, panel in pairs( self.Items ) do
if ( panel:IsVisible() ) then
local OwnLine = ( panel.m_strLineState && panel.m_strLineState == "ownline" )
local w = panel:GetWide()
local h = panel:GetTall()
if ( x > self.Padding && ( x + w > self:GetWide() || OwnLine ) ) then
x = self.Padding
y = y + h + self.Spacing
end
if ( self.m_fAnimTime > 0 && self.m_iBuilds > 1 ) then
panel:MoveTo( x, y, self.m_fAnimTime, 0, self.m_fAnimEase )
else
panel:SetPos( x, y )
end
x = x + w + self.Spacing
Offset = y + h + self.Spacing
if ( OwnLine ) then
x = self.Padding
y = y + h + self.Spacing
end
end
end
else
for k, panel in pairs( self.Items ) do
if ( panel:IsVisible() ) then
if ( self.m_bNoSizing ) then
panel:SizeToContents()
if ( self.m_fAnimTime > 0 && self.m_iBuilds > 1 ) then
panel:MoveTo( ( self:GetCanvas():GetWide() - panel:GetWide() ) * 0.5, self.Padding + Offset, self.m_fAnimTime, 0, self.m_fAnimEase )
else
panel:SetPos( ( self:GetCanvas():GetWide() - panel:GetWide() ) * 0.5, self.Padding + Offset )
end
else
panel:SetSize( self:GetCanvas():GetWide() - self.Padding * 2, panel:GetTall() )
if ( self.m_fAnimTime > 0 && self.m_iBuilds > 1 ) then
panel:MoveTo( self.Padding, self.Padding + Offset, self.m_fAnimTime, self.m_fAnimEase )
else
panel:SetPos( self.Padding, self.Padding + Offset )
end
end
-- Changing the width might ultimately change the height
-- So give the panel a chance to change its height now,
-- so when we call GetTall below the height will be correct.
-- True means layout now.
panel:InvalidateLayout( true )
Offset = Offset + panel:GetTall() + self.Spacing
end
end
Offset = Offset + self.Padding
end
self:GetCanvas():SetTall( Offset + self.Padding - self.Spacing )
-- Although this behaviour isn't exactly implied, center vertically too
if ( self.m_bNoSizing && self:GetCanvas():GetTall() < self:GetTall() ) then
self:GetCanvas():SetPos( 0, ( self:GetTall() - self:GetCanvas():GetTall() ) * 0.5 )
end
end
function PANEL:OnMouseWheeled( dlta )
if ( self.VBar ) then
return self.VBar:OnMouseWheeled( dlta )
end
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "PanelList", self, w, h )
return true
end
function PANEL:OnVScroll( iOffset )
self.pnlCanvas:SetPos( 0, iOffset )
end
function PANEL:PerformLayout()
local Wide = self:GetWide()
local Tall = self.pnlCanvas:GetTall()
local YPos = 0
if ( !self.Rebuild ) then
debug.Trace()
end
self:Rebuild()
if ( self.VBar ) then
self.VBar:SetPos( self:GetWide() - 13, 0 )
self.VBar:SetSize( 13, self:GetTall() )
self.VBar:SetUp( self:GetTall(), self.pnlCanvas:GetTall() ) -- Disables scrollbar if nothing to scroll
YPos = self.VBar:GetOffset()
if ( self.VBar.Enabled ) then Wide = Wide - 13 end
end
self.pnlCanvas:SetPos( 0, YPos )
self.pnlCanvas:SetWide( Wide )
self:Rebuild()
if ( self:GetAutoSize() ) then
self:SetTall( self.pnlCanvas:GetTall() )
self.pnlCanvas:SetPos( 0, 0 )
end
if ( self.VBar && !self:GetAutoSize() && Tall != self.pnlCanvas:GetTall() ) then
self.VBar:SetScroll( self.VBar:GetScroll() ) -- Make sure we are not too far down!
end
end
function PANEL:OnChildRemoved()
self:CleanList()
self:InvalidateLayout()
end
function PANEL:ScrollToChild( panel )
local x, y = self.pnlCanvas:GetChildPosition( panel )
local w, h = panel:GetSize()
y = y + h * 0.5
y = y - self:GetTall() * 0.5
self.VBar:AnimateTo( y, 0.5, 0, 0.5 )
end
function PANEL:SortByMember( key, desc )
desc = desc || true
table.sort( self.Items, function( a, b )
if ( desc ) then
local ta = a
local tb = b
a = tb
b = ta
end
if ( a[ key ] == nil ) then return false end
if ( b[ key ] == nil ) then return true end
return a[ key ] > b[ key ]
end )
end
derma.DefineControl( "DPanelList", "A Panel that neatly organises other panels", PANEL, "DPanel" )

View File

@@ -0,0 +1,81 @@
--[[
| 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 InnerCorner8 = surface.GetTextureID( "gui/icorner8" )
local PANEL = {}
AccessorFunc( PANEL, "m_Color", "Color" )
AccessorFunc( PANEL, "m_Type", "Type" )
function PANEL:Init()
self:SetColor( color_white )
self:SetMouseInputEnabled( false )
self:SetKeyboardInputEnabled( false )
self:SetType( 1 )
end
function PANEL:PaintInnerCorners( size )
local w, h = self:GetSize()
surface.SetTexture( InnerCorner8 )
surface.DrawTexturedRectRotated( size * 0.5, size * 0.5, size, size, 0 )
surface.DrawTexturedRectRotated( w - size * 0.5, size * 0.5, size, size, -90 )
surface.DrawTexturedRectRotated( w - size * 0.5, h - size * 0.5, size, size, 180 )
surface.DrawTexturedRectRotated( size * 0.5, h - size * 0.5, size, size, 90 )
end
function PANEL:PaintDifferentColours( cola, colb, colc, cold, size )
local w, h = self:GetSize()
surface.SetTexture( InnerCorner8 )
surface.SetDrawColor( cola )
surface.DrawTexturedRectRotated( size * 0.5, size * 0.5, size, size, 0 )
surface.SetDrawColor( colb )
surface.DrawTexturedRectRotated( w - size * 0.5, size * 0.5, size, size, -90 )
surface.SetDrawColor( colc )
surface.DrawTexturedRectRotated( w - size * 0.5, h - size * 0.5, size, size, 180 )
surface.SetDrawColor( cold )
surface.DrawTexturedRectRotated( size * 0.5, h - size * 0.5, size, size, 90 )
end
function PANEL:Paint()
self:SetPos( 0, 0 )
self:SetSize( self:GetParent():GetSize() )
surface.SetDrawColor( self.m_Color.r, self.m_Color.g, self.m_Color.b, self.m_Color.a )
if ( self.m_Type == 1 ) then
return self:PaintInnerCorners( 8 )
end
if ( self.m_Type == 2 ) then
return self:PaintInnerCorners( 4 )
end
if ( self.m_Type == 3 ) then
local c = Color( 40, 40, 40, 255 )
return self:PaintDifferentColours( c, c, self.m_Color, self.m_Color, 8 )
end
return true
end
derma.DefineControl( "DPanelOverlay", "", PANEL, "DPanel" )

102
lua/vgui/dpanelselect.lua Normal file
View File

@@ -0,0 +1,102 @@
--[[
| 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 = {}
-- This function is used as the paint function for selected buttons.
local function DrawSelected( self )
surface.SetDrawColor( 255, 200, 0, 255 )
for i = 2, 3 do
surface.DrawOutlinedRect( i, i, self:GetWide() - i * 2, self:GetTall() - i * 2 )
end
end
function PANEL:Init()
self:EnableHorizontal( true )
self:EnableVerticalScrollbar()
self:SetSpacing( 2 )
self:SetPadding( 2 )
end
function PANEL:AddPanel( pnl, tblConVars )
pnl.tblConVars = tblConVars
pnl.DoClick = function() self:SelectPanel( pnl ) end
self:AddItem( pnl )
self:FindBestActive()
end
function PANEL:OnActivePanelChanged( pnlOld, pnlNew )
-- For override
end
function PANEL:SelectPanel( pnl )
self:OnActivePanelChanged( self.SelectedPanel, pnl )
if ( self.SelectedPanel ) then
self.SelectedPanel.PaintOver = self.OldSelectedPaintOver
self.SelectedPanel = nil
end
-- Run all the convars, if it has any..
if ( pnl.tblConVars ) then
for k, v in pairs( pnl.tblConVars ) do RunConsoleCommand( k, v ) end
end
self.SelectedPanel = pnl
if ( self.SelectedPanel ) then
self.OldSelectedPaintOver = self.SelectedPanel.PaintOver
self.SelectedPanel.PaintOver = DrawSelected
end
end
function PANEL:FindBestActive()
-- Select the item that resembles the chosen panel the closest
local BestCandidate = nil
local BestNumMatches = 0
for id, panel in pairs( self:GetItems() ) do
local ItemMatches = 0
if ( panel.tblConVars ) then
for key, value in pairs( panel.tblConVars ) do
if ( GetConVarString( key ) == tostring( value ) ) then ItemMatches = ItemMatches + 1 end
end
end
if ( ItemMatches > BestNumMatches ) then
BestCandidate = panel
BestNumMatches = ItemMatches
end
end
if ( BestCandidate ) then
self:SelectPanel( BestCandidate )
end
end
derma.DefineControl( "DPanelSelect", "", PANEL, "DPanelList" )

35
lua/vgui/dprogress.lua Normal file
View File

@@ -0,0 +1,35 @@
--[[
| 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_fFraction", "Fraction" )
Derma_Hook( PANEL, "Paint", "Paint", "Progress" )
function PANEL:Init()
self:SetMouseInputEnabled( false )
self:SetFraction( 0 )
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetFraction( 0.6 )
ctrl:SetSize( 300, 20 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DProgress", "", PANEL, "Panel" )

272
lua/vgui/dproperties.lua Normal file
View File

@@ -0,0 +1,272 @@
--[[
| 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/
--]]
--
-- The row - contained in a category.
--
local tblRow = vgui.RegisterTable( {
Init = function( self )
self:Dock( TOP )
self.Label = self:Add( "DLabel" )
self.Label:Dock( LEFT )
self.Label:DockMargin( 4, 2, 2, 2 )
self.Container = self:Add( "Panel" )
self.Container:Dock( FILL )
end,
PerformLayout = function( self )
self:SetTall( 20 )
self.Label:SetWide( self:GetWide() * 0.45 )
end,
Setup = function( self, rowType, vars )
self.Container:Clear()
local Name = "DProperty_" .. rowType
-- Nice shortcuts for Entity:NetworkVar()
if ( !vgui.GetControlTable( Name ) ) then
if ( rowType == "Bool" ) then rowType = "Boolean" end
if ( rowType == "Vector" ) then rowType = "Generic" end
if ( rowType == "Angle" ) then rowType = "Generic" end
if ( rowType == "String" ) then rowType = "Generic" end
Name = "DProperty_" .. rowType
end
if ( vgui.GetControlTable( Name ) ) then
self.Inner = self.Container:Add( Name )
else
print( "DProperties: Failed to create panel (" .. Name .. ")" )
end
if ( !IsValid( self.Inner ) ) then self.Inner = self.Container:Add( "DProperty_Generic" ) end
self.Inner:SetRow( self )
self.Inner:Dock( FILL )
self.Inner:Setup( vars )
-- First copy the value if it was somehow set before Setup() was
self.Inner:SetEnabled( self:IsEnabled() )
-- Then override our methods so they affect Inner element instead
self.IsEnabled = function( slf )
return slf.Inner:IsEnabled()
end
self.SetEnabled = function( slf, b )
slf.Inner:SetEnabled( b )
end
-- If the field is read only, disable it
if ( vars && vars.readonly ) then
self:SetEnabled( false )
end
end,
SetValue = function( self, val )
--
-- Don't update the value if our cache'd value is the same.
--
if ( self.CacheValue && self.CacheValue == val ) then return end
self.CacheValue = val
if ( IsValid( self.Inner ) ) then
self.Inner:SetValue( val )
end
end,
Paint = function( self, w, h )
if ( !IsValid( self.Inner ) ) then return end
local Skin = self:GetSkin()
local editing = self.Inner:IsEditing()
local disabled = !self.Inner:IsEnabled() || !self:IsEnabled()
if ( disabled ) then
surface.SetDrawColor( Skin.Colours.Properties.Column_Disabled )
surface.DrawRect( w * 0.45, 0, w, h )
elseif ( editing ) then
surface.SetDrawColor( Skin.Colours.Properties.Column_Selected )
surface.DrawRect( 0, 0, w * 0.45, h )
end
surface.SetDrawColor( Skin.Colours.Properties.Border )
surface.DrawRect( w - 1, 0, 1, h )
surface.DrawRect( w * 0.45, 0, 1, h )
surface.DrawRect( 0, h - 1, w, 1 )
if ( disabled ) then
self.Label:SetTextColor( Skin.Colours.Properties.Label_Disabled )
elseif ( editing ) then
self.Label:SetTextColor( Skin.Colours.Properties.Label_Selected )
else
self.Label:SetTextColor( Skin.Colours.Properties.Label_Normal )
end
end
}, "Panel" )
--
-- The category - contained in a dproperties
--
local tblCategory = vgui.RegisterTable( {
Init = function( self )
self:Dock( TOP )
self.Rows = {}
self.Header = self:Add( "Panel" )
self.Label = self.Header:Add( "DLabel" )
self.Label:Dock( FILL )
self.Label:SetContentAlignment( 4 )
self.Expand = self.Header:Add( "DExpandButton" )
self.Expand:Dock( LEFT )
self.Expand:SetSize( 16, 16 )
self.Expand:DockMargin( 0, 4, 0, 4 )
self.Expand:SetExpanded( true )
self.Expand.DoClick = function()
self.Container:SetVisible( !self.Container:IsVisible() )
self.Expand:SetExpanded( self.Container:IsVisible() )
self:InvalidateLayout()
end
self.Header:Dock( TOP )
self.Container = self:Add( "Panel" )
self.Container:Dock( TOP )
self.Container:DockMargin( 16, 0, 0, 0 )
self.Container.Paint = function( pnl, w, h )
surface.SetDrawColor( color_white )
surface.DrawRect( 0, 0, w, h )
end
end,
PerformLayout = function( self )
self.Container:SizeToChildren( false, true )
self:SizeToChildren( false, true )
local Skin = self:GetSkin()
self.Label:SetTextColor( Skin.Colours.Properties.Title )
self.Label:DockMargin( 4, 0, 0, 0 )
end,
GetRow = function( self, name, bCreate )
if ( IsValid( self.Rows[ name ] ) ) then return self.Rows[ name ] end
if ( !bCreate ) then return end
local row = self.Container:Add( tblRow )
row.Label:SetText( name )
self.Rows[ name ] = row
return row
end,
Paint = function( self, w, h )
local Skin = self:GetSkin()
surface.SetDrawColor( Skin.Colours.Properties.Border )
surface.DrawRect( 0, 0, w, h )
end
}, "Panel" )
--[[---------------------------------------------------------
DProperties
-----------------------------------------------------------]]
local PANEL = {}
function PANEL:Init()
self.Categories = {}
end
--
-- Size to children vertically
--
function PANEL:PerformLayout()
self:SizeToChildren( false, true )
end
function PANEL:Clear()
self:GetCanvas():Clear()
end
function PANEL:GetCanvas()
if ( !IsValid( self.Canvas ) ) then
self.Canvas = self:Add( "DScrollPanel" )
self.Canvas:Dock( FILL )
end
return self.Canvas
end
--
-- Get or create a category
--
function PANEL:GetCategory( name, bCreate )
local cat = self.Categories[ name ]
if ( IsValid( cat ) ) then return cat end
if ( !bCreate ) then return end
cat = self:GetCanvas():Add( tblCategory )
cat.Label:SetText( name )
self.Categories[ name ] = cat
return cat
end
--
-- Creates a row under the specified category.
-- You should then call :Setup on the row.
--
function PANEL:CreateRow( category, name )
local cat = self:GetCategory( category, true )
return cat:GetRow( name, true )
end
derma.DefineControl( "DProperties", "", PANEL, "Panel" )

453
lua/vgui/dpropertysheet.lua Normal file
View File

@@ -0,0 +1,453 @@
--[[
| 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_pPropertySheet", "PropertySheet" )
AccessorFunc( PANEL, "m_pPanel", "Panel" )
Derma_Hook( PANEL, "Paint", "Paint", "Tab" )
function PANEL:Init()
self:SetMouseInputEnabled( true )
self:SetContentAlignment( 7 )
self:SetTextInset( 0, 4 )
end
function PANEL:Setup( label, pPropertySheet, pPanel, strMaterial )
self:SetText( label )
self:SetPropertySheet( pPropertySheet )
self:SetPanel( pPanel )
if ( strMaterial ) then
self.Image = vgui.Create( "DImage", self )
self.Image:SetImage( strMaterial )
self.Image:SizeToContents()
self:InvalidateLayout()
end
end
function PANEL:IsActive()
return self:GetPropertySheet():GetActiveTab() == self
end
function PANEL:DoClick()
self:GetPropertySheet():SetActiveTab( self )
end
function PANEL:PerformLayout()
self:ApplySchemeSettings()
if ( !self.Image ) then return end
self.Image:SetPos( 7, 3 )
if ( !self:IsActive() ) then
self.Image:SetImageColor( Color( 255, 255, 255, 155 ) )
else
self.Image:SetImageColor( color_white )
end
end
function PANEL:UpdateColours( skin )
if ( self:IsActive() ) then
if ( self:GetDisabled() ) then return self:SetTextStyleColor( skin.Colours.Tab.Active.Disabled ) end
if ( self:IsDown() ) then return self:SetTextStyleColor( skin.Colours.Tab.Active.Down ) end
if ( self.Hovered ) then return self:SetTextStyleColor( skin.Colours.Tab.Active.Hover ) end
return self:SetTextStyleColor( skin.Colours.Tab.Active.Normal )
end
if ( self:GetDisabled() ) then return self:SetTextStyleColor( skin.Colours.Tab.Inactive.Disabled ) end
if ( self:IsDown() ) then return self:SetTextStyleColor( skin.Colours.Tab.Inactive.Down ) end
if ( self.Hovered ) then return self:SetTextStyleColor( skin.Colours.Tab.Inactive.Hover ) end
return self:SetTextStyleColor( skin.Colours.Tab.Inactive.Normal )
end
function PANEL:GetTabHeight()
if ( self:IsActive() ) then
return 28
else
return 20
end
end
function PANEL:ApplySchemeSettings()
local ExtraInset = 10
if ( self.Image ) then
ExtraInset = ExtraInset + self.Image:GetWide()
end
self:SetTextInset( ExtraInset, 4 )
local w, h = self:GetContentSize()
h = self:GetTabHeight()
self:SetSize( w + 10, h )
DLabel.ApplySchemeSettings( self )
end
--
-- DragHoverClick
--
function PANEL:DragHoverClick( HoverTime )
self:DoClick()
end
function PANEL:GenerateExample()
-- Do nothing!
end
function PANEL:DoRightClick()
if ( !IsValid( self:GetPropertySheet() ) ) then return end
local tabs = DermaMenu()
for k, v in pairs( self:GetPropertySheet().Items ) do
if ( !v || !IsValid( v.Tab ) || !v.Tab:IsVisible() ) then continue end
local option = tabs:AddOption( v.Tab:GetText(), function()
if ( !v || !IsValid( v.Tab ) || !IsValid( self:GetPropertySheet() ) || !IsValid( self:GetPropertySheet().tabScroller ) ) then return end
v.Tab:DoClick()
self:GetPropertySheet().tabScroller:ScrollToChild( v.Tab )
end )
if ( IsValid( v.Tab.Image ) ) then option:SetIcon( v.Tab.Image:GetImage() ) end
end
tabs:Open()
end
derma.DefineControl( "DTab", "A Tab for use on the PropertySheet", PANEL, "DButton" )
--[[---------------------------------------------------------
DPropertySheet
-----------------------------------------------------------]]
local PANEL = {}
Derma_Hook( PANEL, "Paint", "Paint", "PropertySheet" )
AccessorFunc( PANEL, "m_pActiveTab", "ActiveTab" )
AccessorFunc( PANEL, "m_iPadding", "Padding" )
AccessorFunc( PANEL, "m_fFadeTime", "FadeTime" )
AccessorFunc( PANEL, "m_bShowIcons", "ShowIcons" )
function PANEL:Init()
self:SetShowIcons( true )
self.tabScroller = vgui.Create( "DHorizontalScroller", self )
self.tabScroller:SetOverlap( 5 )
self.tabScroller:Dock( TOP )
self.tabScroller:DockMargin( 3, 0, 3, 0 )
self:SetFadeTime( 0.1 )
self:SetPadding( 8 )
self.animFade = Derma_Anim( "Fade", self, self.CrossFade )
self.Items = {}
end
function PANEL:AddSheet( label, panel, material, NoStretchX, NoStretchY, Tooltip )
if ( !IsValid( panel ) ) then
ErrorNoHalt( "DPropertySheet:AddSheet tried to add invalid panel!" )
debug.Trace()
return
end
local Sheet = {}
Sheet.Name = label
Sheet.Tab = vgui.Create( "DTab", self )
Sheet.Tab:SetTooltip( Tooltip )
Sheet.Tab:Setup( label, self, panel, material )
Sheet.Panel = panel
Sheet.Panel.NoStretchX = NoStretchX
Sheet.Panel.NoStretchY = NoStretchY
Sheet.Panel:SetPos( self:GetPadding(), 20 + self:GetPadding() )
Sheet.Panel:SetVisible( false )
panel:SetParent( self )
table.insert( self.Items, Sheet )
if ( !self:GetActiveTab() ) then
self:SetActiveTab( Sheet.Tab )
Sheet.Panel:SetVisible( true )
end
self.tabScroller:AddPanel( Sheet.Tab )
return Sheet
end
function PANEL:SetActiveTab( active )
if ( !IsValid( active ) || self.m_pActiveTab == active ) then return end
if ( IsValid( self.m_pActiveTab ) ) then
-- Only run this callback when we actually switch a tab, not when a tab is initially set active
self:OnActiveTabChanged( self.m_pActiveTab, active )
if ( self:GetFadeTime() > 0 ) then
self.animFade:Start( self:GetFadeTime(), { OldTab = self.m_pActiveTab, NewTab = active } )
else
self.m_pActiveTab:GetPanel():SetVisible( false )
end
end
self.m_pActiveTab = active
self:InvalidateLayout()
end
function PANEL:OnActiveTabChanged( old, new )
-- For override
end
function PANEL:Think()
self.animFade:Run()
end
function PANEL:GetItems()
return self.Items
end
function PANEL:CrossFade( anim, delta, data )
if ( !data || !IsValid( data.OldTab ) || !IsValid( data.NewTab ) ) then return end
local old = data.OldTab:GetPanel()
local new = data.NewTab:GetPanel()
if ( !IsValid( old ) && !IsValid( new ) ) then return end
if ( anim.Finished ) then
if ( IsValid( old ) ) then
old:SetAlpha( 255 )
old:SetZPos( 0 )
old:SetVisible( false )
end
if ( IsValid( new ) ) then
new:SetAlpha( 255 )
new:SetZPos( 0 )
new:SetVisible( true ) -- In case new == old
end
return
end
if ( anim.Started ) then
if ( IsValid( old ) ) then
old:SetAlpha( 255 )
old:SetZPos( 0 )
end
if ( IsValid( new ) ) then
new:SetAlpha( 0 )
new:SetZPos( 1 )
end
end
if ( IsValid( old ) ) then
old:SetVisible( true )
if ( !IsValid( new ) ) then old:SetAlpha( 255 * ( 1 - delta ) ) end
end
if ( IsValid( new ) ) then
new:SetVisible( true )
new:SetAlpha( 255 * delta )
end
end
function PANEL:PerformLayout()
local ActiveTab = self:GetActiveTab()
local Padding = self:GetPadding()
if ( !IsValid( ActiveTab ) ) then return end
-- Update size now, so the height is definitiely right.
ActiveTab:InvalidateLayout( true )
--self.tabScroller:StretchToParent( Padding, 0, Padding, nil )
self.tabScroller:SetTall( ActiveTab:GetTall() )
local ActivePanel = ActiveTab:GetPanel()
for k, v in pairs( self.Items ) do
if ( v.Tab:GetPanel() == ActivePanel ) then
if ( IsValid( v.Tab:GetPanel() ) ) then v.Tab:GetPanel():SetVisible( true ) end
v.Tab:SetZPos( 100 )
else
if ( IsValid( v.Tab:GetPanel() ) ) then v.Tab:GetPanel():SetVisible( false ) end
v.Tab:SetZPos( 1 )
end
v.Tab:ApplySchemeSettings()
end
if ( IsValid( ActivePanel ) ) then
if ( !ActivePanel.NoStretchX ) then
ActivePanel:SetWide( self:GetWide() - Padding * 2 )
else
ActivePanel:CenterHorizontal()
end
if ( !ActivePanel.NoStretchY ) then
local _, y = ActivePanel:GetPos()
ActivePanel:SetTall( self:GetTall() - y - Padding )
else
ActivePanel:CenterVertical()
end
ActivePanel:InvalidateLayout()
end
-- Give the animation a chance
self.animFade:Run()
end
function PANEL:SizeToContentWidth()
local wide = 0
for k, v in pairs( self.Items ) do
if ( IsValid( v.Panel ) ) then
v.Panel:InvalidateLayout( true )
wide = math.max( wide, v.Panel:GetWide() + self:GetPadding() * 2 )
end
end
self:SetWide( wide )
end
function PANEL:SwitchToName( name )
for k, v in pairs( self.Items ) do
if ( v.Name == name ) then
v.Tab:DoClick()
return true
end
end
return false
end
function PANEL:SetupCloseButton( func )
self.CloseButton = self.tabScroller:Add( "DImageButton" )
self.CloseButton:SetImage( "icon16/circlecross.png" )
self.CloseButton:SetColor( Color( 10, 10, 10, 200 ) )
self.CloseButton:DockMargin( 1, 1, 1, 9 )
self.CloseButton:SetWide( 18 )
self.CloseButton:Dock( RIGHT )
self.CloseButton.DoClick = function()
if ( func ) then func() end
end
end
function PANEL:CloseTab( tab, bRemovePanelToo )
for k, v in pairs( self.Items ) do
if ( v.Tab != tab ) then continue end
table.remove( self.Items, k )
end
for k, v in pairs( self.tabScroller.Panels ) do
if ( v != tab ) then continue end
table.remove( self.tabScroller.Panels, k )
end
self.tabScroller:InvalidateLayout( true )
if ( tab == self:GetActiveTab() ) then
self.m_pActiveTab = self.Items[ #self.Items ].Tab
end
local pnl = tab:GetPanel()
if ( bRemovePanelToo ) then
pnl:Remove()
end
tab:Remove()
self:InvalidateLayout( true )
return pnl
end
derma.DefineControl( "DPropertySheet", "", PANEL, "Panel" )

94
lua/vgui/drgbpicker.lua Normal file
View File

@@ -0,0 +1,94 @@
--[[
| 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_RGB", "RGB" )
function PANEL:Init()
self:SetRGB( color_white )
self.Material = Material( "gui/colors.png" ) -- TODO: Light/Dark
self.LastX = -100
self.LastY = -100
end
function PANEL:GetPosColor( x, y )
local con_x = ( x / self:GetWide() ) * self.Material:Width()
local con_y = ( y / self:GetTall() ) * self.Material:Height()
con_x = math.Clamp( con_x, 0, self.Material:Width() - 1 )
con_y = math.Clamp( con_y, 0, self.Material:Height() - 1 )
local col = self.Material:GetColor( con_x, con_y )
return col, con_x, con_y
end
function PANEL:OnCursorMoved( x, y )
if ( !input.IsMouseDown( MOUSE_LEFT ) ) then return end
local col = self:GetPosColor( x, y )
if ( col ) then
self.m_RGB = col
self.m_RGB.a = 255
self:OnChange( self.m_RGB )
end
self.LastX = x
self.LastY = y
end
function PANEL:OnChange( col )
-- Override me
end
function PANEL:OnMousePressed( mcode )
self:MouseCapture( true )
self:OnCursorMoved( self:CursorPos() )
end
function PANEL:OnMouseReleased( mcode )
self:MouseCapture( false )
self:OnCursorMoved( self:CursorPos() )
end
function PANEL:Paint( w, h )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( self.Material )
surface.DrawTexturedRect( 0, 0, w, h )
surface.SetDrawColor( 0, 0, 0, 250 )
self:DrawOutlinedRect()
surface.DrawRect( 0, self.LastY - 2, w, 3 )
surface.SetDrawColor( 255, 255, 255, 250 )
surface.DrawRect( 0, self.LastY - 1, w, 1 )
end
derma.DefineControl( "DRGBPicker", "", PANEL, "DPanel" )

View File

@@ -0,0 +1,30 @@
--[[
| 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 = {}
function PANEL:Init()
end
function PANEL:OnMousePressed()
self:GetParent():Grip( 1 )
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "ScrollBarGrip", self, w, h )
return true
end
derma.DefineControl( "DScrollBarGrip", "A Scrollbar Grip", PANEL, "DPanel" )

155
lua/vgui/dscrollpanel.lua Normal file
View File

@@ -0,0 +1,155 @@
--[[
| 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, "Padding", "Padding" )
AccessorFunc( PANEL, "pnlCanvas", "Canvas" )
function PANEL:Init()
self.pnlCanvas = vgui.Create( "Panel", self )
self.pnlCanvas.OnMousePressed = function( slf, code ) slf:GetParent():OnMousePressed( code ) end
self.pnlCanvas:SetMouseInputEnabled( true )
self.pnlCanvas.PerformLayout = function( pnl )
self:PerformLayoutInternal()
self:InvalidateParent()
end
-- Create the scroll bar
self.VBar = vgui.Create( "DVScrollBar", self )
self.VBar:Dock( RIGHT )
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():GetWide()
end
function PANEL:Rebuild()
self:GetCanvas():SizeToChildren( false, true )
-- Although this behaviour isn't exactly implied, center vertically too
if ( self.m_bNoSizing && self:GetCanvas():GetTall() < self:GetTall() ) then
self:GetCanvas():SetPos( 0, ( self:GetTall() - self:GetCanvas():GetTall() ) * 0.5 )
end
end
function PANEL:OnMouseWheeled( dlta )
return self.VBar:OnMouseWheeled( dlta )
end
function PANEL:OnVScroll( iOffset )
self.pnlCanvas:SetPos( 0, iOffset )
end
function PANEL:ScrollToChild( panel )
self:InvalidateLayout( true )
local x, y = self.pnlCanvas:GetChildPosition( panel )
local w, h = panel:GetSize()
y = y + h * 0.5
y = y - self:GetTall() * 0.5
self.VBar:AnimateTo( y, 0.5, 0, 0.5 )
end
-- Avoid an infinite loop
function PANEL:PerformLayoutInternal()
local Tall = self.pnlCanvas:GetTall()
local Wide = self:GetWide()
local YPos = 0
self:Rebuild()
self.VBar:SetUp( self:GetTall(), self.pnlCanvas:GetTall() )
YPos = self.VBar:GetOffset()
if ( self.VBar.Enabled ) then Wide = Wide - self.VBar:GetWide() end
self.pnlCanvas:SetPos( 0, YPos )
self.pnlCanvas:SetWide( Wide )
self:Rebuild()
if ( Tall != self.pnlCanvas:GetTall() ) then
self.VBar:SetScroll( self.VBar:GetScroll() ) -- Make sure we are not too far down!
end
end
function PANEL:PerformLayout()
self:PerformLayoutInternal()
end
function PANEL:Clear()
return self.pnlCanvas:Clear()
end
derma.DefineControl( "DScrollPanel", "", PANEL, "DPanel" )

49
lua/vgui/dshape.lua Normal file
View File

@@ -0,0 +1,49 @@
--[[
| 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_Color", "Color" )
AccessorFunc( PANEL, "m_BorderColor", "BorderColor" )
AccessorFunc( PANEL, "m_Type", "Type" )
local RenderTypes = {}
function RenderTypes.Rect( pnl )
surface.SetDrawColor( pnl:GetColor() )
surface.DrawRect( 0, 0, pnl:GetSize() )
end
function PANEL:Init()
self:SetColor( color_white )
self:SetMouseInputEnabled( false )
self:SetKeyboardInputEnabled( false )
end
function PANEL:Paint()
RenderTypes[ self.m_Type ]( self )
end
derma.DefineControl( "DShape", "A shape", PANEL, "DPanel" )
-- Convenience function
function VGUIRect( x, y, w, h )
local shape = vgui.Create( "DShape" )
shape:SetType( "Rect" )
shape:SetPos( x, y )
shape:SetSize( w, h )
return shape
end

View File

@@ -0,0 +1,31 @@
--[[
| 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_bSizeX", "SizeX", FORCE_BOOL )
AccessorFunc( PANEL, "m_bSizeY", "SizeY", FORCE_BOOL )
function PANEL:Init()
self:SetMouseInputEnabled( true )
self:SetSizeX( true )
self:SetSizeY( true )
end
function PANEL:PerformLayout()
self:SizeToChildren( self.m_bSizeX, self.m_bSizeY )
end
derma.DefineControl( "DSizeToContents", "", PANEL, "Panel" )

288
lua/vgui/dslider.lua Normal file
View File

@@ -0,0 +1,288 @@
--[[
| 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_fSlideX", "SlideX" )
AccessorFunc( PANEL, "m_fSlideY", "SlideY" )
AccessorFunc( PANEL, "m_iLockX", "LockX" )
AccessorFunc( PANEL, "m_iLockY", "LockY" )
AccessorFunc( PANEL, "Dragging", "Dragging" )
AccessorFunc( PANEL, "m_bTrappedInside", "TrapInside" )
Derma_Hook( PANEL, "Paint", "Paint", "Slider" )
function PANEL:Init()
self:SetMouseInputEnabled( true )
self:SetSlideX( 0.5 )
self:SetSlideY( 0.5 )
self.Knob = vgui.Create( "DButton", self )
self.Knob:SetText( "" )
self.Knob:SetSize( 15, 15 )
self.Knob:NoClipping( true )
self.Knob.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "SliderKnob", panel, w, h ) end
self.Knob.OnCursorMoved = function( panel, x, y )
x, y = panel:LocalToScreen( x, y )
x, y = self:ScreenToLocal( x, y )
self:OnCursorMoved( x, y )
end
self.Knob.OnMousePressed = function( panel, mcode )
if ( mcode == MOUSE_MIDDLE ) then
self:ResetToDefaultValue()
return
end
DButton.OnMousePressed( panel, mcode )
end
-- Why is this set by default?
self:SetLockY( 0.5 )
end
--
-- We we currently editing?
--
function PANEL:IsEditing()
return self.Dragging || self.Knob.Depressed
end
function PANEL:ResetToDefaultValue()
-- Override me
local x, y = self:TranslateValues( 0.5, 0.5 )
self:SetSlideX( x )
self:SetSlideY( y )
end
function PANEL:SetBackground( img )
if ( !self.BGImage ) then
self.BGImage = vgui.Create( "DImage", self )
end
self.BGImage:SetImage( img )
self:InvalidateLayout()
end
function PANEL:SetEnabled( b )
self.Knob:SetEnabled( b )
FindMetaTable( "Panel" ).SetEnabled( self, b ) -- There has to be a better way!
end
function PANEL:OnCursorMoved( x, y )
if ( !self.Dragging && !self.Knob.Depressed ) then return end
local w, h = self:GetSize()
local iw, ih = self.Knob:GetSize()
if ( self.m_bTrappedInside ) then
w = w - iw
h = h - ih
x = x - iw * 0.5
y = y - ih * 0.5
end
x = math.Clamp( x, 0, w ) / w
y = math.Clamp( y, 0, h ) / h
if ( self.m_iLockX ) then x = self.m_iLockX end
if ( self.m_iLockY ) then y = self.m_iLockY end
x, y = self:TranslateValues( x, y )
self:SetSlideX( x )
self:SetSlideY( y )
self:InvalidateLayout()
end
function PANEL:OnMousePressed( mcode )
if ( !self:IsEnabled() ) then return true end
-- When starting dragging with not pressing on the knob.
self.Knob.Hovered = true
self:SetDragging( true )
self:MouseCapture( true )
local x, y = self:CursorPos()
self:OnCursorMoved( x, y )
end
function PANEL:OnMouseReleased( mcode )
-- This is a hack. Panel.Hovered is not updated when dragging a panel (Source's dragging, not Lua Drag'n'drop)
self.Knob.Hovered = vgui.GetHoveredPanel() == self.Knob
self:SetDragging( false )
self:MouseCapture( false )
end
function PANEL:PerformLayout()
local w, h = self:GetSize()
local iw, ih = self.Knob:GetSize()
if ( self.m_bTrappedInside ) then
w = w - iw
h = h - ih
self.Knob:SetPos( ( self.m_fSlideX || 0 ) * w, ( self.m_fSlideY || 0 ) * h )
else
self.Knob:SetPos( ( self.m_fSlideX || 0 ) * w - iw * 0.5, ( self.m_fSlideY || 0 ) * h - ih * 0.5 )
end
if ( self.BGImage ) then
self.BGImage:StretchToParent( 0, 0, 0, 0 )
self.BGImage:SetZPos( -10 )
end
-- In case m_fSlideX/m_fSlideY changed multiple times a frame, we do this here
self:ConVarChanged( self.m_fSlideX, self.m_strConVarX )
self:ConVarChanged( self.m_fSlideY, self.m_strConVarY )
end
function PANEL:Think()
self:ConVarXNumberThink()
self:ConVarYNumberThink()
end
function PANEL:SetSlideX( i )
self.m_fSlideX = i
self:OnValuesChangedInternal()
end
function PANEL:SetSlideY( i )
self.m_fSlideY = i
self:OnValuesChangedInternal()
end
function PANEL:GetDragging()
return self.Dragging || self.Knob.Depressed
end
function PANEL:OnValueChanged( x, y )
-- For override
end
function PANEL:OnValuesChangedInternal()
self:OnValueChanged( self.m_fSlideX, self.m_fSlideY )
self:InvalidateLayout()
end
function PANEL:TranslateValues( x, y )
-- Give children the chance to manipulate the values..
return x, y
end
-- ConVars
function PANEL:SetConVarX( strConVar )
self.m_strConVarX = strConVar
end
function PANEL:SetConVarY( strConVar )
self.m_strConVarY = strConVar
end
function PANEL:ConVarChanged( newValue, cvar )
if ( !cvar || cvar:len() < 2 ) then return end
GetConVar( cvar ):SetFloat( newValue )
-- Prevent extra convar loops
if ( cvar == self.m_strConVarX ) then self.m_strConVarXValue = GetConVarNumber( self.m_strConVarX ) end
if ( cvar == self.m_strConVarY ) then self.m_strConVarYValue = GetConVarNumber( self.m_strConVarY ) end
end
function PANEL:ConVarXNumberThink()
if ( !self.m_strConVarX || #self.m_strConVarX < 2 ) then return end
local numValue = GetConVarNumber( self.m_strConVarX )
-- In case the convar is a "nan"
if ( numValue != numValue ) then return end
if ( self.m_strConVarXValue == numValue ) then return end
self.m_strConVarXValue = numValue
self:SetSlideX( self.m_strConVarXValue )
end
function PANEL:ConVarYNumberThink()
if ( !self.m_strConVarY || #self.m_strConVarY < 2 ) then return end
local numValue = GetConVarNumber( self.m_strConVarY )
-- In case the convar is a "nan"
if ( numValue != numValue ) then return end
if ( self.m_strConVarYValue == numValue ) then return end
self.m_strConVarYValue = numValue
self:SetSlideY( self.m_strConVarYValue )
end
-- Deprecated
AccessorFunc( PANEL, "NumSlider", "NumSlider" )
AccessorFunc( PANEL, "m_iNotches", "Notches" )
function PANEL:SetImage( strImage )
-- RETIRED
end
function PANEL:SetImageColor( color )
-- RETIRED
end
function PANEL:SetNotchColor( color )
self.m_cNotchClr = color
end
function PANEL:GetNotchColor()
return self.m_cNotchClr || self:GetSkin().colNumSliderNotch
end
derma.DefineControl( "DSlider", "", PANEL, "Panel" )

65
lua/vgui/dsprite.lua Normal file
View File

@@ -0,0 +1,65 @@
--[[
| 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_Material", "Material" )
AccessorFunc( PANEL, "m_Color", "Color" )
AccessorFunc( PANEL, "m_Rotation", "Rotation" )
AccessorFunc( PANEL, "m_Handle", "Handle" )
function PANEL:Init()
self:SetColor( color_white )
self:SetRotation( 0 )
self:SetHandle( Vector( 0.5, 0.5, 0 ) )
self:SetMouseInputEnabled( false )
self:SetKeyboardInputEnabled( false )
self:NoClipping( true )
end
function PANEL:Paint()
local Mat = self.m_Material
if ( !Mat ) then return true end
surface.SetMaterial( Mat )
surface.SetDrawColor( self.m_Color.r, self.m_Color.g, self.m_Color.b, self.m_Color.a )
local w, h = self:GetSize()
local x, y = 0, 0
surface.DrawTexturedRectRotated( x, y, w, h, self.m_Rotation )
return true
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetMaterial( Material( "brick/brick_model" ) )
ctrl:SetSize( 200, 200 )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DSprite", "A sprite", PANEL, "DPanel" )
-- Convenience function
function CreateSprite( mat )
local sprite = vgui.Create( "DSprite" )
sprite:SetMaterial( mat )
return sprite
end

439
lua/vgui/dtextentry.lua Normal file
View File

@@ -0,0 +1,439 @@
--[[
| 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 = {}
local strAllowedNumericCharacters = "1234567890.-"
AccessorFunc( PANEL, "m_bAllowEnter", "EnterAllowed", FORCE_BOOL )
AccessorFunc( PANEL, "m_bUpdateOnType", "UpdateOnType", FORCE_BOOL ) -- Update the convar as we type
AccessorFunc( PANEL, "m_bNumeric", "Numeric", FORCE_BOOL )
AccessorFunc( PANEL, "m_bHistory", "HistoryEnabled", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDisableTabbing", "TabbingDisabled", FORCE_BOOL )
AccessorFunc( PANEL, "m_FontName", "Font" )
AccessorFunc( PANEL, "m_bBorder", "DrawBorder" )
AccessorFunc( PANEL, "m_bBackground", "PaintBackground" )
AccessorFunc( PANEL, "m_bBackground", "DrawBackground" ) -- Deprecated
AccessorFunc( PANEL, "m_colText", "TextColor" )
AccessorFunc( PANEL, "m_colHighlight", "HighlightColor" )
AccessorFunc( PANEL, "m_colCursor", "CursorColor" )
AccessorFunc( PANEL, "m_colPlaceholder", "PlaceholderColor" )
AccessorFunc( PANEL, "m_txtPlaceholder", "PlaceholderText" )
Derma_Install_Convar_Functions( PANEL )
function PANEL:Init()
self:SetHistoryEnabled( false )
self.History = {}
self.HistoryPos = 0
--
-- We're going to draw these ourselves in
-- the skin system - so disable them here.
-- This will leave it only drawing text.
--
self:SetPaintBorderEnabled( false )
self:SetPaintBackgroundEnabled( false )
--
-- These are Lua side commands
-- Defined above using AccessorFunc
--
self:SetDrawBorder( true )
self:SetPaintBackground( true )
self:SetEnterAllowed( true )
self:SetUpdateOnType( false )
self:SetNumeric( false )
self:SetAllowNonAsciiCharacters( true )
-- Nicer default height
self:SetTall( 20 )
-- Clear keyboard focus when we click away
self.m_bLoseFocusOnClickAway = true
-- Beam Me Up Scotty
self:SetCursor( "beam" )
self:SetFont( "DermaDefault" )
end
function PANEL:IsEditing()
return self == vgui.GetKeyboardFocus()
end
function PANEL:OnKeyCodeTyped( code )
self:OnKeyCode( code )
if ( code == KEY_ENTER && !self:IsMultiline() && self:GetEnterAllowed() ) then
if ( IsValid( self.Menu ) ) then
self.Menu:Remove()
end
self:FocusNext()
self:OnEnter( self:GetText() )
self.HistoryPos = 0
end
if ( self.m_bHistory || IsValid( self.Menu ) ) then
if ( code == KEY_UP ) then
self.HistoryPos = self.HistoryPos - 1
self:UpdateFromHistory()
end
if ( code == KEY_DOWN || code == KEY_TAB ) then
self.HistoryPos = self.HistoryPos + 1
self:UpdateFromHistory()
end
end
end
function PANEL:OnKeyCode( code )
end
function PANEL:ApplySchemeSettings()
self:SetFontInternal( self.m_FontName )
derma.SkinHook( "Scheme", "TextEntry", self )
end
function PANEL:GetTextColor()
return self.m_colText || self:GetSkin().colTextEntryText
end
function PANEL:GetPlaceholderColor()
return self.m_colPlaceholder || self:GetSkin().colTextEntryTextPlaceholder
end
function PANEL:GetHighlightColor()
return self.m_colHighlight || self:GetSkin().colTextEntryTextHighlight
end
function PANEL:GetCursorColor()
return self.m_colCursor || self:GetSkin().colTextEntryTextCursor
end
function PANEL:UpdateFromHistory()
if ( IsValid( self.Menu ) ) then
return self:UpdateFromMenu()
end
local pos = self.HistoryPos
-- Is the Pos within bounds?
if ( pos < 0 ) then pos = #self.History end
if ( pos > #self.History ) then pos = 0 end
local text = self.History[ pos ]
if ( !text ) then text = "" end
self:SetText( text )
self:SetCaretPos( utf8.len( text ) )
self:OnTextChanged()
self.HistoryPos = pos
end
function PANEL:UpdateFromMenu()
local pos = self.HistoryPos
local num = self.Menu:ChildCount()
self.Menu:ClearHighlights()
if ( pos < 0 ) then pos = num end
if ( pos > num ) then pos = 0 end
local item = self.Menu:GetChild( pos )
if ( !item ) then
self:SetText( "" )
self.HistoryPos = pos
return
end
self.Menu:HighlightItem( item )
local txt = item:GetText()
self:SetText( txt )
self:SetCaretPos( utf8.len( txt ) )
self:OnTextChanged( true )
self.HistoryPos = pos
end
function PANEL:OnTextChanged( noMenuRemoval )
self.HistoryPos = 0
if ( self:GetUpdateOnType() ) then
self:UpdateConvarValue()
self:OnValueChange( self:GetText() )
end
if ( IsValid( self.Menu ) && !noMenuRemoval ) then
self.Menu:Remove()
end
local tab = self:GetAutoComplete( self:GetText() )
if ( tab ) then
self:OpenAutoComplete( tab )
end
self:OnChange()
end
function PANEL:OnChange()
end
function PANEL:OpenAutoComplete( tab )
if ( !tab ) then return end
if ( #tab == 0 ) then return end
self.Menu = DermaMenu()
for k, v in pairs( tab ) do
self.Menu:AddOption( v, function() self:SetText( v ) self:SetCaretPos( utf8.len( v ) ) self:RequestFocus() end )
end
local x, y = self:LocalToScreen( 0, self:GetTall() )
self.Menu:SetMinimumWidth( self:GetWide() )
self.Menu:Open( x, y, true, self )
self.Menu:SetPos( x, y )
self.Menu:SetMaxHeight( ( ScrH() - y ) - 10 )
end
function PANEL:Think()
self:ConVarStringThink()
end
function PANEL:OnRemove()
if ( IsValid( self.Menu ) ) then
self.Menu:Remove()
end
end
function PANEL:OnEnter( val )
-- For override
self:UpdateConvarValue()
self:OnValueChange( self:GetText() )
end
function PANEL:UpdateConvarValue()
-- This only kicks into action if this variable has
-- a ConVar associated with it.
self:ConVarChanged( self:GetValue() )
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "TextEntry", self, w, h )
return false
end
function PANEL:PerformLayout()
derma.SkinHook( "Layout", "TextEntry", self )
end
function PANEL:SetValue( strValue )
-- Don't update if we're typing into it!
-- I'm sure a lot of people will want to reverse this behaviour :(
if ( vgui.GetKeyboardFocus() == self ) then return end
local CaretPos = self:GetCaretPos()
self:SetText( strValue )
self:OnValueChange( strValue )
self:SetCaretPos( CaretPos )
end
function PANEL:OnValueChange( strValue )
-- For Override
end
function PANEL:CheckNumeric( strValue )
-- Not purely numeric, don't run the check
if ( !self:GetNumeric() ) then return false end
-- God I hope numbers look the same in every language
if ( !string.find( strAllowedNumericCharacters, strValue, 1, true ) ) then
-- Noisy Error?
return true
end
return false
end
function PANEL:SetDisabled( bDisabled )
self:SetEnabled( !bDisabled )
end
function PANEL:GetDisabled( bDisabled )
return !self:IsEnabled()
end
function PANEL:AllowInput( strValue )
-- This is layed out like this so you can easily override and
-- either keep or remove this numeric check.
if ( self:CheckNumeric( strValue ) ) then return true end
end
function PANEL:SetEditable( b )
self:SetKeyboardInputEnabled( b )
self:SetMouseInputEnabled( b )
end
function PANEL:OnGetFocus()
--
-- These hooks are here for the sake of things like the spawn menu
-- which don't have key focus until you click on one of the text areas.
--
-- If you make a control for the spawnmenu that requires keyboard input
-- You should have these 3 functions in your panel, so it can handle it.
--
hook.Run( "OnTextEntryGetFocus", self )
end
function PANEL:OnLoseFocus()
self:UpdateConvarValue()
hook.Call( "OnTextEntryLoseFocus", nil, self )
end
function PANEL:OnMousePressed( mcode )
if ( mcode == MOUSE_LEFT ) then
self:OnGetFocus()
end
end
function PANEL:AddHistory( txt )
if ( !txt || txt == "" ) then return end
table.RemoveByValue( self.History, txt )
table.insert( self.History, txt )
end
function PANEL:GetAutoComplete( txt )
-- for override. Return a table of strings.
end
function PANEL:GetInt()
local num = tonumber( self:GetText() )
if ( !num ) then return nil end
return math.Round( num )
end
function PANEL:GetFloat()
return tonumber( self:GetText() )
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetText( "Edit Me!" )
ctrl:SetWide( 150 )
ctrl.OnEnter = function( slf ) Derma_Message( "You Typed: " .. slf:GetValue() ) end
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DTextEntry", "A simple TextEntry control", PANEL, "TextEntry" )
--[[---------------------------------------------------------
Clear the focus when we click away from us..
-----------------------------------------------------------]]
function TextEntryLoseFocus( panel, mcode )
local pnl = vgui.GetKeyboardFocus()
if ( !pnl ) then return end
if ( pnl == panel ) then return end
if ( !pnl.m_bLoseFocusOnClickAway ) then return end
-- We gotta find the EdtiablePanel parent and call KillFocus on it
-- We do it from the panel clicked, not the KB focus, which is necessary for DTextEntry autocomplete to not break
local prnt = panel
while ( IsValid( prnt ) ) do
if ( prnt:GetClassName() == "EditablePanel" || prnt:GetClassName() == "LuaEditablePanel" ) then
prnt:KillFocus()
return
end
prnt = prnt:GetParent()
end
end
hook.Add( "VGUIMousePressed", "TextEntryLoseFocus", TextEntryLoseFocus )

286
lua/vgui/dtilelayout.lua Normal file
View 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" )

158
lua/vgui/dtooltip.lua Normal file
View File

@@ -0,0 +1,158 @@
--[[
| 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/
--]]
--
-- The delay before a tooltip appears
-- Can be overridden with PANEL:SetTooltipDelay
--
local tooltip_delay = CreateConVar( "tooltip_delay", "0.5", FCVAR_ARCHIVE + FCVAR_DONTRECORD, "Delay between hovering over a panel, and a tooltip appearing, if it has one." )
local PANEL = {}
function PANEL:Init()
self:SetDrawOnTop( true )
self.DeleteContentsOnClose = false
self:SetText( "" )
self:SetFont( "Default" )
end
function PANEL:UpdateColours( skin )
return self:SetTextStyleColor( skin.Colours.TooltipText )
end
function PANEL:SetContents( panel, bDelete )
panel:SetParent( self )
self.Contents = panel
self.DeleteContentsOnClose = bDelete or false
self.Contents:SizeToContents()
self:InvalidateLayout( true )
self.Contents:SetVisible( false )
end
function PANEL:PerformLayout()
if ( IsValid( self.Contents ) ) then
self:SetWide( self.Contents:GetWide() + 8 )
self:SetTall( self.Contents:GetTall() + 8 )
self.Contents:SetPos( 4, 4 )
self.Contents:SetVisible( true )
else
local w, h = self:GetContentSize()
self:SetSize( w + 8, h + 6 )
self:SetContentAlignment( 5 )
end
end
local Mat = Material( "vgui/arrow" )
function PANEL:DrawArrow( x, y )
self.Contents:SetVisible( true )
surface.SetMaterial( Mat )
surface.DrawTexturedRect( self.ArrowPosX + x, self.ArrowPosY + y, self.ArrowWide, self.ArrowTall )
end
function PANEL:PositionTooltip()
if ( !IsValid( self.TargetPanel ) ) then
self:Close()
return
end
self:InvalidateLayout( true )
local x, y = input.GetCursorPos()
local w, h = self:GetSize()
local lx, ly = self.TargetPanel:LocalToScreen( 0, 0 )
y = y - 50
y = math.min( y, ly - h - 10 )
if ( y < 2 ) then y = 2 end
-- Fixes being able to be drawn off screen
self:SetPos( math.Clamp( x - w * 0.5, 0, ScrW() - self:GetWide() ), math.Clamp( y, 0, ScrH() - self:GetTall() ) )
end
function PANEL:Paint( w, h )
self:PositionTooltip()
derma.SkinHook( "Paint", "Tooltip", self, w, h )
end
function PANEL:OpenForPanel( panel )
self.TargetPanel = panel
self.OpenDelay = isnumber( panel.numTooltipDelay ) and panel.numTooltipDelay or tooltip_delay:GetFloat()
self:PositionTooltip()
-- Use the parent panel's skin
self:SetSkin( panel:GetSkin().Name )
if ( self.OpenDelay > 0 ) then
self:SetVisible( false )
timer.Simple( self.OpenDelay, function()
if ( !IsValid( self ) ) then return end
if ( !IsValid( panel ) ) then return end
self:PositionTooltip()
self:SetVisible( true )
end )
end
end
function PANEL:Close()
if ( !self.DeleteContentsOnClose and IsValid( self.Contents ) ) then
self.Contents:SetVisible( false )
self.Contents:SetParent( nil )
end
self:Remove()
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( "DButton" )
ctrl:SetText( "Hover me" )
ctrl:SetWide( 200 )
ctrl:SetTooltip( "This is a tooltip" )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DTooltip", "", PANEL, "DLabel" )

153
lua/vgui/dtree.lua Normal file
View File

@@ -0,0 +1,153 @@
--[[
| 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_bShowIcons", "ShowIcons" )
AccessorFunc( PANEL, "m_iIndentSize", "IndentSize" )
AccessorFunc( PANEL, "m_iLineHeight", "LineHeight" )
AccessorFunc( PANEL, "m_pSelectedItem", "SelectedItem" )
AccessorFunc( PANEL, "m_bClickOnDragHover", "ClickOnDragHover" )
function PANEL:Init()
--self:SetMouseInputEnabled( true )
--self:SetClickOnDragHover( false )
self:SetShowIcons( true )
self:SetIndentSize( 14 )
self:SetLineHeight( 17 )
--self:SetPadding( 2 )
self.RootNode = self:GetCanvas():Add( "DTree_Node" )
self.RootNode:SetRoot( self )
self.RootNode:SetParentNode( self )
self.RootNode:Dock( TOP )
self.RootNode:SetText( "" )
self.RootNode:SetExpanded( true, true )
self.RootNode:DockMargin( 0, 4, 0, 0 )
self:SetPaintBackground( true )
end
--
-- Get the root node
--
function PANEL:Root()
return self.RootNode
end
function PANEL:AddNode( strName, strIcon )
return self.RootNode:AddNode( strName, strIcon )
end
function PANEL:ChildExpanded( bExpand )
self:InvalidateLayout()
end
function PANEL:ShowIcons()
return self.m_bShowIcons
end
function PANEL:ExpandTo( bExpand )
end
function PANEL:SetExpanded( bExpand )
-- The top most node shouldn't react to this.
end
function PANEL:Clear()
self:Root():Clear()
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "Tree", self, w, h )
return true
end
function PANEL:DoClick( node )
return false
end
function PANEL:DoRightClick( node )
return false
end
function PANEL:SetSelectedItem( node )
if ( IsValid( self.m_pSelectedItem ) ) then
self.m_pSelectedItem:SetSelected( false )
end
self.m_pSelectedItem = node
if ( node ) then
node:SetSelected( true )
node:OnNodeSelected( node )
end
end
function PANEL:OnNodeSelected( node )
end
function PANEL:MoveChildTo( child, pos )
self:InsertAtTop( child )
end
function PANEL:LayoutTree()
self:InvalidateChildren( true )
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
--ctrl:SetPadding( 5 )
ctrl:SetSize( 300, 300 )
local node = ctrl:AddNode( "Node One" )
local node = ctrl:AddNode( "Node Two" )
local cnode = node:AddNode( "Node 2.1" )
local cnode = node:AddNode( "Node 2.2" )
local cnode = node:AddNode( "Node 2.3" )
local cnode = node:AddNode( "Node 2.4" )
local cnode = node:AddNode( "Node 2.5" )
for i = 1, 64 do
local gcnode = cnode:AddNode( "Node 2.5." .. i )
end
local cnode = node:AddNode( "Node 2.6" )
local node = ctrl:AddNode( "Node Three ( Maps Folder )" )
node:MakeFolder( "maps", "GAME" )
local node = ctrl:AddNode( "Node Four" )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DTree", "Tree View", PANEL, "DScrollPanel" )

709
lua/vgui/dtree_node.lua Normal file
View File

@@ -0,0 +1,709 @@
--[[
| 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_pRoot", "Root" )
AccessorFunc( PANEL, "m_pParentNode", "ParentNode" )
AccessorFunc( PANEL, "m_strFolder", "Folder" )
AccessorFunc( PANEL, "m_strFileName", "FileName" )
AccessorFunc( PANEL, "m_strPathID", "PathID" )
AccessorFunc( PANEL, "m_strWildCard", "WildCard" )
AccessorFunc( PANEL, "m_bNeedsPopulating", "NeedsPopulating" )
AccessorFunc( PANEL, "m_bShowFiles", "ShowFiles", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDirty", "Dirty", FORCE_BOOL )
AccessorFunc( PANEL, "m_bHideExpander", "HideExpander", FORCE_BOOL )
AccessorFunc( PANEL, "m_bNeedsChildSearch", "NeedsChildSearch", FORCE_BOOL )
AccessorFunc( PANEL, "m_bForceShowExpander", "ForceShowExpander", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDoubleClickToOpen", "DoubleClickToOpen", FORCE_BOOL )
AccessorFunc( PANEL, "m_bLastChild", "LastChild", FORCE_BOOL )
AccessorFunc( PANEL, "m_bDrawLines", "DrawLines", FORCE_BOOL )
AccessorFunc( PANEL, "m_bExpanded", "Expanded", FORCE_BOOL )
AccessorFunc( PANEL, "m_strDraggableName", "DraggableName" )
function PANEL:Init()
self:SetDoubleClickToOpen( true )
self.Label = vgui.Create( "DTree_Node_Button", self )
self.Label:SetDragParent( self )
self.Label.DoClick = function() self:InternalDoClick() end
self.Label.DoDoubleClick = function() self:InternalDoClick() end
self.Label.DoRightClick = function() self:InternalDoRightClick() end
self.Label.DragHover = function( s, t ) self:DragHover( t ) end
self.Expander = vgui.Create( "DExpandButton", self )
self.Expander.DoClick = function() self:SetExpanded( !self:GetExpanded() ) end
self.Expander:SetVisible( false )
self.Icon = vgui.Create( "DImage", self )
self.Icon:SetImage( "icon16/folder.png" )
self.Icon:SizeToContents()
self.animSlide = Derma_Anim( "Anim", self, self.AnimSlide )
self.fLastClick = SysTime()
self:SetDrawLines( false )
self:SetLastChild( false )
end
function PANEL:IsRootNode()
return self.m_pRoot == self.m_pParentNode
end
function PANEL:InternalDoClick()
self:GetRoot():SetSelectedItem( self )
if ( self:DoClick() ) then return end
if ( self:GetRoot():DoClick( self ) ) then return end
if ( !self.m_bDoubleClickToOpen || ( SysTime() - self.fLastClick < 0.3 ) ) then
self:SetExpanded( !self:GetExpanded() )
end
self.fLastClick = SysTime()
end
function PANEL:OnNodeSelected( node )
local parent = self:GetParentNode()
if ( IsValid( parent ) && parent.OnNodeSelected ) then
parent:OnNodeSelected( node )
end
end
function PANEL:OnNodeAdded( node )
-- Called when Panel.AddNode is called on this node
end
function PANEL:InternalDoRightClick()
if ( self:DoRightClick() ) then return end
if ( self:GetRoot():DoRightClick( self ) ) then return end
end
function PANEL:DoClick()
return false
end
function PANEL:DoRightClick()
return false
end
function PANEL:Clear()
if ( IsValid( self.ChildNodes ) ) then self.ChildNodes:Clear() end
end
function PANEL:AnimSlide( anim, delta, data )
if ( !IsValid( self.ChildNodes ) ) then anim:Stop() return end
if ( anim.Started ) then
data.To = self:GetTall()
data.Visible = self.ChildNodes:IsVisible()
end
if ( anim.Finished ) then
self:InvalidateLayout()
self.ChildNodes:SetVisible( data.Visible )
self:SetTall( data.To )
self:GetParentNode():ChildExpanded()
return
end
self.ChildNodes:SetVisible( true )
self:SetTall( Lerp( delta, data.From, data.To ) )
self:GetParentNode():ChildExpanded()
end
function PANEL:SetIcon( str )
if ( !str || str == "" ) then return end
self.Icon:SetImage( str )
end
function PANEL:ShowIcons()
return self:GetParentNode():ShowIcons()
end
function PANEL:GetLineHeight()
return self:GetParentNode():GetLineHeight()
end
function PANEL:GetIndentSize()
return self:GetParentNode():GetIndentSize()
end
function PANEL:SetText( strName )
self.Label:SetText( strName )
end
function PANEL:ExpandRecurse( bExpand )
self:SetExpanded( bExpand, true )
if ( !IsValid( self.ChildNodes ) ) then return end
for k, Child in pairs( self.ChildNodes:GetChildren() ) do
if ( Child.ExpandRecurse ) then
Child:ExpandRecurse( bExpand )
end
end
end
function PANEL:ExpandTo( bExpand )
self:SetExpanded( bExpand, true )
self:GetParentNode():ExpandTo( bExpand )
end
function PANEL:SetExpanded( bExpand, bSurpressAnimation )
self:GetParentNode():ChildExpanded( bExpand )
self.Expander:SetExpanded( bExpand )
self.m_bExpanded = bExpand
self:InvalidateLayout( true )
if ( !IsValid( self.ChildNodes ) ) then return end
local StartTall = self:GetTall()
self.animSlide:Stop()
-- Populate the child folders..
if ( bExpand && self:PopulateChildrenAndSelf( true ) ) then
-- Could really do with a 'loading' thing here
return
end
if ( IsValid( self.ChildNodes ) ) then
self.ChildNodes:SetVisible( bExpand )
if ( bExpand ) then
self.ChildNodes:InvalidateLayout( true )
end
end
self:InvalidateLayout( true )
-- Do animation..
if ( !bSurpressAnimation ) then
self.animSlide:Start( 0.3, { From = StartTall } )
self.animSlide:Run()
end
end
function PANEL:ChildExpanded( bExpand )
self.ChildNodes:InvalidateLayout( true )
self:InvalidateLayout( true )
self:GetParentNode():ChildExpanded( bExpand )
end
function PANEL:Paint()
end
function PANEL:HasChildren()
if ( !IsValid( self.ChildNodes ) ) then return false end
return self.ChildNodes:HasChildren()
end
function PANEL:DoChildrenOrder()
if ( !IsValid( self.ChildNodes ) ) then return end
local children = self.ChildNodes:GetChildren()
local last = #children
for i = 1, (last - 1) do
children[i]:SetLastChild( false )
end
children[last]:SetLastChild( true )
end
function PANEL:PerformRootNodeLayout()
self.Expander:SetVisible( false )
self.Label:SetVisible( false )
self.Icon:SetVisible( false )
if ( IsValid( self.ChildNodes ) ) then
self.ChildNodes:Dock( TOP )
self:SetTall( self.ChildNodes:GetTall() )
end
end
function PANEL:PerformLayout()
if ( self:IsRootNode() ) then
return self:PerformRootNodeLayout()
end
if ( self.animSlide:Active() ) then return end
local LineHeight = self:GetLineHeight()
if ( self.m_bHideExpander ) then
self.Expander:SetPos( -11, 0 )
self.Expander:SetSize( 15, 15 )
self.Expander:SetVisible( false )
else
self.Expander:SetPos( 2, 0 )
self.Expander:SetSize( 15, 15 )
self.Expander:SetVisible( self:HasChildren() || self:GetForceShowExpander() )
self.Expander:SetZPos( 10 )
end
self.Label:StretchToParent( 0, nil, 0, nil )
self.Label:SetTall( LineHeight )
if ( self:ShowIcons() ) then
self.Icon:SetVisible( true )
self.Icon:SetPos( self.Expander.x + self.Expander:GetWide() + 4, ( LineHeight - self.Icon:GetTall() ) * 0.5 )
self.Label:SetTextInset( self.Icon.x + self.Icon:GetWide() + 4, 0 )
else
self.Icon:SetVisible( false )
self.Label:SetTextInset( self.Expander.x + self.Expander:GetWide() + 4, 0 )
end
if ( !IsValid( self.ChildNodes ) || !self.ChildNodes:IsVisible() ) then
self:SetTall( LineHeight )
return
end
self.ChildNodes:SizeToContents()
self:SetTall( LineHeight + self.ChildNodes:GetTall() )
self.ChildNodes:StretchToParent( LineHeight, LineHeight, 0, 0 )
self:DoChildrenOrder()
end
function PANEL:CreateChildNodes()
if ( IsValid( self.ChildNodes ) ) then return end
self.ChildNodes = vgui.Create( "DListLayout", self )
self.ChildNodes:SetDropPos( "852" )
self.ChildNodes:SetVisible( self:GetExpanded() )
self.ChildNodes.OnChildRemoved = function()
self.ChildNodes:InvalidateLayout()
-- Root node should never be closed
if ( !self.ChildNodes:HasChildren() && !self:IsRootNode() ) then
self:SetExpanded( false )
end
end
self.ChildNodes.OnModified = function()
self:OnModified()
end
self:InvalidateLayout()
end
function PANEL:AddPanel( pPanel )
self:CreateChildNodes()
self.ChildNodes:Add( pPanel )
self:InvalidateLayout()
end
function PANEL:AddNode( strName, strIcon )
self:CreateChildNodes()
local pNode = vgui.Create( "DTree_Node", self )
pNode:SetText( strName )
pNode:SetParentNode( self )
pNode:SetTall( self:GetLineHeight() )
pNode:SetRoot( self:GetRoot() )
pNode:SetIcon( strIcon )
pNode:SetDrawLines( !self:IsRootNode() )
self:InstallDraggable( pNode )
self.ChildNodes:Add( pNode )
self:InvalidateLayout()
-- Let addons do whatever they need
self:OnNodeAdded( pNode )
return pNode
end
function PANEL:InsertNode( pNode )
self:CreateChildNodes()
pNode:SetParentNode( self )
pNode:SetRoot( self:GetRoot() )
self:InstallDraggable( pNode )
self.ChildNodes:Add( pNode )
self:InvalidateLayout()
return pNode
end
function PANEL:InstallDraggable( pNode )
local DragName = self:GetDraggableName()
if ( !DragName ) then return end
-- Make this node draggable
pNode:SetDraggableName( DragName )
pNode:Droppable( DragName )
-- Allow item dropping onto us
self.ChildNodes:MakeDroppable( DragName, true )
end
function PANEL:DroppedOn( pnl )
self:InsertNode( pnl )
self:SetExpanded( true )
end
function PANEL:AddFolder( strName, strFolder, strPath, bShowFiles, strWildCard, bDontForceExpandable )
local node = self:AddNode( strName )
node:MakeFolder( strFolder, strPath, bShowFiles, strWildCard, bDontForceExpandable )
return node
end
function PANEL:MakeFolder( strFolder, strPath, bShowFiles, strWildCard, bDontForceExpandable )
-- Store the data
self:SetNeedsPopulating( true )
self:SetWildCard( strWildCard || "*" )
self:SetFolder( strFolder )
self:SetPathID( strPath )
self:SetShowFiles( bShowFiles || false )
self:CreateChildNodes()
self:SetNeedsChildSearch( true )
if ( !bDontForceExpandable ) then
self:SetForceShowExpander( true )
end
-- If the parent is already open, populate myself. Do not require the user to collapse and expand for this to happen
if ( self:GetParentNode():GetExpanded() ) then
-- Yuck! This is basically a hack for gameprops.lua
timer.Simple( 0, function()
if ( !IsValid( self ) ) then return end
self:PopulateChildrenAndSelf()
end )
end
end
function PANEL:FilePopulateCallback( files, folders, foldername, path, bAndChildren, wildcard )
local showfiles = self:GetShowFiles()
self.ChildNodes:InvalidateLayout( true )
local FileCount = 0
if ( folders ) then
for k, File in SortedPairsByValue( folders ) do
local Node = self:AddNode( File )
Node:MakeFolder( string.Trim( foldername .. "/" .. File, "/" ), path, showfiles, wildcard, true )
FileCount = FileCount + 1
end
end
if ( showfiles ) then
for k, File in SortedPairs( files ) do
local icon = "icon16/page_white.png"
local Node = self:AddNode( File, icon )
Node:SetFileName( string.Trim( foldername .. "/" .. File, "/" ) )
FileCount = FileCount + 1
end
end
if ( FileCount == 0 ) then
self.ChildNodes:Remove()
self.ChildNodes = nil
self:SetNeedsPopulating( false )
self:SetShowFiles( nil )
self:SetWildCard( nil )
self:InvalidateLayout()
self.Expander:SetExpanded( true )
return
end
self:InvalidateLayout()
end
function PANEL:FilePopulate( bAndChildren, bExpand )
if ( !self:GetNeedsPopulating() ) then return end
local folder = self:GetFolder()
local path = self:GetPathID()
local wildcard = self:GetWildCard()
if ( !folder || !wildcard || !path ) then return false end
local files, folders = file.Find( string.Trim( folder .. "/" .. wildcard, "/" ), path )
if ( folders && folders[ 1 ] == "/" ) then table.remove( folders, 1 ) end
self:SetNeedsPopulating( false )
self:SetNeedsChildSearch( false )
self:FilePopulateCallback( files, folders, folder, path, bAndChildren, wildcard )
if ( bExpand ) then
self:SetExpanded( true )
end
return true
end
function PANEL:PopulateChildren()
if ( !IsValid( self.ChildNodes ) ) then return end
for k, v in ipairs( self.ChildNodes:GetChildren() ) do
timer.Simple( k * 0.1, function()
if ( IsValid( v ) ) then
v:FilePopulate( false )
end
end )
end
end
function PANEL:PopulateChildrenAndSelf( bExpand )
-- Make sure we're populated
if ( self:FilePopulate( true, bExpand ) ) then return true end
self:PopulateChildren()
end
function PANEL:SetSelected( b )
self.Label:SetSelected( b )
self.Label:InvalidateLayout()
end
function PANEL:Think()
self.animSlide:Run()
end
--
-- DragHoverClick
--
function PANEL:DragHoverClick( HoverTime )
if ( !self:GetExpanded() ) then
self:SetExpanded( true )
end
if ( self:GetRoot():GetClickOnDragHover() ) then
self:InternalDoClick()
end
end
function PANEL:MoveToTop()
local parent = self:GetParentNode()
if ( !IsValid( parent ) ) then return end
self:GetParentNode():MoveChildTo( self, 1 )
end
function PANEL:MoveChildTo( child )
self.ChildNodes:InsertAtTop( child )
end
function PANEL:GetText()
return self.Label:GetText()
end
function PANEL:GetIcon()
return self.Icon:GetImage()
end
function PANEL:CleanList()
for k, panel in pairs( self.Items ) do
if ( !IsValid( panel ) || panel:GetParent() != self.pnlCanvas ) then
self.Items[k] = nil
end
end
end
function PANEL:Insert( pNode, pNodeNextTo, bBefore )
pNode:SetParentNode( self )
pNode:SetRoot( self:GetRoot() )
self:CreateChildNodes()
if ( bBefore ) then
self.ChildNodes:InsertBefore( pNodeNextTo, pNode )
else
self.ChildNodes:InsertAfter( pNodeNextTo, pNode )
end
self:InvalidateLayout()
end
function PANEL:LeaveTree( pnl )
self.ChildNodes:RemoveItem( pnl, true )
self:InvalidateLayout()
end
function PANEL:OnModified()
-- Override Me
end
function PANEL:GetChildNode( iNum )
if ( !IsValid( self.ChildNodes ) ) then return end
return self.ChildNodes:GetChild( iNum )
end
function PANEL:GetChildNodes()
if ( !IsValid( self.ChildNodes ) ) then return {} end
return self.ChildNodes:GetChildren()
end
function PANEL:GetChildNodeCount()
if ( !IsValid( self.ChildNodes ) ) then return 0 end
return self.ChildNodes:ChildCount()
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "TreeNode", self, w, h )
end
function PANEL:Copy()
local copy = vgui.Create( "DTree_Node", self:GetParent() )
copy:SetText( self:GetText() )
copy:SetIcon( self:GetIcon() )
copy:SetRoot( self:GetRoot() )
copy:SetParentNode( self:GetParentNode() )
if ( self.ChildNodes ) then
for k, v in ipairs( self.ChildNodes:GetChildren() ) do
local childcopy = v:Copy()
copy:InsertNode( childcopy )
end
end
self:SetupCopy( copy )
return copy
end
function PANEL:SetupCopy( copy )
-- TODO.
end
derma.DefineControl( "DTree_Node", "Tree Node", PANEL, "DPanel" )

View File

@@ -0,0 +1,47 @@
--[[
| 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 = {}
function PANEL:Init()
self:SetTextInset( 32, 0 )
self:SetContentAlignment( 4 )
end
function PANEL:Paint( w, h )
derma.SkinHook( "Paint", "TreeNodeButton", self, w, h )
--
-- Draw the button text
--
return false
end
function PANEL:UpdateColours( skin )
if ( self:IsSelected() ) then return self:SetTextStyleColor( skin.Colours.Tree.Selected ) end
if ( self.Hovered ) then return self:SetTextStyleColor( skin.Colours.Tree.Hover ) end
return self:SetTextStyleColor( skin.Colours.Tree.Normal )
end
function PANEL:GenerateExample()
-- Do nothing!
end
derma.DefineControl( "DTree_Node_Button", "Tree Node Button", PANEL, "DButton" )

View File

@@ -0,0 +1,184 @@
--[[
| 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 = {}
function PANEL:Init()
self:SetCursor( "sizens" )
self:SetPaintBackground( false )
end
function PANEL:OnMousePressed( mcode )
if ( mcode == MOUSE_LEFT ) then
self:GetParent():StartGrab()
end
end
derma.DefineControl( "DVerticalDividerBar", "", PANEL, "DPanel" )
--[[---------------------------------------------------------
DVerticalDivider
-----------------------------------------------------------]]
local PANEL = {}
AccessorFunc( PANEL, "m_pTop", "Top" )
AccessorFunc( PANEL, "m_pBottom", "Bottom" )
AccessorFunc( PANEL, "m_pMiddle", "Middle" )
AccessorFunc( PANEL, "m_iDividerHeight", "DividerHeight" )
AccessorFunc( PANEL, "m_iTopHeight", "TopHeight" )
AccessorFunc( PANEL, "m_bDragging", "Dragging" )
AccessorFunc( PANEL, "m_iTopHeightMin", "TopMin" )
AccessorFunc( PANEL, "m_iTopHeightMax", "TopMax" )
AccessorFunc( PANEL, "m_iBottomHeightMin", "BottomMin" )
AccessorFunc( PANEL, "m_iHoldPos", "HoldPos" )
function PANEL:Init()
self:SetDividerHeight( 8 )
self:SetTopHeight( 100 )
self:SetTopMin( 50 )
self:SetTopMax( 4096 )
self:SetBottomMin( 50 )
self:SetPaintBackground( false )
self.m_DragBar = vgui.Create( "DVerticalDividerBar", self )
end
function PANEL:LoadCookies()
self:SetTopHeight( self:GetCookieNumber( "TopHeight", self:GetTopHeight() ) )
end
function PANEL:SetTop( pnl )
self.m_pTop = pnl
self.m_pTop:SetParent( self )
end
function PANEL:SetBottom( pnl )
self.m_pBottom = pnl
self.m_pBottom:SetParent( self )
end
function PANEL:DoConstraints()
if ( self:GetTall() == 0 ) then return end
self.m_iTopHeight = math.Clamp( self.m_iTopHeight, self:GetTopMin(), self:GetTall() - self:GetBottomMin() - self:GetDividerHeight() )
end
function PANEL:PerformLayout()
self:DoConstraints()
if ( self.m_pTop ) then
self.m_pTop:StretchToParent( 0, 0, 0, nil )
self.m_pTop:SetTall( self.m_iTopHeight )
self.m_pTop:InvalidateLayout()
end
if ( self.m_pBottom ) then
self.m_pBottom:StretchToParent( 0, self.m_iTopHeight + self.m_iDividerHeight, 0, 0 )
self.m_pBottom:InvalidateLayout()
end
self.m_DragBar:StretchToParent( 0, self.m_iTopHeight, 0, 0 )
self.m_DragBar:SetTall( self.m_iDividerHeight )
self.m_DragBar:SetZPos( -1 )
if ( self.m_pMiddle ) then
self.m_pMiddle:StretchToParent( 0, 0, 0, 0 )
self.m_pMiddle:InvalidateLayout()
end
end
function PANEL:SetMiddle( Middle )
self.m_pMiddle = Middle
if ( Middle ) then
Middle:SetParent( self.m_DragBar )
end
end
function PANEL:OnCursorMoved( x, y )
if ( !self:GetDragging() ) then return end
self.m_iTopHeight = y - self:GetHoldPos()
self.m_iTopHeight = math.min( self.m_iTopHeight, self:GetTopMax() )
self:InvalidateLayout( true )
end
function PANEL:StartGrab()
self:SetCursor( "sizens" )
local x, y = self.m_DragBar:CursorPos()
self:SetHoldPos( y )
self:SetDragging( true )
self:MouseCapture( true )
end
function PANEL:OnMouseReleased( mcode )
if ( mcode == MOUSE_LEFT ) then
self:SetCursor( "none" )
self:SetDragging( false )
self:MouseCapture( false )
self:SetCookie( "TopHeight", self.m_iTopHeight )
end
end
function PANEL:GenerateExample( ClassName, PropertySheet, Width, Height )
local ctrl = vgui.Create( ClassName )
ctrl:SetSize( 256, 256 )
ctrl:SetTop( vgui.Create( "DButton" ) )
ctrl:SetBottom( vgui.Create( "DButton" ) )
PropertySheet:AddSheet( ClassName, ctrl, nil, true, true )
end
derma.DefineControl( "DVerticalDivider", "", PANEL, "DPanel" )

308
lua/vgui/dvscrollbar.lua Normal file
View 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" )

182
lua/vgui/fingerposer.lua Normal file
View File

@@ -0,0 +1,182 @@
--[[
| 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 = {}
local ow = 310
local oh = 270
PANEL.FingerPositions = {
{ 60 / ow, 215 / oh },
{ 50 / ow, 175 / oh },
{ 55 / ow, 130 / oh },
{ 117 / ow, 135 / oh },
{ 128 / ow, 85 / oh },
{ 149 / ow, 45 / oh },
{ 155 / ow, 145 / oh },
{ 172 / ow, 100 / oh },
{ 197 / ow, 60 / oh },
{ 185 / ow, 160 / oh },
{ 215 / ow, 115 / oh },
{ 235 / ow, 85 / oh },
{ 215 / ow, 175 / oh },
{ 245 / ow, 145 / oh },
{ 272 / ow, 120 / oh },
}
function PANEL:Init()
self.Hand = 0
self.FingerVars = {}
self.Label:SetBright( true )
for i = 0, 14 do
if ( self.NumVars == 18 && i > 10 ) then break end
self.FingerVars[ i ] = vgui.Create( "FingerVar", self )
self.FingerVars[ i ]:SetVarName( "finger_" .. i )
if ( i > 2 && i % 3 != 0 ) then
self.FingerVars[ i ]:SetRestrictX( true )
end
end
end
function PANEL:ControlValues( kv )
if ( kv.hand == 1 ) then
self.Label:SetText( "#tool.finger.righthand" )
self.Hand = 1
else
self.Label:SetText( "#tool.finger.lefthand" )
self.Hand = 0
end
self.NumVars = kv.numvars
self:InvalidateLayout( true )
end
function PANEL:PerformLayout( w, h )
local size = math.min( w, h )
local targetH = math.Clamp( w, 256, 512 )
local bgXoffset = w / 2 - size / 2
self.Label:SetPos( 10 + bgXoffset, 5 )
self.Label:SetWide( w )
for finger = 0, 4 do
for var = 0, 2 do
local ID = ( finger * 3 ) + var
local Pos = self.FingerPositions[ ID + 1 ]
if ( Pos && self.FingerVars[ ID ] ) then
-- Scale the finger "sliders" a bit
local fsize = math.floor( math.Remap( targetH, 256, 512, 48, 64 ) )
self.FingerVars[ ID ]:SetSize( fsize, fsize )
self.FingerVars[ ID ]:SetPos( bgXoffset + Pos[1] * size - fsize / 2, Pos[2] * size - fsize / 2 )
end
end
end
self:SetTall( targetH )
end
local bg_mat = Material( "gui/hand_human_left.png" )
function PANEL:Paint( w, h )
surface.SetMaterial( bg_mat )
surface.SetDrawColor( 255, 255, 255, 255 )
local size = math.min( w, h )
render.PushFilterMag( TEXFILTER.ANISOTROPIC )
render.PushFilterMin( TEXFILTER.ANISOTROPIC )
surface.DrawTexturedRect( w / 2 - size / 2, 0, size, size )
render.PopFilterMag()
render.PopFilterMin()
return true
end
function PANEL:Think()
self:UpdateHovered()
end
function PANEL:UpdateHovered()
if ( self.Dragging ) then return end
local x, y = self:CursorPos()
local distance = 256
local hovered = nil
for k, v in pairs( self.FingerVars ) do
local val = v:GetValue()
local AddX = val[1] * v:GetWide()
local AddY = val[2] * v:GetTall()
local dist = math.Distance( x, y, v.x + v:GetWide() / 2 + AddX, v.y + v:GetTall() / 2 + AddY )
if ( dist < distance ) then
hovered = v
distance = dist
end
end
if ( !hovered || hovered != self.HoveredPanel ) then
if ( IsValid( self.HoveredPanel ) ) then
self.HoveredPanel.HoveredFingerVar = nil
end
self.HoveredPanel = hovered
if ( IsValid( self.HoveredPanel ) ) then
self.HoveredPanel.HoveredFingerVar = true
end
end
end
function PANEL:OnMousePressed( mousecode )
self:UpdateHovered()
if ( !IsValid( self.HoveredPanel ) ) then return end
self.HoveredPanel:OnMousePressed( mousecode )
end
vgui.Register( "fingerposer", PANEL, "ContextBase" )

177
lua/vgui/fingervar.lua Normal file
View File

@@ -0,0 +1,177 @@
--[[
| 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 ConVar_RestrictFingers = CreateClientConVar( "finger_restrict", "1", false, false, "Whether to restrict non-root Fingerposer sliders to the Y axis only." )
local PANEL = {}
local MAX_ANGLE_X = 100
local MAX_ANGLE_Y = 100
function PANEL:Init()
self.Value = { 0, 0 }
self.UpdateTimer = 0
self.LastShiftState = false
-- Don't update convars straight away.
self.NextUpdate = CurTime() + 0.5
-- The parent will feed mouse presses to us
self:SetMouseInputEnabled( false )
self:SetSize( 48, 48 )
end
function PANEL:SetVarName( _name_ )
self.VarName = _name_
end
function PANEL:SetRestrictX( bRestrict )
self.RestrictX = bRestrict
end
function PANEL:IsRestricted()
return self.RestrictX && ConVar_RestrictFingers:GetBool()
end
function PANEL:GetValue()
return { self.Value[1] / MAX_ANGLE_X, self.Value[2] / MAX_ANGLE_Y }
end
function PANEL:UpdateConVar()
if ( !self.VarName ) then return end
if ( self.NextUpdate > CurTime() ) then return end
local Val = Format( "%.2f %.2f", self.Value[1], self.Value[2] )
RunConsoleCommand( self.VarName, Val )
end
function PANEL:SetValue( x, y )
x = math.Clamp( x, -0.5, 0.5 ) * MAX_ANGLE_X
y = math.Clamp( y, -0.5, 0.5 ) * MAX_ANGLE_Y
if ( self:IsRestricted() ) then x = 0 end
self.Value = { x, y }
end
function PANEL:OnMousePressed( mousecode )
if ( mousecode == MOUSE_RIGHT || mousecode == MOUSE_MIDDLE ) then
self:SetValue( 0, 0 )
self:UpdateConVar()
return
end
self:SetMouseInputEnabled( true )
self:MouseCapture( true )
self.Dragging = true
self:GetParent().Dragging = true
self:OnCursorMoved( self:LocalCursorPos() )
end
function PANEL:OnMouseReleased( mousecode )
self:MouseCapture( false )
self.Dragging = nil
self:SetMouseInputEnabled( false )
self:GetParent().Dragging = false
end
function PANEL:OnCursorMoved( x, y )
if ( !self.Dragging ) then return end
local w = self:GetWide()
local h = self:GetTall()
-- If holding shift, give double the "precision"
if ( input.IsShiftDown() ) then
x = x / 2 + w / 4
y = y / 2 + h / 4
end
self:SetValue( ( x / w ) - 0.5, ( y / h ) - 0.5 )
self:UpdateConVar()
end
function PANEL:Think()
-- Update shift state change when cursor not moving
if ( self.Dragging && self.LastShiftState != input.IsShiftDown() ) then
self.LastShiftState = input.IsShiftDown()
self:OnCursorMoved( self:LocalCursorPos() )
end
if ( self.UpdateTimer > CurTime() ) then return end
self.UpdateTimer = CurTime() + 0.1
local Value = string.Explode( " ", GetConVarString( self.VarName ) )
self.Value[1] = tonumber( Value[1] )
self.Value[2] = tonumber( Value[2] )
end
function PANEL:Paint( w, h )
-- This part is dirty, the whole fingerposer needs redoing, it's messy
local wep = LocalPlayer():GetWeapon( "gmod_tool" )
if ( !IsValid( wep ) ) then return end
local ent = wep:GetNWEntity( "HandEntity" )
if ( !IsValid( ent ) || !ent.FingerIndex ) then return end
local boneid = ent.FingerIndex[ tonumber( self.VarName:sub( 8 ) ) + 1 + 15 * wep:GetNWInt( "HandNum", 0 ) ]
if ( !boneid || ent:GetBoneName( boneid ) == "__INVALIDBONE__" ) then return end
local v = self:GetValue()
local x = ( v[1] * w ) + w / 2
local y = ( v[2] * h ) + h / 2
x = math.Clamp( x, 3, w - 3 )
y = math.Clamp( y, 3, h - 3 )
surface.SetDrawColor( 0, 0, 0, 250 )
if ( self.HoveredFingerVar ) then surface.SetDrawColor( 255, 255, 255, 255 ) end
surface.DrawLine( x, y, w / 2, h / 2 )
surface.DrawRect( w / 2 - 1, h / 2 - 1, 2, 2 )
surface.DrawRect( x - 3, y - 3, 6, 6 )
surface.SetDrawColor( 255, 255, 0, 255 )
if ( self:IsRestricted() ) then surface.SetDrawColor( 30, 180, 255, 255 ) end
surface.DrawRect( x - 2, y - 2, 4, 4 )
end
vgui.Register( "FingerVar", PANEL, "Panel" )

View File

@@ -0,0 +1,77 @@
--[[
| 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 = {}
function PANEL:SetMaterial( On )
if ( self.MatOn ) then
self.MatOn:Remove()
end
self.MatOn = vgui.Create( "Material", self )
self.MatOn:SetSize( 16, 16 )
self.MatOn:SetMaterial( On )
self:InvalidateLayout( true )
end
function PANEL:SetChecked( bOn )
if ( self.State == bOn ) then return end
self.MatOn:SetVisible( bOn )
self.State = bOn
end
function PANEL:GetChecked()
return self.State
end
function PANEL:Set( bOn )
self:SetChecked( bOn )
end
function PANEL:DoClick()
self:SetChecked( !self.State )
end
function PANEL:SizeToContents()
if ( self.MatOn ) then
self:SetSize( self.MatOn:GetWide(), self.MatOn:GetTall() )
end
self:InvalidateLayout()
end
function PANEL:Paint()
draw.RoundedBox( 4, 0, 0, self:GetWide(), self:GetTall(), Color( 0, 0, 0, 50 ) )
return true
end
function PANEL:PerformLayout()
self.MatOn:SetPos( ( self:GetWide() - self.MatOn:GetWide() ) / 2, ( self:GetTall() - self.MatOn:GetTall() ) / 2 )
end
vgui.Register( "ImageCheckBox", PANEL, "Button" )

70
lua/vgui/material.lua Normal file
View File

@@ -0,0 +1,70 @@
--[[
| 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 = {}
function PANEL:Init()
self.Material = nil
self.AutoSize = true
self:SetAlpha( 255 )
self:SetMouseInputEnabled( false )
self:SetKeyboardInputEnabled( false )
end
function PANEL:Paint()
if (!self.Material) then return true end
surface.SetMaterial( self.Material )
surface.SetDrawColor( 255, 255, 255, self.Alpha )
surface.DrawTexturedRect( 0, 0, self:GetSize() )
return true
end
function PANEL:SetAlpha( _alpha_ )
self.Alpha = _alpha_
end
function PANEL:SetMaterial( _matname_ )
--self.Material = surface.GetTextureID( _matname_ )
self.Material = Material( _matname_ )
local Texture = self.Material:GetTexture( "$basetexture" )
if ( Texture ) then
self.Width = Texture:Width()
self.Height = Texture:Height()
else
self.Width = 32
self.Height = 32
end
self:InvalidateLayout()
end
function PANEL:PerformLayout()
if ( !self.Material ) then return end
if ( !self.AutoSize ) then return end
self:SetSize( self.Width, self.Height )
end
vgui.Register( "Material", PANEL, "Button" )

267
lua/vgui/matselect.lua Normal file
View File

@@ -0,0 +1,267 @@
--[[
| 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, "ItemWidth", "ItemWidth", FORCE_NUMBER )
AccessorFunc( PANEL, "ItemHeight", "ItemHeight", FORCE_NUMBER )
AccessorFunc( PANEL, "Height", "NumRows", FORCE_NUMBER )
AccessorFunc( PANEL, "m_bSizeToContent", "AutoHeight", FORCE_BOOL )
local border = 0
local border_w = 8
local matHover = Material( "gui/ps_hover.png", "nocull" )
local boxHover = GWEN.CreateTextureBorder( border, border, 64 - border * 2, 64 - border * 2, border_w, border_w, border_w, border_w, matHover )
-- This function is used as the paint function for selected buttons
function PANEL:SelectedItemPaintOver( w, h )
-- self in this context would be the selected item!
boxHover( 0, 0, w, h, color_white )
end
function PANEL:Init()
-- A panellist is a panel that you shove other panels
-- into and it makes a nice organised frame.
self.List = vgui.Create( "DPanelList", self )
self.List:EnableHorizontal( true )
self.List:EnableVerticalScrollbar()
self.List:SetSpacing( 1 )
self.List:SetPadding( 3 )
self.Controls = {}
self.Height = 2
self:SetItemWidth( 128 )
self:SetItemHeight( 128 )
end
function PANEL:SetAutoHeight( bAutoHeight )
self.m_bSizeToContent = bAutoHeight
self.List:SetAutoSize( bAutoHeight )
self:InvalidateLayout()
end
function PANEL:AddMaterial( label, value )
local Mat = vgui.Create( "DImageButton", self )
Mat:SetOnViewMaterial( value, "models/wireframe" )
Mat:SetTooltip( label )
Mat.AutoSize = false
Mat.Value = value
self:SetItemSize( Mat )
Mat.DoClick = function( button )
-- Select the material
self:SelectMaterial( button )
-- Update the convar
RunConsoleCommand( self:ConVar(), value )
end
Mat.DoRightClick = function( button )
local menu = DermaMenu()
menu:AddOption( "#spawnmenu.menu.copy", function() SetClipboardText( value ) end ):SetIcon( "icon16/page_copy.png" )
menu:Open()
end
-- Add the icon to ourselves
self.List:AddItem( Mat )
table.insert( self.Controls, Mat )
self:InvalidateLayout()
return Mat
end
function PANEL:AddMaterialEx( label, material, value, convars )
local Mat = vgui.Create( "DImageButton", self )
Mat:SetImage( material )
Mat:SetTooltip( label )
Mat.AutoSize = false
Mat.Value = value
Mat.ConVars = convars
self:SetItemSize( Mat )
Mat.DoClick = function ( button )
-- Can't do this due to faceposer
-- self:SelectMaterial( button )
-- Update the convars
for cvar, val in pairs( convars ) do RunConsoleCommand( cvar, val ) end
end
Mat.DoRightClick = function( button )
local menu = DermaMenu()
menu:AddOption( "#spawnmenu.menu.copy", function() SetClipboardText( material ) end ):SetIcon( "icon16/page_copy.png" )
menu:Open()
end
-- Add the icon to ourselves
self.List:AddItem( Mat )
table.insert( self.Controls, Mat )
self:InvalidateLayout()
return Mat
end
function PANEL:SelectMaterial( mat )
-- Restore the current overlay
if ( self.SelectedMaterial ) then
self.SelectedMaterial.PaintOver = self.OldSelectedPaintOver
end
-- Add the overlay to this button
self.OldSelectedPaintOver = mat.PaintOver
mat.PaintOver = self.SelectedItemPaintOver
-- Set our selected values
self.SelectedMaterial = mat
self.CurrentValue = mat.Value
end
function PANEL:Clear()
for k, Mat in pairs( self.Controls ) do
Mat:Remove()
self.Controls[k] = nil
end
self.List:CleanList()
self.SelectedMaterial = nil
self.OldSelectedPaintOver = nil
end
function PANEL:FindMaterialByValue( value )
for k, Mat in pairs( self.Controls ) do
if ( Mat.Value == value ) then return Mat end
end
end
function PANEL:SetItemSize( pnl )
local maxW = self:GetWide()
if ( self.List.VBar && self.List.VBar.Enabled ) then maxW = maxW - self.List.VBar:GetWide() end
local w = self.ItemWidth
if ( w < 1 ) then
local numIcons = math.floor( 1 / w )
w = math.floor( ( maxW - self.List:GetPadding() * 2 - self.List:GetSpacing() * ( numIcons - 1 ) ) / numIcons )
end
local h = self.ItemHeight
if ( h < 1 ) then
local numIcons = math.floor( 1 / h )
h = math.floor( ( maxW - self.List:GetPadding() * 2 - self.List:GetSpacing() * ( numIcons - 1 ) ) / numIcons )
end
pnl:SetSize( w, h )
end
function PANEL:ControlValues( kv )
self.BaseClass.ControlValues( self, kv )
self.Height = kv.height or 2
-- Load the list of models from our keyvalues file
if ( kv.options ) then
for k, v in pairs( kv.options ) do
self:AddMaterial( k, v )
end
end
self.ItemWidth = kv.itemwidth or 32
self.ItemHeight = kv.itemheight or 32
for k, v in pairs( self.Controls ) do
v:SetSize( self.ItemWidth, self.ItemHeight )
end
self:InvalidateLayout()
end
function PANEL:PerformLayout()
self.List:SetPos( 0, 0 )
for k, v in pairs( self.List:GetItems() ) do
self:SetItemSize( v )
end
if ( self.m_bSizeToContent ) then
self.List:SetWide( self:GetWide() )
self.List:InvalidateLayout( true )
self:SetTall( self.List:GetTall() + 5 )
return
end
self.List:InvalidateLayout( true ) -- Rebuild
local maxW = self:GetWide()
if ( self.List.VBar && self.List.VBar.Enabled ) then maxW = maxW - self.List.VBar:GetWide() end
local h = self.ItemHeight
if ( h < 1 ) then
local numIcons = math.floor( 1 / h )
h = math.floor( ( maxW - self.List:GetPadding() * 2 - self.List:GetSpacing() * ( numIcons - 1 ) ) / numIcons )
end
local Height = ( h * self.Height ) + ( self.List:GetPadding() * 2 ) + self.List:GetSpacing() * ( self.Height - 1 )
self.List:SetSize( self:GetWide(), Height )
self:SetTall( Height + 5 )
end
function PANEL:FindAndSelectMaterial( value )
self.CurrentValue = value
local mat = self:FindMaterialByValue( value )
if ( !mat ) then return end
self:SelectMaterial( mat )
end
function PANEL:TestForChanges()
local cvar = self:ConVar()
if ( !cvar ) then return end
local value = GetConVarString( cvar )
if ( value == self.CurrentValue ) then return end
self:FindAndSelectMaterial( value )
end
vgui.Register( "MatSelect", PANEL, "ContextBase" )

59
lua/vgui/prop_boolean.lua Normal file
View File

@@ -0,0 +1,59 @@
--[[
| 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/
--]]
--
-- prop_generic is the base for all other properties.
-- All the business should be done in :Setup using inline functions.
-- So when you derive from this class - you should ideally only override Setup.
--
local PANEL = {}
function PANEL:Init()
end
function PANEL:Setup( vars )
self:Clear()
local ctrl = self:Add( "DCheckBox" )
ctrl:SetPos( 0, 2 )
-- Return true if we're editing
self.IsEditing = function( slf )
return ctrl:IsEditing()
end
-- Enabled/disabled support
self.IsEnabled = function( slf )
return ctrl:IsEnabled()
end
self.SetEnabled = function( slf, b )
ctrl:SetEnabled( b )
end
-- Set the value
self.SetValue = function( slf, val )
ctrl:SetChecked( tobool( val ) )
end
-- Alert row that value changed
ctrl.OnChange = function( slf, newval )
if ( newval ) then newval = 1 else newval = 0 end
self:ValueChanged( newval )
end
end
derma.DefineControl( "DProperty_Boolean", "", PANEL, "DProperty_Generic" )

82
lua/vgui/prop_combo.lua Normal file
View File

@@ -0,0 +1,82 @@
--[[
| 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 = {}
function PANEL:Init()
end
function PANEL:Setup( vars )
vars = vars or {}
self:Clear()
local combo = vgui.Create( "DComboBox", self )
combo:Dock( FILL )
combo:DockMargin( 0, 1, 2, 2 )
combo:SetValue( vars.text or "Select..." )
local hasIcons, icon = istable( vars.icons )
for id, thing in pairs( vars.values or {} ) do
if ( hasIcons ) then
icon = vars.icons[ id ]
else
icon = vars.icons
end
combo:AddChoice( id, thing, id == vars.select, icon )
end
self.IsEditing = function( slf )
return combo:IsMenuOpen()
end
self.SetValue = function( slf, val )
for id, data in pairs( combo.Data ) do
if ( data == val ) then
combo:ChooseOptionID( id )
end
end
end
combo.OnSelect = function( _, id, val, data )
self:ValueChanged( data, true )
end
combo.Paint = function( slf, w, h )
if ( self:IsEditing() or self:GetRow():IsHovered() or self:GetRow():IsChildHovered() ) then
DComboBox.Paint( slf, w, h )
end
end
self:GetRow().AddChoice = function( slf, value, data, select )
combo:AddChoice( value, data, select )
end
self:GetRow().SetSelected = function( slf, id )
combo:ChooseOptionID( id )
end
-- Enabled/disabled support
self.IsEnabled = function( slf )
return combo:IsEnabled()
end
self.SetEnabled = function( slf, b )
combo:SetEnabled( b )
end
end
derma.DefineControl( "DProperty_Combo", "", PANEL, "DProperty_Generic" )

69
lua/vgui/prop_entity.lua Normal file
View File

@@ -0,0 +1,69 @@
--[[
| 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/
--]]
--
-- prop_generic is the base for all other properties.
-- All the business should be done in :Setup using inline functions.
-- So when you derive from this class - you should ideally only override Setup.
--
DEFINE_BASECLASS( "DProperty_Generic" )
local PANEL = {}
function PANEL:Init()
end
function PANEL:Setup( vars )
vars = vars or {}
BaseClass.Setup( self, vars )
local btn = self:Add( "DButton" )
btn:Dock( LEFT )
btn:DockMargin( 0, 1, 4, 1 )
btn:SetWide( 24 )
btn:SetText( "" )
btn:SetImage( "icon16/wand.png" )
-- Use the world picked to select an entity
btn.DoClick = function( s )
-- Make it look different when selecting things
s:SetEnabled( false )
util.worldpicker.Start( function( tr )
self:SetEnabled( true )
if ( !IsValid( tr.Entity ) ) then return end
-- TODO: Maybe this should be EntSerial()?
self:ValueChanged( tr.Entity:EntIndex(), true )
end )
end
-- Enabled/disabled support
self.IsEnabled = function( slf )
return btn:IsEnabled()
end
local oldSetEnabled = self.SetEnabled
self.SetEnabled = function( slf, b )
btn:SetEnabled( b )
oldSetEnabled( b ) -- Also handle the text entry
end
end
derma.DefineControl( "DProperty_Entity", "", PANEL, "DProperty_Generic" )

87
lua/vgui/prop_float.lua Normal file
View File

@@ -0,0 +1,87 @@
--[[
| 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/
--]]
--
-- prop_generic is the base for all other properties.
-- All the business should be done in :Setup using inline functions.
-- So when you derive from this class - you should ideally only override Setup.
--
local PANEL = {}
function PANEL:Init()
end
function PANEL:GetDecimals()
return 2
end
function PANEL:Setup( vars )
self:Clear()
vars = vars or {}
local ctrl = self:Add( "DNumSlider" )
ctrl:Dock( FILL )
ctrl:SetDark( true )
ctrl:SetDecimals( self:GetDecimals() )
-- Apply vars
ctrl:SetMin( vars.min or 0 )
ctrl:SetMax( vars.max or 1 )
-- The label needs mouse input so we can scratch
self:GetRow().Label:SetMouseInputEnabled( true )
-- Take the scratch and place it on the Row's label
ctrl.Scratch:SetParent( self:GetRow().Label )
-- Hide the numslider's label
ctrl.Label:SetVisible( false )
-- Move the text area to the left
ctrl.TextArea:Dock( LEFT )
-- Add a margin onto the slider - so it's not right up the side
ctrl.Slider:DockMargin( 0, 3, 8, 3 )
-- Return true if we're editing
self.IsEditing = function( slf )
return ctrl:IsEditing()
end
-- Enabled/disabled support
self.IsEnabled = function( slf )
return ctrl:IsEnabled()
end
self.SetEnabled = function( slf, b )
ctrl:SetEnabled( b )
end
-- Set the value
self.SetValue = function( slf, val )
ctrl:SetValue( val )
end
-- Alert row that value changed
ctrl.OnValueChanged = function( slf, newval )
self:ValueChanged( newval )
end
self.Paint = function()
-- PERFORMANCE !!!
ctrl.Slider:SetVisible( self:IsEditing() or self:GetRow():IsChildHovered() )
end
end
derma.DefineControl( "DProperty_Float", "", PANEL, "DProperty_Generic" )

87
lua/vgui/prop_generic.lua Normal file
View File

@@ -0,0 +1,87 @@
--[[
| 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/
--]]
--
-- prop_generic is the base for all other properties.
-- All the business should be done in :Setup using inline functions.
-- So when you derive from this class - you should ideally only override Setup.
--
local PANEL = {}
AccessorFunc( PANEL, "m_pRow", "Row" )
function PANEL:Init()
end
function PANEL:Think()
--
-- Periodically update the value
--
if ( !self:IsEditing() && isfunction( self.m_pRow.DataUpdate ) ) then
self.m_pRow:DataUpdate()
end
end
--
-- Called by this control, or a derived control, to alert the row of the change
--
function PANEL:ValueChanged( newval, bForce )
if ( ( self:IsEditing() || bForce ) && isfunction( self.m_pRow.DataChanged ) ) then
self.m_pRow:DataChanged( newval )
end
end
function PANEL:Setup( vars )
self:Clear()
local text = self:Add( "DTextEntry" )
if ( !vars || !vars.waitforenter ) then text:SetUpdateOnType( true ) end
text:SetPaintBackground( false )
text:Dock( FILL )
-- Return true if we're editing
self.IsEditing = function( slf )
return text:IsEditing()
end
-- Enabled/disabled support
self.IsEnabled = function( slf )
return text:IsEnabled()
end
self.SetEnabled = function( slf, b )
text:SetEnabled( b )
end
-- Set the value
self.SetValue = function( slf, val )
text:SetText( util.TypeToString( val ) )
end
-- Alert row that value changed
text.OnValueChange = function( slf, newval )
self:ValueChanged( newval )
end
end
derma.DefineControl( "DProperty_Generic", "", PANEL, "Panel" )

27
lua/vgui/prop_int.lua Normal file
View File

@@ -0,0 +1,27 @@
--[[
| 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/
--]]
--
-- prop_generic is the base for all other properties.
-- All the business should be done in :Setup using inline functions.
-- So when you derive from this class - you should ideally only override Setup.
--
local PANEL = {}
function PANEL:Init()
end
function PANEL:GetDecimals()
return 0
end
derma.DefineControl( "DProperty_Int", "", PANEL, "DProperty_Float" )

103
lua/vgui/prop_rgbcolor.lua Normal file
View File

@@ -0,0 +1,103 @@
--[[
| 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/
--]]
DEFINE_BASECLASS( "DProperty_Generic" )
local PANEL = {}
function PANEL:Init()
end
function PANEL:ValueChanged( newval, bForce )
BaseClass.ValueChanged( self, newval, bForce )
self.VectorValue = Vector( newval )
end
function PANEL:Setup( vars )
vars = vars or {}
self:Clear()
local text = self:Add( "DTextEntry" )
if ( not vars.waitforenter ) then text:SetUpdateOnType( true ) end
text:SetDrawBackground( false )
text:Dock( FILL )
self.IsEditing = function( self )
return text:IsEditing()
end
text.OnValueChange = function( text, newval )
self:ValueChanged( newval )
end
local btn = self:Add( "DButton" )
btn:Dock( LEFT )
btn:DockMargin( 0, 2, 4, 2 )
btn:SetWide( 20 - 4 )
btn:SetText( "" )
btn.Paint = function( btn, w, h )
local veccol = self.VectorValue
if ( veccol ) then
surface.SetDrawColor( veccol.r, veccol.g, veccol.b, 255 )
surface.DrawRect( 2, 2, w - 4, h - 4 )
end
surface.SetDrawColor( 0, 0, 0, 150 )
surface.DrawOutlinedRect( 0, 0, w, h )
end
btn.DoClick = function()
local color = vgui.Create( "DColorCombo", self )
color:SetupCloseButton( function() CloseDermaMenus() end )
color.OnValueChanged = function( color, newcol )
self:ValueChanged( tostring( newcol.r ).." "..tostring( newcol.g ).." "..tostring( newcol.b ), true )
end
local veccol = self.VectorValue
color:SetColor( Color( veccol.r, veccol.g, veccol.b, 255 ) )
local menu = DermaMenu()
menu:AddPanel( color )
menu:SetDrawBackground( false )
menu:Open( gui.MouseX() + 8, gui.MouseY() + 10 )
end
self.SetValue = function( self, val )
text:SetText( tostring( math.Round( val.r ) ).." "..tostring( math.Round( val.g ) ).." "..tostring( math.Round( val.b ) ) )
self.VectorValue = val
end
end
derma.DefineControl( "DProperty_RGBColor", "", PANEL, "DProperty_Generic" )

View File

@@ -0,0 +1,128 @@
--[[
| 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/
--]]
--
-- prop_generic is the base for all other properties.
-- All the business should be done in :Setup using inline functions.
-- So when you derive from this class - you should ideally only override Setup.
--
local function ColorToString( col )
return math.floor( col.r ) .. " " .. math.floor( col.g ) .. " " .. math.floor( col.b ) .. " " .. math.floor( col.a )
end
DEFINE_BASECLASS( "DProperty_Generic" )
local PANEL = {}
function PANEL:Init()
end
--
-- Called by this control, or a derived control, to alert the row of the change
--
function PANEL:ValueChanged( newval, bForce )
BaseClass.ValueChanged( self, newval, bForce )
if ( isvector( self.VectorValue ) ) then
self.VectorValue = Vector( newval )
else
self.VectorValue = string.ToColor( newval )
end
end
function PANEL:Setup( vars )
vars = vars or {}
BaseClass.Setup( self, vars )
local __SetValue = self.SetValue
local btn = self:Add( "DButton" )
btn:Dock( LEFT )
btn:DockMargin( 0, 2, 4, 2 )
btn:SetWide( 16 )
btn:SetText( "" )
btn.Paint = function( btn_slf, w, h )
if ( self.VectorValue ) then
if ( isvector( self.VectorValue ) ) then
surface.SetDrawColor( self.VectorValue:ToColor() )
else
surface.SetDrawColor( self.VectorValue )
end
surface.DrawRect( 2, 2, w - 4, h - 4 )
end
surface.SetDrawColor( 0, 0, 0, 150 )
surface.DrawOutlinedRect( 0, 0, w, h )
end
--
-- Pop up a colour selector when we click on the button
--
btn.DoClick = function()
local color = vgui.Create( "DColorCombo", self )
if ( istable( self.VectorValue ) ) then color.Mixer:SetAlphaBar( true ) end
color:SetupCloseButton( function() CloseDermaMenus() end )
color.OnValueChanged = function( colorCombo, newcol )
if ( isvector( self.VectorValue ) ) then
-- convert color to vector
local vec = Vector( newcol.r / 255, newcol.g / 255, newcol.b / 255 )
self:ValueChanged( tostring( vec ), true )
else
self:ValueChanged( ColorToString( newcol ), true )
end
end
local col = self.VectorValue
if ( isvector( self.VectorValue ) ) then col = self.VectorValue:ToColor() end
color:SetColor( col )
local menu = DermaMenu()
menu:AddPanel( color )
menu:SetPaintBackground( false )
menu:Open( gui.MouseX() + 8, gui.MouseY() + 10 )
end
-- Set the value
self.SetValue = function( slf, val )
slf.VectorValue = val
if ( isvector( slf.VectorValue ) ) then
__SetValue( slf, val )
else
__SetValue( slf, ColorToString( val ) )
end
end
-- Enabled/disabled support
self.IsEnabled = function( slf )
return btn:IsEnabled()
end
local oldSetEnabled = self.SetEnabled
self.SetEnabled = function( slf, b )
btn:SetEnabled( b )
oldSetEnabled( b ) -- Also handle the text entry
end
end
derma.DefineControl( "DProperty_VectorColor", "", PANEL, "DProperty_Generic" )

199
lua/vgui/propselect.lua Normal file
View File

@@ -0,0 +1,199 @@
--[[
| 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 = {}
local border = 0
local border_w = 8
local matHover = Material( "gui/ps_hover.png", "nocull" )
local boxHover = GWEN.CreateTextureBorder( border, border, 64 - border * 2, 64 - border * 2, border_w, border_w, border_w, border_w, matHover )
-- This function is used as the paint function for selected buttons.
local function HighlightedButtonPaint( self, w, h )
boxHover( 0, 0, w, h, color_white )
end
function PANEL:Init()
-- A panellist is a panel that you shove other panels
-- into and it makes a nice organised frame.
self.List = vgui.Create( "DPanelList", self )
self.List:EnableHorizontal( true )
self.List:EnableVerticalScrollbar()
self.List:SetSpacing( 1 )
self.List:SetPadding( 3 )
Derma_Hook( self.List, "Paint", "Paint", "Panel" )
self.Controls = {}
self.Height = 2
end
function PANEL:AddModel( model, ConVars )
if ( ConVars && !istable( ConVars ) ) then
ErrorNoHaltWithStack( "bad argument #2 to 'PropSelect.AddModel' (table expected, got " .. type( ConVars ) .. ")" )
ConVars = nil
end
-- Creeate a spawnicon and set the model
local Icon = vgui.Create( "SpawnIcon", self )
Icon:SetModel( model )
Icon:SetTooltip( model )
Icon.Model = model
Icon.ConVars = ConVars || {}
local ConVarName = self:ConVar()
-- Run a console command when the Icon is clicked
Icon.DoClick = function ( pnl )
for k, v in pairs( pnl.ConVars ) do
LocalPlayer():ConCommand( Format( "%s \"%s\"\n", k, v ) )
end
-- Note: We run this command after all the optional stuff
LocalPlayer():ConCommand( Format( "%s \"%s\"\n", ConVarName, model ) )
end
Icon.OpenMenu = function( button )
local menu = DermaMenu()
menu:AddOption( "#spawnmenu.menu.copy", function() SetClipboardText( model ) end ):SetIcon( "icon16/page_copy.png" )
menu:Open()
end
-- Add the Icon us
self.List:AddItem( Icon )
table.insert( self.Controls, Icon )
return Icon
end
function PANEL:AddModelEx( name, model, skin )
-- Creeate a spawnicon and set the model
local Icon = vgui.Create( "SpawnIcon", self )
Icon:SetModel( model, skin )
Icon:SetTooltip( model )
Icon.Model = model
Icon.Value = name
Icon.ConVars = {}
local ConVarName = self:ConVar()
-- Run a console command when the Icon is clicked
Icon.DoClick = function ( pnl ) LocalPlayer():ConCommand( Format( "%s \"%s\"\n", ConVarName, Icon.Value ) ) end
Icon.OpenMenu = function( button )
local menu = DermaMenu()
menu:AddOption( "Copy to Clipboard", function() SetClipboardText( model ) end ):SetIcon( "icon16/page_copy.png" )
menu:Open()
end
-- Add the Icon us
self.List:AddItem( Icon )
table.insert( self.Controls, Icon )
return Icon
end
function PANEL:ControlValues( kv )
self.BaseClass.ControlValues( self, kv )
self.Height = kv.height || 2
-- Load the list of models from our keyvalues file
-- This is the old way
if ( kv.models ) then
for k, v in SortedPairs( kv.models ) do
self:AddModel( k, v )
end
end
--
-- Passing in modelstable is the new way
--
if ( kv.modelstable ) then
local tmp = {} -- HACK: Order by skin too.
for k, v in SortedPairsByMemberValue( kv.modelstable, "model" ) do
tmp[ k ] = v.model:lower() .. ( v.skin || 0 )
end
for k, v in SortedPairsByValue( tmp ) do
v = kv.modelstable[ k ]
self:AddModelEx( k, v.model, v.skin || 0 )
end
end
self:InvalidateLayout( true )
end
function PANEL:PerformLayout( w, h )
local y = self.BaseClass.PerformLayout( self, w, h )
if ( self.Height >= 1 ) then
local Height = ( 64 + self.List:GetSpacing() ) * math.max( self.Height, 1 ) + self.List:GetPadding() * 2 - self.List:GetSpacing()
self.List:SetPos( 0, y )
self.List:SetSize( self:GetWide(), Height )
y = y + Height
self:SetTall( y + 5 )
else -- Height is set to 0 or less, auto stretch
self.List:SetWide( self:GetWide() )
self.List:SizeToChildren( false, true )
self:SetTall( self.List:GetTall() + 5 )
end
end
function PANEL:FindAndSelectButton( Value )
self.CurrentValue = Value
for k, Icon in pairs( self.Controls ) do
if ( Icon.Model == Value || Icon.Value == Value ) then
-- Remove the old overlay
if ( self.SelectedIcon ) then
self.SelectedIcon.PaintOver = self.OldSelectedPaintOver
end
-- Add the overlay to this button
self.OldSelectedPaintOver = Icon.PaintOver
Icon.PaintOver = HighlightedButtonPaint
self.SelectedIcon = Icon
end
end
end
function PANEL:TestForChanges()
local Value = GetConVarString( self:ConVar() )
if ( Value == self.CurrentValue ) then return end
self:FindAndSelectButton( Value )
end
vgui.Register( "PropSelect", PANEL, "ContextBase" )

209
lua/vgui/slidebar.lua Normal file
View File

@@ -0,0 +1,209 @@
--[[
| 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 = {}
function PANEL:Init()
self:SetEnabled( true )
self:SetScroll( 0 )
self:SetBarScale( 4 )
self.Velocity = 0
self.HasChanged = true
end
function PANEL:SetEnabled( b )
self.Enabled = b
if ( !b ) then
self:SetScroll( 0 )
self.HasChanged = true
end
self:SetMouseInputEnabled( b )
end
function PANEL:SetScroll( _float_ )
self.Pos = math.Clamp( _float_, 0, 1 )
end
function PANEL:Value()
return self.Pos
end
function PANEL:SetBarScale( _scale_ )
self.BarScale = _scale_
self:SetEnabled( self.BarScale > 1 )
end
function PANEL:Rebuild( item )
local Offset = 0
if ( self.Horizontal ) then
local x, y = 0, 0
for k, panel in pairs( self.Items ) do
local w = panel:GetWide()
local h = panel:GetTall()
if ( x + w > self:GetWide() ) then
x = 0
y = y + h + self.Spacing
end
panel:SetPos( x, y )
x = x + w + self.Spacing
Offset = y + h + self.Spacing
end
else
for k, panel in pairs( self.Items ) do
panel:SetSize( self:GetCanvas():GetWide(), panel:GetTall() )
panel:SetPos( 0, Offset )
Offset = Offset + panel:GetTall() + self.Spacing
end
end
self:GetCanvas():SetSize( self:GetCanvas():GetWide(), Offset + self.Padding * 2 - self.Spacing )
end
function PANEL:OnMouseWheeled( dlta )
if ( !self.Enabled ) then return end
self:AddVelocity( dlta )
return true
end
function PANEL:AddVelocity( vel )
self.Velocity = self.Velocity + vel * -2
end
function PANEL:Changed()
if ( self.HasChanged ) then
self.HasChanged = nil
return true
end
return false
end
function PANEL:ScrollbarSize()
return self:GetTall() / self.BarScale
end
function PANEL:Think()
if ( self.Dragging ) then
-- Accumulate Velocity
local PixelDiff = ( gui.MouseY() - self.StartDraggingPos ) * self.DragDirection
self.Velocity = ( self.Velocity + PixelDiff ) / 2
-- Scroll
local Span = self:GetTall() - self:ScrollbarSize()
self.Pos = self.Pos * Span + PixelDiff
self:SetScroll( self.Pos / Span )
self.HasChanged = true
self.StartDraggingPos = gui.MouseY()
self.Dragging = 2
return
end
if ( self.Velocity != 0 ) then
self.HasChanged = true
self.Pos = self.Pos + ( self.Velocity / self.BarScale ) * FrameTime()
self.Velocity = math.Approach( self.Velocity, 0, FrameTime() * self.Velocity * 10 )
if ( self.Pos < 0 || self.Pos > 1 ) then
--self.Velocity = self.Velocity * -0.5
self.Velocity = 0
self.Pos = math.Clamp( self.Pos, 0, 1 )
end
end
end
function PANEL:Paint()
if ( !self.Enabled || self.BarScale <= 0 ) then return true end
draw.RoundedBox( 4, 0, 0, self:GetWide(), self:GetTall(), Color( 200, 200, 200, 100 ) )
local Pos = ( self:GetTall() - self:ScrollbarSize() ) * self.Pos
draw.RoundedBox( 4, 2, Pos + 2, self:GetWide() - 4, self:ScrollbarSize() - 4, Color( 0, 0, 0, 200 ) )
return true
end
function PANEL:OnMousePressed()
self:RequestFocus()
self:Grip( 1 )
end
function PANEL:Grip( direction )
if ( !self.Enabled ) then return end
self:MouseCapture( true )
self.DragDirection = direction || ( -1 / self.BarScale )
self.Dragging = 1
self.Velocity = 0
self.StartDraggingPos = gui.MouseY()
end
function PANEL:OnMouseReleased()
self:MouseCapture( false )
self.Dragging = nil
end
vgui.Register( "SlideBar", PANEL, "Panel" )

359
lua/vgui/spawnicon.lua Normal file
View File

@@ -0,0 +1,359 @@
--[[
| 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_strModelName", "ModelName" )
AccessorFunc( PANEL, "m_iSkin", "SkinID" )
AccessorFunc( PANEL, "m_strBodyGroups", "BodyGroup" )
AccessorFunc( PANEL, "m_strIconName", "IconName" )
function PANEL:Init()
self:SetDoubleClickingEnabled( false )
self:SetText( "" )
self.Icon = vgui.Create( "ModelImage", self )
self.Icon:SetMouseInputEnabled( false )
self.Icon:SetKeyboardInputEnabled( false )
self:SetSize( 64, 64 )
self.m_strBodyGroups = "000000000"
self.OverlayFade = 0
end
function PANEL:DoRightClick()
local pCanvas = self:GetSelectionCanvas()
if ( IsValid( pCanvas ) && pCanvas:NumSelectedChildren() > 0 && self:IsSelected() ) then
return hook.Run( "SpawnlistOpenGenericMenu", pCanvas )
end
self:OpenMenu()
end
function PANEL:DoClick()
end
function PANEL:OpenMenu()
end
function PANEL:Paint( w, h )
-- Do not draw the default background
end
function PANEL:Think()
self.OverlayFade = math.Clamp( self.OverlayFade - RealFrameTime() * 640 * 2, 0, 255 )
if ( dragndrop.IsDragging() or !self:IsHovered() ) then return end
self.OverlayFade = math.Clamp( self.OverlayFade + RealFrameTime() * 640 * 8, 0, 255 )
end
local border = 4
local border_w = 5
local matHover = Material( "gui/sm_hover.png", "nocull" )
local boxHover = GWEN.CreateTextureBorder( border, border, 64 - border * 2, 64 - border * 2, border_w, border_w, border_w, border_w, matHover )
function PANEL:PaintOver( w, h )
if ( self.OverlayFade > 0 ) then
boxHover( 0, 0, w, h, Color( 255, 255, 255, self.OverlayFade ) )
end
self:DrawSelections()
end
function PANEL:PerformLayout()
if ( self:IsDown() && !self.Dragging ) then
self.Icon:StretchToParent( 6, 6, 6, 6 )
else
self.Icon:StretchToParent( 0, 0, 0, 0 )
end
end
function PANEL:OnSizeChanged( newW, newH )
self.Icon:SetSize( newW, newH )
end
function PANEL:SetSpawnIcon( name )
self.m_strIconName = name
self.Icon:SetSpawnIcon( name )
end
function PANEL:SetBodyGroup( k, v )
if ( k < 0 ) then return end
if ( k > 9 ) then return end
if ( v < 0 ) then return end
if ( v > 9 ) then return end
self.m_strBodyGroups = self.m_strBodyGroups:SetChar( k + 1, v )
end
function PANEL:SetModel( mdl, iSkin, BodyGroups )
if ( !mdl ) then debug.Trace() return end
self:SetModelName( mdl )
self:SetSkinID( iSkin or 0 )
if ( tostring( BodyGroups ):len() != 9 ) then
BodyGroups = "000000000"
end
self.m_strBodyGroups = BodyGroups
self.Icon:SetModel( mdl, iSkin, BodyGroups )
if ( iSkin && iSkin > 0 ) then
self:SetTooltip( Format( "%s (Skin %i)", mdl, iSkin + 1 ) )
else
self:SetTooltip( Format( "%s", mdl ) )
end
end
function PANEL:RebuildSpawnIcon()
self.Icon:RebuildSpawnIcon()
end
function PANEL:RebuildSpawnIconEx( t )
self.Icon:RebuildSpawnIconEx( t )
end
function PANEL:ToTable( bigtable )
local tab = {}
tab.type = "model"
tab.model = self:GetModelName()
if ( self:GetSkinID() != 0 ) then
tab.skin = self:GetSkinID()
end
if ( self:GetBodyGroup() != "000000000" ) then
tab.body = "B" .. self:GetBodyGroup()
end
if ( self:GetWide() != 64 ) then
tab.wide = self:GetWide()
end
if ( self:GetTall() != 64 ) then
tab.tall = self:GetTall()
end
table.insert( bigtable, tab )
end
function PANEL:Copy()
local copy = vgui.Create( "SpawnIcon", self:GetParent() )
copy:SetModel( self:GetModelName(), self:GetSkinID() )
copy:CopyBase( self )
copy.DoClick = self.DoClick
copy.OpenMenu = self.OpenMenu
return copy
end
-- Icon has been editied, they changed the skin
-- what should we do?
function PANEL:SkinChanged( i )
-- This is called from Icon Editor. Mark the spawnlist as changed. Ideally this would check for GetTriggerSpawnlistChange on the parent
hook.Run( "SpawnlistContentChanged" )
-- Change the skin, and change the model
-- this way we can edit the spawnmenu....
self:SetSkinID( i )
self:SetModel( self:GetModelName(), self:GetSkinID(), self:GetBodyGroup() )
end
function PANEL:BodyGroupChanged( k, v )
-- This is called from Icon Editor. Mark the spawnlist as changed. Ideally this would check for GetTriggerSpawnlistChange on the parent
hook.Run( "SpawnlistContentChanged" )
self:SetBodyGroup( k, v )
self:SetModel( self:GetModelName(), self:GetSkinID(), self:GetBodyGroup() )
end
-- A little hack to prevent code duplication
function PANEL:InternalAddResizeMenu( menu, callback, label )
local submenu_r, submenu_r_option = menu:AddSubMenu( label or "#spawnmenu.menu.resize", function() end )
submenu_r_option:SetIcon( "icon16/arrow_out.png" )
-- Generate the sizes
local function AddSizeOption( submenu, w, h, curW, curH )
local p = submenu:AddOption( w .. " x " .. h, function() callback( w, h ) end )
if ( w == ( curW or 64 ) && h == ( curH or 64 ) ) then p:SetIcon( "icon16/accept.png" ) end
end
local sizes = { 64, 128, 256, 512 }
for id, size in pairs( sizes ) do
for _, size2 in pairs( sizes ) do
AddSizeOption( submenu_r, size, size2, self:GetWide(), self:GetTall() )
end
if ( id <= #sizes - 1 ) then
submenu_r:AddSpacer()
end
end
end
vgui.Register( "SpawnIcon", PANEL, "DButton" )
--
-- Action on creating a model from the spawnlist
--
spawnmenu.AddContentType( "model", function( container, obj )
local icon = vgui.Create( "SpawnIcon", container )
if ( obj.body ) then
obj.body = string.Trim( tostring( obj.body ), "B" )
end
if ( obj.wide ) then
icon:SetWide( obj.wide )
end
if ( obj.tall ) then
icon:SetTall( obj.tall )
end
icon:InvalidateLayout( true )
icon:SetModel( obj.model, obj.skin or 0, obj.body )
icon:SetTooltip( string.Replace( string.GetFileFromFilename( obj.model ), ".mdl", "" ) )
icon.DoClick = function( s )
surface.PlaySound( "ui/buttonclickrelease.wav" )
RunConsoleCommand( "gm_spawn", s:GetModelName(), s:GetSkinID() or 0, s:GetBodyGroup() or "" )
end
icon.OpenMenu = function( pnl )
-- Use the containter that we are dragged onto, not the one we were created on
if ( pnl:GetParent() && pnl:GetParent().ContentContainer ) then
container = pnl:GetParent().ContentContainer
end
local menu = DermaMenu()
menu:AddOption( "#spawnmenu.menu.copy", function() SetClipboardText( string.gsub( obj.model, "\\", "/" ) ) end ):SetIcon( "icon16/page_copy.png" )
menu:AddOption( "#spawnmenu.menu.spawn_with_toolgun", function()
RunConsoleCommand( "gmod_tool", "creator" )
RunConsoleCommand( "creator_type", "4" )
RunConsoleCommand( "creator_name", obj.model )
end ):SetIcon( "icon16/brick_add.png" )
local submenu, submenu_opt = menu:AddSubMenu( "#spawnmenu.menu.rerender", function()
if ( IsValid( pnl ) ) then pnl:RebuildSpawnIcon() end
end )
submenu_opt:SetIcon( "icon16/picture_save.png" )
submenu:AddOption( "#spawnmenu.menu.rerender_this", function()
if ( IsValid( pnl ) ) then pnl:RebuildSpawnIcon() end
end ):SetIcon( "icon16/picture.png" )
submenu:AddOption( "#spawnmenu.menu.rerender_all", function()
if ( IsValid( container ) ) then container:RebuildAll() end
end ):SetIcon( "icon16/pictures.png" )
menu:AddOption( "#spawnmenu.menu.edit_icon", function()
if ( !IsValid( pnl ) ) then return end
local editor = vgui.Create( "IconEditor" )
editor:SetIcon( pnl )
editor:Refresh()
editor:MakePopup()
editor:Center()
end ):SetIcon( "icon16/pencil.png" )
-- Do not allow removal/size changes from read only panels
if ( IsValid( pnl:GetParent() ) && pnl:GetParent().GetReadOnly && pnl:GetParent():GetReadOnly() ) then menu:Open() return end
pnl:InternalAddResizeMenu( menu, function( w, h )
if ( !IsValid( pnl ) ) then return end
pnl:SetSize( w, h )
pnl:InvalidateLayout( true )
container:OnModified()
container:Layout()
pnl:SetModel( obj.model, obj.skin or 0, obj.body )
end )
menu:AddSpacer()
menu:AddOption( "#spawnmenu.menu.delete", function()
if ( !IsValid( pnl ) ) then return end
pnl:Remove()
hook.Run( "SpawnlistContentChanged" )
end ):SetIcon( "icon16/bin_closed.png" )
menu:Open()
end
icon:InvalidateLayout( true )
if ( IsValid( container ) ) then
container:Add( icon )
end
--[[
if ( iSkin != 0 ) then return end
local iSkinCount = NumModelSkins( strModel )
if ( iSkinCount <= 1 ) then return end
for i=1, iSkinCount-1, 1 do
self:AddModel( strModel, i )
end
]]
return icon
end )

View File

@@ -0,0 +1,36 @@
--[[
| 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/
--]]
--[[--------------------------------------------------------------------------
-- Namespace Tables
--------------------------------------------------------------------------]]--
local PANEL = {}
--[[--------------------------------------------------------------------------
-- Namespace Functions
--------------------------------------------------------------------------]]--
--[[--------------------------------------------------------------------------
--
-- PANEL:OpenPresetEditor()
--
--]]--
function PANEL:OpenPresetEditor()
if ( not self.m_strPreset ) then return end
self.Window = vgui.Create( "StackerPresetEditor" )
self.Window:MakePopup()
self.Window:Center()
self.Window:SetType( self.m_strPreset )
self.Window:SetConVars( self.ConVars )
self.Window:SetPresetControl( self )
end
vgui.Register( "StackerControlPresets", PANEL, "ControlPresets" )

View File

@@ -0,0 +1,60 @@
--[[
| 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/
--]]
--[[--------------------------------------------------------------------------
-- Namespace Tables
--------------------------------------------------------------------------]]--
local PANEL = {}
--[[--------------------------------------------------------------------------
-- Localized Functions & Variables
--------------------------------------------------------------------------]]--
local math = math
local vgui = vgui
local tonumber = tonumber
--[[--------------------------------------------------------------------------
-- Namespace Functions
--------------------------------------------------------------------------]]--
--[[--------------------------------------------------------------------------
--
-- PANEL:SetValue( string, boolean )
--
--]]--
function PANEL:SetValue( val, bSuppress )
val = math.Clamp( tonumber( val ) or 0, self:GetMin(), self:GetMax() )
if ( val == nil ) then return end
if ( self:GetValue() == val ) then return end
self.Scratch:SetFloatValue( val )
self:ValueChanged( self:GetValue(), bSuppress )
end
--[[--------------------------------------------------------------------------
--
-- PANEL:ValueChanged( string, value)
--
--]]--
function PANEL:ValueChanged( val, bSuppress )
val = math.Clamp( tonumber( val ) or 0, self:GetMin(), self:GetMax() )
self.Slider:SetSlideX( self.Scratch:GetFraction( val ) )
if ( self.TextArea ~= vgui.GetKeyboardFocus() ) then
self.TextArea:SetValue( self.Scratch:GetTextValue() )
end
if ( not bSuppress ) then
self:OnValueChanged( val )
end
end
vgui.Register( "StackerDNumSlider", PANEL, "DNumSlider" )

View File

@@ -0,0 +1,60 @@
--[[
| 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/
--]]
--[[--------------------------------------------------------------------------
-- Namespace Tables
--------------------------------------------------------------------------]]--
local PANEL = {}
--[[--------------------------------------------------------------------------
-- Localized Functions & Variables
--------------------------------------------------------------------------]]--
local vgui = vgui
local pairs = pairs
local AccessorFunc = AccessorFunc
local GetConVarString = GetConVarString
--[[--------------------------------------------------------------------------
-- Namespace Functions
--------------------------------------------------------------------------]]--
AccessorFunc( PANEL, "m_ConCommands", "ConCommands" )
--[[--------------------------------------------------------------------------
--
-- PANEL:Add()
--
--]]--
function PANEL:Add()
if ( not self.m_ConVars ) then return end
local ToName = self.txtName:GetValue()
if ( not ToName or ToName == "" ) then return end
-- Todo, Handle name collision
local tabValues = {}
for k, v in pairs( self.m_ConVars ) do
tabValues[ v.CCmd ] = GetConVarString( v.CVar )
end
presets.Add( self.m_strType, ToName, tabValues )
self:Update()
self.PresetList:SelectByName( ToName )
self.txtName:SetText( "" )
if ( self.m_PresetControl ) then
self.m_PresetControl:Update()
end
end
vgui.Register( "StackerPresetEditor", PANEL, "PresetEditor" )

180
lua/vgui/vgui_panellist.lua Normal file
View File

@@ -0,0 +1,180 @@
--[[
| 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 = {}
function PANEL:Init()
self.pnlCanvas = vgui.Create( "Panel", self )
self.Items = {}
self.YOffset = 0
self:SetSpacing( 0 )
self:SetPadding( 4 )
self:EnableHorizontal( false )
self.BackgroundColor = Color( 0, 0, 0, 200 )
end
function PANEL:EnableHorizontal( bHoriz )
self.Horizontal = bHoriz
end
function PANEL:EnableVerticalScrollbar()
if ( IsValid( self.VBar ) ) then return end
self.VBar = vgui.Create( "SlideBar", self )
self:InvalidateLayout()
end
function PANEL:GetCanvas()
return self.pnlCanvas
end
function PANEL:Clear()
for k, panel in pairs( self.Items ) do
panel:Remove()
end
self.Items = {}
end
function PANEL:AddItem( item )
item:SetParent( self:GetCanvas() )
table.insert( self.Items, item )
self:InvalidateLayout()
end
function PANEL:Rebuild()
local Offset = 0
if ( self.Horizontal ) then
local x, y = 0, 0
for k, panel in pairs( self.Items ) do
local w = panel:GetWide()
local h = panel:GetTall()
if ( x + w > self:GetWide() ) then
x = 0
y = y + h + self.Spacing
end
panel:SetPos( x, y )
x = x + w + self.Spacing
Offset = y + h + self.Spacing
end
else
for k, panel in pairs( self.Items ) do
panel:SetSize( self:GetCanvas():GetWide(), panel:GetTall() )
panel:SetPos( 0, Offset )
Offset = Offset + panel:GetTall() + self.Spacing
end
end
self:GetCanvas():SetSize( self:GetCanvas():GetWide(), Offset + self.Padding * 2 - self.Spacing )
end
function PANEL:OnMouseWheeled( dlta )
if ( IsValid( self.VBar ) ) then
return self.VBar:AddVelocity( dlta )
end
end
function PANEL:Paint()
draw.RoundedBox( 4, 0, 0, self:GetWide(), self:GetTall(), self.BackgroundColor )
return true
end
function PANEL:SetSpacing( _num_ )
self.Spacing = _num_
end
function PANEL:SetPadding( _num_ )
self.Padding = _num_
end
function PANEL:Think()
if ( IsValid( self.VBar ) && self.VBar:Changed() ) then
local MaxOffset = self.pnlCanvas:GetTall() - self:GetTall()
self.YOffset = MaxOffset * self.VBar:Value()
self:InvalidateLayout()
end
end
function PANEL:PerformLayout()
local Wide = self:GetWide()
if ( IsValid( self.VBar ) ) then
self.VBar:SetPos( self:GetWide() - 18, 2 )
self.VBar:SetSize( 16, self:GetTall() - 4 )
self.VBar:SetBarScale( self.pnlCanvas:GetTall() / self:GetTall() )
if ( self.VBar.Enabled ) then Wide = Wide - 20 end
end
self.pnlCanvas:SetPos( self.Padding, self.YOffset * -1 + self.Padding )
self.pnlCanvas:SetSize( Wide - self.Padding * 2, self.pnlCanvas:GetTall() )
self:Rebuild()
end
function PANEL:OnMousePressed( mcode )
if ( mcode == MOUSE_RIGHT && IsValid( self.VBar ) ) then
self.VBar:Grip()
end
end
vgui.Register( "PanelList", PANEL, "Panel" )