Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lua/autorun/sh_pixelui_loader.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ PIXEL = PIXEL or {}
PIXEL.UI = PIXEL.UI or {}
PIXEL.UI.Version = "1.4.1"

--- Loads all Lua files in a directory, applying realm rules per filename prefix.
--- On client: includes all files. On server: cl_ files are AddCSLuaFile only, sh_ files
--- are AddCSLuaFile + include, and other files are included server-side.
---@param path string Directory to load.
---@return string[] files Files found in the directory.
---@return string[] folders Subfolders found in the directory.
function PIXEL.LoadDirectory(path)
local files, folders = file.Find(path .. "/*", "LUA")

Expand All @@ -42,6 +48,8 @@ function PIXEL.LoadDirectory(path)
return files, folders
end

--- Recursively loads Lua files in a directory and its subfolders using the same realm rules.
---@param basePath string Base directory to traverse.
function PIXEL.LoadDirectoryRecursive(basePath)
local _, folders = PIXEL.LoadDirectory(basePath)
for _, folderName in ipairs(folders) do
Expand Down
59 changes: 59 additions & 0 deletions lua/pixelui/core/cl_color.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@

do
local format = string.format
--- Converts a decimal value to a hex string.
---@param dec number Decimal value to convert.
---@param zeros number|nil Minimum digit count (defaults to 2).
---@return string hex Hex string representation.
function PIXEL.DecToHex(dec, zeros)
return format("%0" .. (zeros or 2) .. "x", dec)
end

