cbox/lua/cbox/cl_chatbox.lua

183 lines
4.8 KiB
Lua

local DisableClipping = DisableClipping
local ScrW = ScrW
local ScrH = ScrH
local render = render
local string = string
local surface = surface
local render_UpdateScreenEffectTexture = render.UpdateScreenEffectTexture
local surface_DrawRect = surface.DrawRect
local surface_DrawTexturedRect = surface.DrawTexturedRect
local surface_SetDrawColor = surface.SetDrawColor
local surface_SetMaterial = surface.SetMaterial
cbox.chatbox = cbox.chatbox or {}
cbox.chatbox.tabs = cbox.chatbox.tabs or {}
cbox.chatbox.panels = cbox.chatbox.panels or {}
local CHATBOX_COLOR = CreateClientConVar("cbox_chatbox_color", "160 160 160", true, false, "Chatbox background color")
local CHATBOX_ALPHA = CreateClientConVar("cbox_chatbox_alpha", "128", true, false, "Chatbox background alpha")
local CHATBOX_BLUR = CreateClientConVar("cbox_chatbox_blur", "0", true, false, "Chatbox background is blurred")
---@param height number
---@return number
local function _ScreenScaleH(height)
return height * (ScrH() / 480)
end
local ScreenScaleH = ScreenScaleH or _ScreenScaleH
---@return number x
---@return number y
---@return number w
---@return number h
local function GetDefaultBounds()
return ScreenScaleH(10), ScreenScaleH(275), ScreenScaleH(320), ScreenScaleH(120)
end
---Add a new chatbox tab
---@param key string Internal unique name
---@param name string Display name
---@param icon string Path to icon
---@param callback fun(): Panel What to do when the tab is created
function cbox.chatbox.AddTab(key, name, icon, callback)
cbox.chatbox.tabs[key] = {
name = name,
icon = icon,
callback = callback,
}
end
local MATERIAL_BLUR = Material("pp/blurscreen")
local oldSkin = SKIN
SKIN = derma.GetDefaultSkin()
local CLOSE_BUTTON = GWEN.CreateTextureNormal(32, 452, 29, 17)
local CLOSE_BUTTON_HOVER = GWEN.CreateTextureNormal(64, 452, 29, 17)
local CLOSE_BUTTON_DOWN = GWEN.CreateTextureNormal(96, 452, 29, 17)
SKIN = oldSkin
local COLOR_DISABLED = Color(255, 255, 255, 50)
local function CreateChatbox()
if IsValid(cbox.chatbox.panels.frame) then
cbox.chatbox.panels.frame:Remove()
end
local frame = vgui.Create("DFrame", nil, "cbox.chatbox")
frame:SetCookieName("cbox_chatbox")
frame:SetDeleteOnClose(false)
frame:SetSizable(true)
frame:SetScreenLock(true)
frame:DockPadding(4, 4, 4, 4)
frame.btnMinim:SetVisible(false)
frame.btnMaxim:SetVisible(false)
frame.lblTitle:SetVisible(false)
function frame:Paint(w, h)
local alpha = CHATBOX_ALPHA:GetInt()
if CHATBOX_BLUR:GetBool() and alpha ~= 255 then
local x, y = self:LocalToScreen(0, 0)
surface_SetMaterial(MATERIAL_BLUR)
surface_SetDrawColor(255, 255, 255, 255)
for i = 0.33, 1, 0.33 do
MATERIAL_BLUR:SetFloat("$blur", 5 * i)
MATERIAL_BLUR:Recompute()
render_UpdateScreenEffectTexture()
surface_DrawTexturedRect(x * -1, y * -1, ScrW(), ScrH())
end
end
local color = string.Explode(" ", CHATBOX_COLOR:GetString())
surface_SetDrawColor(tonumber(color[1]), tonumber(color[2]), tonumber(color[3]), alpha)
surface_DrawRect(0, 0, w, h)
end
local dx, dy, dw, dh = GetDefaultBounds()
-- TODO: make this configurable
frame:SetMinWidth(dw)
frame:SetMinWidth(dh)
-- TODO: save resizing/moving
frame:SetPos(dx, dy)
frame:SetSize(dw, dh)
frame:SetVisible(false)
cbox.chatbox.panels.frame = frame
local tabs = vgui.Create("DPropertySheet", frame, "cbox.chatbox.tabs")
tabs:Dock(FILL)
tabs:SetPadding(0)
function tabs:Paint(w, h)
surface_SetDrawColor(0, 0, 0, 72)
surface_DrawRect(0, 20, w, h - 20)
end
for id, tab in next, cbox.chatbox.tabs do
local function catch(err)
cbox.utils.RealmError(("Failed to create tab %q:"):format(id), err)
end
local ok, ret = xpcall(tab.callback, catch)
if not ok then continue end
if not ispanel(ret) then
cbox.utils.RealmError(("Got non-panel for tab %q!"):format(id))
continue
end
tabs:AddSheet(tab.name, ret, tab.icon)
end
frame.btnClose:SetZPos(99)
end
if not IsValid(cbox.chatbox.panels.frame) then
CreateChatbox()
end
---Opens the chatbox
---@param alt? boolean Was this request to open made by messagemode2 (team chat)
function cbox.chatbox.Open(alt)
alt = alt ~= nil and alt or false
if not IsValid(cbox.chatbox.panels.frame) then
CreateChatbox()
end
cbox.chatbox.panels.frame:SetVisible(true)
cbox.chatbox.panels.frame:MakePopup()
cbox.chatbox.panels.input:RequestFocus()
hook.Run("StartChat")
end
---Closes the chatbox
function cbox.chatbox.Close()
cbox.chatbox.panels.frame:Close()
hook.Run("FinishChat")
cbox.chatbox.panels.input:SetText("")
hook.Run("ChatTextChanged", "")
end
hook.Add("PlayerBindPress", "cbox.chatbox", function(ply, bind, pressed)
if bind ~= "messagemode" and bind ~= "messagemode2" then return end
cbox.chatbox.Open(bind == "messagemode2")
return true
end)
concommand.Add("cbox_chatbox_reload", function()
CreateChatbox()
end, nil, "Reloads the chatbox")