Redesign
This commit is contained in:
parent
4d0503ad8c
commit
aa7d729cfb
@ -6,4 +6,6 @@ AddCSLuaFile("cfc_disconnect_interface/client/cl_ponger.lua")
|
||||
AddCSLuaFile("cfc_disconnect_interface/client/cl_api.lua")
|
||||
AddCSLuaFile("cfc_disconnect_interface/client/cl_interface.lua")
|
||||
|
||||
resource.AddSingleFile("materials/icons/cross.png")
|
||||
|
||||
include("cfc_disconnect_interface/server/sv_pinger.lua")
|
@ -13,7 +13,7 @@ surface.CreateFont( "CFC_Normal",
|
||||
surface.CreateFont( "CFC_Special",
|
||||
{
|
||||
font = "coolvetica",
|
||||
size = 26,
|
||||
size = 30,
|
||||
weight = 500
|
||||
}
|
||||
)
|
||||
@ -33,11 +33,16 @@ local GAME_WIDTH = 1256
|
||||
|
||||
local interfaceDerma = false
|
||||
|
||||
local TIME_TO_RESTART = 10
|
||||
local TIME_TO_RESTART = 180
|
||||
local timeDown = 0
|
||||
local apiState
|
||||
local previouslyShown = false
|
||||
|
||||
-- Helper function
|
||||
function getFrom(i, ...)
|
||||
return ({...})[i]
|
||||
end
|
||||
|
||||
-- Colors
|
||||
primaryCol = Color( 36, 41, 67 )
|
||||
secondaryCol = Color( 42, 47, 74 )
|
||||
@ -84,7 +89,7 @@ end
|
||||
-- Creates and populates a title bar for the frame
|
||||
local function addTitleBar(frame)
|
||||
local frameW, frameH = frame:GetSize()
|
||||
local titleBarHeight = 32
|
||||
local titleBarHeight = 70
|
||||
|
||||
-- The bar itself
|
||||
local titleBar = vgui.Create( "DPanel", frame )
|
||||
@ -96,11 +101,12 @@ local function addTitleBar(frame)
|
||||
end
|
||||
|
||||
-- Close button, could be removed, but I personally think it should stay, allows you to save e2/sf files
|
||||
local closeBtnPadding = (titleBarHeight - 16) / 2
|
||||
local closeBtnSize = 32
|
||||
local closeBtnPadding = (titleBarHeight - closeBtnSize) / 2
|
||||
local closeBtn = vgui.Create( "DImageButton", titleBar )
|
||||
closeBtn:SetSize( 16, 16 )
|
||||
closeBtn:SetPos( frameW - 16 - closeBtnPadding, closeBtnPadding)
|
||||
closeBtn:SetImage( "icon16/cross.png" )
|
||||
closeBtn:SetSize( closeBtnSize, closeBtnSize )
|
||||
closeBtn:SetPos( frameW - closeBtnSize - closeBtnPadding, closeBtnPadding)
|
||||
closeBtn:SetImage( "icons/cross.png" )
|
||||
function closeBtn:DoClick()
|
||||
frame:Close()
|
||||
end
|
||||
@ -109,10 +115,16 @@ local function addTitleBar(frame)
|
||||
local titleLabelPadding = (titleBarHeight - 26) / 2
|
||||
local titleLabel = vgui.Create( "DLabel", titleBar )
|
||||
titleLabel:SetFont( "CFC_Special" )
|
||||
titleLabel:SetText( "Oops! Looks like the server crashed..." )
|
||||
titleLabel:SizeToContents()
|
||||
titleLabel:SetPos( 0, titleLabelPadding + 2 )
|
||||
titleLabel:CenterHorizontal()
|
||||
|
||||
local function setTitle(title)
|
||||
titleLabel:SetText( title )
|
||||
titleLabel:SizeToContents()
|
||||
titleLabel:SetPos( 0, titleLabelPadding + 2 )
|
||||
titleLabel:CenterHorizontal()
|
||||
end
|
||||
|
||||
setTitle("Oops! Looks like you disconnected...")
|
||||
titleBar.setTitle = setTitle
|
||||
|
||||
return titleBar
|
||||
end
|
||||
@ -121,18 +133,21 @@ end
|
||||
-- xFraction is 0-1 for how far across the button should be
|
||||
-- Colours are self explan
|
||||
local function makeButton(frame, text, xFraction, doClick, outlineCol, fillCol, hoverOutlineCol, hoverFillCol)
|
||||
-- Defaults for colours
|
||||
outlineCol = outlineCol or Color( 255, 255, 255 )
|
||||
fillCol = fillCol or primaryCol
|
||||
hoverOutlineCol = hoverOutlineCol or Color(155,241,255)
|
||||
hoverFillCol = hoverFillCol or primaryCol
|
||||
|
||||
|
||||
local frameW, frameH = frame:GetSize()
|
||||
local btn = vgui.Create( "DButton", frame )
|
||||
|
||||
-- Defaults for colours
|
||||
btn.outlineCol = outlineCol or Color( 255, 255, 255 )
|
||||
btn.fillCol = fillCol or primaryCol
|
||||
btn.hoverOutlineCol = hoverOutlineCol or Color( 255, 255, 255 )
|
||||
btn.hoverFillCol = hoverFillCol or primaryCol
|
||||
|
||||
btn:SetText( text )
|
||||
btn:SetTextColor( Color( 255, 255, 255 ) )
|
||||
btn:SetFont( "CFC_Button" )
|
||||
btn:SetSize( frameW * 0.4, frameH * 0.6 )
|
||||
btn:SetSize( frameW * 0.3, frameH )
|
||||
btn:CenterHorizontal( xFraction )
|
||||
btn:CenterVertical()
|
||||
btn.DoClick = doClick
|
||||
@ -141,7 +156,7 @@ local function makeButton(frame, text, xFraction, doClick, outlineCol, fillCol,
|
||||
btn.fadeState = 0
|
||||
btn.prevTime = CurTime()
|
||||
|
||||
local btnAnimSpeed = 0.05 * 60
|
||||
local btnAnimSpeed = 0.1 * 60
|
||||
|
||||
function btn:Think()
|
||||
-- Make anim same speed for all framerates
|
||||
@ -160,47 +175,99 @@ local function makeButton(frame, text, xFraction, doClick, outlineCol, fillCol,
|
||||
function btn:Paint(w, h)
|
||||
local lineCol
|
||||
local bgCol
|
||||
local borderWeight
|
||||
if self:GetDisabled() then
|
||||
lineCol = Color( 74, 74, 74 )
|
||||
bgCol = fillCol
|
||||
bgCol = self.fillCol
|
||||
borderWeight = btnBorderWeight
|
||||
self:SetCursor( "no" )
|
||||
else
|
||||
lineCol = lerpColor(self.fadeState, outlineCol, hoverOutlineCol)
|
||||
bgCol = lerpColor(self.fadeState, fillCol, hoverFillCol)
|
||||
lineCol = lerpColor(self.fadeState, self.outlineCol, self.hoverOutlineCol)
|
||||
bgCol = lerpColor(self.fadeState, self.fillCol, self.hoverFillCol)
|
||||
borderWeight = 1.5 * btnBorderWeight + 1.5 * self.fadeState * btnBorderWeight
|
||||
self:SetCursor( "hand" )
|
||||
end
|
||||
|
||||
self:SetTextColor( lineCol )
|
||||
surface.SetDrawColor( lineCol )
|
||||
surface.DrawRect( 0, 0, w, h )
|
||||
surface.SetDrawColor( bgCol )
|
||||
surface.DrawRect( btnBorderWeight, btnBorderWeight,
|
||||
w - (btnBorderWeight*2), h - (btnBorderWeight*2) )
|
||||
draw.RoundedBox(h/2, 0, 0, w, h, lineCol)
|
||||
|
||||
local nw, nh = w - (borderWeight*2), h - (borderWeight*2)
|
||||
draw.RoundedBox(nh/2, borderWeight, borderWeight, nw, nh, bgCol)
|
||||
|
||||
end
|
||||
|
||||
return btn
|
||||
end
|
||||
|
||||
local function showMessage(msg)
|
||||
if interfaceDerma and (interfaceDerma.messageLabel:GetText() ~= msg or not interfaceDerma.messageLabel:IsVisible()) then
|
||||
if interfaceDerma.messageLabel:IsVisible() then
|
||||
interfaceDerma.messageLabel:AlphaTo(0, 0.25)
|
||||
timer.Simple(0.25, function()
|
||||
interfaceDerma.messageLabel:setTextAndAlign(msg)
|
||||
interfaceDerma.messageLabel:AlphaTo(255, 0.25)
|
||||
end)
|
||||
else
|
||||
interfaceDerma.messageLabel:setTextAndAlign(msg)
|
||||
interfaceDerma.messageLabel:Show()
|
||||
interfaceDerma.messageLabel:AlphaTo(255, 0.5)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function hideMessage(msg)
|
||||
if interfaceDerma and interfaceDerma.messageLabel:IsVisible() then
|
||||
interfaceDerma.messageLabel:AlphaTo(0, 0.25)
|
||||
timer.Simple(0.25, function()
|
||||
interfaceDerma.messageLabel:Hide()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- Create bar panel and add buttons
|
||||
local function addButtonsBar(frame)
|
||||
local frameW, frameH = frame:GetSize()
|
||||
|
||||
local buttonBarHeight = 64
|
||||
local buttonBarHeight = 90
|
||||
local buttonBarOffset = 90
|
||||
|
||||
local barPanel = vgui.Create( "DPanel", frame )
|
||||
barPanel:SetSize( frameW, buttonBarHeight )
|
||||
barPanel:SetPos( 0, frameH - buttonBarHeight )
|
||||
function barPanel:Paint(w, h)
|
||||
surface.SetDrawColor( accentCol )
|
||||
surface.DrawLine( 16, 0, w - 16, 0 )
|
||||
end
|
||||
barPanel:SetPos( 0, frameH - buttonBarHeight - buttonBarOffset )
|
||||
barPanel.Paint = nil
|
||||
|
||||
-- Put buttons onto the panel as members for easy access
|
||||
barPanel.reconBtn = makeButton(barPanel, "RECONNECT", 0.25, rejoin,
|
||||
Color( 74, 251, 191 ), nil, Color( 74, 251, 191 ), Color( 64, 141, 131 ))
|
||||
barPanel.reconBtn = makeButton(barPanel, "RECONNECT", 0.25, function()
|
||||
if not barPanel.disconMode then
|
||||
rejoin()
|
||||
else
|
||||
leave()
|
||||
end
|
||||
end)
|
||||
--Color( 74, 251, 191 ), nil, Color( 74, 251, 191 ), Color( 64, 141, 131 ))
|
||||
-- Reconnect button will usually start as disabled
|
||||
barPanel.reconBtn:SetDisabled( true )
|
||||
barPanel.disconBtn = makeButton(barPanel, "DISCONNECT", 0.75, leave)
|
||||
barPanel.disconBtn = makeButton( barPanel, "DISCONNECT", 0.75, function(self)
|
||||
if not barPanel.disconMode then
|
||||
showMessage("Are you sure? Hang in there, the server will restart soon...")
|
||||
barPanel.disconMode = true
|
||||
barPanel.disconPrevDisabled = barPanel.reconBtn:GetDisabled()
|
||||
barPanel.reconBtn:SetDisabled(false)
|
||||
self:SetText("NO")
|
||||
self.fadeState = 0
|
||||
self.hoverOutlineCol = Color( 255, 0, 0 )
|
||||
barPanel.reconBtn.hoverOutlineCol = Color( 0, 255, 0 )
|
||||
barPanel.reconBtn:SetText("YES")
|
||||
else
|
||||
hideMessage()
|
||||
barPanel.disconMode = false
|
||||
self:SetText("DISCONNECT")
|
||||
self.hoverOutlineCol = Color( 255, 255, 255 )
|
||||
barPanel.reconBtn:SetText("RECONNECT")
|
||||
barPanel.reconBtn.hoverOutlineCol = Color( 255, 255, 255 )
|
||||
barPanel.reconBtn:SetDisabled(barPanel.disconPrevDisabled)
|
||||
end
|
||||
end)
|
||||
|
||||
return barPanel
|
||||
end
|
||||
@ -209,26 +276,30 @@ end
|
||||
local function makeLabel(frame, text, top, col, xFraction)
|
||||
col = col or Color( 255, 255, 255 )
|
||||
local label = vgui.Create( "DLabel", frame )
|
||||
label:SetText( text )
|
||||
label:SetFont( "CFC_Special" )
|
||||
label:SizeToContents()
|
||||
label:SetPos( 0, top )
|
||||
label:SetTextColor( col )
|
||||
label:CenterHorizontal( xFraction )
|
||||
function label:setTextAndAlign( str )
|
||||
self:SetText( str )
|
||||
self:SizeToContents()
|
||||
self:SetPos( 0, top )
|
||||
self:SetTextColor( col )
|
||||
self:CenterHorizontal( xFraction )
|
||||
end
|
||||
label:setTextAndAlign(text)
|
||||
return label
|
||||
end
|
||||
|
||||
-- Text for internet down on body
|
||||
local function populateBodyInternetDown(body)
|
||||
local label1 = makeLabel(body, "Looks like your internet has gone down!", 20)
|
||||
local label2 = makeLabel(body, "Stick around for when it comes back", 64)
|
||||
local label1 = makeLabel(body, "Please check you're still connected to the internet.", 20)
|
||||
local label2 = makeLabel(body, "In the meantime,", 80)
|
||||
return "Oops, looks like you disconnected"
|
||||
end
|
||||
|
||||
-- Text for server down on body
|
||||
local function populateBodyServerDown(body)
|
||||
|
||||
local frameW, frameH = body:GetSize()
|
||||
local restartTimeStr = "The server normally takes about " .. secondsAsTime(TIME_TO_RESTART) .. " to restart!"
|
||||
local restartTimeStr = "The server normally takes about " .. secondsAsTime(TIME_TO_RESTART) .. " to restart."
|
||||
local restartTimeLabel = makeLabel(body, restartTimeStr, 0)
|
||||
local curTimePreLabel = makeLabel(body, "It has been down for", 32)
|
||||
-- When the server comes back up, "It has been down for" => "It was down for"
|
||||
@ -242,50 +313,51 @@ local function populateBodyServerDown(body)
|
||||
end
|
||||
end
|
||||
|
||||
-- Label for when timeDown > averageTimeDown
|
||||
-- Currently on the right, change the 0.8 at the end to move it horizontally
|
||||
local tooLongLabel = makeLabel(body, "Uh oh, seems it's taking a little longer than usual!", 70, Color( 251, 191, 83 ), 0.8)
|
||||
tooLongLabel:SetAlpha(0)
|
||||
tooLongLabel:Hide()
|
||||
|
||||
-- Text for downTime, update its value in Think
|
||||
-- If server comes back up, make it green and stop updating it
|
||||
-- If timeDown > averageTimeDown, make it red and show the tooLongLabel
|
||||
-- If timeDown > averageTimeDown, make it red and show the messageLabel
|
||||
local curTimeLabel = makeLabel(body, secondsAsTime(math.floor(timeDown)), 70, Color( 251, 191, 83 ))
|
||||
function curTimeLabel:Think()
|
||||
if apiState ~= crashApi.SERVER_UP then
|
||||
self:SetText(secondsAsTime(math.floor(timeDown)))
|
||||
if timeDown > TIME_TO_RESTART then
|
||||
self:SetTextColor(Color(255, 0, 0))
|
||||
if not tooLongLabel:IsVisible() then
|
||||
tooLongLabel:Show()
|
||||
tooLongLabel:AlphaTo(255, 1)
|
||||
if not messageLabel:IsVisible() then
|
||||
showMessage("Uh oh, seems it's taking a little longer than usual...")
|
||||
end
|
||||
end
|
||||
else
|
||||
self:SetTextColor(Color(0, 255, 0))
|
||||
end
|
||||
end
|
||||
|
||||
return "Oops, looks like the server crashed..."
|
||||
end
|
||||
|
||||
-- Fill the body with elements, body created elsewhere as it's size relies on size of titleBar and buttonsBar
|
||||
local function populateBody(body)
|
||||
body.Paint = nil
|
||||
local title
|
||||
local frameW, frameH = body:GetSize()
|
||||
|
||||
-- Warning message label
|
||||
interfaceDerma.messageLabel = makeLabel(body, "", frameH - 45, Color( 255, 255, 0 ), 0.5)
|
||||
interfaceDerma.messageLabel:SetAlpha(0)
|
||||
interfaceDerma.messageLabel:Hide()
|
||||
|
||||
-- Fill top text based on crashApi state
|
||||
if apiState == crashApi.NO_INTERNET then
|
||||
populateBodyInternetDown(body)
|
||||
title = populateBodyInternetDown(body)
|
||||
else -- Server down or up via api, and down via net
|
||||
populateBodyServerDown(body)
|
||||
title = populateBodyServerDown(body)
|
||||
end
|
||||
|
||||
local frameW, frameH = 0.8 * ScrW(), 0.8 * ScrH()
|
||||
local playGameLabel = makeLabel(body, "Why not play a game while you wait? (Press space)", 108)
|
||||
|
||||
-- Game wrapper, in case we ever want to make a game that runs in lua
|
||||
local gamePanel = vgui.Create( "DPanel", body )
|
||||
gamePanel:SetSize( frameW - 20, frameH - 134 - 15 )
|
||||
gamePanel:SetPos( -6, 134 + 10 )
|
||||
gamePanel:SetPos( 10, 134 )
|
||||
gamePanel.Paint = nil
|
||||
|
||||
-- HTML element rending game at GAME_URL, constantly grabs focus
|
||||
@ -296,6 +368,8 @@ local function populateBody(body)
|
||||
function gameHtml:Think()
|
||||
if not gameHtml:HasFocus() then gameHtml:RequestFocus() end
|
||||
end
|
||||
|
||||
return title
|
||||
end
|
||||
|
||||
-- Entry point for creating the interface
|
||||
@ -328,9 +402,10 @@ local function createInterface()
|
||||
|
||||
-- Create body that fills the unused space
|
||||
local body = vgui.Create( "DPanel", frame )
|
||||
body:SetSize(frameW - 32, frameH - 32 - titlePanel:GetTall() - btnsPanel:GetTall())
|
||||
body:SetSize(frameW - 32, getFrom(2, btnsPanel:GetPos()) - 32 - titlePanel:GetTall())
|
||||
body:SetPos(16, titlePanel:GetTall() + 16)
|
||||
populateBody(body)
|
||||
local title = populateBody(body)
|
||||
titlePanel.setTitle( title )
|
||||
|
||||
-- If server fully recovers without crashing, close menu
|
||||
-- If server reboots, enabled the reconnect button
|
||||
@ -340,7 +415,6 @@ local function createInterface()
|
||||
elseif apiState == crashApi.SERVER_UP then
|
||||
if btnsPanel.reconBtn:GetDisabled() == true then
|
||||
btnsPanel.reconBtn:SetDisabled( false ) -- Server back up
|
||||
-- Maybe show a "The server is back up, click here to reconnect?"
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -350,6 +424,8 @@ local function createInterface()
|
||||
end
|
||||
end
|
||||
|
||||
concommand.Add("cfc_interface", createInterface)
|
||||
|
||||
hook.Add("cfc_di_crashTick", "cfc_di_interfaceUpdate", function(isCrashing, _timeDown, _apiState)
|
||||
timeDown = _timeDown or 0
|
||||
apiState = _apiState
|
||||
@ -362,7 +438,7 @@ hook.Add("cfc_di_crashTick", "cfc_di_interfaceUpdate", function(isCrashing, _tim
|
||||
if not isCrashing then
|
||||
previouslyShown = false
|
||||
if interfaceDerma then
|
||||
interfaceDerma:Close()
|
||||
--interfaceDerma:Close()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
BIN
materials/icons/cross.png
Normal file
BIN
materials/icons/cross.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
Loading…
Reference in New Issue
Block a user