local max = math.max
local min = math.min
--- Converts a Color to a "#RRGGBB" hex string.
---@param color Color Color to convert.
---@return string hex Hex string representation.
function PIXEL.ColorToHex(color)
return format("#%02X%02X%02X",
max(min(color.r, 255), 0),
Expand All @@ -32,6 +39,11 @@ do
end
end

--- Converts a Color to HSL values.
---@param col Color Color to convert.
---@return number h Hue component (0-1).
---@return number s Saturation component (0-1).
---@return number l Lightness component (0-1).
function PIXEL.ColorToHSL(col)
local r = col.r / 255
local g = col.g / 255
Expand Down Expand Up @@ -68,6 +80,12 @@ do
return p
end

--- Converts HSL values to a Color (alpha defaults to 1).
---@param h number Hue component (0-1).
---@param s number Saturation component (0-1).
---@param l number Lightness component (0-1).
---@param a number|nil Alpha multiplier (0-1, defaults to 1).
---@return Color color Converted color.
function PIXEL.HSLToColor(h, s, l, a)
local r, g, b
local t = h / (2 * math.pi)
Expand All @@ -92,10 +110,17 @@ do
end
end

--- Returns a new instance of a Colour with the same values.
---@param col Color Color to copy.
---@return Color copy New color instance.
function PIXEL.CopyColor(col)
return createColor(col.r, col.g, col.b, col.a)
end

--- Returns a Color with RGB channels offset by the given amount.
---@param col Color Base color to offset.
---@param offset number Amount to add to each RGB channel.
---@return Color offsetColor Offset color copy.
function PIXEL.OffsetColor(col, offset)
return createColor(col.r + offset, col.g + offset, col.b + offset)
end
Expand All @@ -104,6 +129,9 @@ do
local match = string.match
local tonumber = tonumber

--- Converts a "#RRGGBB" hex string to a Color.
---@param hex string Hex string to convert.
---@return Color color Converted color.
function PIXEL.HexToColor(hex)
local r, g, b = match(hex, "#(..)(..)(..)")
return createColor(
Expand All @@ -121,6 +149,8 @@ do
local lastUpdate = 0
local lastCol = createColor(0, 0, 0)

--- Returns a cached rainbow Color based on CurTime.
---@return Color color Cached rainbow color.
function PIXEL.GetRainbowColor()
local time = curTime()
if lastUpdate == time then return lastCol end
Expand All @@ -135,25 +165,50 @@ end
do
local colorToHSL = ColorToHSL

--- Returns true if the color is considered light.
---@param col Color Color to evaluate.
---@return boolean isLight True when lightness is >= 0.5.
function PIXEL.IsColorLight(col)
local _, _, lightness = colorToHSL(col)
return lightness >= .5
end
end

--- Linearly interpolates between two colors.
---@param t number Lerp fraction between 0 and 1.
---@param from Color Starting color.
---@param to Color Target color.
---@return Color color Interpolated color.
function PIXEL.LerpColor(t, from, to)
return createColor(from.r, from.g, from.b, from.a):Lerp(to, t)
end

--- Returns true if two Colors are equal.
---@param from Color First color to compare.
---@param to Color Second color to compare.
---@return boolean isEqual True when all RGBA channels match.
function PIXEL.IsColorEqualTo(from, to)
return from.r == to.r and from.g == to.g and from.b == to.b and from.a == to.a
end

local colorMeta = FindMetaTable("Color")
--- Returns a copy of this color.
---@param self Color Color instance to copy.
---@return Color copy New color instance.
colorMeta.Copy = PIXEL.CopyColor
--- Returns true if this color is considered light.
---@param self Color Color instance to evaluate.
---@return boolean isLight True when lightness is >= 0.5.
colorMeta.IsLight = PIXEL.IsColorLight
--- Returns true if this color equals another color.
---@param self Color Color instance to compare.
---@param to Color Color to compare against.
---@return boolean isEqual True when all RGBA channels match.
colorMeta.EqualTo = PIXEL.IsColorEqualTo

--- Offsets this color's RGB channels in place.
---@param offset number Amount to add to each RGB channel.
---@return Color self Updated color.
function colorMeta:Offset(offset)
self.r = self.r + offset
self.g = self.g + offset
Expand All @@ -166,6 +221,10 @@ if not colorMeta.Lerp then
local lerp = Lerp
local isColor = IsColor
local deprecation_warning_shown = false
--- Interpolates this color towards a target color.
---@param target Color Target color to interpolate towards.
---@param fraction number Lerp fraction between 0 and 1.
---@return Color self Updated color.
function colorMeta:Lerp(target, fraction)
if isColor(fraction) then
-- Don't break addons using this based on Pixel UI for now.
Expand Down
20 changes: 20 additions & 0 deletions lua/pixelui/core/cl_fonts.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ do
PIXEL.UI.SharedFonts = PIXEL.UI.SharedFonts or {}
local sharedFonts = PIXEL.UI.SharedFonts

--- Registers a font without applying PIXEL scaling.
---@param name string Alias used to reference the font.
---@param font string Base font name to register.
---@param size number Font size before scaling.
---@param weight number|nil Font weight (defaults to 500).
function PIXEL.RegisterFontUnscaled(name, font, size, weight)
weight = weight or 500

Expand All @@ -47,6 +52,11 @@ do
PIXEL.UI.ScaledFonts = PIXEL.UI.ScaledFonts or {}
local scaledFonts = PIXEL.UI.ScaledFonts

--- Registers a font and scales it using PIXEL.Scale.
---@param name string Alias used to reference the font.
---@param font string Base font name to register.
---@param size number Font size before scaling.
---@param weight number|nil Font weight (defaults to 500).
function PIXEL.RegisterFont(name, font, size, weight)
scaledFonts[name] = {
font = font,
Expand Down Expand Up @@ -76,14 +86,24 @@ do
setFont(font)
end

--- Sets the active font, mapping PIXEL aliases to registered fonts.
---@param font string PIXEL alias or raw font name.
PIXEL.SetFont = setPixelFont

local getTextSize = surface.GetTextSize
--- Returns text size, optionally swapping to a PIXEL font first.
---@param text string Text to measure.
---@param font string|nil Optional PIXEL alias or raw font name to measure with.
---@return number width Width of the text in pixels.
---@return number height Height of the text in pixels.
function PIXEL.GetTextSize(text, font)
if font then setPixelFont(font) end
return getTextSize(text)
end

--- Returns the registered font name for a PIXEL alias.
---@param font string PIXEL alias to resolve.
---@return string|nil fontName Real font name or nil if unregistered.
function PIXEL.GetRealFont(font)
return registeredFonts[font]
end
Expand Down
9 changes: 9 additions & 0 deletions lua/pixelui/core/cl_images.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ local function processQueue()
end
end

--- Fetches or loads an image and calls back with a Material.
---@param url string Image URL to fetch/cache.
---@param callback fun(mat: IMaterial) Callback that receives the cached material.
---@param matSettings string|nil Optional material settings string.
function PIXEL.GetImage(url, callback, matSettings)
local protocol = url:match("^([%a]+://)")

Expand Down Expand Up @@ -122,6 +126,11 @@ function PIXEL.GetImage(url, callback, matSettings)
end


--- Loads an Imgur PNG by ID and returns a Material in the callback.
---@param id string Imgur image ID (without extension).
---@param callback fun(mat: IMaterial) Callback that receives the cached material.
---@param _ any|nil Unused legacy argument.
---@param matSettings string|nil Optional material settings string.
function PIXEL.GetImgur(id, callback, _, matSettings)
local url = "https://i.imgur.com/" .. id .. ".png"
PIXEL.GetImage(url, callback, matSettings)
Expand Down
9 changes: 8 additions & 1 deletion lua/pixelui/core/cl_overrides.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,25 @@

PIXEL.UI.Overrides = PIXEL.UI.Overrides or {}

--- Creates a wrapper that swaps between an override and the original method.
---@param method fun(...): any Original method to call when override is disabled.
---@param override fun(...): any Override method to call when enabled.
---@param toggleGetter fun(...): boolean Callback that returns true when override should run.
---@return fun(...): any Wrapper function that dispatches based on toggleGetter.
function PIXEL.UI.CreateToggleableOverride(method, override, toggleGetter)
return function(...)
return toggleGetter(...) and override(...) or method(...)
end
end

local overridePopupsCvar = CreateClientConVar("pixel_ui_override_popups", (PIXEL.OverrideDermaMenus > 1) and "1" or "0", true, false, "Should the default derma popups be restyled with PIXEL UI?", 0, 1)
--- Returns whether PIXEL UI should override Derma popups.
---@return boolean enabled True when popup overrides are active.
function PIXEL.UI.ShouldOverrideDermaPopups()
local overrideSetting = PIXEL.OverrideDermaMenus

if not overrideSetting or overrideSetting == 0 then return false end
if overrideSetting == 3 then return true end

return overridePopupsCvar:GetBool()
end
end
9 changes: 9 additions & 0 deletions lua/pixelui/core/cl_scaling.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,26 @@

local scrH = ScrH
local max = math.max
--- Scales a value based on screen height (min 1).
---@param value number Value to scale.
---@return number scaled Scaled value.
function PIXEL.Scale(value)
return max(value * (scrH() / 1080), 1)
end

local constants = {}
local scaledConstants = {}
--- Registers a constant that auto-scales on screen-size changes.
---@param varName string Name of the constant.
---@param size number Base size before scaling.
function PIXEL.RegisterScaledConstant(varName, size)
constants[varName] = size
scaledConstants[varName] = PIXEL.Scale(size)
end

--- Returns the scaled value for a registered constant.
---@param varName string Name of the constant.
---@return number|nil scaled Scaled value or nil if missing.
function PIXEL.GetScaledConstant(varName)
return scaledConstants[varName]
end
Expand Down
8 changes: 7 additions & 1 deletion lua/pixelui/core/sh_formatting.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ do
local abs = math.abs
local round = math.Round

--- Formats a number using the current gamemode currency settings.
---@param val number|nil Value to format; nil defaults to 0.
---@return string formatted Currency string.
function PIXEL.FormatMoney(val)
if not val then return addCurrency("0") end

Expand Down Expand Up @@ -66,6 +69,9 @@ do
end

local floor, format = math.floor, string.format
--- Formats seconds into a compact time string.
---@param time number|nil Time in seconds; nil returns nil.
---@return string|nil formatted Compact time string.
function PIXEL.FormatTime(time)
if not time then return end

Expand All @@ -90,4 +96,4 @@ function PIXEL.FormatTime(time)
end

return format("%im %is", m, s)
end
end
23 changes: 22 additions & 1 deletion lua/pixelui/drawing/cl_circle.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ do
}

local max = math.max
--- Draws a circle using cached circle textures.
---@param x number X position.
---@param y number Y position.
---@param w number Width.
---@param h number Height.
---@param col Color Circle color.
function PIXEL.DrawCircle(x, y, w, h, col)
local size = max(w, h)
local id = materials[1]
Expand All @@ -48,6 +54,14 @@ do
local insert = table.insert
local rad, sin, cos = math.rad, math.sin, math.cos

--- Creates a polygon table for a circle segment.
---@param x number Center X position.
---@param y number Center Y position.
---@param ang number Start angle in degrees.
---@param seg number Segment count.
---@param pct number Arc coverage in degrees.
---@param radius number Circle radius.
---@return table points Polygon point table.
function PIXEL.CreateCircle(x, y, ang, seg, pct, radius)
local circle = {}

Expand All @@ -64,6 +78,13 @@ end

local createCircle = PIXEL.CreateCircle
local drawPoly = surface.DrawPoly
--- Draws a circle polygon directly without caching.
---@param x number Center X position.
---@param y number Center Y position.
---@param ang number Start angle in degrees.
---@param seg number Segment count.
---@param pct number Arc coverage in degrees.
---@param radius number Circle radius.
function PIXEL.DrawCircleUncached(x, y, ang, seg, pct, radius)
drawPoly(createCircle(x, y, ang, seg, pct, radius))
end
end
Loading
Loading