mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
294 lines
9.0 KiB
Lua
294 lines
9.0 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 PANEL = {}
|
|
|
|
local font = slib.createFont("Roboto", 15)
|
|
local textcolor, maincolor_7, linecol, neutralcolor, margin = slib.getTheme("textcolor"), slib.getTheme("maincolor", 7), Color(24,24,24,160), slib.getTheme("neutralcolor"), slib.getTheme("margin")
|
|
|
|
function PANEL:Init()
|
|
self.Columns = self.Columns or {}
|
|
self.Lines = self.Lines or {}
|
|
|
|
self.columniteration = 0
|
|
self.lineiteration = 0
|
|
|
|
self.assortment = self.assortment or {}
|
|
|
|
slib.wrapFunction(self, "Dock", nil, function() return self end, true)
|
|
slib.wrapFunction(self, "SetSize", nil, function() return self end, true)
|
|
slib.wrapFunction(self, "Center", nil, function() return self end, true)
|
|
slib.wrapFunction(self, "SetPos", nil, function() return self end, true)
|
|
slib.wrapFunction(self, "MakePopup", nil, function() return self end, true)
|
|
end
|
|
|
|
function PANEL:getColumnPos(col)
|
|
local result = self.Columns[col]:GetPos()
|
|
return select(1, result)
|
|
end
|
|
|
|
function PANEL:getColumnWide(col)
|
|
return self.Columns[col]:GetWide()
|
|
end
|
|
|
|
local function differenciate(a, b)
|
|
if isfunction(a) then a = a() end
|
|
if isfunction(b) then b = b() end
|
|
if isnumber(tonumber(a)) and isnumber(tonumber(b)) then return tonumber(a), tonumber(b) end
|
|
|
|
if !(isstring(a) == isstring(b)) or isbool(a) or isbool(b) then
|
|
return tostring(a), tostring(b)
|
|
end
|
|
|
|
return a, b
|
|
end
|
|
|
|
function PANEL:addColumn(name)
|
|
if !IsValid(self.topbar) then
|
|
self.topbar = vgui.Create("EditablePanel", self)
|
|
self.topbar:Dock(TOP)
|
|
self.topbar:SetZPos(-32768)
|
|
self.topbar:SetTall(slib.getScaledSize(25, "y"))
|
|
|
|
self.topbar.Paint = function(s,w,h)
|
|
surface.SetDrawColor(maincolor_7)
|
|
surface.DrawRect(0, 0, w, h)
|
|
|
|
surface.SetDrawColor(linecol)
|
|
surface.DrawRect(0, h - 1, w - 1, 1)
|
|
end
|
|
end
|
|
|
|
self.columniteration = self.columniteration + 1
|
|
|
|
local iteration = self.columniteration
|
|
local ignoreWidth = false
|
|
|
|
|
|
if istable(name) then
|
|
if name[2] then
|
|
ignoreWidth = name[2]
|
|
end
|
|
name = name[1]
|
|
end
|
|
|
|
self.Columns[iteration] = vgui.Create("DButton", self.topbar)
|
|
self.Columns[iteration]:Dock(LEFT)
|
|
self.Columns[iteration]:SetWide(self:GetWide() / #self.Columns)
|
|
self.Columns[iteration].Width = self:GetWide() / #self.Columns
|
|
self.Columns[iteration]:SetText("")
|
|
self.Columns[iteration].name = name
|
|
self.Columns[iteration].iteration = iteration
|
|
self.Columns[iteration].ignoreWidth = ignoreWidth
|
|
|
|
self.Columns[iteration].DoClick = function()
|
|
if self.assortment.iteration == iteration then
|
|
self.assortment.ascending = !self.assortment.ascending
|
|
else
|
|
self.assortment.iteration = iteration
|
|
self.assortment.ascending = true
|
|
end
|
|
|
|
local basictable = {}
|
|
local cleantable = {}
|
|
|
|
for i=1,#self.Lines do
|
|
local tbl = self.Columns[iteration]["lines"][i]
|
|
local sortvalue = istable(tbl) and (tbl.sortvalue or tbl.text) or tbl
|
|
|
|
table.insert(basictable, sortvalue)
|
|
end
|
|
|
|
if self.assortment.ascending then
|
|
table.sort(basictable, function(a, b) a, b = differenciate(a, b) return a > b end)
|
|
else
|
|
table.sort(basictable, function(a, b) a, b = differenciate(a, b) return a < b end)
|
|
end
|
|
|
|
for i, z in pairs(basictable) do
|
|
cleantable[z] = i
|
|
end
|
|
|
|
for i=1,#self.Lines do
|
|
local tbl = self.Columns[iteration]["lines"][i]
|
|
local final = istable(tbl) and (tbl.sortvalue or tbl.text) or tbl
|
|
|
|
if !IsValid(self.Lines[i]) then continue end
|
|
|
|
self.Lines[i]:SetZPos(cleantable[final])
|
|
end
|
|
end
|
|
|
|
self.Columns[iteration].Paint = function(s,w,h)
|
|
draw.SimpleText(name, font, slib.getTheme("margin"), h * .5, textcolor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function PANEL:addColumns(...)
|
|
local args = {...}
|
|
|
|
for k,v in pairs(args) do
|
|
self:addColumn(v)
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
function PANEL:addLine(...)
|
|
local args = {...}
|
|
if !IsValid(self.frame) then
|
|
self.frame = vgui.Create("SScrollPanel", self)
|
|
self.frame:Dock(FILL)
|
|
self.frame:SetTall(slib.getScaledSize(25, "y"))
|
|
end
|
|
|
|
self.lineiteration = self.lineiteration + 1
|
|
|
|
local iteration = self.lineiteration
|
|
|
|
for k,v in ipairs(args) do
|
|
local display = istable(v) and v[1] or v
|
|
local sortingvalue
|
|
|
|
if istable(v) and v[2] then
|
|
sortingvalue = v[2]
|
|
end
|
|
|
|
self.Columns[k]["lines"] = self.Columns[k]["lines"] or {}
|
|
self.Columns[k]["lines"][iteration] = self.Columns[k]["lines"][iteration] or {}
|
|
|
|
self.Columns[k]["lines"][iteration]["text"] = display
|
|
|
|
if sortingvalue then
|
|
self.Columns[k]["lines"][iteration]["sortvalue"] = sortingvalue
|
|
end
|
|
end
|
|
|
|
self.Lines[iteration] = vgui.Create("DButton", self)
|
|
self.Lines[iteration]:Dock(TOP)
|
|
self.Lines[iteration]:SetTall(slib.getScaledSize(25, "y"))
|
|
self.Lines[iteration]:SetText("")
|
|
self.Lines[iteration].InitDoClick = self.Lines[iteration].DoClick
|
|
|
|
self.Lines[iteration].Think = function()
|
|
self.Lines[iteration]:SetMouseInputEnabled(self.Lines[iteration].DoClick ~= self.Lines[iteration].InitDoClick)
|
|
end
|
|
|
|
self.Lines[iteration].Paint = function(s,w,h)
|
|
local wantedcolor = neutralcolor
|
|
|
|
if !s:IsHovered() then
|
|
wantedcolor = table.Copy(wantedcolor)
|
|
wantedcolor.a = 0
|
|
end
|
|
|
|
surface.SetDrawColor(slib.lerpColor(s, wantedcolor))
|
|
surface.DrawRect(0, 0, w, h)
|
|
|
|
for i = 1,#self.Columns do
|
|
local display = self.Columns[i]["lines"][iteration].text
|
|
|
|
if isfunction(display) then
|
|
display = display()
|
|
end
|
|
|
|
local x,y = self:getColumnPos(i), h * .5
|
|
local w = self:getColumnWide(i)
|
|
|
|
if w < (self:getTextWidth(display, self.Columns[i].maxTxtLen) + margin * 2) then self:resizeColumns() end
|
|
if i == 1 then
|
|
s.name = display
|
|
end
|
|
|
|
if self.Columns[i].ignoreWidth or self.Columns[i].maxTxtLen then
|
|
surface.SetFont(font)
|
|
local txt_h = select(2, surface.GetTextSize(display))
|
|
local screen_x, screen_y = s:LocalToScreen(0,0)
|
|
|
|
render.SetScissorRect(screen_x + x, screen_y, screen_x + x + self.Columns[i]:GetWide() - margin, screen_y + h, true)
|
|
draw.SimpleText(display, font, x + slib.getTheme("margin"), y, textcolor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
|
|
render.SetScissorRect(0, 0, 0, 0, false)
|
|
else
|
|
|
|
if self.Columns[i].customRender and self.Columns[i].customRender(x, 0, w, h, s) == true then return end
|
|
|
|
draw.SimpleText(display, font, x + slib.getTheme("margin"), y, textcolor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
|
|
end
|
|
end
|
|
end
|
|
|
|
self:resizeColumns()
|
|
|
|
return self, self.Lines[iteration]
|
|
end
|
|
|
|
function PANEL:getTextWidth(txt, max)
|
|
txt = tostring(txt)
|
|
|
|
if max then
|
|
txt = string.sub(txt, 1, max)
|
|
end
|
|
|
|
surface.SetFont(font)
|
|
|
|
return surface.GetTextSize(txt)
|
|
end
|
|
|
|
function PANEL:resizeColumns()
|
|
local columnsizes = {}
|
|
local fullwidth = self:GetWide()
|
|
local spaceleft = 0
|
|
|
|
for k, v in pairs(self.Columns) do
|
|
local ignoreWidth = self.Columns[k].ignoreWidth
|
|
surface.SetFont(font)
|
|
|
|
local longest = self:getTextWidth(self.Columns[k].name)
|
|
if ignoreWidth then columnsizes[k] = isstring(ignoreWidth) and self:getTextWidth(ignoreWidth) or longest continue end
|
|
if !self.Columns[k]["lines"] then continue end
|
|
for i, z in pairs(self.Columns[k]["lines"]) do
|
|
local compare = isfunction(z.text) and z.text() or z.text
|
|
local width = self:getTextWidth(compare, self.Columns[k].maxTxtLen) + (slib.getTheme("margin") * 10)
|
|
if longest < width then longest = width end
|
|
end
|
|
|
|
columnsizes[k] = longest
|
|
end
|
|
|
|
local occupiedspace = 0
|
|
for k,v in pairs(columnsizes) do
|
|
occupiedspace = occupiedspace + v
|
|
end
|
|
|
|
for k,v in pairs(self.Columns) do
|
|
local v = columnsizes[k] or 0
|
|
|
|
local gapadd = (fullwidth - occupiedspace) / #self.Columns
|
|
self.Columns[k]:SetWide(v + gapadd)
|
|
end
|
|
end
|
|
|
|
function PANEL:OnSizeChanged()
|
|
self:resizeColumns()
|
|
end
|
|
|
|
function PANEL:PaintOver(w,h)
|
|
for k,v in pairs(self.Columns) do
|
|
if k >= #self.Columns then break end
|
|
local x,y = self:getColumnPos(k), h * .5
|
|
local w = self:getColumnWide(k)
|
|
surface.SetDrawColor(linecol)
|
|
surface.DrawRect(x + w - 1, 0, 1, h)
|
|
end
|
|
end
|
|
|
|
vgui.Register("SListView", PANEL, "SScrollPanel") |