mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
2150 lines
62 KiB
Lua
2150 lines
62 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 settings
|
|
local bg_color = Color(255,255,255)
|
|
local slider_col = Color(91,156,214)
|
|
local b_alpha = Color(0,0,0,60)
|
|
local c_alpha = Color(0,0,0,20)
|
|
|
|
|
|
-- Add SF Setting vgui
|
|
local function empty() end
|
|
local function wrapText(sText, wide)
|
|
wide = wide - 10
|
|
local tw,th = surface.GetTextSize(language.GetPhrase(sText))
|
|
local lines,b = 1, false
|
|
local tab = {""}
|
|
for w in string.gmatch(sText, "[^%s,]+") do
|
|
local tt = tab[#tab] .. (b and " " or "") .. w
|
|
if surface.GetTextSize(tt) >= wide then
|
|
table.insert(tab, w)
|
|
lines = lines + 1
|
|
else
|
|
tab[#tab] = tt
|
|
end
|
|
b = true
|
|
end
|
|
return tab, lines
|
|
end
|
|
local function niceName(sName)
|
|
sName = string.Replace(sName, "_", " ")
|
|
local str = ""
|
|
for s in string.gmatch(sName, "[^%s]+") do
|
|
str = str .. string.upper(s[1]) .. string.sub(s, 2) .. " "
|
|
end
|
|
return string.TrimRight(str, " ")
|
|
end
|
|
-- function to overwrite the textentity, and display the current temp setting.
|
|
local function makeTempDisplay( panel )
|
|
panel._DrawTextEntryText = panel.DrawTextEntryText
|
|
function panel:DrawTextEntryText( ... )
|
|
local s = self:GetText()
|
|
self:SetText(s .. StormFox2.Temperature.GetDisplaySymbol())
|
|
self:_DrawTextEntryText( ... )
|
|
self:SetText(s)
|
|
end
|
|
end
|
|
|
|
-- Functions to convert the temperature to the clients settings
|
|
local function valToTemp( val )
|
|
return StormFox2.Temperature.GetDisplay(val) .. StormFox2.Temperature.GetDisplaySymbol()
|
|
end
|
|
|
|
local function tempToVal( val )
|
|
return StormFox2.Temperature.Convert(StormFox2.Temperature.GetDisplayType(),"celsius",val)
|
|
end
|
|
|
|
local function PaintOver(self, w, h)
|
|
--surface.SetDrawColor(color_black)
|
|
--surface.DrawOutlinedRect(0,0,w,h)
|
|
if not self.dMark then return end
|
|
local b = self.dMark - CurTime()
|
|
if b <= 0 then
|
|
self.dMark = nil
|
|
return
|
|
end
|
|
local a = math.sin(b * math.pi * 2 )
|
|
surface.SetDrawColor(0,0,0, a * 100)
|
|
surface.DrawRect(0,0,w,h)
|
|
end
|
|
|
|
local function FindPercent( x, a, b )
|
|
return (x - a) / (b - a)
|
|
end
|
|
|
|
local function FindPercentClam( x, a, b )
|
|
return math.Clamp(FindPercent( x, a, b ), 0, 1)
|
|
end
|
|
|
|
|
|
|
|
local vgui_Create
|
|
do
|
|
local function overrideConVar( PANEL )
|
|
function PANEL:SetConVar( sName )
|
|
self._sfobj = StormFox2.Setting.GetObject( sName )
|
|
end
|
|
function PANEL:ConVarChanged( strNewValue )
|
|
if not self._sfobj then return end
|
|
self._sfobj:SetFromString( strNewValue )
|
|
end
|
|
-- Todo: Think only every 0.1 seconds?
|
|
function PANEL:ConVarStringThink()
|
|
if not self._sfobj then return end
|
|
if self.m_LV ~= nil and self._sfobj:GetValue() == self.m_LV then return end
|
|
self.m_LV = self._sfobj:GetValue()
|
|
self:SetValue( self._sfobj:GetString() )
|
|
end
|
|
function PANEL:ConVarNumberThink()
|
|
if not self._sfobj then return end
|
|
if self.m_NV ~= nil and self._sfobj:GetValue() == self.m_NV then return end
|
|
self.m_NV = self._sfobj:GetValue()
|
|
self:SetValue( tonumber(num) )
|
|
end
|
|
end
|
|
local function overrideAll( PANEL )
|
|
if not IsValid( PANEL ) then return end
|
|
if PANEL.ConVarChanged then
|
|
overrideConVar(PANEL)
|
|
end
|
|
for _, v in ipairs( PANEL:GetChildren() ) do
|
|
overrideAll( v )
|
|
end
|
|
end
|
|
function vgui_Create( str_type, self )
|
|
local PANEL = vgui.Create( str_type, self )
|
|
-- Override convar functions
|
|
overrideAll(PANEL)
|
|
return PANEL
|
|
end
|
|
end
|
|
|
|
-- Title
|
|
do
|
|
local PANEL = {}
|
|
PANEL.PaintOver = PaintOver
|
|
derma.DefineControl( "SFTitle", "", PANEL, "DLabel" )
|
|
end
|
|
-- Slider
|
|
do
|
|
local cir_size = 14
|
|
local barSize = 6
|
|
local shadowSize = 18
|
|
local sh = Material("vgui/slider")
|
|
local barSpace = 7
|
|
|
|
local PANEL = {}
|
|
AccessorFunc(PANEL, "min", "Min")
|
|
AccessorFunc(PANEL, "max", "Max")
|
|
AccessorFunc(PANEL, "value", "Value")
|
|
AccessorFunc(PANEL, "float", "Float")
|
|
-- Make sure we set a flag, if edited
|
|
function PANEL:SetMin( v )
|
|
self._set = true
|
|
self.min = v
|
|
end
|
|
function PANEL:SetMax( v )
|
|
self._set = true
|
|
self.max = v
|
|
end
|
|
function PANEL:Init()
|
|
self:SetValue( -1 )
|
|
self:SetMin(0)
|
|
self:SetMax(1)
|
|
self._set = false -- Reset flag
|
|
self:SetCursor( "hand" )
|
|
self._flagOff = false
|
|
end
|
|
function PANEL:GetValueFromPercent( p )
|
|
local range = self:GetMax() - self:GetMin()
|
|
return self:GetMin() + range * p
|
|
end
|
|
function PANEL:GetPercentFromValue( var )
|
|
return FindPercentClam( var, self:GetMin(), self:GetMax() )
|
|
end
|
|
function PANEL:GetPercentFromPoint( xPos )
|
|
local bar_width = self:GetWide() - barSpace * 2
|
|
local range = self:GetMax() - self:GetMin()
|
|
return math.Clamp((xPos - barSpace) / bar_width, 0, 1)
|
|
end
|
|
function PANEL:GetPointFromPercent( p )
|
|
local bar_width = self:GetWide() - barSpace * 2
|
|
return barSpace + bar_width * p
|
|
end
|
|
local m_cir = Material("vgui/circle")
|
|
|
|
-- Tells the slider that -1, is used to indecate it can be turned off
|
|
function PANEL:SetFlagOff( bool )
|
|
self._flagOff = bool
|
|
self:SetMin(0)
|
|
end
|
|
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
self._sfobj = StormFox2.Setting.GetObject( sName )
|
|
if not self._sfobj then return end
|
|
-- If we haven't edited the min / max, then use the convars setting. If not then make a range.
|
|
local min = self._set and self:GetMin() or self._sfobj:GetMin() or 0
|
|
local max = self._set and self:GetMax() or self._sfobj:GetMax() or self._sfobj:GetDefault() or 1
|
|
if self._flagOff then
|
|
self:SetMin(0)
|
|
else
|
|
self:SetMin(min)
|
|
end
|
|
self:SetMax(max)
|
|
local target = math.Clamp(self._sfobj:GetValue(), min, max)
|
|
self:SetValue(target)
|
|
end
|
|
|
|
function PANEL:Think()
|
|
if not self._sfobj then return end
|
|
local range = self:GetMax() - self:GetMin()
|
|
local target = self._sfobj:GetValue()
|
|
if self._flagOff and target <= 0 then
|
|
target = 0
|
|
end
|
|
local delta = math.abs(self:GetValue() - target)
|
|
self:SetValue( math.Approach(self:GetValue(), target, FrameTime() * math.max(range * 0.1, delta * 10)) )
|
|
end
|
|
|
|
function PANEL:OnMousePressed( keyCode )
|
|
if keyCode ~= MOUSE_LEFT then return end
|
|
self._down = true
|
|
self:MouseCapture( true )
|
|
end
|
|
|
|
function PANEL:OnMouseReleased( keyCode )
|
|
if keyCode == MOUSE_RIGHT then
|
|
local menu = DermaMenu(false, self)
|
|
menu:AddOption( "Reset", function()
|
|
self._sfobj:Revert()
|
|
end):SetIcon( "icon16/package.png" )
|
|
menu:Open()
|
|
return true
|
|
elseif keyCode == MOUSE_LEFT then
|
|
if not self._down then return end
|
|
self._down = false
|
|
self:MouseCapture( false )
|
|
if not self._sfobj then return end
|
|
|
|
local val = self:GetValueFromPercent(self:GetPercentFromPoint( self:CursorPos() ))
|
|
if not self:GetFloat() then
|
|
val = math.Round(val, 0)
|
|
else
|
|
val = math.Round(val, 3)
|
|
end
|
|
self._sfobj:SetValue(val)
|
|
self:SetValue(val)
|
|
end
|
|
end
|
|
function PANEL:Paint(w, h)
|
|
local bar_width = w - barSpace * 2
|
|
local bar_y = math.Round(h / 2)
|
|
local val
|
|
local min, max = self:GetMin(), self:GetMax()
|
|
if self._flagOff and self:GetValue() < 0 then
|
|
val = 0
|
|
elseif self._down then
|
|
val = self:GetValueFromPercent(self:GetPercentFromPoint( self:CursorPos() ))
|
|
if not self:GetFloat() then
|
|
self._downvalue = math.Clamp(math.Round(val), min, max)
|
|
else
|
|
self._downvalue = math.Clamp(math.Round(val,3), min, max)
|
|
end
|
|
elseif self:GetValue() < 0 and false then -- Unset
|
|
local p = ((math.sin(SysTime() * 3) + 1) / 2)
|
|
val = min + p * max
|
|
else
|
|
val = self:GetValue()
|
|
end
|
|
local percentage = FindPercentClam( val , self:GetMin() or 0, max or 1 )
|
|
if percentage < 1 then
|
|
draw.RoundedBox(30, barSpace, bar_y - barSize / 2, bar_width ,barSize, b_alpha)
|
|
end
|
|
if percentage > 0 then
|
|
draw.RoundedBox(30, barSpace, bar_y - barSize / 2, bar_width * percentage, barSize, slider_col)
|
|
end
|
|
|
|
local cir_x = self:GetPointFromPercent( percentage )
|
|
surface.SetMaterial(sh)
|
|
surface.SetDrawColor(c_alpha)
|
|
surface.DrawTexturedRectRotated(cir_x, bar_y, shadowSize, shadowSize,0)
|
|
surface.DrawTexturedRectRotated(cir_x, bar_y, shadowSize + 2, shadowSize + 2,0)
|
|
surface.SetMaterial(m_cir)
|
|
if self._down then
|
|
surface.SetDrawColor(slider_col)
|
|
else
|
|
surface.SetDrawColor(bg_color)
|
|
end
|
|
surface.DrawTexturedRectRotated(cir_x, bar_y, cir_size, cir_size,0)
|
|
end
|
|
derma.DefineControl( "SF_Slider", "", PANEL, "DPanel" )
|
|
|
|
-- DoubleSlider
|
|
local PANEL = {}
|
|
AccessorFunc(PANEL, "min", "Min")
|
|
AccessorFunc(PANEL, "max", "Max")
|
|
AccessorFunc(PANEL, "value", "MinValue")
|
|
AccessorFunc(PANEL, "value2", "MaxValue")
|
|
AccessorFunc(PANEL, "float", "Float")
|
|
function PANEL:Init()
|
|
self:SetMinValue( 0 )
|
|
self:SetMaxValue( 0 )
|
|
self:SetMin(0)
|
|
self:SetMax(1)
|
|
self:SetCursor( "hand" )
|
|
end
|
|
local m_cir = Material("vgui/circle")
|
|
|
|
function PANEL:SetSettingMin( sName, sType, Description )
|
|
self._sfobj = StormFox2.Setting.GetObject( sName )
|
|
if not self._sfobj then return end
|
|
local min = self._sfobj:GetMin() or self:GetMin() or 0
|
|
self:SetMin(min)
|
|
self:SetMax(math.max(min, self:GetMax() or 1))
|
|
end
|
|
|
|
function PANEL:SetSettingMax( sName, sType, Description )
|
|
self._sfobj2 = StormFox2.Setting.GetObject( sName )
|
|
if not self._sfobj2 then return end
|
|
local max = self._sfobj:GetMax() or self:GetMax() or 1
|
|
self:SetMax(max)
|
|
self:SetMin(max, self:GetMax() or 1)
|
|
end
|
|
|
|
function PANEL:Think()
|
|
if not self._sfobj then return end
|
|
if not self._sfobj2 then return end
|
|
local range = self:GetMax() - self:GetMin()
|
|
-- Min
|
|
local delta = math.abs(self:GetMinValue() - self._sfobj:GetValue())
|
|
self:SetMinValue( math.Approach(self:GetMinValue(), self._sfobj:GetValue(), FrameTime() * math.max(range * 0.1, delta * 10)) )
|
|
-- Max
|
|
local delta = math.abs(self:GetMaxValue() - self._sfobj2:GetValue())
|
|
self:SetMaxValue( math.Approach(self:GetMaxValue(), self._sfobj2:GetValue(), FrameTime() * math.max(range * 0.1, delta * 10)) )
|
|
end
|
|
|
|
local cir_size = 14
|
|
local barSize = 6
|
|
local shadowSize = 18
|
|
local sh = Material("vgui/slider")
|
|
local barSpace = 7
|
|
function PANEL:OnMousePressed( keyCode )
|
|
if keyCode ~= MOUSE_LEFT then return end
|
|
-- Select the closest type
|
|
local cur_p = self:GetPercentFromPoint( self:CursorPos() )
|
|
local percentage = FindPercentClam( (self:GetMinValue() + self:GetMaxValue()) / 2 , self:GetMin() or 0, self:GetMax() or 1 ) -- Center
|
|
if cur_p < percentage then
|
|
self._down = 1 -- Min
|
|
else
|
|
self._down = 2 -- Max
|
|
end
|
|
self:MouseCapture( true )
|
|
end
|
|
function PANEL:OnMouseReleased( keyCode )
|
|
if keyCode ~= MOUSE_LEFT then return end
|
|
if not self._down then return end
|
|
|
|
self:MouseCapture( false )
|
|
if not self._sfobj then return end
|
|
|
|
local val = self:GetValueFromPercent(self:GetPercentFromPoint( self:CursorPos() ))
|
|
if not self:GetFloat() then
|
|
val = math.Round(val, 0)
|
|
else
|
|
val = math.Round(val, 3)
|
|
end
|
|
if self._down == 0 then
|
|
self._sfobj:SetValue(val)
|
|
self:SetMinValue(val)
|
|
else
|
|
self._sfobj2:SetValue(val)
|
|
self:SetMaxValue(val)
|
|
end
|
|
self._down = false
|
|
end
|
|
function PANEL:Paint(w, h)
|
|
local bar_width = w - barSpace * 2
|
|
local bar_y = math.Round(h / 2)
|
|
local valMin, valMax = self:GetMinValue(), self:GetMaxValue()
|
|
if self._down then
|
|
local val = self:GetValueFromPercent(self:GetPercentFromPoint( self:CursorPos() ))
|
|
if not self:GetFloat() then
|
|
self._downvalue = math.Clamp(math.Round(val), self:GetMin(), self:GetMax())
|
|
else
|
|
self._downvalue = math.Clamp(math.Round(val,3), self:GetMin(), self:GetMax())
|
|
end
|
|
if self._down == 1 then
|
|
valMin = val
|
|
else
|
|
valMax = val
|
|
end
|
|
end
|
|
local minP = FindPercentClam( valMin , self:GetMin() or 0, self:GetMax() or 1 )
|
|
local maxP = FindPercentClam( valMax , self:GetMin() or 0, self:GetMax() or 1 )
|
|
|
|
-- BG bar
|
|
draw.RoundedBox(30, barSpace, bar_y - barSize / 2, bar_width ,barSize, b_alpha)
|
|
|
|
local cir_x = self:GetPointFromPercent( minP )
|
|
local cir_x2 = self:GetPointFromPercent( maxP )
|
|
|
|
draw.RoundedBox(30, cir_x, bar_y - barSize / 2, cir_x2 - cir_x, barSize, slider_col)
|
|
|
|
-- Min
|
|
surface.SetMaterial(sh)
|
|
surface.SetDrawColor(c_alpha)
|
|
surface.DrawTexturedRectRotated(cir_x, bar_y, shadowSize, shadowSize,0)
|
|
surface.DrawTexturedRectRotated(cir_x, bar_y, shadowSize + 2, shadowSize + 2,0)
|
|
surface.SetMaterial(m_cir)
|
|
if self._down then
|
|
surface.SetDrawColor(slider_col)
|
|
else
|
|
surface.SetDrawColor(bg_color)
|
|
end
|
|
surface.DrawTexturedRectRotated(cir_x, bar_y, cir_size, cir_size,0)
|
|
-- Max
|
|
surface.SetMaterial(sh)
|
|
surface.SetDrawColor(c_alpha)
|
|
surface.DrawTexturedRectRotated(cir_x2, bar_y, shadowSize, shadowSize,0)
|
|
surface.DrawTexturedRectRotated(cir_x2, bar_y, shadowSize + 2, shadowSize + 2,0)
|
|
surface.SetMaterial(m_cir)
|
|
if self._down then
|
|
surface.SetDrawColor(slider_col)
|
|
else
|
|
surface.SetDrawColor(bg_color)
|
|
end
|
|
surface.DrawTexturedRectRotated(cir_x2, bar_y, cir_size, cir_size,0)
|
|
end
|
|
derma.DefineControl( "SF_DoubleSlider", "", PANEL, "SF_Slider" )
|
|
end
|
|
-- Description Box
|
|
do
|
|
local lineHeight
|
|
local function getLineHeight()
|
|
if lineHeight then return lineHeight end
|
|
local ws,hs = surface.GetTextSize("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
|
lineHeight = hs
|
|
return hs
|
|
end
|
|
local PANEL = {}
|
|
function PANEL:Init()
|
|
self.t_text = {}
|
|
self.text = "No description"
|
|
self.font = "DermaDefault"
|
|
self.strikeout = false
|
|
end
|
|
function PANEL:SetFont( str )
|
|
self.font = str
|
|
end
|
|
function PANEL:SetStrikeOut( b )
|
|
self.strikeout = b
|
|
end
|
|
function PANEL:SetText( str )
|
|
self.text = str
|
|
surface.SetFont(self.font)
|
|
local t_text, lines = wrapText(str, self:GetWide())
|
|
self:SetTall(lines * getLineHeight())
|
|
self.t_text = t_text
|
|
end
|
|
function PANEL:PerformLayout(w, h)
|
|
surface.SetFont(self.font)
|
|
local t_text, lines = wrapText(self.text, w)
|
|
self:SetTall(lines * getLineHeight())
|
|
self.t_text = t_text
|
|
end
|
|
function PANEL:GetTextLines()
|
|
if not self.t_text then return 1 end
|
|
return math.max(1, #self.t_text)
|
|
end
|
|
function PANEL:Paint(w, h)
|
|
surface.SetDrawColor(color_white)
|
|
surface.DrawRect(0,0,w,h)
|
|
surface.SetFont(self.font)
|
|
surface.SetTextColor(color_black)
|
|
local lh = getLineHeight()
|
|
for y, str in ipairs( self.t_text ) do
|
|
local z = (y - 1) * lh
|
|
surface.SetTextPos(0, z )
|
|
surface.DrawText( str )
|
|
if self.strikeout then
|
|
surface.SetDrawColor(color_black)
|
|
local wide = #self.t_text > 1 and w or surface.GetTextSize(str)
|
|
local c = z + lh / 2 + 1
|
|
surface.DrawLine(0, c, wide, c)
|
|
end
|
|
end
|
|
end
|
|
derma.DefineControl( "SF2_TextBox", "", PANEL, "DPanel" )
|
|
end
|
|
-- Setting Tab
|
|
do
|
|
local PANEL = {}
|
|
PANEL.PaintOver = PaintOver
|
|
--PANEL.Paint = empty
|
|
function PANEL:Init()
|
|
self:DockMargin(5,0,10,0)
|
|
local label_name = vgui_Create( "DLabel", self )
|
|
label_name:SetText("Unknown Setting")
|
|
label_name:SetColor(color_black)
|
|
label_name:SetFont("DermaDefaultBold")
|
|
label_name:SizeToContents()
|
|
label_name:Dock(TOP)
|
|
self.label_name = label_name
|
|
local description = vgui_Create( "SF2_TextBox", self )
|
|
description:SetText("No description.")
|
|
description:SetPos(25, label_name:GetTall() + 2)
|
|
self.description = description
|
|
self._SetSetting = self.SetSetting
|
|
self:DockMargin(15,0,15,5)
|
|
self._cross = false
|
|
end
|
|
function PANEL:SetStrikeOut( b )
|
|
self.description:SetStrikeOut( b )
|
|
end
|
|
function PANEL:SetTitle( str )
|
|
self.label_name:SetText( language.GetPhrase(str) or str )
|
|
end
|
|
function PANEL:SetDescription( str )
|
|
self.description:SetText( language.GetPhrase(str) or str )
|
|
end
|
|
function PANEL:PerformLayout(w, h)
|
|
local maxH = 0
|
|
local x = self.description:GetPos()
|
|
self.description:SetWide(w - x)
|
|
for _, v in ipairs( self:GetChildren() ) do
|
|
local x, y = v:GetPos()
|
|
maxH = math.max(maxH, y + v:GetTall())
|
|
end
|
|
if h == maxH then return end
|
|
self:SetTall(maxH + 5)
|
|
end
|
|
function PANEL:HideTitle( bool )
|
|
if bool == false then
|
|
self.label_name:Show()
|
|
for _, v in ipairs( self:GetChildren() ) do
|
|
local x, y = v:GetPos()
|
|
v:SetPos(x, y + self.label_name:GetTall())
|
|
end
|
|
else
|
|
self.label_name:Hide()
|
|
for _, v in ipairs( self:GetChildren() ) do
|
|
local x, y = v:GetPos()
|
|
v:SetPos(x, y - self.label_name:GetTall())
|
|
end
|
|
end
|
|
self:InvalidateLayout()
|
|
return self
|
|
end
|
|
PANEL.Paint = empty
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
sType = sType or StormFox2.Setting.GetType( sName )
|
|
local obj = StormFox2.Setting.GetObject( sName )
|
|
local tName = Description and "#" .. Description or (obj and "sf_" .. obj:GetName()) or "Unknown"
|
|
self.label_name:SetText( language.GetPhrase(tName) or tName )
|
|
self.description:SetText( language.GetPhrase(tName .. ".desc") or "Unknown" )
|
|
for _, v in ipairs( self:GetChildren() ) do
|
|
if not v.SetSetting then continue end
|
|
v:SetSetting( sName, sType, Description )
|
|
end
|
|
end
|
|
function PANEL:MoveDescription( x, y )
|
|
if y then
|
|
self.description:SetPos( math.max(25, 10 + x), self.label_name:GetTall() + math.max(2, y) )
|
|
else
|
|
local x2, y2 = self.description:GetPos()
|
|
self.description:SetPos( math.max(25, 10 + x), y2 )
|
|
end
|
|
end
|
|
derma.DefineControl( "SF_Setting", "", PANEL, "DPanel" )
|
|
end
|
|
|
|
-- Boolean setting
|
|
do
|
|
local PANEL = {}
|
|
function PANEL:Init()
|
|
self.check = vgui_Create("DCheckBox", self)
|
|
self.check:SetPos(5,14)
|
|
function self.check:DoClick() -- If we're a radio-type. Never turn off.
|
|
if not self._sfobj then return end
|
|
if self:GetChecked() and self._block then return end
|
|
self._sfobj:SetValue( not self:GetChecked() )
|
|
end
|
|
function self.check:DragMousePress( keyCode )
|
|
if keyCode ~= MOUSE_RIGHT then return end
|
|
local menu = DermaMenu(false, self)
|
|
menu:AddOption( "Reset", function()
|
|
self._sfobj:Revert()
|
|
end):SetIcon( "icon16/package.png" )
|
|
menu:Open()
|
|
end
|
|
function self.check:Think()
|
|
if not self._sfobj then return end
|
|
self:SetChecked(self._sfobj:GetValue())
|
|
end
|
|
end
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
self:_SetSetting( sName, sType, Description ) -- Set title and textbox
|
|
self.check._sfobj = StormFox2.Setting.GetObject(sName)
|
|
self.check._block = self.check._sfobj:IsRadio()
|
|
|
|
end
|
|
derma.DefineControl( "SF_Setting_Bool", "", PANEL, "SF_Setting" )
|
|
end
|
|
|
|
-- String setting
|
|
do
|
|
local PANEL = {}
|
|
function PANEL:Init()
|
|
self.text = vgui_Create("DTextEntry", self)
|
|
self.text:SetPos(5,14)
|
|
self.text:SetWide(120)
|
|
self:MoveDescription(120)
|
|
end
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
self:_SetSetting( sName, sType, Description ) -- Set title and textbox
|
|
self.text:SetConVar( sName )
|
|
return self
|
|
end
|
|
derma.DefineControl( "SF_Setting_String", "", PANEL, "SF_Setting" )
|
|
end
|
|
|
|
-- Float setting
|
|
local barLength = 220 + 50
|
|
do
|
|
local PANEL = {}
|
|
function PANEL:Init()
|
|
self.text = vgui_Create("DTextEntry", self)
|
|
self.text:SetNumeric(true)
|
|
self.text:SetDrawLanguageID( false )
|
|
self.slider = vgui_Create("SF_Slider", self)
|
|
self.slider:SetPos(5,14)
|
|
self.slider:SetWide(barLength)
|
|
self.slider:SetFloat(true)
|
|
self.text:SetPos(barLength + 8,18)
|
|
self.text:SetSize(55,18)
|
|
self:MoveDescription(barLength + 60, 6)
|
|
self._isTemp = false
|
|
end
|
|
function PANEL:SetMin( v )
|
|
self.slider:SetMin( v )
|
|
return self
|
|
end
|
|
function PANEL:SetMax( v )
|
|
self.slider:SetMax( v )
|
|
return self
|
|
end
|
|
function PANEL:SetTemperature(bool)
|
|
self._isTemp = bool
|
|
return self
|
|
end
|
|
function PANEL:Think()
|
|
if not self._sfobj then return end
|
|
if self.slider._down and self.slider._downvalue then
|
|
local text
|
|
if self._isTemp then
|
|
text = self.slider._downvalue and valToTemp(self.slider._downvalue) or "?"
|
|
else
|
|
text = self.slider._downvalue
|
|
end
|
|
self.text:SetText(text)
|
|
elseif not self.text:IsEditing() then
|
|
local text
|
|
if self._flagoff and self._sfobj:GetValue() <= (self._sfobj:GetMin() or -1) then
|
|
text = ""
|
|
elseif self._isTemp then
|
|
text = valToTemp(self._sfobj:GetValue())
|
|
else
|
|
text = self._sfobj:GetValue()
|
|
end
|
|
self.text:SetText(text)
|
|
end
|
|
end
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
local _sfobj = StormFox2.Setting.GetObject( sName )
|
|
self._sfobj = _sfobj
|
|
self:_SetSetting( sName, sType, Description ) -- Set title and textbox
|
|
--self.text:SetConVar( sName )
|
|
function self.text:OnEnter( val )
|
|
val = string.match(val, "[%d%.-]+") or val
|
|
if _sfobj:GetMin() then
|
|
val = math.max(_sfobj:GetMin(), val)
|
|
end
|
|
if _sfobj:GetMax() then
|
|
val = math.min(_sfobj:GetMax(), val)
|
|
end
|
|
_sfobj:SetValue(val)
|
|
self:SetText(tostring(val))
|
|
end
|
|
return self
|
|
end
|
|
derma.DefineControl( "SF_Setting_Float", "", PANEL, "SF_Setting" )
|
|
end
|
|
-- Int setting
|
|
do
|
|
local PANEL = {}
|
|
function PANEL:Init()
|
|
self.text = vgui_Create("DTextEntry", self)
|
|
self.text:SetNumeric(true)
|
|
self.text:SetDrawLanguageID( false )
|
|
self.slider = vgui_Create("SF_Slider", self)
|
|
self.slider:SetPos(5,14)
|
|
self.slider:SetWide(barLength)
|
|
self.text:SetPos(barLength + 8,18)
|
|
self.text:SetSize(55,18)
|
|
self:MoveDescription(barLength + 60, 6)
|
|
self._isTemp = false
|
|
end
|
|
function PANEL:SetMin( v )
|
|
self.slider:SetMin( v )
|
|
return self
|
|
end
|
|
function PANEL:SetMax( v )
|
|
self.slider:SetMax( v )
|
|
return self
|
|
end
|
|
function PANEL:SetTemperature(bool)
|
|
self._isTemp = bool
|
|
return self
|
|
end
|
|
function PANEL:Think()
|
|
if not self._sfobj then return end
|
|
if self.slider._down and self.slider._downvalue then
|
|
local text
|
|
if self._isTemp then
|
|
text = self.slider._downvalue and valToTemp(self.slider._downvalue) or "?"
|
|
else
|
|
text = self.slider._downvalue
|
|
end
|
|
self.text:SetText(text)
|
|
elseif not self.text:IsEditing() then
|
|
local text
|
|
if self._isTemp then
|
|
text = valToTemp(self._sfobj:GetValue())
|
|
else
|
|
text = self._sfobj:GetValue()
|
|
end
|
|
self.text:SetText(text)
|
|
end
|
|
end
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
local _sfobj = StormFox2.Setting.GetObject( sName )
|
|
self._sfobj = _sfobj
|
|
self:_SetSetting( sName, sType, Description ) -- Set title and textbox
|
|
--self.text:SetConVar( sName )
|
|
function self.text:OnEnter( val )
|
|
val = string.match(val, "[%d%.-]+") or val
|
|
local clamp = tonumber( val ) or 0
|
|
if _sfobj:GetMax() then
|
|
clamp = math.min(clamp, _sfobj:GetMax())
|
|
end
|
|
if _sfobj:GetMin() then
|
|
clamp = math.max(clamp, _sfobj:GetMin())
|
|
end
|
|
_sfobj:SetValue(clamp)
|
|
self:SetText(tostring(clamp))
|
|
end
|
|
return self
|
|
end
|
|
derma.DefineControl( "SF_Setting_Int", "", PANEL, "SF_Setting" )
|
|
end
|
|
-- Table / Enums
|
|
do
|
|
local sortNum = function(a,b)
|
|
if type(a) == "boolean" then
|
|
return a or b
|
|
end
|
|
return a>b
|
|
end
|
|
local sortStr = function(a,b) return a<b end
|
|
|
|
local PANEL = {}
|
|
function PANEL:Init()
|
|
self.cbox = vgui_Create("DComboBox", self)
|
|
self.cbox:SetPos(5,14)
|
|
self.cbox:SetSize(80,20)
|
|
self:MoveDescription(80)
|
|
end
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
sType = sType or StormFox2.Setting.GetType( sName )
|
|
local tab, sortorder = sType[1], sType[2]
|
|
self._options = tab
|
|
self:_SetSetting( sName, sType, Description ) -- Set title and textbox
|
|
self.cbox:SetConVar( sName )
|
|
local options = table.GetKeys( tab )
|
|
local _sfobj = StormFox2.Setting.GetObject( sName )
|
|
self._sfobj = _sfobj
|
|
local s_type = type(_sfobj:GetValue())
|
|
local sort_func = (s_type == "number" or s_type == "boolean") and sortNum or sortStr
|
|
-- Change width to match the options
|
|
do
|
|
surface.SetFont("DermaDefault")
|
|
local width = 80 -- Min size
|
|
for k,v in pairs(options) do
|
|
local text = niceName( language.GetPhrase(tab[v]) )
|
|
local tw = surface.GetTextSize(text) + 24
|
|
width = math.max(width, tw)
|
|
end
|
|
self.cbox:SetWide(width)
|
|
self:MoveDescription(width)
|
|
end
|
|
if not sortorder then -- We don't have an order
|
|
table.sort(options, sort_func)
|
|
for k,v in ipairs(options) do
|
|
local text = niceName( language.GetPhrase(tab[v]))
|
|
self.cbox:AddChoice( text, v, _sfobj:GetValue() == v )
|
|
end
|
|
else
|
|
for _,v in ipairs(sortorder) do
|
|
local text = niceName( language.GetPhrase(tab[v] or "UNKNOWN"))
|
|
self.cbox:AddChoice( text, v, _sfobj:GetValue() == v )
|
|
end
|
|
if #sortorder ~= #tab then -- Add the rest
|
|
table.sort(options, sort_func)
|
|
for _,v in ipairs(options) do
|
|
if table.HasValue(sortorder, v) then continue end
|
|
local text = niceName( language.GetPhrase(tab[v]))
|
|
self.cbox:AddChoice( text, v, _sfobj:GetValue() == v )
|
|
end
|
|
end
|
|
end
|
|
function self.cbox:OnSelect( index, text, data )
|
|
if not data then data = false end -- Somehow, false doesn't get returned
|
|
_sfobj:SetValue(data)
|
|
end
|
|
return self
|
|
end
|
|
function PANEL:Think()
|
|
if not self._sfobj or not self._options then return end
|
|
self.cbox:SetText(self._options[self._sfobj:GetValue()] or "?")
|
|
end
|
|
derma.DefineControl( "SF_Setting_Enum", "", PANEL, "SF_Setting" )
|
|
end
|
|
-- Float-Special (CheckBox makes it lowest or -1)
|
|
do
|
|
local PANEL = {}
|
|
local OldPanel = vgui.GetControlTable("SF_Setting_Float")
|
|
local mat = Material("icon16/cross.png")
|
|
function PANEL:Init()
|
|
self.check = vgui_Create("DCheckBox", self)
|
|
self.check:SetPos(5,18)
|
|
self.slider:SetPos(5 + 18,14)
|
|
self.text:SetPos(barLength + 8,18)
|
|
self.slider:SetWide(barLength - 18)
|
|
self.slider:SetFlagOff( true ) -- Tells the slider that anything below -1, is disabled
|
|
self._flagoff = true
|
|
function self.text:PaintOver(w,h)
|
|
if #self:GetText() > 0 or self:IsHovered() then return end
|
|
surface.SetMaterial(mat)
|
|
surface.SetDrawColor(color_white)
|
|
surface.DrawTexturedRect(w / 2 - 8, h / 2 - 8, 16, 16)
|
|
end
|
|
function self.check:DoClick() -- If we're a radio-type. Never turn off.
|
|
if self:GetChecked() and self._block then return end
|
|
self:Toggle()
|
|
end
|
|
self:MoveDescription(barLength + 60, 6)
|
|
end
|
|
function PANEL:SetMin( v )
|
|
self.slider:SetMin( v )
|
|
return self
|
|
end
|
|
function PANEL:SetMax( v )
|
|
self.slider:SetMax( v )
|
|
return self
|
|
end
|
|
function PANEL:Think()
|
|
if not self._sfobj then return end
|
|
OldPanel["Think"](self)
|
|
local min = self._sfobj:GetMin() or -1
|
|
self.check:SetChecked(self._sfobj:GetValue() > min)
|
|
end
|
|
|
|
function PANEL:SetDefaultEnable( var )
|
|
self.defaultEnable = var
|
|
end
|
|
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
self:_SetSetting( sName, sType, Description ) -- Set title and textbox
|
|
local _sfobj = StormFox2.Setting.GetObject( sName )
|
|
self._sfobj = _sfobj
|
|
--self.text:SetConVar( sName )
|
|
self.check._block = _sfobj:IsRadio()
|
|
function self.text:OnEnter( val )
|
|
val = tonumber( string.match(val, "[%d%.-]+") or val ) or 0
|
|
if _sfobj:GetMin() then
|
|
val = math.max(_sfobj:GetMin(), val)
|
|
end
|
|
if _sfobj:GetMax() then
|
|
val = math.min(_sfobj:GetMax(), val)
|
|
end
|
|
_sfobj:SetValue(val)
|
|
self:SetText(tostring(val))
|
|
end
|
|
local mainPanel = self
|
|
function self.check:DoClick()
|
|
local min = _sfobj:GetMin() or -1
|
|
local b = _sfobj:GetValue() > 0
|
|
if b then
|
|
_sfobj:SetValue(min)
|
|
else
|
|
local n = math.max(mainPanel.defaultEnable or _sfobj:GetDefault(), 1)
|
|
_sfobj:SetValue(n)
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
derma.DefineControl( "SF_Setting_FloatSpecial", "", PANEL, "SF_Setting_Float" )
|
|
end
|
|
-- Time Object
|
|
local PANEL = {}
|
|
local function OnMousePressed( self, mcode )
|
|
if ( mcode == MOUSE_LEFT ) then
|
|
self:OnGetFocus()
|
|
else
|
|
local menu = DermaMenu(false, self.base)
|
|
local obj = StormFox2.Setting.GetObject("12h_display")
|
|
local text = (obj:GetValue() and "24-" or "12-") .. language.GetPhrase("clock")
|
|
menu:AddOption( text, function()
|
|
obj:SetValue( not obj:GetValue())
|
|
end):SetIcon( "icon16/clock.png" )
|
|
return true
|
|
end
|
|
end
|
|
local function NewPaint(self, w, h, off)
|
|
surface.SetFont("SF2_TimeSet")
|
|
local tex = (self:GetValue() or "")
|
|
local tw,th = surface.GetTextSize(tex)
|
|
|
|
surface.SetTextColor(self.color or color_black)
|
|
surface.SetTextPos(w / 2 - tw / 2,h / 2 - th / 2)
|
|
|
|
if self:HasFocus() then
|
|
local e = (math.Round(SysTime() % 1) == 1 and "_" or "")
|
|
surface.DrawText( tex .. e )
|
|
else
|
|
surface.DrawText( tex )
|
|
end
|
|
end
|
|
|
|
function PANEL:BGThink()
|
|
if self.lastDisplay ~= cDis then
|
|
self:InvalidateLayout()
|
|
self.lastDisplay = cDis
|
|
end
|
|
local _12 = StormFox2.Setting.Get("12h_display")
|
|
if not self.hour:IsEditing() and not self.hour._SETONLOST then
|
|
local h = StormFox2.Time.GetHours( self.value, _12 )
|
|
if h < 10 then h = "0" .. h end
|
|
self.hour:SetText(h)
|
|
end
|
|
if not self.min:IsEditing() then
|
|
local m = StormFox2.Time.GetMinutes( self.value )
|
|
if m < 10 then m = "0" .. m end
|
|
self.min:SetText(m)
|
|
end
|
|
if _12 then
|
|
self.ampm:SetText( StormFox2.Time.GetAMPM() )
|
|
end
|
|
end
|
|
|
|
function PANEL:Init()
|
|
self.bg = vgui_Create("DPanel",self)
|
|
function self.bg:IsSelected() return false end
|
|
function self.bg:GetToggle() return false end
|
|
local hour = vgui.Create("DTextEntry", self.bg)
|
|
self.hour = hour
|
|
local min = vgui.Create("DTextEntry", self.bg)
|
|
self.min = min
|
|
self.ampm = vgui.Create("DButton", self)
|
|
function self.bg:Paint( w, h )
|
|
local cDis = StormFox2.Setting.Get("12h_display")
|
|
self.Hovered = hour.Hovered or min.Hovered
|
|
self.Depressed= hour:IsEditing() or min:IsEditing()
|
|
derma.SkinHook( "Paint", "Button", self, w, h )
|
|
surface.SetFont("SF2_TimeSet")
|
|
local tw,th = surface.GetTextSize(":")
|
|
|
|
surface.SetTextColor(self.color or color_black)
|
|
surface.SetTextPos(w / 2 - tw / 2,h / 2 - th / 2 - 2)
|
|
surface.DrawText(":")
|
|
end
|
|
function self.bg:IsHovered()
|
|
return hour:IsHovered() or min:IsHovered()
|
|
end
|
|
function self.bg:IsDown()
|
|
return hour:IsEditing() or min:IsEditing()
|
|
end
|
|
function self.hour.OnGetFocus(self)
|
|
local tex = self._SETONFOC or ""
|
|
self:SetValue(tex)
|
|
self:SetCaretPos(#tex)
|
|
self._SETONFOC = nil
|
|
end
|
|
self.min.OnGetFocus = self.hour.OnGetFocus
|
|
function self.min:OnLoseFocus()
|
|
if hour._SETONLOST then -- hour got unset variables
|
|
self.base:_SetNewVar( )
|
|
hour._SETONLOST = nil
|
|
end
|
|
end
|
|
|
|
self.bg:SetPos( 2,0 )
|
|
self.hour:SetPos(0,0)
|
|
self.hour:SetWide(30)
|
|
self.hour:SetTall(30)
|
|
self.hour.Paint = NewPaint
|
|
self.hour.OnMousePressed = OnMousePressed
|
|
self.hour.base = self
|
|
self.min:SetPos(32,0)
|
|
self.min:SetWide(30)
|
|
self.min:SetTall(30)
|
|
self.min.Paint = NewPaint
|
|
self.min.OnMousePressed = OnMousePressed
|
|
self.min.base = self
|
|
|
|
self.ampm:SetPos(66 + 2,0)
|
|
self.ampm:SetWide(34)
|
|
self.ampm:SetTall(30)
|
|
self.ampm:SetFont("SF2_TimeSetAM")
|
|
self.ampm.base = self
|
|
if not StormFox2.Setting.Get("12h_display") then
|
|
self.ampm:Hide()
|
|
self.lastDisplay = false
|
|
else
|
|
self.lastDisplay = true
|
|
self.ampm:SetText("AM")
|
|
end
|
|
self.hour:SetDrawLanguageID( false )
|
|
self.min:SetDrawLanguageID( false )
|
|
self.hour:SetNumeric(true)
|
|
self.min:SetNumeric(true)
|
|
self:SetValue( 0 )
|
|
self:SetTall( 30 )
|
|
-- Logic
|
|
function self.hour:OnChange( str )
|
|
if #self:GetValue() <= 2 then return end
|
|
self._SETONLOST = self:GetValue():sub(0,2)
|
|
min._SETONFOC = self:GetValue():sub(3)
|
|
self:KillFocus()
|
|
min:RequestFocus()
|
|
self:SetText(self._SETONLOST )
|
|
end
|
|
function self.hour:OnEnter()
|
|
self.base:_SetNewVar()
|
|
end
|
|
self.min.OnEnter = self.hour.OnEnter
|
|
function self.ampm:DoClick()
|
|
self:SetText( self:GetText() == "AM" and "PM" or "AM")
|
|
self.base:_SetNewVar()
|
|
end
|
|
end
|
|
function PANEL:SetValue( num )
|
|
self.value = num
|
|
end
|
|
function PANEL:GetValue()
|
|
return self.value
|
|
end
|
|
function PANEL:_SetNewVar()
|
|
local str = self.hour:GetText() .. ":" .. self.min:GetText()
|
|
if StormFox2.Setting.Get("12h_display") then
|
|
str = str .. " " .. self.ampm:GetText()
|
|
end
|
|
self.value = StormFox2.Time.StringToTime( str )
|
|
self:OnNewValue( self.value )
|
|
end
|
|
PANEL.OnNewValue = function() end
|
|
PANEL.Paint = PANEL.BGThink
|
|
function PANEL:PerformLayout(pw, ph)
|
|
local w = (pw - 8) / 2
|
|
if StormFox2.Setting.Get("12h_display") then
|
|
w = (pw - 8) / 3
|
|
self.ampm:Show( )
|
|
else
|
|
self.ampm:Hide( true )
|
|
end
|
|
self.hour:SetWide(w)
|
|
self.min:SetWide(w)
|
|
self.ampm:SetWide(w)
|
|
|
|
self.bg:SetWide(w * 2)
|
|
self.bg:SetHeight( ph )
|
|
|
|
--self.hour:SetPos(0,0)
|
|
self.min:SetPos(w, 0)
|
|
self.ampm:SetPos(w * 2 + 6, 0)
|
|
self.hour:SetHeight( ph )
|
|
self.min:SetHeight( ph )
|
|
self.ampm:SetHeight( ph )
|
|
end
|
|
derma.DefineControl( "SF_TIME", "", PANEL, "DPanel" )
|
|
-- Time
|
|
do
|
|
local PANEL = {}
|
|
surface.CreateFont("SF2_TimeSet", {
|
|
font = "Arial", -- Use the font-name which is shown to you by your operating system Font Viewer, not the file name
|
|
extended = false,
|
|
size = 26,
|
|
weight = 50,
|
|
blursize = 0,
|
|
scanlines = 0,
|
|
antialias = true,
|
|
underline = false,
|
|
italic = false,
|
|
strikeout = false,
|
|
symbol = false,
|
|
rotary = false,
|
|
shadow = false,
|
|
additive = false,
|
|
outline = false,
|
|
} )
|
|
surface.CreateFont("SF2_TimeSetAM", {
|
|
font = "Arial", -- Use the font-name which is shown to you by your operating system Font Viewer, not the file name
|
|
extended = false,
|
|
size = 22,
|
|
weight = 50,
|
|
blursize = 0,
|
|
scanlines = 0,
|
|
antialias = true,
|
|
underline = false,
|
|
italic = false,
|
|
strikeout = false,
|
|
symbol = false,
|
|
rotary = false,
|
|
shadow = false,
|
|
additive = false,
|
|
outline = false,
|
|
} )
|
|
local function NewPaint(self, w, h, off)
|
|
surface.SetFont("SF2_TimeSet")
|
|
local tw,th = surface.GetTextSize("ABCDEFGHIJ")
|
|
|
|
surface.SetTextColor(color_black)
|
|
surface.SetTextPos(2,h / 2 - th / 2)
|
|
local tex = (self:GetValue() or "")
|
|
local e = (math.Round(SysTime() % 1) == 1 and "_" or "")
|
|
if self:HasFocus() and #tex < 2 then
|
|
surface.DrawText( tex .. e )
|
|
else
|
|
surface.DrawText( tex )
|
|
end
|
|
if self:HasFocus() and #tex == 2 then
|
|
local tw = surface.GetTextSize(tex:sub(0,1))
|
|
surface.SetTextPos(2 + tw,h / 2 - th / 2)
|
|
surface.DrawText( e )
|
|
end
|
|
end
|
|
local function OnMousePressed( self, mcode )
|
|
if ( mcode == MOUSE_LEFT ) then
|
|
self:OnGetFocus()
|
|
else
|
|
local menu = DermaMenu(false, self)
|
|
local obj = StormFox2.Setting.GetObject("12h_display")
|
|
local text = (obj:GetValue() and "24-" or "12-") .. language.GetPhrase("clock")
|
|
menu:AddOption( text, function()
|
|
obj:SetValue( not obj:GetValue())
|
|
end):SetIcon( "icon16/clock.png" )
|
|
menu:AddOption( "Reset", function()
|
|
self._sfobj:Revert()
|
|
end):SetIcon( "icon16/package.png" )
|
|
menu:Open()
|
|
return true
|
|
end
|
|
end
|
|
function PANEL:Init()
|
|
local b = vgui_Create("DPanel", self) -- All options
|
|
b.Paint = empty
|
|
local bg = vgui_Create("DPanel", b) -- Background
|
|
self.hour = vgui.Create("DTextEntry", b)
|
|
self.min = vgui.Create("DTextEntry", b)
|
|
self.ampm = vgui.Create("DButton", b)
|
|
self.bg = bg
|
|
self.b = b
|
|
self.bar_ex = 0
|
|
|
|
b:SetPos(6,14)
|
|
b:SetSize(66 + 34 + 2, 30)
|
|
bg:SetSize(66, 30)
|
|
function bg:IsSelected() return false end
|
|
function bg:GetToggle() return false end
|
|
function bg:IsDown()
|
|
return hour:IsEditing() or min:IsEditing()
|
|
end
|
|
local hour, min = self.hour, self.min
|
|
do
|
|
|
|
function bg:Paint( w, h )
|
|
self.Hovered = hour.Hovered or min.Hovered
|
|
self.Depressed= hour:IsEditing() or min:IsEditing()
|
|
derma.SkinHook( "Paint", "Button", self, w, h )
|
|
surface.SetFont("SF2_TimeSet")
|
|
local tw,th = surface.GetTextSize(":")
|
|
|
|
surface.SetTextColor(color_black)
|
|
surface.SetTextPos(w / 2 - tw / 2,h / 2 - th / 2 - 2)
|
|
surface.DrawText(":")
|
|
end
|
|
end
|
|
|
|
self.hour:SetPos(2,0)
|
|
self.hour:SetWide(30)
|
|
self.hour:SetTall(30)
|
|
|
|
self.min:SetPos(34,0)
|
|
self.min:SetWide(30)
|
|
self.min:SetTall(30)
|
|
|
|
self.ampm:SetPos(66 + 2,0)
|
|
self.ampm:SetWide(34)
|
|
self.ampm:SetTall(30)
|
|
self.ampm:SetFont("SF2_TimeSetAM")
|
|
function self.ampm: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( color_black )
|
|
end
|
|
|
|
self.hour:SetNumeric(true)
|
|
self.hour:SetDrawLanguageID( false )
|
|
self.hour.Paint = NewPaint
|
|
self.hour:SetText("00")
|
|
local panel = self
|
|
function self.hour.OnGetFocus(self)
|
|
self:SetValue("")
|
|
end
|
|
function self.hour:OnEnter()
|
|
local num = tonumber( self:GetValue() or "" ) or 0
|
|
local lim = StormFox2.Setting.Get("12h_display") and 12 or 24
|
|
num = math.Clamp(num, 0, lim)
|
|
if num < 10 then
|
|
self:SetText("0" .. num)
|
|
else
|
|
self:SetText(num)
|
|
end
|
|
panel:OnNewValue()
|
|
end
|
|
function self.hour:OnChange()
|
|
if string.find(self:GetValue(), "-") then
|
|
self:SetText(string.Replace(self:GetValue(), "-", ""))
|
|
end
|
|
if #self:GetValue() >= 3 then -- Can't enter more numbers
|
|
self:FocusPrevious()
|
|
self:OnEnter()
|
|
elseif #self:GetValue() == 2 then
|
|
--self:OnEnter()
|
|
self:KillFocus()
|
|
min:RequestFocus()
|
|
min._setonlosefocus = true
|
|
end
|
|
end
|
|
function self.hour.OnLoseFocus( self )
|
|
if #self:GetText() < 2 then return end
|
|
-- We lost focus and the player has entered two numbers in. Should be set. Not everyone hits enter
|
|
self:OnEnter()
|
|
end
|
|
self.min:SetNumeric(true)
|
|
self.min:SetDrawLanguageID( false )
|
|
self.min.Paint = NewPaint
|
|
self.min:SetText("00")
|
|
function self.min.OnGetFocus(self)
|
|
self._oldVar = self:GetValue()
|
|
self:SetValue("")
|
|
end
|
|
function self.min:OnEnter()
|
|
-- Hour value has changed, and this is empty. We then use the last value instead.
|
|
if #self:GetText() < 1 and self._setonlosefocus and self._oldVar then
|
|
self:SetValue( self._oldVar )
|
|
end
|
|
self._setonlosefocus = nil
|
|
local num = tonumber( self:GetValue() or "" ) or 0
|
|
num = math.Clamp(num, 0, 59)
|
|
if num < 10 then
|
|
self:SetText("0" .. num)
|
|
else
|
|
self:SetText(num)
|
|
end
|
|
panel:OnNewValue( num )
|
|
end
|
|
function self.min:OnChange()
|
|
if string.find(self:GetValue(), "-") then
|
|
self:SetText(string.Replace(self:GetValue(), "-", ""))
|
|
end
|
|
if #self:GetValue() >= 2 then -- Can't enter more numbers
|
|
self:FocusPrevious()
|
|
self:OnEnter()
|
|
end
|
|
end
|
|
function self.min.OnLoseFocus( self )
|
|
-- We lost focus and the player has entered two numbers in. Should be set
|
|
if #self:GetText() < 2 and not (self._oldVar and self._setonlosefocus) then return end
|
|
-- We have a set-on-leave flag
|
|
if self._setonlosefocus and self._oldVar then
|
|
self:SetValue(self._oldVar)
|
|
end
|
|
self._setonlosefocus = nil
|
|
self:OnEnter()
|
|
|
|
end
|
|
function self.ampm:DoClick()
|
|
if self:GetText() == "AM" then
|
|
self:SetText("PM")
|
|
else
|
|
self:SetText("AM")
|
|
end
|
|
panel:OnNewValue()
|
|
end
|
|
|
|
hour.OnMousePressed = OnMousePressed
|
|
min.OnMousePressed = OnMousePressed
|
|
|
|
self:MoveDescription(105 + self.bar_ex,4)
|
|
end
|
|
|
|
function PANEL:OnNewValue()
|
|
local str = tonumber(self.hour:GetText()) .. ":" .. tonumber(self.min:GetText())
|
|
if StormFox2.Setting.Get("12h_display") then
|
|
str = str .. self.ampm:GetText()
|
|
end
|
|
self._sfobj:SetValue( StormFox2.Time.StringToTime(str) )
|
|
end
|
|
|
|
function PANEL:Think()
|
|
var = var or 0
|
|
if not self._sfobj then return end
|
|
local _12 = StormFox2.Setting.Get("12h_display")
|
|
local var = self._sfobj:GetValue()
|
|
if var < 0 then
|
|
self.b:SetDisabled( true )
|
|
self.hour:SetText("00")
|
|
self.min:SetText("00")
|
|
self.ampm:SetText("AM")
|
|
if _12 then
|
|
self.ampm:SetText(StormFox2.Time.GetAMPM( self._sfobj:GetValue() ))
|
|
if not self.ampm:IsVisible() then
|
|
self.ampm:Show()
|
|
self:MoveDescription(105 + self.bar_ex,4)
|
|
end
|
|
else
|
|
if self.ampm:IsVisible() then
|
|
self.ampm:Hide()
|
|
self:MoveDescription(70 + self.bar_ex,4)
|
|
end
|
|
end
|
|
else
|
|
self.b:SetDisabled( false )
|
|
if not self.hour:IsEditing() then
|
|
local h = StormFox2.Time.GetHours( self._sfobj:GetValue(), _12 )
|
|
if h < 10 then
|
|
h = "0" .. h
|
|
end
|
|
self.hour:SetText(h)
|
|
end
|
|
if not self.min:IsEditing() then
|
|
local h = StormFox2.Time.GetMinutes( self._sfobj:GetValue(), _12 )
|
|
if h < 10 then
|
|
h = "0" .. h
|
|
end
|
|
self.min:SetText(h)
|
|
end
|
|
if _12 then
|
|
self.ampm:SetText(StormFox2.Time.GetAMPM( self._sfobj:GetValue() ))
|
|
if not self.ampm:IsVisible() then
|
|
self.ampm:Show()
|
|
self:MoveDescription(105 + self.bar_ex,4)
|
|
end
|
|
else
|
|
if self.ampm:IsVisible() then
|
|
self.ampm:Hide()
|
|
self:MoveDescription(70 + self.bar_ex,4)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
self:_SetSetting( sName, sType, Description ) -- Set title and textbox
|
|
self._sfobj = StormFox2.Setting.GetObject( sName )
|
|
self.min._sfobj = self._sfobj
|
|
self.hour._sfobj = self._sfobj
|
|
--self.check:SetConVar( sName )
|
|
return self
|
|
end
|
|
derma.DefineControl( "SF_Setting_Time", "", PANEL, "SF_Setting" )
|
|
end
|
|
-- Time Toggle
|
|
do
|
|
local OldPanel = vgui.GetControlTable("SF_Setting_Time")
|
|
local PANEL = {}
|
|
function PANEL:Init()
|
|
self.check = vgui_Create("DCheckBox", self)
|
|
self.check:SetPos(5,20)
|
|
self.b:SetPos(24,14)
|
|
self:MoveDescription(105 + 18,4)
|
|
self.bar_ex = 18
|
|
end
|
|
function PANEL:Think()
|
|
OldPanel.Think(self)
|
|
if not self._sfobj then return end
|
|
local b = self._sfobj:GetValue() >= 0
|
|
self.check:SetChecked(b)
|
|
end
|
|
function PANEL:SetSetting( sName, sType, Description )
|
|
OldPanel.SetSetting( self, sName, sType, Description )
|
|
local _sfobj = StormFox2.Setting.GetObject( sName )
|
|
self.check._block = _sfobj:IsRadio()
|
|
function self.check:DoClick()
|
|
if self:GetChecked() and self._block then return end
|
|
local b = _sfobj:GetValue() > 0
|
|
if b then
|
|
_sfobj:SetValue(-1)
|
|
else
|
|
local default = _sfobj:GetDefault()
|
|
if default < 0 then default = 720 end
|
|
_sfobj:SetValue(default)
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
derma.DefineControl( "SF_Setting_TimeToggle", "", PANEL, "SF_Setting_Time" )
|
|
end
|
|
-- DoubleInt setting
|
|
do
|
|
local PANEL = {}
|
|
function PANEL:Init()
|
|
self.text = vgui_Create("DTextEntry", self)
|
|
self.text:SetNumeric(true)
|
|
self.text:SetDrawLanguageID( false )
|
|
self.slider = vgui_Create("SF_DoubleSlider", self)
|
|
self.slider:SetPos(5,14)
|
|
self.slider:SetWide(barLength)
|
|
self.text:SetPos(barLength + 8,18)
|
|
self.text:SetSize(55,18)
|
|
self:MoveDescription(barLength + 60, 6)
|
|
self._isTemp = false
|
|
end
|
|
function PANEL:SetTemperature(bool)
|
|
self._isTemp = bool
|
|
end
|
|
function PANEL:Think()
|
|
if not self._sfobj then return end
|
|
if self.slider._down and self.slider._downvalue then
|
|
local text
|
|
if self._isTemp then
|
|
text = self.slider._downvalue and valToTemp(self.slider._downvalue) or "?"
|
|
else
|
|
text = self.slider._downvalue
|
|
end
|
|
self.text:SetText(text)
|
|
elseif not self.text:IsEditing() then
|
|
local text
|
|
if self._isTemp then
|
|
text = valToTemp(self._sfobj:GetValue())
|
|
else
|
|
text = self._sfobj:GetValue()
|
|
end
|
|
self.text:SetText(text)
|
|
end
|
|
end
|
|
function PANEL:SetSettingMin( sName, sType, Description )
|
|
local _sfobj = StormFox2.Setting.GetObject( sName )
|
|
self._sfobj = _sfobj
|
|
self:_SetSetting( sName, sType, Description ) -- Set title and textbox
|
|
self.slider:SetSettingMin( sName, sType, Description )
|
|
--self.text:SetConVar( sName )
|
|
function self.text:OnEnter( val )
|
|
val = string.match(val, "[%d%.]+") or val
|
|
local clamp = math.Clamp(tonumber( val ), _sfobj:GetMin(), _sfobj:GetMax())
|
|
_sfobj:SetValue(clamp)
|
|
self:SetText(tostring(clamp))
|
|
end
|
|
end
|
|
function PANEL:SetSettingMax( sName, sType, Description )
|
|
local _sfobj2 = StormFox2.Setting.GetObject( sName )
|
|
self._sfobj2 = _sfobj
|
|
self:_SetSetting( sName, sType, Description ) -- Set title and textbox
|
|
self.slider:SetSettingMax( sName, sType, Description )
|
|
--self.text:SetConVar( sName )
|
|
end
|
|
function PANEL:SetMin( var )
|
|
self.slider:SetMin( var )
|
|
end
|
|
function PANEL:SetMax( var )
|
|
self.slider:SetMax( var )
|
|
end
|
|
derma.DefineControl( "SF_Setting_Double", "", PANEL, "SF_Setting" )
|
|
end
|
|
|
|
-- Hud Ring
|
|
do
|
|
local PANEL = {}
|
|
local m_ring = Material("stormfox2/hud/hudring.png")
|
|
local cCol1 = Color(55,55,55,55)
|
|
local cCol2 = Color(55,55,255,105)
|
|
local seg = 40
|
|
function PANEL:SetColor(r,g,b,a)
|
|
self.cCol2 = (r and g and b) and Color(r,g,b,a or 105) or r
|
|
return self
|
|
end
|
|
function PANEL:Init()
|
|
self._val = 1
|
|
self._off = 0.05
|
|
self.cCol1 = cCol1
|
|
self.cCol2 = cCol2
|
|
end
|
|
function PANEL:SetValue(nNum)
|
|
self._val = math.Clamp(nNum, 0, 1)
|
|
self:RebuildPoly()
|
|
return self
|
|
end
|
|
function PANEL:SetText(sText)
|
|
self._text = sText
|
|
return self
|
|
end
|
|
function PANEL:RebuildPoly()
|
|
local pw, ph = self:GetWide(), self:GetTall()
|
|
local x,y = pw / 2, ph / 2
|
|
local polyMul = 1.2
|
|
local radius = math.min(pw, ph) / 2 * polyMul
|
|
local mul2 = 2 / polyMul
|
|
|
|
-- Generate poly
|
|
self._poly = {}
|
|
local seg = 40
|
|
table.insert( self._poly, { x = x, y = y, u = 0.5, v = 0.5 } )
|
|
local n = self._val * seg
|
|
for i = 0, n do
|
|
local a = math.rad( ( i / seg ) * -360 )
|
|
table.insert( self._poly, { x = x + math.sin( a ) * radius, y = y + math.cos( a ) * radius, u = math.sin( a ) / mul2 + 0.5, v = math.cos( a ) / mul2 + 0.5 } )
|
|
end
|
|
local a = math.rad( ( n / seg ) * -360 )
|
|
table.insert( self._poly, { x = x + math.sin( a ) * radius, y = y + math.cos( a ) * radius, u = math.sin( a ) / mul2 + 0.5, v = math.cos( a ) / mul2 + 0.5 } )
|
|
table.insert( self._poly, { x = x, y = y, u = 0.5, v = 0.5 } )
|
|
end
|
|
function PANEL:PerformLayout(pw, ph)
|
|
self:RebuildPoly()
|
|
end
|
|
function PANEL:Paint(w,h)
|
|
if self._text then
|
|
local td = string.Explode("\n",self._text)
|
|
for k,v in ipairs(td) do
|
|
local n = k - 1
|
|
draw.SimpleText(v, "DermaDefault", w / 2, h / 2 + n * 12 - (#td - 1) * 6, color_black, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
|
end
|
|
else
|
|
draw.SimpleText(self._val, "DermaDefault", w / 2, h / 2, color_black, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
|
end
|
|
if not self._poly then return end
|
|
surface.SetMaterial(m_ring)
|
|
surface.SetDrawColor(self.cCol1)
|
|
surface.DrawTexturedRect(self._x or 0,self._y or 0,self._w or w,self._h or h)
|
|
surface.SetDrawColor(self.cCol2)
|
|
surface.DrawPoly(self._poly)
|
|
end
|
|
derma.DefineControl( "SF_Setting_Ring", "", PANEL, "DPanel" )
|
|
end
|
|
|
|
-- Old
|
|
-- Ring
|
|
do
|
|
local PANEL = {}
|
|
derma.DefineControl( "SF_HudRing", "", PANEL, "DPanel" )
|
|
end
|
|
-- World Display
|
|
do
|
|
local PANEL = {}
|
|
local owm = Material("stormfox2/hud/openweather.png")
|
|
local PANEL = {}
|
|
AccessorFunc( PANEL, "m_lat", "Lat" )
|
|
AccessorFunc( PANEL, "m_lon", "Lon" )
|
|
AccessorFunc( PANEL, "m_zoom","Zoom" )
|
|
local w_map = Material("stormfox2/hud/world.png")
|
|
local c = Color(0,0,0,55)
|
|
function PANEL:GetUV( lat, lon )
|
|
lat = math.Clamp(lat / 90, -1, 1) * 0.5
|
|
lon = math.Clamp(lon / 180, -1, 1) * 0.5
|
|
return 0.5 + lon, 0.5 - lat
|
|
end
|
|
function PANEL:Init()
|
|
self._map = vgui.Create("DPanel", self)
|
|
self:SetLat(StormFox2.Setting.Get("openweathermap_lat", 52.6139095))
|
|
self:SetLon(StormFox2.Setting.Get("openweathermap_lon", -2.0059601))
|
|
self:SetSize(400, 300)
|
|
self:SetZoom(0)
|
|
self._range = 1
|
|
self._map._s = self
|
|
function self._map:GetUV( lat, lon )
|
|
return self._s:GetUV( lat, lon )
|
|
end
|
|
function self._map:Paint(w,h)
|
|
if self._s:GetDisabled() then return end
|
|
surface.SetDrawColor(color_white)
|
|
surface.SetMaterial( w_map )
|
|
surface.DrawTexturedRect(0,0,w,h)
|
|
local u, v = self:GetUV( self._s:GetLat(), self._s:GetLon())
|
|
local ws = math.ceil(w / 360)
|
|
local hs = math.ceil(h / 180)
|
|
surface.SetDrawColor(color_black)
|
|
local xx,yy = u * w - ws / 2, v * h - hs / 2
|
|
surface.DrawOutlinedRect(xx,yy, ws, hs)
|
|
surface.SetDrawColor(c)
|
|
c.a = 150 + math.sin(SysTime() * 10) * 50
|
|
local xT = math.max(1, ws / 4)
|
|
local yT = math.max(1, hs / 4)
|
|
-- X
|
|
surface.DrawRect(0, yy + hs * .5 - xT / 2, xx, yT)
|
|
surface.DrawRect(xx + ws, yy + hs * .5 - xT / 2, w - xx - ws, yT)
|
|
--Y
|
|
surface.DrawRect(xx + ws * 0.5 - yT / 2, 0, xT, yy)
|
|
surface.DrawRect(xx + ws * 0.5 - yT / 2, yy + hs, xT, h - yy - hs)
|
|
end
|
|
self:SetMouseInputEnabled( true )
|
|
StormFox2.Setting.Callback("openweathermap_lat",function(vVar,_,_, self)
|
|
self:SetLat( tonumber(vVar) )
|
|
self:ReSize()
|
|
end,self)
|
|
StormFox2.Setting.Callback("openweathermap_lon",function(vVar,_,_, self)
|
|
self:SetLon( tonumber(vVar) )
|
|
self:ReSize()
|
|
end,self)
|
|
end
|
|
function PANEL:ReSize()
|
|
local z = self:GetZoom() * 0.5
|
|
local w,h = 1617 * z, 808 * z
|
|
if w < self:GetWide() or h < self:GetTall() then
|
|
z = math.max(self:GetWide() / 1617, self:GetTall() / 808)
|
|
w = 1617 * z
|
|
h = 808 * z
|
|
end
|
|
self._map:SetSize(w, h)
|
|
local u, v = self:GetUV( self:GetLat(), self:GetLon())
|
|
local px,py = -w * u + self:GetWide() / 2, -h * v + self:GetTall() / 2
|
|
px = math.Clamp(px, -w, 0)
|
|
py = math.Clamp(py, -h, 0)
|
|
|
|
self._map:SetPos(px,py)
|
|
end
|
|
function PANEL:OnMouseWheeled( sD )
|
|
local z = self:GetZoom() + sD / 2
|
|
self:SetZoom( math.Clamp(z, 1, 28) )
|
|
self:ReSize()
|
|
return true
|
|
end
|
|
function PANEL:PerformLayout()
|
|
self:ReSize()
|
|
end
|
|
local c = Color( 254, 254, 234 )
|
|
function PANEL:Paint(w,h)
|
|
if self:GetDisabled() then return end
|
|
surface.SetDrawColor(c)
|
|
surface.DrawRect(0,0,w,h)
|
|
local x, y = self._map:GetPos()
|
|
local ws, hs = self._map:GetSize()
|
|
surface.SetDrawColor(color_white)
|
|
surface.SetMaterial( w_map )
|
|
if x < 0 then
|
|
surface.DrawTexturedRect(x + ws,y,ws,hs)
|
|
else
|
|
surface.DrawTexturedRect(x - ws,y,ws,hs)
|
|
end
|
|
end
|
|
function PANEL:PaintOver(w,h)
|
|
surface.SetDrawColor(color_black)
|
|
surface.SetMaterial(owm)
|
|
local tw = w / 5
|
|
local th = tw * 0.42
|
|
surface.DrawTexturedRect(0, h - th, tw, th)
|
|
end
|
|
derma.DefineControl( "SF_WorldMap", "", PANEL, "DPanel" )
|
|
end
|
|
|
|
-- Day Display
|
|
do
|
|
local PANEL = {}
|
|
derma.DefineControl( "SF_WeatherHour", "", PANEL, "DPanel" )
|
|
end
|
|
|
|
-- Weather Display
|
|
do
|
|
local PANEL = {}
|
|
derma.DefineControl( "SF_WeatherMap", "", PANEL, "DPanel" )
|
|
end
|
|
-- Menu
|
|
do
|
|
local function empty() end
|
|
local function switch(sName, tab, buttons, sCookie)
|
|
sName = string.lower(sName)
|
|
local pnl
|
|
for k, v in pairs(tab) do
|
|
if k == sName then
|
|
v:Show()
|
|
pnl = v
|
|
else
|
|
v:Hide()
|
|
end
|
|
end
|
|
if not IsValid(pnl) or pnl:GetDisabled() then
|
|
pnl = tab["start"]
|
|
sName = "start"
|
|
if IsValid(pnl) then
|
|
pnl:Show()
|
|
end
|
|
end
|
|
for k,v in pairs(buttons) do
|
|
v._selected = k == sName
|
|
end
|
|
if sCookie then
|
|
cookie.Set(sCookie, sName)
|
|
end
|
|
return pnl
|
|
end
|
|
local function addSetting(sName, pPanel, _type, _desc)
|
|
local setting
|
|
if type(_type) == "table" then
|
|
setting = vgui_Create("SF_Setting_Enum", pPanel)
|
|
elseif _type == "boolean" or _type == "bool" then
|
|
setting = vgui_Create("SF_Setting_Bool", pPanel)
|
|
elseif _type == "float" then
|
|
setting = vgui_Create("SF_Setting_Float", pPanel)
|
|
elseif _type == "special_float" then
|
|
setting = vgui_Create("SF_Setting_FloatSpecial", pPanel)
|
|
elseif _type == "number" then
|
|
setting = vgui_Create("SF_Setting_Int", pPanel)
|
|
elseif _type == "time" then
|
|
setting = vgui_Create("SF_Setting_Time", pPanel)
|
|
elseif _type == "string" then
|
|
setting = vgui_Create("SF_Setting_String", pPanel)
|
|
elseif _type == "time_toggle" then
|
|
setting = vgui_Create("SF_Setting_TimeToggle", pPanel)
|
|
elseif _type == "temp" or _type == "temperature" then
|
|
setting = vgui_Create("SF_Setting_Float", pPanel)
|
|
setting:SetTemperature( true )
|
|
elseif _type == "double_number" then
|
|
setting = vgui_Create("SF_DDSliderNum", pPanel)
|
|
setting:SetSetting(sName[1],sName[2], _type, _desc)
|
|
return setting
|
|
else
|
|
StormFox2.Warning("Unknown Setting Variable: " .. sName .. " [" .. tostring(_type) .. "]")
|
|
return
|
|
end
|
|
if not setting then
|
|
StormFox2.Warning("Unknown Setting Variable: " .. sName .. " [" .. tostring(_type) .. "]")
|
|
return
|
|
end
|
|
--local setting = _type == "boolean" and vgui_Create("SFConVar_Bool", board) or vgui_Create("SFConVar", board)
|
|
setting:SetSetting(sName, _type, _desc)
|
|
return setting
|
|
end
|
|
local col = {Color(230,230,230), color_white}
|
|
local col_dis = Color(0,0,0,55)
|
|
local col_dis2 = Color(0,0,0,55)
|
|
local bh_col = Color(55,55,55,55)
|
|
local sb_col = Color(91,155,213)
|
|
|
|
local icon = Material("icon16/zoom.png")
|
|
local icon_c = Color(255,255,255,180)
|
|
|
|
local s = 20
|
|
local side_button = function(self, w, h)
|
|
if self:IsHovered() and not self:GetDisabled() then
|
|
surface.SetDrawColor(bh_col)
|
|
surface.DrawRect(0,0,w,h)
|
|
end
|
|
|
|
surface.SetDrawColor(self:GetDisabled() and col_dis or color_black)
|
|
surface.SetMaterial(self.icon)
|
|
surface.DrawTexturedRect(24 - s / 2, (h - s) / 2, s,s)
|
|
|
|
local t = self.text or "ERROR"
|
|
surface.SetFont("DermaDefault")
|
|
local tw,th = surface.GetTextSize( t )
|
|
surface.SetTextColor(self:GetDisabled() and col_dis2 or color_black)
|
|
surface.SetTextPos(48, h / 2 - th / 2)
|
|
surface.DrawText(t)
|
|
|
|
if self._selected then
|
|
surface.SetDrawColor(sb_col)
|
|
surface.DrawRect(4,4,4,h - 8)
|
|
end
|
|
end
|
|
|
|
local t_mat = "icon16/font.png"
|
|
local s_mat = "icon16/cog.png"
|
|
local s = 60
|
|
local n_vc = Color(55,255,55)
|
|
local n_bm = Material("vgui/notices/undo")
|
|
|
|
local PANEL = {}
|
|
function PANEL:Init()
|
|
-- BG
|
|
self:SetTitle("")
|
|
function self:SetTitle( str )
|
|
self._title = str
|
|
end
|
|
self:SetSize(64 * 11, 500)
|
|
self:Center()
|
|
self:DockPadding(0,24,0,0)
|
|
function self:Paint(w, h)
|
|
surface.SetDrawColor( col[2] )
|
|
surface.DrawRect(0,0,w,h)
|
|
surface.SetDrawColor( col[1] )
|
|
if self.p_left then
|
|
surface.DrawRect(0,0,self.p_left:GetWide(),24)
|
|
else
|
|
surface.DrawRect(0,0,w,24)
|
|
end
|
|
|
|
surface.SetDrawColor(55,55,55,255)
|
|
surface.DrawRect(0, 0, w, 24)
|
|
|
|
local t = self._title or "Window"
|
|
surface.SetFont("DermaDefault")
|
|
local tw,th = surface.GetTextSize( t )
|
|
surface.SetTextColor(color_white)
|
|
surface.SetTextPos(5, 12 - th / 2)
|
|
surface.DrawText(t)
|
|
end
|
|
-- Left panel
|
|
local p_left = vgui_Create("DPanel", self)
|
|
self.p_left = p_left
|
|
p_left:SetWide(180)
|
|
p_left:Dock( LEFT )
|
|
p_left:DockPadding(0,0,0,0)
|
|
function p_left:Paint(w, h)
|
|
surface.SetDrawColor( col[1] )
|
|
surface.DrawRect(0,0,w,h)
|
|
end
|
|
-- Right panel
|
|
local p_right = vgui_Create("DPanel", self)
|
|
self.p_right = p_right
|
|
p_right:Dock( FILL )
|
|
p_right.Paint = empty
|
|
p_right.sub = {}
|
|
end
|
|
function PANEL:CreateLayout( tabs, setting_list )
|
|
local p = self
|
|
local p_right = self.p_right
|
|
local p_left = self.p_left
|
|
p_right.sub = {}
|
|
|
|
for k,v in ipairs( tabs ) do
|
|
local p = vgui_Create("DScrollPanel", self.p_right)
|
|
p:Dock(FILL)
|
|
self.p_right.sub[string.lower(v[1])] = p
|
|
p:Hide()
|
|
end
|
|
p_right.sub["start"]._isstart = true
|
|
|
|
p_left.buttons = {}
|
|
-- Add Start
|
|
local b = vgui_Create("DButton", p_left)
|
|
b:Dock(TOP)
|
|
b:SetTall(40)
|
|
b:SetText("")
|
|
b.icon = tabs[1][3]
|
|
b.text = niceName( language.GetPhrase(tabs[1][2]) )
|
|
b.Paint = side_button
|
|
p_left.buttons["start"] = b
|
|
function b:DoClick()
|
|
switch("start", p_right.sub, p_left.buttons, p._cookie)
|
|
end
|
|
|
|
-- Add search bar
|
|
local sp = vgui_Create("DPanel", p_left)
|
|
p_left.sp = sp
|
|
local search_tab = {}
|
|
sp:Dock(TOP)
|
|
sp:SetTall(40)
|
|
function sp:Paint() end
|
|
sp.searchbar = vgui_Create("DTextEntry",sp)
|
|
sp.searchbar:SetText("")
|
|
sp.searchbar:Dock(TOP)
|
|
sp.searchbar:SetHeight(20)
|
|
sp.searchbar:DockMargin(4,10,4,0)
|
|
function sp.searchbar:OptionSelected( sName, page, vguiObj )
|
|
local board = switch(page, p_right.sub, p_left.buttons, p._cookie)
|
|
if vguiObj then
|
|
vguiObj.dMark = 2 + CurTime()
|
|
if board then
|
|
board:ScrollToChild(vguiObj)
|
|
end
|
|
timer.Simple(1, function() vguiObj:RequestFocus() end )
|
|
end
|
|
self:SetText("")
|
|
self:KillFocus()
|
|
end
|
|
function sp.searchbar:OnChange( )
|
|
local val = self:GetText()
|
|
local tab = {}
|
|
if self.result and IsValid(self.result) then
|
|
self.result:Remove()
|
|
end
|
|
local OnlyTitles = val == ""
|
|
self.result = vgui_Create("DMenu")
|
|
function self.result:OptionSelected( pnl, text )
|
|
if not search_tab[pnl.sName] then return end
|
|
sp.searchbar:OptionSelected( text, search_tab[pnl.sName][1], search_tab[pnl.sName][2] )
|
|
end
|
|
for sName, v in pairs( search_tab ) do
|
|
local phrase = language.GetPhrase( sName )
|
|
if string.find(string.lower(phrase),string.lower(val), nil, true) then
|
|
if OnlyTitles and v[3]~=t_mat then continue end
|
|
table.insert(tab, {sName, v[1], v[2]})
|
|
local op = self.result:AddOption( phrase )
|
|
if v[3] then
|
|
op:SetIcon(v[3])
|
|
end
|
|
op.sName = sName
|
|
end
|
|
end
|
|
local x,y = self:LocalToScreen(0,0)
|
|
self.result:Open(x, y + self:GetTall())
|
|
end
|
|
function sp.searchbar:OnGetFocus()
|
|
self:OnChange( )
|
|
end
|
|
function sp.searchbar:OnLoseFocus()
|
|
if not self.result then return end
|
|
self.result:Remove()
|
|
self.result = nil
|
|
end
|
|
function sp.searchbar:Paint(w,h)
|
|
surface.SetDrawColor(color_white)
|
|
surface.DrawRect(0,0,w,h)
|
|
surface.SetDrawColor(color_black)
|
|
surface.DrawOutlinedRect(0,0,w,h)
|
|
local text = self:GetText()
|
|
if self:IsEditing() then
|
|
if math.Round(SysTime() * 2) % 2 == 0 then
|
|
text = text .. "|"
|
|
end
|
|
elseif #text < 1 then
|
|
text = "#searchbar_placeholer"
|
|
end
|
|
surface.SetMaterial(icon)
|
|
surface.SetDrawColor(icon_c)
|
|
local s = 4
|
|
surface.DrawTexturedRect(w - h + s / 2, s / 2, h - s, h - s)
|
|
draw.DrawText(text, "DermaDefault", 5, 2, color_black, TEXT_ALIGN_BOTTOM)
|
|
end
|
|
for i = 2, #tabs do
|
|
v = tabs[i]
|
|
local b = vgui_Create("DButton", p_left)
|
|
b:Dock(TOP)
|
|
b:SetTall(40)
|
|
b:SetText("")
|
|
b.icon = v[3]
|
|
b.text = niceName( language.GetPhrase(tabs[i][2]) )
|
|
b.sTab = v[1]
|
|
b.Paint = side_button
|
|
p_left.buttons[string.lower(tabs[i][1])] = b
|
|
function b:DoClick()
|
|
switch(self.sTab, p_right.sub,p_left.buttons, p._cookie)
|
|
end
|
|
end
|
|
|
|
-- Move changelog down
|
|
if p_left.buttons["changelog"] then
|
|
p_left.buttons["changelog"]:Dock(BOTTOM)
|
|
p_left.buttons["changelog"]:SetZPos(1)
|
|
end
|
|
|
|
-- Add workshop button
|
|
local b = vgui_Create("DButton", p_left)
|
|
b:Dock(BOTTOM)
|
|
b:SetTall(40)
|
|
b:SetText("")
|
|
b.icon = tabs[1][3]
|
|
b.text = "Workshop"
|
|
b.Paint = side_button
|
|
b.r = 180
|
|
if StormFox2.NewVersion() then
|
|
function b:PaintOver(w,h)
|
|
surface.SetDrawColor(color_white)
|
|
surface.SetMaterial(n_bm)
|
|
if self:IsHovered() then
|
|
local dif = math.abs(math.AngleDifference(self.r, 0)) + 5
|
|
self.r = (self.r + math.max(0.01,dif) * FrameTime() * 5) % 360
|
|
else
|
|
self.r = 180
|
|
end
|
|
surface.DrawTexturedRectRotated(w - 20, h / 2, 20, 20, self.r)
|
|
--surface.DrawRect( - w,0,w,h - 1)
|
|
draw.DrawText( StormFox2.NewVersion() , "SF_Menu_H2", w - 34 , h / 2 - 8, color_black, TEXT_ALIGN_RIGHT)
|
|
end
|
|
end
|
|
p_left.buttons["workshop"] = b
|
|
function b:DoClick()
|
|
gui.OpenURL( StormFox2.WorkShopURL )
|
|
end
|
|
if not StormFox2.WorkShopURL then
|
|
b:SetDisabled(true)
|
|
end
|
|
|
|
do
|
|
local b = vgui_Create("DButton", p_left)
|
|
b:Dock(BOTTOM)
|
|
b:SetTall(40)
|
|
b:SetText("")
|
|
b.icon = Material("stormfox2/discord.png")
|
|
b.text = "Discord"
|
|
b.Paint = side_button
|
|
b.r = 180
|
|
p_left.buttons["discord"] = b
|
|
function b:DoClick()
|
|
gui.OpenURL( "https://discord.gg/mefXXt4u9E" )
|
|
end
|
|
end
|
|
|
|
local used = {}
|
|
function p:AddSetting( sName, group, _type, sDesc )
|
|
if not group then
|
|
group = select(2, StormFox2.Setting.GetType(sName))
|
|
end
|
|
if not group then
|
|
group = "misc"
|
|
elseif not p_right.sub[group] then
|
|
group = "misc"
|
|
end
|
|
local board = p_right.sub[group]
|
|
return board:AddSetting( sName, _type, sDesc )
|
|
end
|
|
function p:MarkUsed( sName )
|
|
used[sName] = true
|
|
end
|
|
for sBName, pnl in pairs(p_right.sub) do
|
|
pnl.sBName = string.lower(sBName)
|
|
pnl._other = false
|
|
function pnl:AddSetting( sName, _type, sDesc )
|
|
if self._other then
|
|
self:AddTitle("#other", true)
|
|
pnl._other = false
|
|
end
|
|
local mul = type( sName ) == "table"
|
|
if not _type then
|
|
_type = StormFox2.Setting.GetType(mul and sName[1] or sName)
|
|
end
|
|
local setting = addSetting(sName, self, _type, sDesc)
|
|
if not setting then return end
|
|
if not mul then
|
|
if not search_tab["sf_" .. sName] or not self._isstart then
|
|
search_tab["sf_" .. sName] = {self.sBName, setting, s_mat}
|
|
end
|
|
used[sName] = true
|
|
else
|
|
for k,v in ipairs(sName) do
|
|
if not search_tab["sf_" .. v] or not self._isstart then
|
|
search_tab["sf_" .. v] = {self.sBName, setting, s_mat}
|
|
end
|
|
used[v] = true
|
|
end
|
|
end
|
|
--local setting = _type == "boolean" and vgui_Create("SFConVar_Bool", board) or vgui_Create("SFConVar", board)
|
|
setting:Dock(TOP)
|
|
self:AddItem(setting)
|
|
return setting
|
|
end
|
|
function pnl:AddTitle( sName, bIgnoreSearch )
|
|
local dL = vgui_Create("SFTitle", self)
|
|
local text = niceName( language.GetPhrase(sName) )
|
|
dL:SetText( text )
|
|
dL:SetDark(true)
|
|
dL:SetFont("SF_Menu_H2")
|
|
dL:SizeToContents()
|
|
dL:Dock(TOP)
|
|
dL:DockMargin(5,self._title and 20 or 0,0,0)
|
|
self._title = true
|
|
self:AddItem(dL)
|
|
if (not search_tab[text] or not self._isstart) and #sName > 0 and not bIgnoreSearch then
|
|
search_tab[text] = {self.sBName, dL, t_mat}
|
|
end
|
|
return dL
|
|
end
|
|
function pnl:MarkUsed( sName )
|
|
p:MarkUsed( sName )
|
|
end
|
|
end
|
|
-- Make the layout
|
|
for _,v in ipairs(tabs) do
|
|
if not v[4] then continue end
|
|
local b = p_right.sub[string.lower(v[1])]
|
|
if not b then continue end
|
|
v[4]( b )
|
|
end
|
|
|
|
-- Add all other settings
|
|
for sBName, pnl in pairs(p_right.sub) do
|
|
pnl._other = true
|
|
end
|
|
for _, sName in ipairs( setting_list ) do
|
|
if used[sName] then continue end
|
|
p:AddSetting( sName )
|
|
end
|
|
-- If there are empty setting-pages, remove them
|
|
for sBName, pnl in pairs(p_right.sub) do
|
|
local n = #pnl:GetChildren()[1]:GetChildren()
|
|
if n > 0 then continue end
|
|
local b = self.p_left.buttons[sBName]
|
|
if IsValid(b) then
|
|
b:SetDisabled(true)
|
|
end
|
|
local p = self.p_right.sub[string.lower(sBName)]
|
|
if IsValid(p) then
|
|
p:SetDisabled(true)
|
|
end
|
|
end
|
|
-- Add space at bottom
|
|
for sBName, pnl in pairs(p_right.sub) do
|
|
pnl.bottom = pnl:AddTitle("")
|
|
end
|
|
end
|
|
function PANEL:SetCookie( sCookie )
|
|
self._cookie = sCookie
|
|
local selected = cookie.GetString(sCookie, "start") or "start"
|
|
if not self.p_right.sub[selected] then -- Unknown page, set it to "start"
|
|
selected = "start"
|
|
end
|
|
switch(selected, self.p_right.sub,self.p_left.buttons, sCookie)
|
|
end
|
|
function PANEL:Select( str_page )
|
|
switch(str_page, self.p_right.sub,self.p_left.buttons, self._cookie)
|
|
end
|
|
derma.DefineControl( "SF_Menu", "", PANEL, "DFrame" )
|
|
end
|
|
|
|
--StormFox2.Menu.OpenController()
|
|
|
|
-- Test vgui objects
|
|
if true then return end
|
|
|
|
if SF_MENU_TEST then SF_MENU_TEST:Remove() end
|
|
SF_MENU_TEST = vgui.Create("DFrame")
|
|
SF_MENU_TEST:MakePopup()
|
|
SF_MENU_TEST:SetSize(600,500)
|
|
SF_MENU_TEST:SetPos(320,ScrH() / 2 - 100)
|
|
|
|
local function Add(_type, _setting)
|
|
local setting = vgui.Create(_type, SF_MENU_TEST)
|
|
setting:SetSetting(_setting)
|
|
setting:SetSize(50,20)
|
|
setting:Dock(TOP)
|
|
return setting
|
|
end
|
|
Add("SF_Setting_Bool", "footprint_enabled")
|
|
Add("SF_Setting_String", "footprint_enabled")
|
|
Add("SF_Setting_Float", "overwrite_extra_darkness")
|
|
Add("SF_Setting_Int", "window_distance"):SetTemperature(true)
|
|
Add("SF_Setting_FloatSpecial", "window_distance")
|
|
Add("SF_Setting_Enum", "12h_display")
|
|
Add("SF_Setting_Time", "sunrise")
|
|
Add("SF_Setting_TimeToggle", "sunrise")
|