Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make config menu more readable #50

Merged
merged 17 commits into from
Feb 4, 2024
Merged
4 changes: 4 additions & 0 deletions lua/includes/modules/schemavalidator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ end

---@class SchemaTypeObject: SchemaType
---@field ValidateField fun(self: SchemaTypeObject, key: any, value: any): (boolean, string)
---@field HasField fun(self: SchemaTypeObject, key: any): boolean
---@field fields { [string]: SchemaType }

---@param tbl { [string]: SchemaType }
Expand All @@ -90,6 +91,9 @@ function SchemaValidator.Object( tbl )
Optional = function( self )
return SchemaValidator.Optional( self )
end,
HasField = function( self, key )
return self.fields[key] ~= nil
end,
ValidateField = function( self, key, value )
local fieldType = self.fields[key]
if not fieldType then
Expand Down
38 changes: 21 additions & 17 deletions lua/mapvote/client/modules/admin_menu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ local function updateconfigKey( key )
end

local configMenuOptions = {
{ "Map Limit", schema.fields.MapLimit, "MapLimit" },
{ "Time Limit", schema.fields.TimeLimit, "TimeLimit" },
{ "Allow Current Map", schema.fields.AllowCurrentMap, "AllowCurrentMap" },
{ "RTV Percent Players Required 0-1", schema.fields.RTVPercentPlayersRequired, "RTVPercentPlayersRequired" },
{ "RTV Wait", schema.fields.RTVWait, "RTVWait" },
{ "Sort Maps", schema.fields.SortMaps, "SortMaps" },
{ "Default Map", schema.fields.DefaultMap, "DefaultMap" },
{ "Enable Cooldown", schema.fields.EnableCooldown, "EnableCooldown" },
{ "Maps Before Revote", schema.fields.MapsBeforeRevote, "MapsBeforeRevote" },
{ "RTV Player Count", schema.fields.RTVPlayerCount, "RTVPlayerCount" },
{ "Minimum Players Before Reset", schema.fields.MinimumPlayersBeforeReset, "MinimumPlayersBeforeReset" },
{ "Time To Reset", schema.fields.TimeToReset, "TimeToReset" },
{ "Map Prefixes", schema.fields.MapPrefixes, "MapPrefixes" },
{ "Player RTV Cooldown", schema.fields.PlyRTVCooldownSeconds, "PlyRTVCooldownSeconds" },
{ seperator = true, text = "Voting" },
{ "The amount of maps in a vote", schema.fields.MapLimit, "MapLimit" },
{ "The length of a vote in seconds", schema.fields.TimeLimit, "TimeLimit" },
{ "Should the current map have a chance to appear in votes", schema.fields.AllowCurrentMap, "AllowCurrentMap" },
{ "Should the maps in a vote be sorted", schema.fields.SortMaps, "SortMaps" },
{ seperator = true, text = "RTV" },
{ "Percentage of players who need to RTV between 0 and 1", schema.fields.RTVPercentPlayersRequired, "RTVPercentPlayersRequired" },
{ "The time RTV is disabled after a map change in seonds", schema.fields.RTVWait, "RTVWait" },
{ "How long should a player wait between RTV commands", schema.fields.PlyRTVCooldownSeconds, "PlyRTVCooldownSeconds" },
{ "Minimum players required to enable RTVing", schema.fields.RTVPlayerCount, "RTVPlayerCount" },
{ seperator = true, text = "Maps" },
{ "Map prefixes automatically enabled, comma seperated list", schema.fields.MapPrefixes, "MapPrefixes" },
{ "Use map prefixes from gamemode.txt", schema.fields.UseGamemodeMapPrefixes, "UseGamemodeMapPrefixes" },
{ "Disable a map after its played", schema.fields.EnableCooldown, "EnableCooldown" },
{ "The amount of maps that need to be played before a map is enabled again", schema.fields.MapsBeforeRevote, "MapsBeforeRevote" },
}

MapVote._mapconfigFrame = nil
Expand All @@ -34,7 +35,7 @@ function MapVote.openconfig()
return
end
local frame = vgui.Create( "MapVote_Frame" ) --[[@as DFrame]]
frame:SetSize( 800, 600 )
frame:SetSize( 1000, ScrH() * 0.9 )
frame:Center()
frame:MakePopup()
frame:SetTitle( "MapVote Config" )
Expand All @@ -43,6 +44,7 @@ function MapVote.openconfig()
local configMenu = vgui.Create( "MapVote_ConfigPanel", frame ) --[[@as ConfigPanel]]
configMenu:SetSize( 800, 600 )
configMenu:Dock( FILL )
configMenu:DockMargin( 10, 10, 10, 10 )

