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