mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
285 lines
6.4 KiB
Lua
285 lines
6.4 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 animationTime = 0.75
|
||
|
|
|
||
|
|
-- notice manager
|
||
|
|
-- this manages positions/animations for notice panels
|
||
|
|
local PANEL = {}
|
||
|
|
|
||
|
|
AccessorFunc(PANEL, "padding", "Padding", FORCE_NUMBER)
|
||
|
|
|
||
|
|
function PANEL:Init()
|
||
|
|
self:SetSize(ScrW() * 0.4, ScrH())
|
||
|
|
self:SetZPos(-99999)
|
||
|
|
self:SetMouseInputEnabled(false)
|
||
|
|
self:SetKeyboardInputEnabled(false)
|
||
|
|
|
||
|
|
self.notices = {}
|
||
|
|
self.padding = 4
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:GetAll()
|
||
|
|
return self.notices
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:Clear()
|
||
|
|
for _, v in ipairs(self.notices) do
|
||
|
|
self:RemoveNotice(v)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:AddNotice(text, bError)
|
||
|
|
if (IsValid(ix.gui.characterMenu) and !ix.gui.characterMenu.bClosing) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local panel = self:Add("ixNotice")
|
||
|
|
panel:SetText(text)
|
||
|
|
panel:SetError(bError or text:utf8sub(#text, #text) == "!")
|
||
|
|
panel:SizeToContents()
|
||
|
|
panel.currentY = -panel:GetTall()
|
||
|
|
panel:SetPos(self.padding, panel.currentY)
|
||
|
|
|
||
|
|
-- setup duration timer
|
||
|
|
panel:CreateAnimation(ix.option.Get("noticeDuration", 8), {
|
||
|
|
index = 2,
|
||
|
|
target = {duration = 1},
|
||
|
|
bIgnoreConfig = true,
|
||
|
|
|
||
|
|
OnComplete = function(animation, this)
|
||
|
|
self:RemoveNotice(this)
|
||
|
|
end
|
||
|
|
})
|
||
|
|
|
||
|
|
table.insert(self.notices, 1, panel)
|
||
|
|
self:Organize()
|
||
|
|
|
||
|
|
-- remove old notice if we've hit the limit of notices
|
||
|
|
if (#self.notices > ix.option.Get("noticeMax", 4)) then
|
||
|
|
for i = #self.notices, 1, -1 do
|
||
|
|
local notice = self.notices[i]
|
||
|
|
|
||
|
|
if (IsValid(notice) and !notice.bClosing) then
|
||
|
|
self:RemoveNotice(notice)
|
||
|
|
break
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return panel
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:RemoveNotice(panel)
|
||
|
|
panel.bClosing = true
|
||
|
|
panel:CreateAnimation(animationTime, {
|
||
|
|
index = 3,
|
||
|
|
target = {outAnimation = 0},
|
||
|
|
easing = "outQuint",
|
||
|
|
|
||
|
|
OnComplete = function(animation, this)
|
||
|
|
local toRemove
|
||
|
|
|
||
|
|
for k, v in ipairs(self.notices) do
|
||
|
|
if (v == this) then
|
||
|
|
toRemove = k
|
||
|
|
break
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if (toRemove) then
|
||
|
|
table.remove(self.notices, toRemove)
|
||
|
|
end
|
||
|
|
|
||
|
|
this:SetText("") -- (hack) text remains for a frame after remove is called, so let's make sure we don't draw it
|
||
|
|
this:Remove()
|
||
|
|
end
|
||
|
|
})
|
||
|
|
end
|
||
|
|
|
||
|
|
-- update target Y positions and animations
|
||
|
|
function PANEL:Organize()
|
||
|
|
local currentTarget = self.padding
|
||
|
|
|
||
|
|
for _, v in ipairs(self.notices) do
|
||
|
|
v:CreateAnimation(animationTime, {
|
||
|
|
index = 1,
|
||
|
|
target = {currentY = currentTarget},
|
||
|
|
easing = "outElastic",
|
||
|
|
|
||
|
|
Think = function(animation, panel)
|
||
|
|
panel:SetPos(
|
||
|
|
self:GetWide() - panel:GetWide() - self.padding,
|
||
|
|
math.min(panel.currentY + 1, currentTarget) -- easing eventually hits subpixel movement so we level it off
|
||
|
|
)
|
||
|
|
end
|
||
|
|
})
|
||
|
|
|
||
|
|
currentTarget = currentTarget + self.padding + v:GetTall()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:Think()
|
||
|
|
if IsValid(ix.gui.menu) and ix.gui.menu:IsVisible() then
|
||
|
|
self:SetPos(ScrW() - ScrW() * 0.4, SScaleMin(50 / 3))
|
||
|
|
else
|
||
|
|
self:SetPos(ScrW() - ScrW() * 0.4, 0)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
vgui.Register("ixNoticeManager", PANEL, "Panel")
|
||
|
|
|
||
|
|
-- notice panel
|
||
|
|
-- these do not manage their own enter/exit animations or lifetime
|
||
|
|
DEFINE_BASECLASS("DLabel")
|
||
|
|
PANEL = {}
|
||
|
|
|
||
|
|
AccessorFunc(PANEL, "bError", "Error", FORCE_BOOL)
|
||
|
|
AccessorFunc(PANEL, "padding", "Padding", FORCE_NUMBER)
|
||
|
|
|
||
|
|
function PANEL:Init()
|
||
|
|
self:SetSize(256, 36)
|
||
|
|
self:SetContentAlignment(5)
|
||
|
|
self:SetExpensiveShadow(1, Color(0, 0, 0, 150))
|
||
|
|
self:SetFont("ixNoticeFont")
|
||
|
|
self:SetTextColor(color_white)
|
||
|
|
self:SetDrawOnTop(true)
|
||
|
|
self:DockPadding(0, 0, 0, 0)
|
||
|
|
self:DockMargin(0, 0, 0, 0)
|
||
|
|
|
||
|
|
self.bError = false
|
||
|
|
self.bHovered = false
|
||
|
|
|
||
|
|
self.errorAnimation = 0
|
||
|
|
self.padding = 8
|
||
|
|
self.currentY = 0
|
||
|
|
self.duration = 0
|
||
|
|
self.outAnimation = 1
|
||
|
|
self.alpha = 255
|
||
|
|
|
||
|
|
LocalPlayer():EmitSound("Helix.Notify")
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:SetError(bValue)
|
||
|
|
self.bError = tobool(bValue)
|
||
|
|
|
||
|
|
if (bValue) then
|
||
|
|
self.errorAnimation = 1
|
||
|
|
self:CreateAnimation(animationTime, {
|
||
|
|
index = 5,
|
||
|
|
target = {errorAnimation = 0},
|
||
|
|
easing = "outQuint"
|
||
|
|
})
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:SizeToContents()
|
||
|
|
local contentWidth, contentHeight = self:GetContentSize()
|
||
|
|
contentWidth = contentWidth + self.padding * 2
|
||
|
|
contentHeight = contentHeight + self.padding * 2
|
||
|
|
|
||
|
|
local manager = ix.gui.notices
|
||
|
|
local maxWidth = math.min(IsValid(manager) and (manager:GetWide() - manager:GetPadding() * 2) or ScrW(), contentWidth)
|
||
|
|
|
||
|
|
if (contentWidth > maxWidth) then
|
||
|
|
self:SetWide(maxWidth)
|
||
|
|
self:SetTextInset(self.padding * 2, 0)
|
||
|
|
self:SetWrap(true)
|
||
|
|
|
||
|
|
self:SizeToContentsY()
|
||
|
|
self:SetWide(self:GetContentSize())
|
||
|
|
else
|
||
|
|
self:SetSize(contentWidth, contentHeight)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:SizeToContentsY()
|
||
|
|
BaseClass.SizeToContentsY(self)
|
||
|
|
self:SetTall(self:GetTall() + self.padding * 2)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:OnMouseHover()
|
||
|
|
self:CreateAnimation(animationTime * 0.5, {
|
||
|
|
index = 4,
|
||
|
|
target = {alpha = 0},
|
||
|
|
easing = "outQuint",
|
||
|
|
|
||
|
|
Think = function(animation, panel)
|
||
|
|
panel:SetAlpha(panel.alpha)
|
||
|
|
end
|
||
|
|
})
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:OnMouseLeave()
|
||
|
|
self:CreateAnimation(animationTime * 0.5, {
|
||
|
|
index = 4,
|
||
|
|
target = {alpha = 255},
|
||
|
|
easing = "outQuint",
|
||
|
|
|
||
|
|
Think = function(animation, panel)
|
||
|
|
panel:SetAlpha(panel.alpha)
|
||
|
|
end
|
||
|
|
})
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:Paint(width, height)
|
||
|
|
if (self.outAnimation < 1) then
|
||
|
|
local x, y = self:LocalToScreen(0, 0)
|
||
|
|
render.SetScissorRect(x, y, x + self:GetWide(), y + (self:GetTall() * self.outAnimation), true)
|
||
|
|
end
|
||
|
|
|
||
|
|
local x, y = self:LocalToScreen(0, 0)
|
||
|
|
local mouseX, mouseY = gui.MousePos()
|
||
|
|
|
||
|
|
if (mouseX >= x and mouseX <= x + width and
|
||
|
|
mouseY >= y and mouseY <= y + height) then
|
||
|
|
if (!self.bHovered) then
|
||
|
|
self.bHovered = true
|
||
|
|
self:OnMouseHover()
|
||
|
|
end
|
||
|
|
elseif (self.bHovered) then
|
||
|
|
self.bHovered = false
|
||
|
|
self:OnMouseLeave()
|
||
|
|
end
|
||
|
|
|
||
|
|
ix.util.DrawBlur(self)
|
||
|
|
|
||
|
|
if (self.errorAnimation > 0) then
|
||
|
|
local color = derma.GetColor("Error", self)
|
||
|
|
|
||
|
|
surface.SetDrawColor(
|
||
|
|
color.r * self.errorAnimation,
|
||
|
|
color.g * self.errorAnimation,
|
||
|
|
color.b * self.errorAnimation,
|
||
|
|
self.errorAnimation * 255 + ((1 - self.errorAnimation) * 66)
|
||
|
|
)
|
||
|
|
else
|
||
|
|
surface.SetDrawColor(0, 0, 0, 66)
|
||
|
|
end
|
||
|
|
|
||
|
|
surface.DrawRect(0, 0, width, height)
|
||
|
|
|
||
|
|
surface.SetDrawColor(self.bError and derma.GetColor("Error", self) or ix.config.Get("color"))
|
||
|
|
surface.DrawRect(0, height - 1, width * self.duration, 1)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PANEL:PaintOver(width, height)
|
||
|
|
render.SetScissorRect(0, 0, 0, 0, false)
|
||
|
|
end
|
||
|
|
|
||
|
|
vgui.Register("ixNotice", PANEL, "DLabel")
|
||
|
|
|
||
|
|
if (IsValid(ix.gui.notices)) then
|
||
|
|
ix.gui.notices:Remove()
|
||
|
|
ix.gui.notices = vgui.Create("ixNoticeManager")
|
||
|
|
else
|
||
|
|
ix.gui.notices = vgui.Create("ixNoticeManager")
|
||
|
|
end
|