---@diagnostic disable-next-line: duplicate-set-field
frame.OnClose = function( _ )
Expand All @@ -55,7 +57,9 @@ function MapVote.openconfig()
MapVote.Net.sendConfigRequest( function()
configMenu:Clear()
for _, option in pairs( configMenuOptions ) do
if IsValid( configMenu ) and configMenu.AddConfigItem then
if option.seperator then
configMenu:AddSeperator( option.text )
elseif IsValid( configMenu ) and configMenu.AddConfigItem then
configMenu:AddConfigItem( option[1], option[2], updateconfigKey( option[3] ), MapVote.config[option[3]] )
end
end
Expand Down Expand Up @@ -110,7 +114,7 @@ function MapVote.addMapRow( map )
local row = vgui.Create( "Panel" ) --[[@as Panel]]
row:SetSize( 800, 128 )

local mapIcon = vgui.Create( "MapVote_MapIcon", row ) --[[@as MapIcon]]
local mapIcon = vgui.Create( "MapVote_MapIcon", row )
mapIcon:SetSize( 128, 128 )
mapIcon:SetMap( map )
mapIcon:Dock( LEFT )
Expand Down
7 changes: 5 additions & 2 deletions lua/mapvote/client/modules/net.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,11 @@ net.Receive( "MapVote_VoteCancelled", function()
end )

net.Receive( "RTV_Delay", function()
chat.AddText( Color( 102, 255, 51 ), "[RTV]", Color( 255, 255, 255 ),
" The vote has been rocked, map vote will begin on round end" )
-- this timer makes sure the message shows up after the RTV message
timer.Simple( 0.2, function()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: A comment describing why the timer is necessary could be nice

chat.AddText( Color( 102, 255, 51 ), "[RTV]", Color( 255, 255, 255 ),
" The vote has been rocked, map vote will begin on round end" )
end )
end )


Expand Down
60 changes: 52 additions & 8 deletions lua/mapvote/client/vgui/config_panel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
local PANEL = {}

function PANEL:Init()
self.largestLabelWidth = 0
end

function PANEL:Paint( w, h )
Expand All @@ -21,13 +22,39 @@ function PANEL:configRow( displayName )
optionPanel:Dock( TOP )

local label = vgui.Create( "DLabel", optionPanel ) --[[@as DLabel]]
label:SetText( displayName .. ": " )
label:SetText( displayName )
label:Dock( LEFT )
label:SetSize( 200, 35 )
label:SetFont( MapVote.style.configLabelFont )
label:SetFont( "MapVote_ConfigItem" )
label:SizeToContents()
self.largestLabelWidth = math.max( self.largestLabelWidth, label:GetWide() )
optionPanel.label = label
return optionPanel
end

function PANEL:PerformLayout()
for _, child in pairs( self:GetCanvas():GetChildren() ) do
if child.label then
child.label:SetWide( self.largestLabelWidth + 50 )
end
end
end

surface.CreateFont( "MapVote_ConfigItem", {
font = "Arial",
size = 20,
weight = 600,
antialias = true,
shadow = false
} )

function PANEL:AddSeperator( text )
local seperator = vgui.Create( "MapVote_Seperator", self )
seperator:SetText( text )
seperator:Dock( TOP )
seperator:DockMargin( 5, 15, 5, 5 )
self:AddItem( seperator )
end

---@param displayName string
---@param itemType SchemaType
function PANEL:AddConfigItem( displayName, itemType, action, startingValue )
Expand Down Expand Up @@ -58,9 +85,11 @@ function PANEL:AddConfigItem( displayName, itemType, action, startingValue )
end
end
elseif itemType.name == "bool" then
entryPanel = vgui.Create( "DCheckBox", optionPanel ) --[[@as DCheckBox]]
entryPanel:SetSize( 25, 25 )
entryPanel:SetValue( startingValue or false )
entryPanel = vgui.Create( "MapVote_Switch", optionPanel )
entryPanel:SetOn( startingValue or false )
entryPanel.ColorOff = MapVote.style.colorSecondaryFG
entryPanel.ColorOn = MapVote.style.colorGreen
entryPanel.ColorSwitch = MapVote.style.colorPrimaryBG
---@diagnostic disable-next-line: duplicate-set-field
entryPanel.OnChange = function( _, val )
local ok, err = itemType:Validate( val )
Expand Down Expand Up @@ -89,7 +118,7 @@ function PANEL:AddConfigItem( displayName, itemType, action, startingValue )
entryPanel:SetSize( 100, 25 )
elseif itemType.name == "string" then
entryPanel = vgui.Create( "MapVote_TextEntry", optionPanel ) --[[@as DTextEntry]]
entryPanel:SetSize( 100, 25 )
entryPanel:SetSize( 300, 25 )
entryPanel:SetValue( startingValue or "" )

---@diagnostic disable-next-line: duplicate-set-field
Expand All @@ -108,7 +137,22 @@ function PANEL:AddConfigItem( displayName, itemType, action, startingValue )
entryPanel = vgui.Create( "MapVote_TextEntry", optionPanel ) --[[@as DTextEntry]]
entryPanel:SetSize( 100, 25 )
entryPanel:SetValue( startingValue or "" )
entryPanel:SetEnabled( false )
entryPanel:SetEnabled( true )
entryPanel.OnValueChanged = function( _, val )
val = string.Split( val, "," )
for i = #val, 1, -1 do
val[i] = string.Trim( val[i] )
if val[i] == "" then
table.remove( val, i )
end
end
local ok, err = itemType:Validate( val )
errLabel:SetText( err or "" )
errLabel:Dock( LEFT )
if ok then
action( val )
end
end
else
error( "Unknown type " .. itemType.name )
end
Expand Down
64 changes: 20 additions & 44 deletions lua/mapvote/client/vgui/frame.lua
Original file line number Diff line number Diff line change
@@ -1,33 +1,6 @@
---@class MapVote_Frame : DFrame
local PANEL = {}

local function disableColor( c )
return Color( c.r / 2, c.g / 2, c.b / 2 )
end

local function drawCircle( x, y, radius, seg )
draw.NoTexture()
local cir = {}

table.insert( cir, { x = x, y = y, u = 0.5, v = 0.5 } )
for i = 0, seg do
local a = math.rad( (i / seg) * -360 )
table.insert( cir,
{
x = x + math.sin( a ) * radius,
y = y + math.cos( a ) * radius,
} )
end

local a = math.rad( 0 ) -- This is needed for non absolute segment counts
table.insert( cir,
{
x = x + math.sin( a ) * radius,
y = y + math.cos( a ) * radius,
} )

surface.DrawPoly( cir )
end
function surface.DrawTexturedRectRotatedPoint( x, y, w, h, rot, x0, y0 )
local c = math.cos( math.rad( rot ) )
local s = math.sin( math.rad( rot ) )
Expand All @@ -42,6 +15,14 @@ function PANEL:SetHideOnClose( hide )
self.hideOnClose = hide
end

surface.CreateFont( "MapVote_CloseButton", {
font = "Marlett",
size = 20,
weight = 1,
extended = true,
symbol = true
} )

function PANEL:Init()
local blur = MapVote.style.frameBlur or 0
if blur > 0 then
Expand All @@ -50,32 +31,27 @@ function PANEL:Init()
self.blurMat:Recompute()
end

local circleSegments = 30
self.btnClose:SetSize( 25, 25 )
---@diagnostic disable-next-line: duplicate-set-field
self.btnClose.Paint = function( _, w, h )
local r = (w - 13) / 2
surface.SetDrawColor( MapVote.style.colorCloseButton )
drawCircle( w / 2, h / 2 + 2, r, circleSegments )
surface.SetDrawColor( MapVote.style.colorTextPrimary )
surface.DrawTexturedRectRotatedPoint( w / 2, h / 2 + 2, r * 1.5, 2, 45, 0, 0 )
surface.DrawTexturedRectRotatedPoint( w / 2, h / 2 + 2, r * 1.5, 2, 315, 0, 0 )
self.btnClose.Paint = function( selfClose, w, h )
if selfClose.Hovered then
draw.RoundedBox( 0, 0, 0, w, h, MapVote.style.colorCloseButton )
end
surface.SetTextColor( Color( 255, 255, 255, 200 ) )
surface.SetFont( "MapVote_CloseButton" )
local tw, th = surface.GetTextSize( "r" )
surface.SetTextPos( w / 2 - tw / 2, h / 2 - th / 2 )
surface.DrawText( "r" )
end

self.btnMaxim:SetSize( 25, 25 )
---@diagnostic disable-next-line: duplicate-set-field
self.btnMaxim.Paint = function( _, w, h )
local r = (w - 13) / 2
surface.SetDrawColor( disableColor( MapVote.style.colorGreen ) )
drawCircle( w / 2, h / 2 + 2, r, circleSegments )
self.btnMaxim.Paint = function()
end

self.btnMinim:SetSize( 25, 25 )
---@diagnostic disable-next-line: duplicate-set-field
self.btnMinim.Paint = function( _, w, h )
local r = (w - 13) / 2
surface.SetDrawColor( disableColor( MapVote.style.colorYellow ) )
drawCircle( w / 2, h / 2 + 2, r, circleSegments )
self.btnMinim.Paint = function()
end
self.btnClose.DoClick = function()
if self.hideOnClose then
Expand Down Expand Up @@ -104,7 +80,7 @@ function PANEL:ApplyBlur()
render.UpdateScreenEffectTexture()

local x, y = self:LocalToScreen( 0, 0 )
surface.DrawTexturedRect( -x, -y, ScrW(), ScrH())
surface.DrawTexturedRect( -x, -y, ScrW(), ScrH() )
end

local basePanel = baseclass.Get( "Panel" )
Expand Down
19 changes: 15 additions & 4 deletions lua/mapvote/client/vgui/map_icon.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@ local PANEL = {}
function PANEL:Init()
self.button = vgui.Create( "DImageButton", self ) --[[@as DImageButton]]
self.button:Dock( FILL )
self.button:DockMargin( 2, 2, 2, 0 )
self.button:DockMargin( 1, 1, 1, 0 )
self.button.DoClick = function()
self:DoClick()
end

self.label = vgui.Create( "DLabel", self ) --[[@as DLabel]]
self.label:Dock( BOTTOM )
self.label:SetContentAlignment( 5 )
self.infoRow = vgui.Create( "Panel", self.button ) --[[@as DPanel]]
self.infoRow:Dock( BOTTOM )
self.infoRow:SetTall( 20 )
self.infoRow.Paint = function( _, w, h )
surface.SetDrawColor( Color( MapVote.style.colorSecondaryFG.r, MapVote.style.colorSecondaryFG.g, MapVote.style.colorSecondaryFG.b, 230 ) )
surface.DrawRect( 0, 0, w, h )
end

self.label = vgui.Create( "DLabel", self.infoRow ) --[[@as DLabel]]
self.label:Dock( LEFT )
self.label:DockMargin( 5, 0, 0, 0 )
self.label:SetContentAlignment( 4 )
self.label:SetFont( "DermaDefaultBold" )
end

Expand All @@ -26,6 +35,8 @@ end

function PANEL:SetMap( map )
self.label:SetText( map )
self.label:SizeToContents()
self.label:SetWide( math.min( self.label:GetWide(), self:GetWide() - 5 ) )

MapVote.ThumbDownloader:QueueDownload( map, function( filepath )
MapVote.TaskManager.AddFunc( function()
Expand Down
20 changes: 12 additions & 8 deletions lua/mapvote/client/vgui/mapvote_panel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ function PANEL:PerformLayout()
-- This is expensive, but must be done so avatar positions dont get misaligned when parent panel is being minimized and resized
for _, map in ipairs( self.maps ) do
for i, voter in ipairs( map.voters ) do
local newX, newY, willOverflow = self:CalculateDesiredAvatarIconPosition( map, i )
voter:SetPos( newX, newY )
voter:SetVisible( not willOverflow )
if not voter.inAnimation then
local newX, newY, willOverflow = self:CalculateDesiredAvatarIconPosition( map, i )
voter:SetPos( newX, newY )
voter:SetVisible( not willOverflow )
end
end
end
end
Expand Down Expand Up @@ -83,8 +85,10 @@ function PANEL:SetVote( identifier, mapIndex )
local voter = oldMapData.voters[i]
local newX, newY, willOverflow = self:CalculateDesiredAvatarIconPosition( oldMapData, i )
voter:SetVisible( true )
voter:MoveTo( newX, newY, 0.2, nil, nil, function( _, pnl )
voter.inAnimation = true
voter:MoveTo( newX, newY, 0.3, nil, 1, function( _, pnl )
pnl:SetVisible( not willOverflow )
pnl.inAnimation = false
end )
end

Expand All @@ -103,10 +107,10 @@ function PANEL:SetVote( identifier, mapIndex )

local newX, newY, willOverflow = self:CalculateDesiredAvatarIconPosition( mapData )
panel:SetVisible( true )
panel:MoveTo( newX, newY, 0.2, nil, nil, function()
if willOverflow then
panel:SetVisible( not willOverflow )
end
panel.inAnimation = true
panel:MoveTo( newX, newY, 0.3, nil, 1, function( _, pnl )
pnl:SetVisible( not willOverflow )
pnl.inAnimation = false
end )
end

Expand Down
Loading
Loading