--[[ | 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" )