round AND blur???, fade in

This commit is contained in:
Cynthia Foxwell 2023-12-18 17:10:01 -07:00
parent 631874aebc
commit fe2785825b
3 changed files with 226 additions and 34 deletions

View file

@ -1,12 +1,32 @@
local DisableClipping = DisableClipping
local ScrW = ScrW local ScrW = ScrW
local ScrH = ScrH local ScrH = ScrH
local Color = Color
local STENCIL_EQUAL = STENCIL_EQUAL
local STENCIL_KEEP = STENCIL_KEEP
local STENCIL_NEVER = STENCIL_NEVER
local STENCIL_REPLACE = STENCIL_REPLACE
local draw = draw
local math = math
local render = render local render = render
local string = string
local surface = surface local surface = surface
local draw_NoTexture = draw.NoTexture
local math_rad = math.rad
local math_sin = math.sin
local math_cos = math.cos
local render_ClearStencil = render.ClearStencil
local render_SetStencilCompareFunction = render.SetStencilCompareFunction
local render_SetStencilEnable = render.SetStencilEnable
local render_SetStencilFailOperation = render.SetStencilFailOperation
local render_SetStencilPassOperation = render.SetStencilPassOperation
local render_SetStencilReferenceValue = render.SetStencilReferenceValue
local render_SetStencilTestMask = render.SetStencilTestMask
local render_SetStencilWriteMask = render.SetStencilWriteMask
local render_SetStencilZFailOperation = render.SetStencilZFailOperation
local render_UpdateScreenEffectTexture = render.UpdateScreenEffectTexture local render_UpdateScreenEffectTexture = render.UpdateScreenEffectTexture
local surface_DrawPoly = surface.DrawPoly
local surface_DrawRect = surface.DrawRect local surface_DrawRect = surface.DrawRect
local surface_DrawTexturedRect = surface.DrawTexturedRect local surface_DrawTexturedRect = surface.DrawTexturedRect
local surface_SetDrawColor = surface.SetDrawColor local surface_SetDrawColor = surface.SetDrawColor
@ -19,6 +39,7 @@ cbox.chatbox.panels = cbox.chatbox.panels or {}
local CHATBOX_COLOR = CreateClientConVar("cbox_chatbox_color", "160 160 160", true, false, "Chatbox background color") 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_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") local CHATBOX_BLUR = CreateClientConVar("cbox_chatbox_blur", "0", true, false, "Chatbox background is blurred")
local CHATBOX_FADE = CreateClientConVar("cbox_chatbox_fade", "1", true, false, "Chatbox fades in and out")
---@param height number ---@param height number
---@return number ---@return number
@ -50,6 +71,55 @@ end
local MATERIAL_BLUR = Material("pp/blurscreen") local MATERIAL_BLUR = Material("pp/blurscreen")
local function add_rounded_poly(poly, x, y, rad, seg, offset)
offset = offset or 0
for i = 0, seg do
local r = math_rad(((i + offset) / seg) * -90)
poly[#poly + 1] = {
x = x + math_sin(r) * rad,
y = y + math_cos(r) * rad,
u = math_sin(r) / 2 + 0.5,
v = math_cos(r) / 2 + 0.5,
}
end
end
local function RoundedBoxPoly(x, y, w, h, rad, seg)
local poly = {}
add_rounded_poly(poly, x + rad, y + rad, rad, seg, seg)
poly[#poly + 1] = {
x = x + (w - rad),
y = y,
u = 0.5,
v = 0.5,
}
add_rounded_poly(poly, x + (w - rad), y + rad, rad, seg, seg * 2)
poly[#poly + 1] = {
x = x + w,
y = y + (h - rad),
u = 0.5,
v = 0.5,
}
add_rounded_poly(poly, x + (w - rad), y + (h - rad), rad, seg, seg * 3)
poly[#poly + 1] = {
x = x + rad,
y = y + h,
u = 0.5,
v = 0.5,
}
add_rounded_poly(poly, x + rad, y + (h - rad), rad, seg)
surface_DrawPoly(poly)
end
local function CreateChatbox() local function CreateChatbox()
if IsValid(cbox.chatbox.panels.frame) then if IsValid(cbox.chatbox.panels.frame) then
cbox.chatbox.panels.frame:Remove() cbox.chatbox.panels.frame:Remove()
@ -60,15 +130,85 @@ local function CreateChatbox()
frame:SetDeleteOnClose(false) frame:SetDeleteOnClose(false)
frame:SetSizable(true) frame:SetSizable(true)
frame:SetScreenLock(true) frame:SetScreenLock(true)
frame:DockPadding(4, 4, 4, 4) frame:DockPadding(8, 8, 8, 8)
frame.btnMinim:SetVisible(false) local dx, dy, dw, dh = GetDefaultBounds()
frame.btnMaxim:SetVisible(false)
frame.lblTitle:SetVisible(false) -- 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)
function frame:PerformLayout() end
frame.btnClose:Remove()
frame.btnMinim:Remove()
frame.btnMaxim:Remove()
frame.lblTitle:Remove()
function frame:CrossFade(anim, delta, out)
if anim.Finished then
if out then
self:Close()
else
self:MakePopup()
end
end
if anim.Started then
if out then
self:SetAlpha(255)
else
self:SetAlpha(0)
end
end
self:SetAlpha(out and 255 * (1 - delta) or 255 * delta)
end
frame.animFade = Derma_Anim("Fade", frame, frame.CrossFade)
frame.oldThink = frame.Think
function frame:Think()
self:oldThink()
self.animFade:Run()
-- TODO: save position and size
end
function frame:Paint(w, h) function frame:Paint(w, h)
local alpha = CHATBOX_ALPHA:GetInt() local alpha = CHATBOX_ALPHA:GetInt()
-- Reset everything to known good
render_SetStencilWriteMask( 0xFF )
render_SetStencilTestMask( 0xFF )
render_SetStencilReferenceValue( 0 )
render_SetStencilPassOperation( STENCIL_KEEP )
render_SetStencilZFailOperation( STENCIL_KEEP )
render_ClearStencil()
-- Enable stencils
render_SetStencilEnable( true )
-- Set everything up everything draws to the stencil buffer instead of the screen
render_SetStencilReferenceValue( 1 )
render_SetStencilCompareFunction( STENCIL_NEVER )
render_SetStencilFailOperation( STENCIL_REPLACE )
draw_NoTexture()
surface_SetDrawColor(255, 255, 255)
RoundedBoxPoly(0, 0, w, h, 8, 24)
-- Only draw things that are in the stencil buffer
render_SetStencilCompareFunction( STENCIL_EQUAL )
render_SetStencilFailOperation( STENCIL_KEEP )
if CHATBOX_BLUR:GetBool() and alpha ~= 255 then if CHATBOX_BLUR:GetBool() and alpha ~= 255 then
local x, y = self:LocalToScreen(0, 0) local x, y = self:LocalToScreen(0, 0)
@ -83,32 +223,26 @@ local function CreateChatbox()
end end
end end
local color = string.Explode(" ", CHATBOX_COLOR:GetString()) local r, g, b = CHATBOX_COLOR:GetString():match("(%d+) (%d+) (%d+)")
surface_SetDrawColor(tonumber(color[1]), tonumber(color[2]), tonumber(color[3]), alpha) surface_SetDrawColor(r, g, b, alpha)
surface_DrawRect(0, 0, w, h) surface_DrawRect(0, 0, w, h)
-- Let everything render normally again
render_SetStencilEnable(false)
end 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 cbox.chatbox.panels.frame = frame
local tabs = vgui.Create("DPropertySheet", frame, "cbox.chatbox.tabs") local tabs = vgui.Create("DPropertySheet", frame, "cbox.chatbox.tabs")
tabs:Dock(FILL) tabs:Dock(FILL)
tabs:SetPadding(0) tabs:SetPadding(0)
function tabs:Paint(w, h) function tabs:Paint(w, h) end
surface_SetDrawColor(0, 0, 0, 128)
surface_DrawRect(0, 20, w, h - 20) function tabs:OnActiveTabChanged( old, new )
if new:GetPanel().cbox_id == "\1chat" then
cbox.chatbox.panels.input:RequestFocus()
end
end end
for id, tab in next, cbox.chatbox.tabs do for id, tab in next, cbox.chatbox.tabs do
@ -123,10 +257,9 @@ local function CreateChatbox()
continue continue
end end
tabs:AddSheet(tab.name, ret, tab.icon) local sheet = tabs:AddSheet(tab.name, ret, tab.icon)
sheet.Panel.cbox_id = id
end end
frame.btnClose:SetZPos(99)
end end
local function Init() local function Init()
@ -142,6 +275,7 @@ local function Init()
hook.Add("PlayerBindPress", "cbox.chatbox", function(ply, bind, pressed) hook.Add("PlayerBindPress", "cbox.chatbox", function(ply, bind, pressed)
if bind ~= "messagemode" and bind ~= "messagemode2" then return end if bind ~= "messagemode" and bind ~= "messagemode2" then return end
if not pressed then return end
cbox.chatbox.Open(bind == "messagemode2") cbox.chatbox.Open(bind == "messagemode2")
@ -154,25 +288,32 @@ end
function cbox.chatbox.Open(alt) function cbox.chatbox.Open(alt)
alt = alt ~= nil and alt or false alt = alt ~= nil and alt or false
if not IsValid(cbox.chatbox.panels.frame) then local frame = cbox.chatbox.panels.frame
if not IsValid(frame) then
CreateChatbox() CreateChatbox()
end end
cbox.chatbox.panels.frame:SetVisible(true) frame:SetVisible(true)
cbox.chatbox.panels.frame:MakePopup()
if frame.animFade and CHATBOX_FADE:GetBool() then
frame.animFade:Start(0.1, false)
else
frame:MakePopup()
end
if not IsValid(cbox.chatbox.panels.input) then if not IsValid(cbox.chatbox.panels.input) then
-- attempt to reinit -- attempt to reinit
if IsValid(cbox.chatbox.panels.frame) then if IsValid(frame) then
cbox.chatbox.panels.frame:Remove() frame:Remove()
end end
Init() Init()
end end
if not IsValid(cbox.chatbox.panels.input) then if not IsValid(cbox.chatbox.panels.input) then
cbox.utils.RealmError("Input isn't valid, chat tab failed to load, bailing!") cbox.utils.RealmError("Input isn't valid, chat tab failed to load, bailing!")
if IsValid(cbox.chatbox.panels.frame) then if IsValid(frame) then
cbox.chatbox.panels.frame:Remove() frame:Remove()
end end
hook.Remove("PlayerBindPress", "cbox.chatbox") hook.Remove("PlayerBindPress", "cbox.chatbox")
return return
@ -185,7 +326,13 @@ end
---Closes the chatbox ---Closes the chatbox
function cbox.chatbox.Close() function cbox.chatbox.Close()
cbox.chatbox.panels.frame:Close() local frame = cbox.chatbox.panels.frame
if frame.animFade and CHATBOX_FADE:GetBool() then
frame.animFade:Start(0.1, true)
else
frame:Close()
end
hook.Run("FinishChat") hook.Run("FinishChat")

View file

@ -1,9 +1,23 @@
local Color = Color
local surface = surface
local surface_DrawRect = surface.DrawRect
local surface_SetDrawColor = surface.SetDrawColor
local INPUT_TEXT_COLOR = Color(221, 221, 221)
local INPUT_HIGHLIGHT_COLOR = Color(192, 28, 0, 140)
cbox.chatbox.AddTab("\1chat", "Chat", "icon16/comments.png", function() cbox.chatbox.AddTab("\1chat", "Chat", "icon16/comments.png", function()
local wrapper = vgui.Create("EditablePanel") local wrapper = vgui.Create("EditablePanel")
-- TODO: custom richtext panel -- TODO: custom richtext panel
local history = vgui.Create("RichText", wrapper) local history = vgui.Create("RichText", wrapper)
history:Dock(FILL) history:Dock(FILL)
function history:Paint(w, h)
surface_SetDrawColor(0, 0, 0, 128)
surface_DrawRect(0, 0, w, h)
end
cbox.chatbox.panels.history = history cbox.chatbox.panels.history = history
function history:PerformLayout() function history:PerformLayout()
@ -13,18 +27,35 @@ cbox.chatbox.AddTab("\1chat", "Chat", "icon16/comments.png", function()
local input_wrapper = vgui.Create("EditablePanel", wrapper) local input_wrapper = vgui.Create("EditablePanel", wrapper)
input_wrapper:SetHeight(20) input_wrapper:SetHeight(20)
input_wrapper:DockMargin(0, 8, 0, 0)
input_wrapper:Dock(BOTTOM) input_wrapper:Dock(BOTTOM)
local input = vgui.Create("DTextEntry", input_wrapper) local input = vgui.Create("DTextEntry", input_wrapper)
input:DockMargin(4, 0, 0, 0)
input:Dock(FILL) input:Dock(FILL)
input:SetFont("ChatFont")
cbox.chatbox.panels.input = input cbox.chatbox.panels.input = input
function input:Paint(w, h)
surface_SetDrawColor(0, 0, 0, 128)
surface_DrawRect(0, 0, w, h)
self:DrawTextEntryText(INPUT_TEXT_COLOR, INPUT_HIGHLIGHT_COLOR, INPUT_TEXT_COLOR)
end
local mode_switch = vgui.Create("DButton", input_wrapper) local mode_switch = vgui.Create("DButton", input_wrapper)
mode_switch:SetFont("ChatFont")
mode_switch:SetTextColor(INPUT_TEXT_COLOR)
mode_switch:SetText("Say") mode_switch:SetText("Say")
mode_switch:SizeToContents() mode_switch:SizeToContents()
mode_switch:Dock(LEFT) mode_switch:Dock(LEFT)
cbox.chatbox.panels.mode_switch = mode_switch cbox.chatbox.panels.mode_switch = mode_switch
function mode_switch:Paint(w, h)
surface_SetDrawColor(0, 0, 0, 128)
surface_DrawRect(0, 0, w, h)
end
function mode_switch:DoClick() function mode_switch:DoClick()
-- TODO -- TODO
end end

View file

@ -0,0 +1,14 @@
local surface = surface
local surface_DrawRect = surface.DrawRect
local surface_SetDrawColor = surface.SetDrawColor
cbox.chatbox.AddTab("zzzzzzzsettings", "Settings", "icon16/cog.png", function()
local wrapper = vgui.Create("EditablePanel")
function wrapper:Paint(w, h)
surface_SetDrawColor(0, 0, 0, 128)
surface_DrawRect(0, 0, w, h)
end
return wrapper
end)