Files
wnsrc/lua/vgui/fingervar.lua
lifestorm 6a58f406b1 Upload
2024-08-04 23:54:45 +03:00

178 lines
3.9 KiB
Lua

--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local 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" )