From de57b9b7060ba5ac53a387914a948724774d14bb Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 12 Dec 2021 14:42:47 +0000 Subject: [PATCH 001/155] ayo cool sidebar --- lua/pixelui/elements/cl_sidebar.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index a519226..6de72ea 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -36,22 +36,28 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent + local backgroundThingCol = ARSENIC.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol + backgroundThingCol = ARSENIC.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol + backgroundThingCol = ARSENIC.Colors.Primary end local animTime = FrameTime() * 12 self.TextCol = PIXEL.LerpColor(animTime, self.TextCol, textCol) self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) - if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) end + if self:GetDrawOutline() then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundThingCol, ARSENIC.Scale(1)) + end local imgurID = self:GetImgurID() if imgurID then @@ -157,4 +163,4 @@ function PANEL:Paint(w, h) end end -vgui.Register("PIXEL.Sidebar", PANEL, "Panel") \ No newline at end of file +vgui.Register("PIXEL.Sidebar", PANEL, "Panel") From f53ba9680da33cac46e295825d7498c7ad94e454 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 12 Dec 2021 14:49:21 +0000 Subject: [PATCH 002/155] Update cl_sidebar.lua --- lua/pixelui/elements/cl_sidebar.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 6de72ea..c038938 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -36,18 +36,18 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent - local backgroundThingCol = ARSENIC.Colors.Transparent + local backgroundStyleCol = ARSENIC.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundThingCol = ARSENIC.Colors.Primary + backgroundStyleCol = ARSENIC.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundThingCol = ARSENIC.Colors.Primary + backgroundStyleCol = ARSENIC.Colors.Primary end local animTime = FrameTime() * 12 @@ -56,7 +56,7 @@ function PANEL:Paint(w, h) if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) - PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundThingCol, ARSENIC.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundStyleCol, ARSENIC.Scale(1)) end local imgurID = self:GetImgurID() From 97fb17aaba6a73e832c6babc94e746db7366ed07 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 12 Dec 2021 14:50:06 +0000 Subject: [PATCH 003/155] Update cl_sidebar.lua --- lua/pixelui/elements/cl_sidebar.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index c038938..bc8573c 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -36,18 +36,18 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent - local backgroundStyleCol = ARSENIC.Colors.Transparent + local backgroundStyleCol = PIXEL.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundStyleCol = ARSENIC.Colors.Primary + backgroundStyleCol = PIXEL.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundStyleCol = ARSENIC.Colors.Primary + backgroundStyleCol = PIXEL.Colors.Primary end local animTime = FrameTime() * 12 @@ -56,7 +56,7 @@ function PANEL:Paint(w, h) if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) - PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundStyleCol, ARSENIC.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundStyleCol, PIXEL.Scale(1)) end local imgurID = self:GetImgurID() From 0093a3370378b91d1a04757be32707c5c4d27874 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 12 Dec 2021 14:57:56 +0000 Subject: [PATCH 004/155] REFACTOR: BETTER STUPID VARAIBLE NAME --- lua/pixelui/elements/cl_sidebar.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index bc8573c..0efda83 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -36,18 +36,18 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent - local backgroundStyleCol = PIXEL.Colors.Transparent + local hoverStyleCol = PIXEL.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundStyleCol = PIXEL.Colors.Primary + hoverStyleCol = PIXEL.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundStyleCol = PIXEL.Colors.Primary + hoverStyleCol = PIXEL.Colors.Primary end local animTime = FrameTime() * 12 @@ -56,7 +56,7 @@ function PANEL:Paint(w, h) if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) - PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundStyleCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverStyleCol, PIXEL.Scale(1)) end local imgurID = self:GetImgurID() From 2fed18fe2cb71e228917a8a80e11737165c805b4 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 14 Dec 2021 19:10:54 +0000 Subject: [PATCH 005/155] CHANGE NAME AGAIN --- lua/pixelui/elements/cl_sidebar.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 0efda83..c7d6f41 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -36,18 +36,18 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent - local hoverStyleCol = PIXEL.Colors.Transparent + local hoverLineCol = PIXEL.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - hoverStyleCol = PIXEL.Colors.Primary + hoverLineCol = PIXEL.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - hoverStyleCol = PIXEL.Colors.Primary + hoverLineCol = PIXEL.Colors.Primary end local animTime = FrameTime() * 12 @@ -56,7 +56,7 @@ function PANEL:Paint(w, h) if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) - PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverStyleCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverLineCol, PIXEL.Scale(1)) end local imgurID = self:GetImgurID() From 7a0889d92f334a135cf36fced9ecd21fdf1a60a5 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 2 Feb 2022 17:57:29 +0000 Subject: [PATCH 006/155] Update cl_frame.lua --- lua/pixelui/elements/cl_frame.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 82b6716..d10f0c8 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -228,7 +228,7 @@ function PANEL:PaintHeader(x, y, w, h) return end - PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(6), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(8), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) end function PANEL:Paint(w, h) From deab0a794bbe8d35aea523b6a5ffdb8e7c7b62fb Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 8 Mar 2022 20:56:58 +0000 Subject: [PATCH 007/155] refactor: Update version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e2cac26..e8ea05d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.3 \ No newline at end of file +1.2.4 From 69b24d7cd2dbf91dbf41a1ece70340f85829e1f5 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 8 Mar 2022 20:57:38 +0000 Subject: [PATCH 008/155] stuff --- README.md | 9 --------- lua/pixelui/core/cl_player.lua | 3 +++ lua/pixelui/sh_config.lua | 4 ++-- 3 files changed, 5 insertions(+), 11 deletions(-) delete mode 100644 README.md create mode 100644 lua/pixelui/core/cl_player.lua diff --git a/README.md b/README.md deleted file mode 100644 index 2a6c1b9..0000000 --- a/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# PIXEL UI -A modern, optimised UI library to replace derma and other slow built in Garry's Mod functions. - -## Example Projects -- [PIXEL HUD](https://github.com/TomDotBat/pixel-hud) -- [PIXEL F4](https://github.com/TomDotBat/pixel-f4) -- [PIXEL Item Lab](https://github.com/TomDotBat/pixel-itemlab) -- [PIXEL Defences](https://github.com/TomDotBat/pixel-defences) -- [PIXEL Spawn Protection](https://github.com/TomDotBat/pixel-spawn-protection) diff --git a/lua/pixelui/core/cl_player.lua b/lua/pixelui/core/cl_player.lua new file mode 100644 index 0000000..cba5a57 --- /dev/null +++ b/lua/pixelui/core/cl_player.lua @@ -0,0 +1,3 @@ +function PIXEL.GetRank(ply) + return ply:GetUserGroup() or ply:GetSeccondaryUserGroup() +end \ No newline at end of file diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index 6776b8f..e977560 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -20,7 +20,7 @@ along with this program. If not, see . Should we override the default derma popups for the PIXEL UI reskins? 0 = No - forced off. 1 = No - but users can opt in via convar (pixel_ui_override_popups). - 2 = Yes - but users can opt out via convar. + 2 = Yes - but users must opt in via convar. 3 = Yes - forced on. ]] PIXEL.OverrideDermaMenus = 0 @@ -52,4 +52,4 @@ PIXEL.Colors = { Bronze = Color(145, 94, 49), Transparent = Color(0, 0, 0, 0) -} +} \ No newline at end of file From 14230994f57e468762c1f3238270a2d277b2a1a5 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 2 Apr 2022 18:46:13 +0100 Subject: [PATCH 009/155] refactor: Update version checker url --- lua/autorun/sh_pixelui_loader.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 39d85d6..0037954 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -61,7 +61,7 @@ resource.AddWorkshop("2468112758") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://raw.githubusercontent.com/TomDotBat/pixel-ui/master/VERSION", function(body) + http.Fetch("https://github.com/Pulsar-Dev/pixel-ui/blob/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) From 9c6e55e022ac8a26dba40ea1e46c876be2f8e227 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 29 May 2022 19:13:37 +0100 Subject: [PATCH 010/155] feat: Theming Support --- lua/autorun/sh_pixelui_loader.lua | 2 +- lua/pixelui/core/cl_imgur.lua | 9 +- .../core/{cl_player.lua => sh_player.lua} | 0 lua/pixelui/core/sh_theme.lua | 64 +++++++++++++ lua/pixelui/elements/cl_avatar.lua | 37 +------- lua/pixelui/elements/cl_sidebar.lua | 4 +- lua/pixelui/sh_config.lua | 89 +++++++++++++++++-- 7 files changed, 159 insertions(+), 46 deletions(-) rename lua/pixelui/core/{cl_player.lua => sh_player.lua} (100%) create mode 100644 lua/pixelui/core/sh_theme.lua diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 0037954..39d85d6 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -61,7 +61,7 @@ resource.AddWorkshop("2468112758") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://github.com/Pulsar-Dev/pixel-ui/blob/master/VERSION", function(body) + http.Fetch("https://raw.githubusercontent.com/TomDotBat/pixel-ui/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) diff --git a/lua/pixelui/core/cl_imgur.lua b/lua/pixelui/core/cl_imgur.lua index a06c784..d1ff5cb 100644 --- a/lua/pixelui/core/cl_imgur.lua +++ b/lua/pixelui/core/cl_imgur.lua @@ -19,12 +19,13 @@ along with this program. If not, see . local materials = {} file.CreateDir("pixel") +file.CreateDir("pixel/icons") function PIXEL.GetImgur(id, callback, useproxy, matSettings) if materials[id] then return callback(materials[id]) end - if file.Exists("pixel/" .. id .. ".png", "DATA") then - materials[id] = Material("../data/pixel/" .. id .. ".png", matSettings or "noclamp smooth mips") + if file.Exists("pixel/icons/" .. id .. ".png", "DATA") then + materials[id] = Material("../data/pixel/icons/" .. id .. ".png", matSettings or "noclamp smooth mips") return callback(materials[id]) end @@ -35,8 +36,8 @@ function PIXEL.GetImgur(id, callback, useproxy, matSettings) return callback(materials[id]) end - file.Write("pixel/" .. id .. ".png", body) - materials[id] = Material("../data/pixel/" .. id .. ".png", matSettings or "noclamp smooth mips") + file.Write("pixel/icons/" .. id .. ".png", body) + materials[id] = Material("../data/pixel/icons/" .. id .. ".png", matSettings or "noclamp smooth mips") return callback(materials[id]) end, diff --git a/lua/pixelui/core/cl_player.lua b/lua/pixelui/core/sh_player.lua similarity index 100% rename from lua/pixelui/core/cl_player.lua rename to lua/pixelui/core/sh_player.lua diff --git a/lua/pixelui/core/sh_theme.lua b/lua/pixelui/core/sh_theme.lua new file mode 100644 index 0000000..9c12f07 --- /dev/null +++ b/lua/pixelui/core/sh_theme.lua @@ -0,0 +1,64 @@ +PIXEL.Colors = { + Background = Color(22, 22, 22), + Header = Color(28, 28, 28), + SecondaryHeader = Color(15, 15, 15), + Scroller = Color(61, 61, 61), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(220, 220, 220), + DisabledText = Color(40, 40, 40), + + Primary = Color(77, 79, 199), + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes = PIXEL.Themes or {} + +function PIXEL.SetTheme(theme) + file.Write("pixel/theme.txt", theme) + + if PIXEL.Themes[theme] then + PIXEL.Colors = PIXEL.Themes[theme] + else + print("PIXELUI: Invalid Theme") + return false + end +end + +local function printThemes() + print("PIXELUI: Valid Theme Options") + for k, v in pairs(PIXEL.Themes) do + print(" - " .. k) + end +end + +hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() + if !file.Exists("pixel/theme.txt", "DATA") then + PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] + return + end + local theme = file.Read("pixel/theme.txt", "DATA") + PIXEL.Colors = PIXEL.Themes[theme] +end) + +concommand.Add("pixel_set_theme", function(ply, cmd, args) + if !args[1] then + printThemes() + return + end + + PIXEL.SetTheme(args[1]) +end) + +concommand.Add("pixel_reset_theme", function(ply, cmd, args) + PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] +end) \ No newline at end of file diff --git a/lua/pixelui/elements/cl_avatar.lua b/lua/pixelui/elements/cl_avatar.lua index 53757f5..9106286 100644 --- a/lua/pixelui/elements/cl_avatar.lua +++ b/lua/pixelui/elements/cl_avatar.lua @@ -1,43 +1,17 @@ - ---[[ -PIXEL UI -Copyright (C) 2021 Tom O'Sullivan (Tom.bat) - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -]] local PANEL = {} -AccessorFunc(PANEL, "MaskSize", "MaskSize", FORCE_NUMBER) +AccessorFunc(PANEL, "Rounding", "Rounding", FORCE_NUMBER) function PANEL:Init() self.Avatar = vgui.Create("AvatarImage", self) self.Avatar:SetPaintedManually(true) self.CirclePoly = {} - self:SetMaskSize(1) + self:SetRounding(10) end function PANEL:PerformLayout(w, h) self.Avatar:SetSize(w, h) - - self.CirclePoly = {} - local maskSize = self:GetMaskSize() - - local t = 0 - for i = 1, 360 do - t = math.rad(i * 720) / 720 - self.CirclePoly[i] = {x = w / 2 + math.cos(t) * maskSize, y = h / 2 + math.sin(t) * maskSize} - end end function PANEL:SetPlayer(ply, size) @@ -48,9 +22,6 @@ function PANEL:SetSteamID(id, size) self.Avatar:SetSteamID(id, size) end -local render = render -local surface = surface -local whiteTexture = surface.GetTextureID("vgui/white") function PANEL:Paint(w, h) render.ClearStencil() render.SetStencilEnable(true) @@ -64,9 +35,7 @@ function PANEL:Paint(w, h) render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NEVER) render.SetStencilReferenceValue(1) - surface.SetTexture(whiteTexture) - surface.SetDrawColor(255, 255, 255, 255) - surface.DrawPoly(self.CirclePoly) + PIXEL.DrawFullRoundedBox(self:GetRounding(), 0, 0, w, h, color_white) render.SetStencilFailOperation(STENCILOPERATION_ZERO) render.SetStencilPassOperation(STENCILOPERATION_REPLACE) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index c7d6f41..62824fb 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -54,7 +54,7 @@ function PANEL:Paint(w, h) self.TextCol = PIXEL.LerpColor(animTime, self.TextCol, textCol) self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) - if self:GetDrawOutline() then + if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverLineCol, PIXEL.Scale(1)) end @@ -62,7 +62,7 @@ function PANEL:Paint(w, h) local imgurID = self:GetImgurID() if imgurID then local iconSize = h * .65 - PIXEL.DrawImgur(PIXEL.Scale(10), (h - iconSize) / 2, iconSize, iconSize, imgurID, self.TextCol) + PIXEL.DrawImgur(PIXEL.Scale(10), (h - iconSize) / 2, iconSize, iconSize, imgurID, Color(255,255,255)) PIXEL.DrawSimpleText(self:GetName(), "SidebarItem", PIXEL.Scale(20) + iconSize, h / 2, self.TextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) return end diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index e977560..b0110eb 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -1,3 +1,7 @@ +function HexColor(hex, alpha) + hex = hex:gsub("#","") + return Color ( tonumber("0x" .. hex:sub(1,2)), tonumber("0x" .. hex:sub(3,4)), tonumber("0x" .. hex:sub(5,6)), alpha or 255 ) +end --[[ PIXEL UI @@ -33,21 +37,96 @@ PIXEL.ProgressImageID = "635PPvg" --[[ Colour definitions. ]] -PIXEL.Colors = { + +PIXEL.DefaultTheme = "Dark" + +PIXEL.Themes = PIXEL.Themes or {} -- do not touch +PIXEL.Themes["Dark"] = { Background = Color(22, 22, 22), Header = Color(28, 28, 28), + SecondaryHeader = Color(43, 43, 43), Scroller = Color(61, 61, 61), PrimaryText = Color(255, 255, 255), SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - Primary = Color(47, 128, 200), + Primary = Color(77, 79, 199), Disabled = Color(180, 180, 180), - Positive = Color(66, 134, 50), - Negative = Color(164, 50, 50), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["Light"] = { + Background = HexColor("#F7F8FA"), + Header = HexColor("#edf1f5"), + SecondaryHeader = HexColor("#DFE1E4"), + Scroller = HexColor("#edf1f5"), + + PrimaryText = HexColor("#292D31"), + SecondaryText = HexColor("#808080"), + DisabledText = HexColor("#9ba0a3"), + + Primary = HexColor("#6f42c1"), + Disabled = HexColor("#9ba0a3"), + Positive = HexColor("#79CB60"), + Negative = HexColor("#d73a49"), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["GitHubDark"] = { + Background = HexColor("#24292e"), + Header = HexColor("#2f363d"), + SecondaryHeader = HexColor("#2b3036"), + Scroller = HexColor("#2f363d"), + + PrimaryText = HexColor("#b7d1d9"), + SecondaryText = HexColor("#c9d1d9"), + DisabledText = HexColor("#39414a"), + + Primary = HexColor("#b392f0"), + Disabled = HexColor("#6a737d"), + Positive = HexColor("#85e89d"), + Negative = HexColor("#f97583"), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["NightOwl"] = { + Background = HexColor("#011627"), -- Background + Header = HexColor("#0b2942"), -- Seccond Background + SecondaryHeader = HexColor("#13344f"), -- Active + Scroller = HexColor("#0b2942"), -- Seccond Background + + PrimaryText = HexColor("#FBFBFB"), -- Text + SecondaryText = HexColor("#d9d9d9"), -- Buttons + DisabledText = HexColor("#697098"), -- Disabled + + Primary = HexColor("#c792ea"), -- Purple + Disabled = HexColor("#697098"), -- Disabled + Positive = HexColor("#addb67"), -- Green + Negative = HexColor("#ff6363"), -- Red - Gold = Color(214, 174, 34), + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), From c66d4af99f589c3d52bcf8b2fa3c22cce30d08a5 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 29 May 2022 20:49:38 +0100 Subject: [PATCH 011/155] feat: Theme changer ui --- lua/pixelui/core/sh_theme.lua | 21 ++--------- lua/pixelui/panels/cl_themeeditor.lua | 54 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 lua/pixelui/panels/cl_themeeditor.lua diff --git a/lua/pixelui/core/sh_theme.lua b/lua/pixelui/core/sh_theme.lua index 9c12f07..2107f90 100644 --- a/lua/pixelui/core/sh_theme.lua +++ b/lua/pixelui/core/sh_theme.lua @@ -28,19 +28,15 @@ function PIXEL.SetTheme(theme) if PIXEL.Themes[theme] then PIXEL.Colors = PIXEL.Themes[theme] + if CLIENT then + local ply = LocalPlayer() + ply.PIXELTheme = theme + end else - print("PIXELUI: Invalid Theme") return false end end -local function printThemes() - print("PIXELUI: Valid Theme Options") - for k, v in pairs(PIXEL.Themes) do - print(" - " .. k) - end -end - hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() if !file.Exists("pixel/theme.txt", "DATA") then PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] @@ -50,15 +46,6 @@ hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() PIXEL.Colors = PIXEL.Themes[theme] end) -concommand.Add("pixel_set_theme", function(ply, cmd, args) - if !args[1] then - printThemes() - return - end - - PIXEL.SetTheme(args[1]) -end) - concommand.Add("pixel_reset_theme", function(ply, cmd, args) PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] end) \ No newline at end of file diff --git a/lua/pixelui/panels/cl_themeeditor.lua b/lua/pixelui/panels/cl_themeeditor.lua new file mode 100644 index 0000000..b846a2e --- /dev/null +++ b/lua/pixelui/panels/cl_themeeditor.lua @@ -0,0 +1,54 @@ +local PANEL = {} +local sc = PIXEL.Scale + +function PANEL:Init() + self:SetSize(sc(200), sc(175)) + self:MakePopup() + self:Center() + + self:SetTitle("Theme Changer") + + local panW, panH = self:GetSize() + + self.DropDown = self:Add("PIXEL.ComboBox") + self.DropDown:SetPos((panW / 2) - (self.DropDown:GetWide() / 2), panH / 2 - sc(15)) + self.DropDown:SetSizeToText(false) + + for k, v in pairs(PIXEL.Themes) do + self.DropDown:AddChoice(k, k, k) + end + self.DropDown:SetValue(LocalPlayer().PIXELTheme) + + local themeSelected + function self.DropDown:OnSelect(index, text, data) + themeSelected = data + end + + self.Submit = self:Add("PIXEL.TextButton") + self.Submit:Dock(BOTTOM) + local dockMargin = sc(10) + self.Submit:DockMargin(dockMargin, dockMargin, dockMargin, dockMargin) + self.Submit:SetText("Submit") + + self.Submit.DoClick = function() + PIXEL.SetTheme(themeSelected) + self:Close() + notification.AddLegacy("PIXELUI: Theme changed to " .. themeSelected, 0, 3) + end +end + +function PANEL:PaintOver(w, h) + PIXEL.DrawSimpleText("Select new theme:", "Lyth_Pulsar.Font.Size20", w / 2, self.DropDown:GetY() - sc(15), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) +end + +vgui.Register("PIXELUI.ThemeChanger", PANEL, "PIXEL.Frame") + +concommand.Add("pixel_change_theme", function() + local ThemeChanger + if not ThemeChanger then + ThemeChanger = vgui.Create("PIXELUI.ThemeChanger") + else + ThemeChanger:Close() + ThemeChanger = vgui.Create("PIXELUI.ThemeChanger") + end +end) \ No newline at end of file From 52dc743dcff2e191630b686d7546604ce7b96331 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 30 May 2022 00:12:06 +0100 Subject: [PATCH 012/155] feat: Notification overwrite --- lua/pixelui/elements/cl_notification.lua | 105 +++++++++++++++++++++++ lua/pixelui/sh_config.lua | 5 ++ 2 files changed, 110 insertions(+) create mode 100644 lua/pixelui/elements/cl_notification.lua diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua new file mode 100644 index 0000000..401261c --- /dev/null +++ b/lua/pixelui/elements/cl_notification.lua @@ -0,0 +1,105 @@ + +local sc = PIXEL.Scale +local Notices = {} +local notifAmount = 0 +surface.CreateFont("PIXEL.NotifyFont", { + font = "Open Sans Bold", + size = 25, + weight = 500, + antialias = true, +}) + + +function PIXEL.Notify(text, type, length) + local parent = nil + if ( GetOverlayPanel ) then parent = GetOverlayPanel() end + + local notif = vgui.Create("PIXEL.Notification", parent) + notif:SetLength(math.max(length, 0)) + notif:SetText(text) + + if notifAmount > 0 then + notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200) - (sc(50) * notifAmount)) + else + notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200)) + end + table.insert(Notices, notif) +end + +hook.Add("Initialize", "NotificationOverride", function() + local oldNotification = notification.AddLegacy + + function notification.AddLegacy(text, type, length) + if PIXEL.DisableNotification then + oldNotification(text, type, length) + else + PIXEL.Notify(text, type, length) + end + end +end) + +local PANEL = {} + +function PANEL:SetText(txt) + self.NotifyText = txt + surface.SetFont("PIXEL.NotifyFont") + self:SetWide(surface.GetTextSize(txt) + sc(25)) +end + +function PANEL:SetLength(sec) + sec = sec + .2 + self.Length = sec + + timer.Simple(sec, function() + self:Close() + end) +end + +function PANEL:Init() + notifAmount = notifAmount + 1 + self:SetTall(sc(40)) + self:SetWide(sc(40)) + self.NotifyText = "" + self:SetVisible(false) + self:Open() +end + +function PANEL:SizeToContents() +end + +function PANEL:SetLegacyType() +end + +function PANEL:Paint(w, h) + local shouldDraw = not (LocalPlayer and IsValid(LocalPlayer()) and IsValid(LocalPlayer():GetActiveWeapon()) and LocalPlayer():GetActiveWeapon():GetClass() == "gmod_camera") + if not shouldDraw then return end + + PIXEL.DrawRoundedBoxEx(sc(6), sc(5), 0, w, h, Color(0, 0, 0, 200), false, true, false, true) + PIXEL.DrawRoundedBoxEx(sc(6), 0, 0, sc(5), h, PIXEL.Colors.Primary, true, false, true, false) + PIXEL.DrawSimpleText(self.NotifyText, "PIXEL.NotifyFont", w / 2, h / 2 - sc(1), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) +end + +function PANEL:SetProgress(frac) +end + +function PANEL:KillSelf() +end + +function PANEL:Open() + self:SetAlpha(0) + self:SetVisible(true) + self:AlphaTo(255, .1, 0) +end + +function PANEL:Close() + self:AlphaTo(0, .1, 0, function(anim, pnl) + if not IsValid(pnl) then return end + pnl:SetVisible(false) + pnl:Remove() + end) + + notifAmount = notifAmount - 1 +end + + +vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index b0110eb..1a25cd7 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -29,6 +29,11 @@ along with this program. If not, see . ]] PIXEL.OverrideDermaMenus = 0 +--[[ + Should we disable the PIXEL UI Reskin of the notification? +]] +PIXEL.DisableNotification = false + --[[ The Imgur ID of the progress image you want to appear when Imgur content is loading. ]] From 83c76f81f1dfd4116ec70e331582bc342a6e4ec5 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 31 May 2022 00:17:30 +0100 Subject: [PATCH 013/155] new themes pog --- lua/pixelui/core/cl_fonts.lua | 19 ++++++++++++ lua/pixelui/core/sh_theme.lua | 1 + lua/pixelui/sh_config.lua | 54 ++++++++++++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/core/cl_fonts.lua b/lua/pixelui/core/cl_fonts.lua index 2d564f3..e7943ca 100644 --- a/lua/pixelui/core/cl_fonts.lua +++ b/lua/pixelui/core/cl_fonts.lua @@ -58,6 +58,25 @@ do PIXEL.RegisterFontUnscaled(name, font, PIXEL.Scale(size), weight) end + function PIXEL.GenerateFont(size, weight, font, name) + weight = weight or 700 + PIXEL.Fonts = PIXEL.Fonts or {} + fontName = name or "PIXEL.Font.Size" .. size + font = font or "Open Sans Bold" + + if !PIXEL.Fonts[fontName] or PIXEL.Fonts[fontName].size != size or PIXEL.Fonts[fontName].weight != weight then + PIXEL.Fonts[fontName] = { + name = fontName, + size = size, + weight = weight + } + PIXEL.RegisterFont(fontName, font, size, weight) + return fontName + end + + return fontName + end + hook.Add("OnScreenSizeChanged", "PIXEL.UI.ReRegisterFonts", function() for k,v in pairs(scaledFonts) do PIXEL.RegisterFont(k, v.font, v.size, v.weight) diff --git a/lua/pixelui/core/sh_theme.lua b/lua/pixelui/core/sh_theme.lua index 2107f90..5bb9ca5 100644 --- a/lua/pixelui/core/sh_theme.lua +++ b/lua/pixelui/core/sh_theme.lua @@ -33,6 +33,7 @@ function PIXEL.SetTheme(theme) ply.PIXELTheme = theme end else + PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] return false end end diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index 1a25cd7..f5c0ec8 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -56,7 +56,7 @@ PIXEL.Themes["Dark"] = { SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - Primary = Color(77, 79, 199), + Primary = Color(74, 61, 255), Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), Negative = Color(235, 68, 68), @@ -79,7 +79,7 @@ PIXEL.Themes["Light"] = { SecondaryText = HexColor("#808080"), DisabledText = HexColor("#9ba0a3"), - Primary = HexColor("#6f42c1"), + Primary = Color(74, 61, 255), Disabled = HexColor("#9ba0a3"), Positive = HexColor("#79CB60"), Negative = HexColor("#d73a49"), @@ -98,7 +98,7 @@ PIXEL.Themes["GitHubDark"] = { SecondaryHeader = HexColor("#2b3036"), Scroller = HexColor("#2f363d"), - PrimaryText = HexColor("#b7d1d9"), + PrimaryText = Color(74, 61, 255), SecondaryText = HexColor("#c9d1d9"), DisabledText = HexColor("#39414a"), @@ -125,7 +125,7 @@ PIXEL.Themes["NightOwl"] = { SecondaryText = HexColor("#d9d9d9"), -- Buttons DisabledText = HexColor("#697098"), -- Disabled - Primary = HexColor("#c792ea"), -- Purple + Primary = Color(74, 61, 255), Disabled = HexColor("#697098"), -- Disabled Positive = HexColor("#addb67"), -- Green Negative = HexColor("#ff6363"), -- Red @@ -135,5 +135,51 @@ PIXEL.Themes["NightOwl"] = { Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["DiscordDark"] = { + Background = Color(54, 57, 63), + Header = Color(47, 49, 54), + SecondaryHeader = Color(51, 54, 59), + Scroller = Color(32, 34, 37), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(185, 187, 190), + DisabledText = Color(40, 40, 40), + + Primary = Color(88, 101, 242), + Disabled = Color(114, 118, 125), + Positive = Color(87, 242, 135), + Negative = Color(237, 66, 69), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["DiscordLight"] = { + Background = Color(255, 255, 255), + Header = Color(242, 243, 245), + SecondaryHeader = Color(220, 223, 227), + Scroller = Color(204, 204, 204), + + PrimaryText = Color(6, 6, 7), + SecondaryText = Color(79, 86, 96), + DisabledText = Color(79, 86, 96), + + Primary = Color(88, 101, 242), + Disabled = Color(79, 86, 96), + Positive = Color(87, 242, 135), + Negative = Color(237, 66, 69), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + Transparent = Color(0, 0, 0, 0) } \ No newline at end of file From 20598ad172621d4ca5a936093b7165a7f7cfb89e Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 20:26:58 +0100 Subject: [PATCH 014/155] feat: add sounds --- lua/effects/pixel_confetti/init.lua | 51 +++++ lua/pixelui/core/cl_sounds.lua | 28 +++ lua/pixelui/core/sh_confetti.lua | 21 ++ lua/pixelui/elements/cl_button.lua | 210 ++++++++++++------ lua/pixelui/elements/cl_category.lua | 2 +- lua/pixelui/elements/cl_combo_box.lua | 9 +- lua/pixelui/elements/cl_frame.lua | 3 + lua/pixelui/elements/cl_imgur_button.lua | 1 + lua/pixelui/elements/cl_menu.lua | 26 ++- lua/pixelui/elements/cl_menu_option.lua | 9 + lua/pixelui/elements/cl_navbar.lua | 1 + lua/pixelui/elements/cl_property_sheet.lua | 1 + lua/pixelui/elements/cl_sidebar.lua | 1 + lua/pixelui/elements/cl_slider.lua | 1 + lua/pixelui/elements/cl_text_button.lua | 9 +- .../buttons-navigation/Button_1.mp3 | Bin 0 -> 2552 bytes .../buttons-navigation/Button_2.mp3 | Bin 0 -> 4851 bytes .../buttons-navigation/Button_3.mp3 | Bin 0 -> 3597 bytes .../buttons-navigation/Button_4.mp3 | Bin 0 -> 1089 bytes .../buttons-navigation/Button_5.mp3 | Bin 0 -> 1507 bytes .../buttons-navigation/Button_6.mp3 | Bin 0 -> 1298 bytes .../buttons-navigation/Button_7.mp3 | Bin 0 -> 1298 bytes .../buttons-navigation/Collapse.mp3 | Bin 0 -> 6732 bytes .../buttons-navigation/Expand.mp3 | Bin 0 -> 4013 bytes .../buttons-navigation/Tab_1.mp3 | Bin 0 -> 1504 bytes .../buttons-navigation/Tab_2.mp3 | Bin 0 -> 3594 bytes .../buttons-navigation/Tab_3.mp3 | Bin 0 -> 2967 bytes .../complete-success/Complete_1.mp3 | Bin 0 -> 13212 bytes .../complete-success/Complete_2.mp3 | Bin 0 -> 5271 bytes .../complete-success/Complete_3.mp3 | Bin 0 -> 2972 bytes .../complete-success/Success_1.mp3 | Bin 0 -> 12166 bytes .../complete-success/Success_2.mp3 | Bin 0 -> 20317 bytes .../complete-success/Success_3.mp3 | Bin 0 -> 12375 bytes .../pixelui-sounds/errors-cancel/Cancel_1.mp3 | Bin 0 -> 1507 bytes .../pixelui-sounds/errors-cancel/Cancel_2.mp3 | Bin 0 -> 1507 bytes .../pixelui-sounds/errors-cancel/Error_1.mp3 | Bin 0 -> 3805 bytes .../pixelui-sounds/errors-cancel/Error_2.mp3 | Bin 0 -> 2969 bytes .../pixelui-sounds/errors-cancel/Error_3.mp3 | Bin 0 -> 4014 bytes .../pixelui-sounds/errors-cancel/Error_4.mp3 | Bin 0 -> 4850 bytes .../pixelui-sounds/errors-cancel/Error_5.mp3 | Bin 0 -> 2969 bytes sound/pixelui-sounds/license.txt | 10 + .../notifications-alerts/Alert_1.mp3 | Bin 0 -> 15299 bytes .../notifications-alerts/Alert_2.mp3 | Bin 0 -> 11955 bytes .../notifications-alerts/Alert_3.mp3 | Bin 0 -> 24912 bytes .../notifications-alerts/Alert_4.mp3 | Bin 0 -> 12791 bytes .../notifications-alerts/Alert_5.mp3 | Bin 0 -> 7151 bytes .../notifications-alerts/Notification_1.mp3 | Bin 0 -> 12380 bytes .../notifications-alerts/Notification_2.mp3 | Bin 0 -> 7574 bytes .../notifications-alerts/Notification_3.mp3 | Bin 0 -> 19486 bytes .../notifications-alerts/Notification_4.mp3 | Bin 0 -> 13216 bytes .../notifications-alerts/Notification_5.mp3 | Bin 0 -> 17607 bytes .../notifications-alerts/Notification_6.mp3 | Bin 0 -> 36204 bytes .../notifications-alerts/Notification_7.mp3 | Bin 0 -> 27427 bytes .../notifications-alerts/Notification_8.mp3 | Bin 0 -> 30771 bytes .../notifications-alerts/Notification_9.mp3 | Bin 0 -> 22411 bytes 55 files changed, 302 insertions(+), 81 deletions(-) create mode 100644 lua/effects/pixel_confetti/init.lua create mode 100644 lua/pixelui/core/cl_sounds.lua create mode 100644 lua/pixelui/core/sh_confetti.lua create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_1.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_2.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_3.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_4.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_5.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_6.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_7.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Collapse.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Expand.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Tab_1.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Tab_2.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Tab_3.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Complete_1.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Complete_2.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Complete_3.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Success_1.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Success_2.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Success_3.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Cancel_1.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Cancel_2.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_1.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_2.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_3.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_4.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_5.mp3 create mode 100644 sound/pixelui-sounds/license.txt create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_1.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_2.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_3.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_4.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_5.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_1.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_2.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_3.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_4.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_5.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_6.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_7.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_8.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_9.mp3 diff --git a/lua/effects/pixel_confetti/init.lua b/lua/effects/pixel_confetti/init.lua new file mode 100644 index 0000000..5216b5a --- /dev/null +++ b/lua/effects/pixel_confetti/init.lua @@ -0,0 +1,51 @@ +-- Credit to GlorifiedPig#6666 For Making This + +AddCSLuaFile() +EFFECT.Mat = Material( "particles/balloon_bit" ) +local particleCount = 200 +local confettiSize = 2 +local confettiSpread = 650 +local confettiLife = 8 + +function EFFECT:Init( data ) + local vOrigin = data:GetOrigin() + local emitter = ParticleEmitter( vOrigin, true ) + + for i = 0, particleCount do + local randomPos = VectorRand() + local particle = emitter:Add( self.Mat, vOrigin + randomPos ) + + if particle then + local vel = math.Rand( 10, confettiSpread ) + particle:SetVelocity( randomPos * vel ) + + particle:SetLifeTime( 0 ) + particle:SetDieTime( confettiLife ) + + particle:SetStartAlpha( 255 ) + particle:SetEndAlpha( 255 ) + + local Size = math.Rand( confettiSize - 1, confettiSize + 2 ) + particle:SetStartSize( Size ) + particle:SetEndSize( 0 ) + particle:SetRoll( math.Rand( 0, 360 ) ) + particle:SetRollDelta( math.Rand( -2, 2 ) ) + + particle:SetAirResistance( 200 ) + particle:SetGravity( Vector( 0, 0, -300 ) ) + + particle:SetColor( math.Rand( 50, 255 ), math.Rand( 50, 255 ), math.Rand( 50, 255 ) ) + + particle:SetCollide( true ) + + particle:SetAngleVelocity( Angle( math.Rand( -160, 160 ), math.Rand( -160, 160 ), math.Rand( -160, 160 ) ) ) + + particle:SetBounce( 1 ) + particle:SetLighting( false ) + end + end + + emitter:Finish() +end + +function EFFECT:Render() end \ No newline at end of file diff --git a/lua/pixelui/core/cl_sounds.lua b/lua/pixelui/core/cl_sounds.lua new file mode 100644 index 0000000..97e37b5 --- /dev/null +++ b/lua/pixelui/core/cl_sounds.lua @@ -0,0 +1,28 @@ +do + function PIXEL.PlaySound(type, sound) + local soundPath = "pixelui-sounds/" .. type .. "/" .. sound .. ".mp3" + + if not file.Exists("sound/" .. soundPath, "GAME") then print(soundPath, "bad") return end + + surface.PlaySound(soundPath) + end + + local buttonSounds = { + [1] = "Button_4", + [2] = "Button_5", + } + + function PIXEL.PlayButtonSound() + local randSound = math.random(1, 2) + PIXEL.PlaySound("buttons-navigation", buttonSounds[randSound]) + end + + + function PIXEL.PlayExpand(type) + if type == "open" then + PIXEL.PlaySound("buttons-navigation", "Expand") + else + PIXEL.PlaySound("buttons-navigation", "Collapse") + end + end +end \ No newline at end of file diff --git a/lua/pixelui/core/sh_confetti.lua b/lua/pixelui/core/sh_confetti.lua new file mode 100644 index 0000000..30398fb --- /dev/null +++ b/lua/pixelui/core/sh_confetti.lua @@ -0,0 +1,21 @@ +if SERVER then + util.AddNetworkString("PIXEL.SpawnConfetti") + util.PrecacheSound("pixel_confetti.mp3") + function PIXEL.SpawnConfetti(ply) + local effectData = EffectData() + effectData:SetOrigin(ply:GetPos()) + util.Effect("pixel_confetti", effectData) + sound.Play("pixelui-sounds/pixel_confetti.mp3", ply:GetPos()) + end + + net.Receive("PIXEL.SpawnConfetti", function(_, ply) + PIXEL.SpawnConfetti(ply) + end) +end + +if CLIENT then + function PIXEL.SpawnConfetti() + net.Start("PIXEL.SpawnConfetti") + net.SendToServer() + end +end \ No newline at end of file diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index 8f52fe3..4529e55 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -20,110 +20,152 @@ local PANEL = {} AccessorFunc(PANEL, "IsToggle", "IsToggle", FORCE_BOOL) AccessorFunc(PANEL, "Toggle", "Toggle", FORCE_BOOL) +AccessorFunc(PANEL, "Clicky", "Clicky", FORCE_BOOL) +AccessorFunc(PANEL, "Sounds", "Sounds", FORCE_BOOL) + function PANEL:Init() - self:SetIsToggle(false) - self:SetToggle(false) - self:SetMouseInputEnabled(true) + self:SetIsToggle(false) + self:SetToggle(false) + self:SetMouseInputEnabled(true) + + self:SetCursor("hand") + self:SetClicky(false) + self:SetSounds(true) - self:SetCursor("hand") + local btnSize = PIXEL.Scale(30) + self:SetSize(btnSize, btnSize) - local btnSize = PIXEL.Scale(30) - self:SetSize(btnSize, btnSize) + self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) + self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) + self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) + self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) + self.ClickyCol = PIXEL.OffsetColor(self.NormalCol, -35) - self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) - self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) - self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) - self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) + self.BackgroundCol = self.NormalCol + self.BackgroundClickyCol = self.ClickyCol - self.BackgroundCol = self.NormalCol + self.ClickyScale = PIXEL.Scale(3) + self.Clicky = self:GetClicky() + self.ClickyMove = false +end + +function PANEL:PerformLayout() + local tall = self:GetTall() + + if tall > 75 then + self.ClickyScale = self:GetTall() / 25 + elseif tall > 50 then + self.ClickyScale = self:GetTall() / 17 + elseif tall > 25 then + self.ClickyScale = self:GetTall() / 10 + elseif tall > 15 then + self.ClickyScale = self:GetTall() / 5 + end end function PANEL:DoToggle(...) - if not self:GetIsToggle() then return end + if not self:GetIsToggle() then return end - self:SetToggle(not self:GetToggle()) - self:OnToggled(self:GetToggle(), ...) + self:SetToggle(not self:GetToggle()) + self:OnToggled(self:GetToggle(), ...) end local localPly function PANEL:OnMousePressed(mouseCode) - if not self:IsEnabled() then return end + if not self:IsEnabled() then return end + self.ClickyMove = true + if self:GetSounds() then + PIXEL.PlayButtonSound() + end - if not localPly then - localPly = LocalPlayer() - end + if not localPly then + localPly = LocalPlayer() + end - if self:IsSelectable() and mouseCode == MOUSE_LEFT and (input.IsShiftDown() or input.IsControlDown()) and not (localPly:KeyDown(IN_FORWARD) or localPly:KeyDown(IN_BACK) or localPly:KeyDown(IN_MOVELEFT) or localPly:KeyDown(IN_MOVERIGHT)) then - return self:StartBoxSelection() - end + if self:IsSelectable() and mouseCode == MOUSE_LEFT and (input.IsShiftDown() or input.IsControlDown()) and not (localPly:KeyDown(IN_FORWARD) or localPly:KeyDown(IN_BACK) or localPly:KeyDown(IN_MOVELEFT) or localPly:KeyDown(IN_MOVERIGHT)) then + return self:StartBoxSelection() + end - self:MouseCapture(true) - self.Depressed = true - self:OnPressed(mouseCode) + self:MouseCapture(true) + self.Depressed = true + self:OnPressed(mouseCode) - self:DragMousePress(mouseCode) + self:DragMousePress(mouseCode) end function PANEL:OnMouseReleased(mouseCode) - self:MouseCapture(false) + self:MouseCapture(false) + + if not self:IsEnabled() then return end + if not self.Depressed and dragndrop.m_DraggingMain ~= self then return end - if not self:IsEnabled() then return end - if not self.Depressed and dragndrop.m_DraggingMain ~= self then return end + self.ClickyMove = false - if self.Depressed then - self.Depressed = nil - self:OnReleased(mouseCode) - end + if self.Depressed then + self.Depressed = nil + self:OnReleased(mouseCode) + end - if self:DragMouseRelease(mouseCode) then - return - end + if self:DragMouseRelease(mouseCode) then + return + end - if self:IsSelectable() and mouseCode == MOUSE_LEFT then - local canvas = self:GetSelectionCanvas() - if canvas then - canvas:UnselectAll() - end - end + if self:IsSelectable() and mouseCode == MOUSE_LEFT then + local canvas = self:GetSelectionCanvas() + if canvas then + canvas:UnselectAll() + end + end - if not self.Hovered then return end + if not self.Hovered then return end - self.Depressed = true + self.Depressed = true - if mouseCode == MOUSE_RIGHT then - self:DoRightClick() - elseif mouseCode == MOUSE_LEFT then - self:DoClick() - elseif mouseCode == MOUSE_MIDDLE then - self:DoMiddleClick() - end + if mouseCode == MOUSE_RIGHT then + self:DoRightClick() + elseif mouseCode == MOUSE_LEFT then + self:DoClick() + elseif mouseCode == MOUSE_MIDDLE then + self:DoMiddleClick() + end - self.Depressed = nil + self.Depressed = nil end function PANEL:PaintExtra(w, h) end function PANEL:Paint(w, h) - if not self:IsEnabled() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.DisabledCol) - self:PaintExtra(w, h) - return - end - - local bgCol = self.NormalCol - - if self:IsDown() or self:GetToggle() then - bgCol = self.ClickedCol - elseif self:IsHovered() then - bgCol = self.HoverCol - end - - self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) - - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) - - self:PaintExtra(w, h) + if not self:IsEnabled() then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.DisabledCol) + self:PaintExtra(w, h) + return + end + + local bgCol = self.NormalCol + + if self:IsDown() or self:GetToggle() then + bgCol = self.ClickedCol + elseif self:IsHovered() and not self.Clicky then + bgCol = self.HoverCol + end + + if not self.Clicky then + self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) + end + + if not self:GetClicky() then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) + else + if self.ClickyMove then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) + else + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.ClickyCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h - self.ClickyScale, self.BackgroundCol) + end + end + + self:PaintExtra(w, h) end function PANEL:IsDown() return self.Depressed end @@ -134,4 +176,30 @@ function PANEL:DoClick(...) self:DoToggle(...) end function PANEL:DoRightClick() end function PANEL:DoMiddleClick() end -vgui.Register("PIXEL.Button", PANEL, "Panel") \ No newline at end of file +vgui.Register("PIXEL.Button", PANEL, "Panel") + +concommand.Add("test", function() + local pnl = vgui.Create("PIXEL.Frame") + pnl:SetTitle("Test") + pnl:SetSize(650, 350) + pnl:Center() + local btn1 = pnl:Add("PIXEL.Button") + btn1:SetClicky(true) + btn1:SetSize(480, 200) + btn1:SetPos(10, 50) + + local btn2 = pnl:Add("PIXEL.Button") + btn2:SetClicky(true) + btn2:SetSize(100, 25) + btn2:SetPos(10, 275) + + local btn3 = pnl:Add("PIXEL.Button") + btn3:SetClicky(true) + btn3:SetSize(50, 200) + btn3:SetPos(525, 50) + + local btn4 = pnl:Add("PIXEL.Button") + btn4:SetClicky(true) + btn4:SetSize(300, 30) + btn4:SetPos(125, 275) +end) \ No newline at end of file diff --git a/lua/pixelui/elements/cl_category.lua b/lua/pixelui/elements/cl_category.lua index 9bc0d81..6cedbb5 100644 --- a/lua/pixelui/elements/cl_category.lua +++ b/lua/pixelui/elements/cl_category.lua @@ -24,7 +24,7 @@ PIXEL.RegisterFont("UI.CategoryHeader", "Open Sans Bold", 19) function PANEL:Init() self.ArrowRotation = 0 - + self:SetClicky(false) self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 6) end diff --git a/lua/pixelui/elements/cl_combo_box.lua b/lua/pixelui/elements/cl_combo_box.lua index 83d6a0f..77df52e 100644 --- a/lua/pixelui/elements/cl_combo_box.lua +++ b/lua/pixelui/elements/cl_combo_box.lua @@ -25,11 +25,12 @@ AccessorFunc(PANEL, "m_bDoSort", "SortItems", FORCE_BOOL) function PANEL:Init() self:SetSizeToText(true) - + self:SetClicky(false) self:Clear() self:SetTextAlign(TEXT_ALIGN_LEFT) self:SetSortItems(true) + self:SetSounds(false) end function PANEL:PerformLayout(w, h) @@ -130,7 +131,7 @@ end function PANEL:OpenMenu(pControlOpener) if pControlOpener and pControlOpener == self.TextEntry then return end - + PIXEL.PlayExpand("open") if #self.Choices == 0 then return end if IsValid(self.Menu) then @@ -172,6 +173,7 @@ function PANEL:OpenMenu(pControlOpener) self.Menu.OnRemove = function(s) if not IsValid(self) then return end + PIXEL.PlayExpand("close") self:SetToggle(false) end end @@ -200,8 +202,7 @@ function PANEL:SetValue(strValue) end function PANEL:DoClick() - if self:IsMenuOpen() then return self:CloseMenu() end - self:OpenMenu() + if not self:IsMenuOpen() then self:OpenMenu() end end function PANEL:PaintOver(w, h) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index d10f0c8..ffdd2d2 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -231,9 +231,12 @@ function PANEL:PaintHeader(x, y, w, h) PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(8), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) end +function PANEL:PaintMore(w,h) end + function PANEL:Paint(w, h) PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Background) self:PaintHeader(0, 0, w, PIXEL.Scale(30)) + self:PaintMore(w, h) end vgui.Register("PIXEL.Frame", PANEL, "EditablePanel") diff --git a/lua/pixelui/elements/cl_imgur_button.lua b/lua/pixelui/elements/cl_imgur_button.lua index a635a78..ff850cf 100644 --- a/lua/pixelui/elements/cl_imgur_button.lua +++ b/lua/pixelui/elements/cl_imgur_button.lua @@ -33,6 +33,7 @@ function PANEL:Init() self:SetHoverColor(color_white) self:SetClickColor(color_white) self:SetDisabledColor(color_white) + self:SetClicky(false) self:SetImageSize(1) end diff --git a/lua/pixelui/elements/cl_menu.lua b/lua/pixelui/elements/cl_menu.lua index 6520fc2..1161ea6 100644 --- a/lua/pixelui/elements/cl_menu.lua +++ b/lua/pixelui/elements/cl_menu.lua @@ -131,10 +131,6 @@ function PANEL:CloseSubMenu(menu) self:SetOpenSubMenu(nil) end -function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) -end - function PANEL:ChildCount() return #self:GetCanvas():GetChildren() end @@ -199,6 +195,28 @@ function PANEL:Open(x, y, skipanimation, ownerpanel) self:MakePopup() self:SetVisible(true) self:SetKeyboardInputEnabled(false) + + self.DrawTall = PIXEL.Scale(0) + local children = self:GetCanvas():GetChildren() + local childTall = children[1]:GetTall() + local childCount = 1 + for k, v in pairs(children) do + v:Hide(false) + end + timer.Create("PIXEL.Menu.Open", 0.025, self:ChildCount(), function() + if not IsValid(self) then return end + self.DrawTall = self.DrawTall + childTall + children[childCount]:Show(true) + childCount = childCount + 1 + + if self:ChildCount() == childCount then + self.DrawTall = self:GetTall() + end + end) +end + +function PANEL:Paint(w, h) + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, self.DrawTall, self.BackgroundCol) end function PANEL:OptionSelectedInternal(option) diff --git a/lua/pixelui/elements/cl_menu_option.lua b/lua/pixelui/elements/cl_menu_option.lua index 02ef824..dfad5e6 100644 --- a/lua/pixelui/elements/cl_menu_option.lua +++ b/lua/pixelui/elements/cl_menu_option.lua @@ -28,10 +28,18 @@ AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) PIXEL.RegisterFont("UI.MenuOption", "Open Sans SemiBold", 18) +function PANEL:Hide() + self.Hidden = true +end +function PANEL:Show() + self.Hidden = false +end + function PANEL:Init() self:SetTextAlign(TEXT_ALIGN_LEFT) self:SetFont("UI.MenuOption") self:SetChecked(false) + self:SetClicky(false) self.NormalCol = PIXEL.Colors.Transparent self.HoverCol = PIXEL.Colors.Scroller @@ -67,6 +75,7 @@ end function PANEL:OnCursorExited() end function PANEL:Paint(w, h) + if self.Hidden then return end self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, self:IsHovered() and self.HoverCol or self.NormalCol) surface.SetDrawColor(self.BackgroundCol) diff --git a/lua/pixelui/elements/cl_navbar.lua b/lua/pixelui/elements/cl_navbar.lua index 52cbfda..b775f0c 100644 --- a/lua/pixelui/elements/cl_navbar.lua +++ b/lua/pixelui/elements/cl_navbar.lua @@ -26,6 +26,7 @@ PIXEL.RegisterFont("UI.NavbarItem", "Open Sans SemiBold", 22) function PANEL:Init() self:SetName("N/A") self:SetColor(PIXEL.Colors.Primary) + self:SetClicky(false) self.NormalCol = PIXEL.Colors.PrimaryText self.HoverCol = PIXEL.Colors.SecondaryText diff --git a/lua/pixelui/elements/cl_property_sheet.lua b/lua/pixelui/elements/cl_property_sheet.lua index a6209e3..ba744f7 100644 --- a/lua/pixelui/elements/cl_property_sheet.lua +++ b/lua/pixelui/elements/cl_property_sheet.lua @@ -25,6 +25,7 @@ AccessorFunc(PANEL, "m_pPanel", "Panel") PIXEL.RegisterFont("UI.Tab", "Open Sans Bold", 16) function PANEL:Init() + self:SetClicky(false) self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, -4) self.SelectedCol = PIXEL.Colors.Primary self.UnselectedTextCol = PIXEL.Colors.SecondaryText diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 62824fb..9cb2fe7 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -27,6 +27,7 @@ PIXEL.RegisterFont("SidebarItem", "Open Sans Bold", 19) function PANEL:Init() self:SetName("N/A") self:SetDrawOutline(true) + self:SetClicky(false) self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) diff --git a/lua/pixelui/elements/cl_slider.lua b/lua/pixelui/elements/cl_slider.lua index 926bc40..d5ddae0 100644 --- a/lua/pixelui/elements/cl_slider.lua +++ b/lua/pixelui/elements/cl_slider.lua @@ -19,6 +19,7 @@ along with this program. If not, see . local PANEL = {} function PANEL:Init() + self:SetClicky(false) self.Fraction = 0 self.Grip = vgui.Create("PIXEL.ImgurButton", self) diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index 779d4b6..2ae6d63 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -32,6 +32,9 @@ function PANEL:Init() self:SetFont("UI.TextButton") self:SetSize(PIXEL.Scale(100), PIXEL.Scale(30)) + self:SetClicky(true) + self:SetSounds(true) + end function PANEL:SizeToText() @@ -48,7 +51,11 @@ function PANEL:PaintExtra(w, h) return end - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + if self:GetClicky() then + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(2), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + else + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + end end vgui.Register("PIXEL.TextButton", PANEL, "PIXEL.Button") \ No newline at end of file diff --git a/sound/pixelui-sounds/buttons-navigation/Button_1.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2f63c46bcd992e0cf1774f8191daa567e3ef196b GIT binary patch literal 2552 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 GZ22AOTuxp9 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Button_2.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0de73c749b4addf68c19f665423d69fca787e1a0 GIT binary patch literal 4851 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 GgZ}`Om+?IS literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Button_3.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..f731b71b2e88a233b6716e07f5444fb4822aa416 GIT binary patch literal 3597 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 P`Z)T!8iSHgC}98qQvQc$ literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Button_5.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_5.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..7d362b4e362ab2998cc9763bd22273927b8b9000 GIT binary patch literal 1507 zcmeZtF=k-^0_KE}h=>RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&mm@FibE+ z3{XW(oD5x2MLoYEX3J20O5QQph$XRK~8FM zaeP5eVr5cdayCL%3@GcGmzbNM;e=gI540BPKiJs^Urr(mz==D|9=M@ zVPN10F^-)g%)q!)YfZVb0Aq^+149sp(2V0#k|pjrY%>sOl96ZObN=Z(;dtlar_6#3 zihmti7AU-tXFtWn#lpxutC6|M!NE|E!|}t99{D!=|C-T@9!fB{=rS-dFf=$U;904$ z{HR3dqS(W1jGrdFJh8O-sV||4W&< zT2?`R^^YAcVp7XIXU)+T5Uu}zE!I?HqTo51MK{;~|Nm1fCpIPZVz100k#4h}G7^Pc zE)P!}V*LL*=m;zG>6O6@GR6#y$y)ITm=!d7cn$_m$=S2%`-0-l%TiWeQabnHu8P`< zWr1JLpDGdl`Fp>%wSAcV`+BcU4X5_*%xX#K`9J@bYMFiLTaD@Vb?Y~Yh4+@<>ihAl zqAMO4=zk*b?_`eQ4~n|cx>+igk6T3T(-Mb_r7I-`N>n0)bk~NQbWPhjE$48$M#qZa z$$#z{{&^X6`BdE8b(YsvzG#O&+o!VX-TX%q7w>qQvR%F0leu+I*PN*)_5c4rVk~{! z_we}Bq?HZNrgE~(@>MMDI|K3%2NTy*mk-Pvl24|0T%CFL#f{_FH!fp6F*9UkX~h|d zLsRmvEDjAcxa!o&vvKDB;KN*2tF~6D8MY?>PiM59IpfN%s42;>)<&?@Ej_mS|5i1v zH3!`P|9`l!E|@KlN%A9yOv#+OJB$-U)NTdNU1^tQ`EbT6Da*#r6|)UHryEMlQ9QG8 zc3EXVTDJH2i z7u?Hux^wHyv3P0Tb?0Dl%dGUy{9f8YF@Q88L zUzl_@MqSG4&)uFIQ{$Izj=I*>C2bP3i^0^Q6zfZF*tT&=WMuDd#tFYq&c9RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&mB^S{OkX zKsGKBxDiIqu-$=L{5F`%q#UUGg)W?s5NKw?p1ZZQKW1YqXX1LZ+p3ib_ff_e$= z6bloWmrN0!1Ub;a%nYCV@puhWiXkL8*cIqmexO5q63fy|E%b~G^bCQafB^r0I~+jp zpe)b4w0s~FsE>geh%^|g34y(Yz<)vjWHr!{$v{UMn}Rqnpu*e$VKQq>_GqsJv;Y4N zIKsfd*^wO>lExr7Nm1v&ya3|_kdzjGdHLQ2GmTO%?@n;kGd#e-$ara4%14ERC;ZNw ze{8|_$kP5COQXO?3lp}MqjO7NA3WUf!|ua>jYkiDAN=tD#~gdT|CawRvcGD)AvuSE zqk}=3v$qxK0LhilrRyvwP5a+)M(k8eBY^A-Ezys!V6X=FEft#Ziz|Gz@jGCY^P-5+zX z(=<||{r~TvBdpBaEsI5D{xC3l@GatzF;o!Z$mcl06LeX%sneu0LU``2()U^63T?jy zJCmiR+O6f--T7*{?&IkqJ-(O1*BTcEXI+hZcV*Mw_5c5${xA1^{<(h@;jEL4t6qvR zN?zR>|Nnb+sXzlOm!@E@)|E>u)Gig9uT=WQCX;wDaK+;5=5@bfP19PIhwB9gOsQZ{ z{gLyO@0>^Y`b*zmwy5y@zPdo;TUMyq**&qHM;9&+Im#@^eLB+LIM`&Bnb6nhh7-V7_$0nsdL4>Sl)Y<+iN~Q`)d* z+j-@XHA`=JEPJ=EQnH~XoK^9aS@5Yz*|zM?|8M=BCUv#KicdxMJlh^Gsff(PMMs=n zmncPap0Zhd$7Jy#^@Cv>Pfn}WNJtP|aOTjBXDidf<{W$J5-Ij+!$#prH97M;wwwsK zId^TZN01W#1mSrmts&Ffey`rCrOY$)A1haP(xFHDySnNFcH4`J{1@?Y^mR1`<&0Ih F005u=;a30v literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Button_7.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_7.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..3192f4f6b15961d1e7b0ae8351be4a91af3c417e GIT binary patch literal 1298 zcmeZtF=k-^0_KE}h=>RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&myfn?o4} z1~^6FQc#A8g@H4=E+jP!A)X;dK>u(7t#c|ZDap@MFo!vT11J{a>>Ge^z6ekxJ+UAs zwYWIGASbahDKR-4Au9%yb00EGa|yn3KK$VbNM;e=gI542X+yG%RYbc4FOaZh1{|-39 zz`*&U)TiWo17rKlH`;~*ObiV9kMBu;|M=}d2Ir2Q)6I`8P;OWu-(JDj;K0N5;34my z3eGRK{OJ>(nDBM1NW9RdA=>UV3G&s_M^znKlzQX~jp^FKXObu~PqU%DgRFMM{0a z-wuc`>ihpY=m<;m>5^I&*&YVYWd69uHHIsiye=IQTjuP+{^Z){$iUDD@fEsiD|(Iy z2&O1JmUH~>t9Z3{j!H{p^mU;s%|##l+Skh5ciU<8_}JpVPhWl2R4V>(XP2gE`>V(! z@l884?^rMU`%hTOL;KaLWh>5HIn?4~U{DyKDD-VcQS&^XtY=JHc+(^u-=5*QDsZIZ z1XED)OtHxhO>LsK-8%aZHoHt%DX^6Dz(dVje7m`3u_rEjIW`Iu?J%jW^Av z`ii`qlj$|HUEJd66ywy1A3z@BVCMc(_k=f5pHrkSoWp!$0FNc-B14yT{%IR}*Su+9 zGLgDsHR0ThfR+tKE=i8X5}ZtvStt2@Y19p>UgVh`V(2u1>yX5!w>9zxCZ(M#ZfbP6 z*+^RC1Vz3%u~uvKt=jmP8jNgg{Wo|-g1gQvwCrB#k}mxs$>z$Iq%gfH=lHK^*&1n0 t?>=~ALbO9jRmn67ecw}Cc?@ENMMZ_ApouX(e)C!%M_*TCP^JjQ3joEf()s`Z literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Collapse.mp3 b/sound/pixelui-sounds/buttons-navigation/Collapse.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..1c6e780de657e523acfc3a4c437870b40c11743a GIT binary patch literal 6732 zcmc(jXIK+kx5p=ikkAP&6e08`7>YFU5D1}15fdqb5IP6}1Q9qY34{*PtCUbgig*M> zv7mq;9RX2MQF^gg6j7O*ocDOn^WNuvxX-;G-v5_bv)1gj*KhBcJu}+y5AlnP^b8N7 z#(GnIj{XxBXGe)NpD^DbS^(COdW;$x32;W>SH5_5oP%_bKf)RksdX~Olh{xp!*yWfUyJH7n?l6?@oPO z3A}sH?>q^iqqMS0RW9dnv19Q+ou@PW!!{_CdlVN8GLgr`5sC7Vy2v&mhOhfZ#~vI4 zGvRQDyUj3&2!tn;LZZYsKLB6pMb+}C_=ovZ*aEkkUWyTY(frPifU9MA zS8K`jxaNF!z4ZQqt1m<>Ur$*tHlj+!Ow%MSj{4iUC-b(GytUk-9<( zW$tZDv!SbVV(iia%zmD;6U@#54?auFM%H*K@qngaT1q*C+PU`gD+fr3&O=D+2DJxu#jAKmSTbtE5r=k20>vii?$STO+j&ytJ}j4HlARb?>&7G zoEKN_gwQejL6F`J0NuRkq1H9_+$cc1bGXxJhSD6M9dv*N2P7{65L~+^3LA9Q*+Ttvu)X zfC;z~9|I<2=?kdXYTWLASmOfm;y%T7F)h{YtJCepa{h5>Hjs;)F=E}V#b-2*9`G%A z1*Ry;ToQ0Wl<=*?LIE8te3FL;?%dH*&{PO6q9l`dBf5!75}VSUDTpI{WDmuJzJy1F zP;f&N{Emm}yxKIY=W|Szv@HXLVr;dW#2tJ`Rgq_JPGS!j1C8aV`JS366$+T$p zh_mo&qC8ws27njb?n=C;{4K)DZ28*B!2)oI`cmfooOb+{e_c*D8lDX=`lx!Dv!2e)1)_yc^7df?fWjrWx}&V7-ssuNzq zdjtH6odZE#CZ5clfYIkRHWU?$R4=fTZ8^L*ewgUc<=w7aZ~vGq#D(rSFy8P7`$6y% zR#T@Rz6A-g$1 z5&%zDq&r5Dj@pU#ASBQs>&`zuVag=?y!UBH2)qIbn7gGj>#uTsNYx-X_cp8byzw}# zw#N+AjyR^F5y%9(p~B|#;#>nZ4Gqn9P3*<(hVJXJWA#tcTL`?oWceLExHBJI#W1XDYbx_*SW_2etTEVOEQtdoLPuh2B}|3s5Dhh| zl8yiaZ7Rm7EWaYPQ%0*6kzRqWnAuQR8h6K4{@KA4G57o_cu;3QG7%tvxTh7f@5#^rIW3aWE?LI&g7XseyZf;r;*Gn z%pKj#S2?w?<&f!MkQ1dLL?iwta|#-((_S@0vcJrWyjzpS0n$tyx@HEg&ZG?OtoFit z@%8vmKC^0D{UZ6BVwKf}SgV~1zXfQ=iN|<9mxLY|WNpsx@#qsYN6ex#PEJXgJ`}!o zs#qtGwyeuPy@?w2ys!FvW*mwzSAnSKAl6F%$s!Iwf;`)>C3A-#^&M%A*;H!c0PTYfC24U%QsX2|8|Lwl zOyqmpv#c6zX*mxKS35C14XJA{vmYsuW85_*jOw}=*nLTn{gGXmB$@P@H@u&9_Hh_x|=2^>U=I>ZZ+09(k!) zu}mt-kUE%7wz577&dsI`;>-AwRSe}%`PlTFlzyV?#l-ZkSRE=YyKrd;1a3 z#`Dw!n9X8ke^|-|V#lcT5w7M;tJ#9# zW3XNY{wy5OLt|EQCrMn$0MwNx{Lp5j%vgoJ$~bRm#~lB2n+tbbIJ@#7HE#FIwsPNbu7X8^g402_5ahFJ(`FKCvfap{{YQYbz!%4p z5^35y3Xh4dI3!5q)naGTm^g>Jrq{9Wafas|BcMD}*gg&rEpaH#5DKCDqtsO9={kb+ z-;4APi<|S`8rY&D26oEJYu-1Ie3%#L9=wp^t6?did)V%IA7mosY@xD3TjlB&;h~(( z%rR5%q5b>mjo!EPr=KG#s#Ma`d7PDOWwOitAkvyPP90i5HyBoZugBAxLtJ^IUK4$G ze^sxrIALOUW7!yOdR)cEwnBkEdud-P-)hRwp7%Yri=PxfB!!AT6w+6Hktfn#VB~cv zrA}nZ$)3N*9smBlLWUjbzUn=nXvDLg#|B$+_cAxqV9{|| zgG!`(GQ)(WJWuarONvm=i1x>WJZ`O3FL!*@U%_nZHQdj$3Y)$W^sTr3`i|!Zm;px@ z3h69Insc$*V0ZB|blT1R&Sa9j_3tQi*l(>b<@KWxqz3Pgx{CYZzhAz**z3?H_7OJp ztT@@&aTlZU|l42oRMP~5(ASEr1KRp;(rJLO~T;!t)w)cY;PLu|aoBG8+g zplF%JeQ79Y##CEIk`71A)4ILr%%!|DcW*HVU$~YR{`o&t!$76&hRZYKAm%Ep0^FG% zoaORL;16x#Q#<^2x71~yfCq3BA)k{zeMf!==a@_)M=znus2o%Eewd~=qaVw6_IaPOm;Y}dJL{mUYjkP zeR~91tkeI(Inkt#+2jl=ydhApq87cq?wNo6_Sqzu$1>`KI&7mj&&76(Ws%dHJ35d6qTq z@%byai3zdw^3m2Y1j(nR5ofGa#cW%(>_m7E8iV#%a=e<#>TvsIEG+kQ(2Srh`np7a z7h}7+{@ma$Gi7+l7lFg&yRxm^2UXnQNxWYeCw8osuL6m1W(JpoWJ7k#&cz;ahN-G+ zr;y?vlH04jmZ|L_R)n%)QeUr4mD-T>o=95N>yFjF3S|z^U50HE8;E%lqNau|&=It~ z+$QSpPLmDD1;N{c%RPL13Qb%atI^c4n+-J^ej{~PnG;=)Lx|O8r>~wuOtpW$3{Bs$ zx|pQy1(&bHtkAm4SU&K@jR0QaZ|(^Tt9w>oYxST+wqP)Ubw6qg+$eF=fKH^mU9Y@k zil2Vm#A3f!TR+zdW76_c#5CC0P*tuLa=B4$0bqAx{6 z60f(&$84RRu^7Q21&3M*-ijmowL{Ji)$^0c2XGvq#{f!s7fL?!FvP58p6tWld9M3~ z;`xt$>4*shlc}@V_oUjds=Pqw~#NS{q>?g*yZ$n_eDob6`O4KcpJHzUo3Sg`u48- zi_^YXA5!l<9VOuy;)>GHWUb7AD*BJ-XO=MpV-Cy;v=SDI?)6JE+aaYxK&9nkG%N{ODg}`Xp@H z#%~})^>WGVfO@UK^!$nDwa!b9cOCVUd^it zf(aV?@Nmp@e^#)IGw=Qr$4OBXuC{2=^biAMGd1?G#OgTmU!7;05ryUn?m zCIy`soaNdA3v%KZUJkquXeT2UtP(adn>TZw{Q49a@;_BIE`e4pTi&O@~Py9 zp~eJWvkYKz5z!y=8uNZ*)XJ1}Sv)LQZT)m)zh?S}s50MDa2@ zK?95@&g73-NW2hyD%aXo<>BCJdq4fe^JRxWfdIY@jh`?{ot_lss#M()^R?c**ArRj z#KTMIi;kTXV{)ZM0#A22NwT3`z=h&w9xM>3lJ83`e;J#MS6VLw!HqzB8L2}zr`3hX zTO>X$Y@iy_)COixALl8TDFO$s1Fs}Aa^)5kt#fc z&j~sT32U665H`7>Ej0i^%Ww^*Fy}cyPXT*leGroRu*XY9uA5r+*mv<%QZQ9#+Hb<& zYX$?CA!HJ`6kzP{jn5IQfrOyZ-r#nSK|Z=913$n@F{0JZ76Wr?!ae;bLu-Y+$XR?Ty9%PCw@2rX6+$}12yU# zI!fs5Y{p2Z?;v)iw~gB7`Y7hbKSHM1%eZY?n71>x>|nLw zhdxo4s<2iqn`}_J0#aO*f(2+HQZO6wj_ao2k}8 zAy;hzOIw99$ov~UA4z^31U8SgxugTiJYVq0-`PYL3Hs?p} zc-Wj`_$X`DzUH{dr5(>GyJlJ*tbOw-xq08*p5VLJPQJOrvA-wqu4ay|==)!3Uy(oe z?};^lP9-Ma=EtTYVq|yR!CPNg(vV5AZvfc!*?&<*H)+!OFiIR4CPs_t?b&U|E&ZdRTkg z%(8IKgap7!)!1PLq%h4 z9Hk=5HApEDB#ozfga=_C2U9qF@cOKO`^GIeGofP-wG}3w46jdX< zx2W*^5a|VEdy7&A_AkV6%l@+O<^Kr4T)zV;GmV>ae-VI4MOr<%xUrFQf@@Sss44v& zd^tG;P8%G_d{3`P=7l)8bsXP}KG%OW1ip1v%nKa&DwwMdC@~NkIq25x`Q#{s*js;E zio-*s9o4z4%WTLeAbhQ_JPp?@(*LRHx52lAQ%#NYzUS$MwzpHkJKxLl2u5%53FH%B8ytf|&@L!B(RrvF9MFs$bLWQ>Nykxh0iNvE zq++8vHZnmsQ8qC4s@s;n1Aq$~Da)eP2wk@Ltk0clb%MI2UWprtE#a&c*7ZdWH#1$j!Cu=d404(3Exal+`GUzS4EDsOC zITxv36Ll0cuC`r$qh2<*SO#`3Btbe-Bo(LwFNMLUN!uy!ewCz<7B_6er8wXCWgWqe z$57HBR=&KOWolLd1{iv*8<)3$zIu;Z59~T{3r(;1*{qD9pLqg+4?hsz$QrZ*P}asx z?7dOu-7Pf&Kto(&3e91bT*FEb1Icm}y7k@@WjP41b#FIH@sVTJj(s`m1H!vcD7DPr zPBkk_%dVRHk=0dOrJ=F;EtVluaqF{+JcS%|Rkzcgkt;f`rO;4%vPd_07yUHQ$_}1> zAb)A6r=0m0kDsj)Xt(ti;C&pHLIy&eL4VmxIiN&F zH!d*O7cAoinCa*EU8&&Z2}29#&7J^!*1%shRb7>3qkQrJyg!o!^6ZjLJUFwe-1>?(R`e<2h2#px%YU0chHM}X@ zOfbEhzV0<#gIM!eq(!ocGa zxwAUIVCSaj=ym{x27BAu)D4HakMH$RADA(Yx8O)YkWQ>olF3xvt7j6Rw7!c7`3hYQ z!p3l%V~OiSWj*+qY2bN>dJr#YJoI!@O9t=uI%u=E5(P)dZ&~X=U|M^1H1%-0!Ud{w zj*%oYe1uc_S((&hHuFdq?4J|6uuHOf+m+7`ynMrd@rrK}alP^7?uGcPwrfUv5^<(J zvS<84y!zRX^+EaB{v|!u*^=qLXUSSWwqJNBeYS!u~o4 zuXyB{N9ONHkL%iM8~U4sp?c>Mx=+cnk1TKOnIfDvwZA+)U4I%Sxrfw{eGzujh|E}q zd4mpzQpDwF$T>W}mt>e7bZS8=K)d?-V^%_a*oO4$F3)4^=Yp+#hhD~wjdJfZL%9#<4`koJexb5t8o%Ibd27;EcK zb88Ow!EYnz|9lwZGY4{dTB@+-X5(9)yN%F>H5>_fRBQv45Zf#6kP)J99}Na#Gfa*6 zrRIwG41c-DC-}d4))qZ1J|*84c0SUk!Fcj@UDI95`O?f)vd)F?#$RzO4TQ(pd!0dKa@{#P8Nu)`XA1Ha*2@RPx{aGd8|F>ayy);bzlQQ zC`!6$V_F;Ez}RXcv%%7uc8ih`H00)gMT1@YD$6mPZ0hV=-r#U0^*beVo|!!1oEginNE_+8m;PralLEcs zjCowQG4<14wFhr*>x?R1Q^AxoenP{h*~$7P;x*u$O;= zwP+8{{^h{7i(fJ|Ln3)Br~{czko5_it~!iOJUVMXZ>v1A_4dv!H z)T-Eh49&)bYy{vh*PTpuNJgAPJ&jXn?;2>(bkSn&)EGK2?5%v3Lw$r=kKHi^S?+mj zV*_s61lZFL1tR4-g?V{-BaJQZ*m?X7I38;f{wiQpXB7dUgfr1Zq(NQ|y$0En_pW>j z4}0>k#sf+4nv0z~G)8ATx}(V9uEO{Cdv`N<<5@Mu;tmCH&}f4tT7jp)a21I|t>#Uq z8z|B(s>&y>Ap~At0n4hYY@hAzdGi?#!mB23GRvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&mzq8bKKb z22h5DIl2g33d%4scQe7Gh9Sf=#0cmgcA#}3iAf5EF#9<`0?xhx2)By>MbZ-sa#D+n z;|p>UE0YqFvk|glKv~zk{6Lwpj;(o8M%j12S)4Ge%{F!2Ak!vPo@PJ8C1 zu^H@|b^qZM|3v7XJS` z;0OZ)=Z}jDA}S4xEt1*xat#bW&nrksY@g7`z?$;*Qinj2fkVL2w@xPxD1fx^aLHO8 zXkY@eB$A#T(aX4aZi?vS?OqCwlN}m6>faT#)q)-Nwj|^HIdS&$zYcQLrKJTaUOaQb z#gVDgGwa6#j+|79rlPg{$>f->-qGrPoh?dn`ToR%Xp6#y?EocYS|tT>kZt$65wHuG_4iR^Jxv z`~N%W2rC13!%m-_M;jRHd9=RIo503!hGPobI-v#EG$!n*IDO%Q(NhK?W;TWkS0l2T zn-VYO&$aVcJJ_69;$9i~!OO}^-R$Z5IVW?sbgtRDf7AApN3tI3|9@6$cUL;FFIb6^|yXLN(spjEO%In1=eOTu&N5&Iz;bl5WA&cB+>MTl1|8?TdzgvP~Yn+9( zye|jbX}lrFZKE>NDbew~L};V(vZ&S#H(z+vNHx^;P7+mqv@K?#d(ZdNvz339ale)^%Ud7~s{ua`8g#to*-uBJYGP zopwKNete@vATsaTTA>6h<%S7Tru;`Aa0rXGx_q#jxsXFCidXM}+QZ*$=E^)GtPE?? zqn3vDCh*@^%3Zbo*z?1yLcM?7^SRHrO~f;kqcdUkt<&cjy>-6^m@o$%QdGLG^#A2+ z-&G7kLP6%zzD7QWws1B`fIP&`z`>#@yI=#$ffgUs( zE&Y;N=Z@(`DHR6keiY2R=Ipvhoj3AW%_eonx#_8872Ur)9xP(eNJwNp)^O-ZFRN>7 or~RX|S9Eml|Nno~m9?d!lI#1L8#LKPJk2ps_tX(kjYqJV-0 z)D@6kga{}gs0+A(6-6wtiVBM6CL3Mn-kG~I_rLr6^?u*)y!qbe%$ekbV2uU=90dG4 zyuH0Sg$$>TAcaN7_y@$0sDXeJ1`h$gWzyV?Lgi%fK{2tENGgE*9zi$}IWi)O6h{dN z590O4{?!~2g)ySUMn-(UGKg~}#p5v5*~Q%nfFL=b@HVD@72L&t+4(#AyTF+IXV>2m zw*Wi{9!4A=AqB&Mwc`2wn8Osq^Fg9bz7^bz0~&+w*#Ttz(-G=$&AWTTx1(W=d&kB5jU+Fj?n+-43j;0qLEtXofJOLjkZpe-bhbAXKLTp=D(zTQ+T%;ufL1UX4TF{KeDns~zU3@vXfd#Yy4)Ko$nX+G66BP#`I%Q9{9 zG-wHbb->BiW^$$K^?{rslsy$utHJJ0bM#bPnI9T%E7ZLi@+6?6PCyzEe%0S8ITO-U zV8ssw)356VUq9VGJLIpweWyWS-?g^%U!n!z75nX+q20bxjFd6mGW+5ffh_$4@s0Cm zv{ck0n!ir_-VN^>HIKY!H_|B#vnbv0tDeNZ1Vivfy5RId0$$EYiYp|TBJzuqLf{K+ zzPJV`JWqW2YAfW`ikmq7&|b(Ve-z&YA>a(<6)03MsM$i_2qx;^k@`3L^ z#)2b+kx;LzMWf8^PTep5SYp5S=qQFMF50)XDrfcGasN#5&(4m0+qqS>bp0fBt@N47 z?4OmlTeOEDdW>Ar`M~1q>URo{D&W*4V8s(eDB)SSTcudDd%F-pY0E`kPtbYbJL>*XcHc0ZGUSxxQ? zaTb#4cB=;h({V&*mJ%29r?gY#YHa#6r3T?rz>W+T+0(Q0>8Nus;tV#nb}+4MOAvamOaEb`V<71KS!GG( zFvLxSBhdoB?OFjaAe;)=?(gi_)tD0%2Mtw9ihwLWoPHBQ2v10QhI`swR1SS#HQdMO zNU)W-7}Alj$E+>ydohTQA*pN&THyP zO;^Vi8!~PT6ijL=i}yRHPJ!udoetVT9^FMc0>Gz(qPd@z3Ee%;)uZPLlfk3nVVJ zX%RW^=EzUp%xI&24s!1})8rA0TrER|2TCT)o8cv`4btN#RUKao!sh%E+OB;XqUB|y z)r>#6{iL8~`{)usJP@p_QQv;LOS-=^ae&|P!8xWxF63!hj;2NKs3-0UI8j<+wn1-# zSzV*RP&GFJhqyLhIpjAis8M2P2FAUpZ?lsN-!sn@GD;hnx8Vms2YbyBEF4VykuIy( zULh?f2CAT#V5oj!=TUpoEc*2m`UULHP4wnZPSaVLSEgvc@yD)}$^WEuiwNDU1()tsOd1fpxx%F3VU^hb_mQ|j1(@3Ow)QmnP!V~x|d zeqlAKzraPZ%F%zwPF`@#EdFE0>hxQOR{ht;v;DU0uc}AWL5S?|8hgCO+L2fX3dTyu zFYjaGatlN8%KI^jY1+-HmqYcsbFJGxSv=le7dDxyr=pxtqkne&YeUQVrhV~7h`g%V z4L1W@8U<D^W}Mts3BOz93k_hUq{Ov zk}(6t@lVW^or#lX-XU$1tLp`K$(^lZ^hOkY=XSqR_9<5Rz(G-9=#{g!+ZA8p0R_dOTr6hEtsL^Z5DLaQ=dP)&6_kFTG#zkh^ z$Zok(7Sg!|$}4Ukip!Dts?<7Fw1|r6C8Zq(74_E2AEX!+wkk+Zgb0 z{box_=IbQksw_!06&)E8-$4U6OvW)lS|@-~6D${4moIPZ=ZJT*L33X>J^u-=5RGPc wP3~QKI&r~BNLGG+J@=m){@*jM5F?EVvC6zmLUR67U^u^2p#S%w|7pH|0l&zzS^xk5 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Tab_3.mp3 b/sound/pixelui-sounds/buttons-navigation/Tab_3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..443e1c42d6f43b4a1968e92b55f819098c9b7833 GIT binary patch literal 2967 zcmd6pX;_l^8pdC714RYb(lj?zDh)x+rA6ET4JAb-om5;XHNZqE&C(LLaZ6JVntI%G z$)a6b+-LilO9J+ zhz>s-^<|g!`!YSw1|7{}(xsD8;>l=oBE#Fqmk1c5B(g?Xe<{TEA03DP?4Yc7{QHaz zTAb|n^*^`%wE)NjGFr@|D87zN4L8I{?*~g7u0+yb*)_$TgVeagQ7l$y++k``I5i^n zFIQXax-%k}kACctp2hX25>}{kx=)ZU*nbBAWkN*<> zf3g6wpP##!R81UYFO^NRwYNf}tgKNeaZf7Insbk|{_{y-(3s+bcn?qp00ZDX9Qng6cE!Bur^HPbVl3Xqh86ggdv6UR8GL=pHQbKrrugPP-*P=Dj03Zth zG7aLR(Qf6<1v~)&z|{8*Fkbgt>iH^xM_y5N-oU`nWIz3zA@aQK>3sl9Mb0L8fNyY8 zM^OU{K7CIFg_Z`O12(0C41p&rNO9?MVFyji{8DkYdle1Y}qktZzfey`Yh8CNd;1 zGt1ince}c+2(IM$Vi%x$|0lkLSn4mSk~(iNyaQ>8nO_?tS{4B)`PwQ1PLpAzvwuGUA#℘u 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/complete-success/Complete_2.mp3 b/sound/pixelui-sounds/complete-success/Complete_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0af95a2d24511e1fee0539472e762b85a19a0386 GIT binary patch literal 5271 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/complete-success/Success_1.mp3 b/sound/pixelui-sounds/complete-success/Success_1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..fedfb994318338b9518c4f7fe64a0e82b7a60d3b GIT binary patch literal 12166 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�l+)VkqY`YhK%-nmLipnjYc$V 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Cancel_1.mp3 b/sound/pixelui-sounds/errors-cancel/Cancel_1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b88d437754a583d8bd4e5a5af15f8803e6811455 GIT binary patch literal 1507 zcmeZtF=k-^0_KE}h=>RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&mzqSwI;E z1~^6FQc#A8g)xRMBsB~no*_m+|8N1Vb56`lPR&s;ggJo&C>G-E8-Q@W2v8(Fu^=b4 zxH!HbC$TaqF*zF{D+ZKx%}dTt$;?Yv2uLhS%q?aBg#gUFdZ0YWOToSYPB1UQoMK@D z^OCt6+>>BWJDC{51t?@Ngaik>0zJzQbcj!4S(>SZo{@o`p@9KV3bKpykY(D)Pgz{3B3 z2OMEw;4~<t)B*y)4E0S?B44Dly#t=;Ho z%(U_Gsk9${Qt2^oxQ-^Djhk}z{_%Y;{@ER5ozMPb!t;MClK=m!|Nl3!|9HX#hXN*P zAx_psjSPVz9<$Cmh^whss~rxXFEdAMqFBn0_cDw&GRqiVJ!_tD&Z4LL{1f4phIgvP zTJgFDzFo-^ZZEpOY)P=Ok*Rmo#s97>H}358Tv@mN7h4ur3s1BCpBrjI+;dnPwEiF5 z`P=<}?%6N@e+M05Y2X(48X!4~fiu5*DfiX}28a1VXaBVnHk&wvS1=1JIb?>hE-#&S zf+0SUvGct;d*xxrBhFn%-%oz!aQ95_q}AWd{buC{dFOxnS$l2vOr=F1yCv&i?pB*w z$Y$vBuyc(-Knz2t=Vg}z>;?zi7^K9H=NEo`Qz+FgVx++v^*CD!9zcyqQ~e_W$E0i%Z@f?hB0G{pGZ$`mJ1#rO8jZ_#GnS@Bdj^F6FY} zNLN7k6EB&+*~gmp*7irNqFN|@6fA>Yt*hr zT$$?qKj|9R(sS!2uKx|$#nh;vBlhT)fA`9e(C!7Br?3h(r3-FK@V{`xHsaHdwF^$_ zO!8J)@#5+Kn<<+nPQ0yUDYcoEh0n@n`qTMOvaUsIS<3%^cT6K8p^@2Zm5-yZt1&2x HuOb8h`=LTt literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Cancel_2.mp3 b/sound/pixelui-sounds/errors-cancel/Cancel_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b32e66ad0441a71cb31322437a70a053932c844d GIT binary patch literal 1507 zcmeZtF=k-^0_KE}h=>RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&mB^8M{Il zKsGKBxDt%n2Mou@Gn90EF{JfFkLM z1v#n3#qk9>iIqu-$=L{5F`%q#UUGg)W?s5NKw?p1ZZQKW1YqXX1LZ+p3ib_ff_e$= z6bloWmz|93j{%qrn13=P;Q-Tcfz!Cae_Q}$HPDgCKt~#zf;cds0#1oQ9`nyzd##+n z!vB8<905jR!A>=ipA4L-(=-p88Ze|!v{;ZU{cyGXO9uU>HHBNIALQU$!ua=lI@Pt%wl408?7pwxsonO z?RY7g6Tu-FDO8$z>HT!iFJ}cjU+LGTI5NBI343|$*;230G1Fm=W4@tj`XvVjWyfBo zVwI4NgRa5e|9=M^VQ1tqNY}f2jDaz>Q_*o>ri1jE)qIwc8%{oatSf!SMaNKM&Y4z0 zjuXcp9;vUK)Tv<>{+Brt$FvPB|0KH=*XvnKPVQ4$VHBwBc-?vPnCytgy+& zvxv7EMR^<^;v?uOxvIK z_3Sz9JPa#ldb>oO=UQ5wzgvAO*UV|lIA%Vb|NF3OrP9KsY@7CMFp>JdNbzT8xaR-1 z1sB*G5`?Bsp0uxWa$`~lvy}J5aFt2wD^F)F)17*^al!G3z23ax(TAh2f8KNL``@dn zH(vGYy->DZGh7#s+2%Y)niI438W9yM;5>HBMP7`tV5p=4C85 zb~j|{s{C~G%V+GdaGo0c=iC4P-{<7*Sfjl+ukRGdLsAVVpZqwvyzwii7^?&0y&ocX z|CQ#v{QBr%UZA()CngWWSaW097kBJ-EDV}`-BogH^vp_g>89Ir8a!ksmCGpno#Wgt znIva9zo~ELn{^N8G~3LK-QL(8JZDC{mE)x7DKjf96erKlpW$o#vsIc|B15;z$I;i- L7?fdGQ6B&RJOw{F literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Error_1.mp3 b/sound/pixelui-sounds/errors-cancel/Error_1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b8930c9d3515eb39007c87e7ef88371ed6cba0ed GIT binary patch literal 3805 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 TI*0&ZD%>eU{!e@TuiE+#OPMbt literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Error_2.mp3 b/sound/pixelui-sounds/errors-cancel/Error_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..6f7f79647a8edbfcc40415e22d1e2b5f3f4a9780 GIT binary patch literal 2969 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 h*-wtY44Du)BgfM7HyGxi2Lkt8VC1oPt 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 AO#lD@ literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Error_4.mp3 b/sound/pixelui-sounds/errors-cancel/Error_4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..623bad17bbe89cd67ca51be77a56efe27474cd7e GIT binary patch literal 4850 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 z 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Alert_2.mp3 b/sound/pixelui-sounds/notifications-alerts/Alert_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..7d40e78af0c1798ffd32569f07ea2e248d310e5a GIT binary patch literal 11955 zcmc(lby!qixA@P{F?0<`3_}aZ&>=N2ba#lt(A{C64Bg!z(v8xJfD$57(jXxM(kT)u zITw82?|Yy7`|I~S_m8{&IJ3@LXYaK>v(Mi9oPD+$QWyug7HmsHQ&ZDxh4NZ=LpghR zTUvXg+-(6Z5d;+Yw~yk+=j49v^SAT%aq@5n;QzRw*Df0mH&2wWleMeezsmajE$rqg zBIM-b;r7p!cGp)r8Tz?v>*#9%Q21XFQ~b9AhyP0v5)}P^EN}(M|7j5v783lQ7C2l& z;Xf9@P|Z;2nuqW@9KzMk+ZQVIPX+|nCPPIn-T%&>`r6`v@^rQH@v-!DMLn`c*|_|- zm-gDL*VeL)kS%u+RtLAR+aeZ=K4iEzX zz5#%MgoKikmiE>yD3qOt=gu7=A#rhOX?b}ib#-lR0|Qf23kwv=-r3p1!`JuW!>3O} zA|hgAlakWXva?^jC@L?nsi~`LZfHx~n@+ddQT)dGn0rBPZH^+;xbj=zmf+RN$VAnL5`mfw$ebX|wQO)q0U%Za_&CVW zn+TYN%0oZ`2=u5Cu10q^VT7M+IObfxhYSn6m&-)vS{fYIXv;AcQ$P{(;6lAe;iw_z z3q_*9=YzP_IQT8EXhB?XnP*X{;|N>fP;WL9__sk`!UANDjsL~rpuO5~^yCpw8RjhL zvg11NwZ#4`RPr;Br(ovqY_uoBj|lyW&qUOTl7V9Z#dyS%PQf*{3V>3jUF}(#$rVED z-BS;q%kt<~%PFcP)W2ZTO%WNn6yqgkOnhIYemmvcFuXL&8|@bucMtko`_19k0S%yE z1=xC$CY52M@gVr?Ltk%z2ttUPa~Xzrm4bbQZS3}_E6NAJ)~52sDe?x!S@@z{1N&hq zpRi$2!BbilUz)W?)*qzpznaoo?VF=<=?$DIgO4ebY5dp9#D`UU;i+4)aIOl|== ziAVvufJs177dH|#*%^Ir$OsELkYQ{xbT~|lpvh^8ObfW1^1V3*H(JvNo4P`z#(S=U z%|t(Y)`*A`39(6~aDH{t#!t`Wd*=MDH3)NZU3o|CO@ym=*i{Ea1=JA0%8C(wAJ>N| z?48id8z4e#;?g{70oOHz7G9Ckt5tb?1APKqnyB!&YQs*@y;M{N>u}lbr`g^!>qx;_ z-a->=QrnMurQH7BGMiPiHBVk1Jz1dLd#T5(jlmpaEIn#3J8lAEE@~0jS1PvIPveBB z*mS=p>aKYcT=_%zt%l4fO&^hHIe7+pOEngWpGr_cU%6cx+_ zH$bGJ1Ap!kken+JMsY#AThKskZRPo_U#ZSv?c#bv4UM!syY0p&U@CUoL)O|Qqdl(o z>TJkiEVS$e@95DFsr93~!mra^mcW}s%w^@;Guew&IQbK(Yf!&sqy zy#A5ygRe%TgPo^ER#qa4shz6ngf2w%jK7@JGEN3c$qD#vo=*k*GBnguk>-4N|6S3q zU-1)u!ou&2E~H;#j?a8Pf1cT{V7-}x2u$IijD`eA0`6GC;cYB*yk7|-q=h)=9Yf*Y zK7=N*^@6Pc0pWo2rxu}q z>NI+J+Va%H#H@JZ_ZAS11Ds;4d1=f#`}?0Hw+h(-^55m=CBDTBPy)EK_H(^}fJUtR zGJN&1pmpN>_yUkg(Mb%kg~sALFign)jTjhb>=C z>Q_{^r@k?%S0(>Cn&*h8l*XS)l>02+`ov|hww@PR^5l;je^?a&;OKH^K>?)d4G=CC zF=GJFt1W_MuO!>NJ${Ow3=1nP;zF;)`qPhR1r1iDu#umXPPp@MTdguyTkYzRfHZ70 z02xm_#gi?Du<|Ul6O_7a3P}{M+qZ)W@|fD6I;u)rcZzfs-8O68Vzggz0>Fd-hXWla zCjn55ORh{yVxShBE=Y=f1i(#k9fYv-|Maj(7H3h>Rt!SX+_1Cv-x%jr#PK1U_T8I4 zPDd`Rm&k>$4tbV@3-x+;AItI2tG}E7gPDG#<9v+*mdLS9yJ!D;Aw7>S@&<_D8pwg; zl~W`ri@bQD174uC^q}yarwsjo>t(zOHwB zuvR$Jv890-+TXDGO!{%gul^TRrc3ko2@~dg3c%7=)&oG$33+%Y=mrQc1PnN^=y*kf zY~$G$_6lYafPzlCxCn~SIq&SB6^Keh&OB&*f=X3UcZsK9D7Pc^=CJaepH?Jqct!8T z*@X)_cUC*p4(CX(or&eZA^LceG-fGQ(NQI&z0Z@7)j{`pPdq5&ucvHQyx2^rF9=Kw z^tF|dSKRhCl-|g3|X}e?=XR z1a;%@>W=`^uFgJHEMZJz%1(7a^{?B2M;{=9(M;)-pr!(HNp67fLo}=$7>3;(KrV5x z{=J$}1`<&R^5JJk6HUUfl}1z1(K`6uae(<}K*X(l>H#$SzMy9K?zX1wSa<3#p+ zg^?0K5v*R&FYNu4KV>uT+*{~4(i!V``NnrAi3cnxkK4%U=}8Tt3FZkt;DzX-1)Ef5 z7$h8dYgm6}N3M6g*|9QO%2@-#NVaKQW%*jCPPRZubRk^mlB z$UKV_FK}egZDwakYG;+0N<$^h_M(Zn;km2bnAbclxfpWjw2+>?_MW?i!O2|wLaopU z#wZ35-vsatJEl>IvZyaiMV!wn@U48ya&Gmq5cev^0yjWpA!>gD7(e^rf)L>E;d_iT zFxTs`TcUfcQ&rJ|_G^)R<9t~fhg?mfQV0eU|)Kd$$=jgb8Hg$oMpwUH4Wmhl> z2!f4N4a~}h~yD~i_n{ddDn7+>d?>AeHsFYm- zPBMWz0A}`VcFWJ?c9?J67*$Yy6;Ef+KAw?>^~rSZ28bzCP1lV2j^k#RXx#UYdrag{ zo$A??QUX+-KZuod@z?L*!@hVh>WD)G6owO^A^PF7@2y!OAz^}OI1@{MuP$LYx!nS# zkLU^w&4tpPdzuPUfrZLdt7c=y#t~Fh?^uG~y)4Cb`Ylk~R$+N!;t7&}KQ_Z^H-ifP z!;dM7-Q|B%6;MODI+$B>YRSxE>th)$yxT$7J^P4Z%|YyXTT{; zsn1CG;U8OcCfrx_&0xVaLS8bh%oBnOKtrth$dwT{Kmws^lV;QcZg^etB(U&38c11~ zbCE^wouy%v5KbA-@`z@yrZCl`Ns=`WZPVIntnEFkSeec8iF6q}i-yfRP5zp>eWW{q zmk;>wr(vdOOw{2(0!q;o>rHqF9)49$M2q)wwqe1mVndTN^V|Yu)s)QVLLU4zq2|_{ zOTQYi0KGId8u>rsMKV0J2>Wnz-G!Y`4ZMjjHI!W64AfuRlTu^gh%sy_X)&^5rterH z%#_7-7QNC^3FzDX;aOg5x8meE&UqWP`U5v47td~hWU>2ev`9&v?1TC7tw9}*Xexd$ z(jfB+XFi!*Mz7Km>&~;^sHpBt57bQBC2DaJM6|Zaqi;j8Kj7;=gl}nmK&>p^1%-Vm zQB;W?n#NVY(j&~(SLpomgwqNlfjby}Wu;+3@=cPoR0Y?4&+0e9Pyo~0tt8fuY)R22wO6L>;+IS!;K-gETi}5HtW2lB0{>PNnupJCwi3lMX@vXbdlXvk zI!&}DEKD$+T{;^4n9?~=xEvJKe$afhh>{rP(f%_HogQM{jjOs9I}Tdlm0T zFaOI{I_>8$zSx(hp~8&V4<#8qImjn&rJ(iWB2RcB?tS!x>Vv>5nmZ+c}>Dw z{SrzwChkV5s47uU&3J}JLU1#d-cAfE3OxIyABXi5AALBG#!RT3ldrmde*z1T5|k6R zai^RWf6dCRn8_kEYCTXHJR$y$FSBhBLUx!~tj$SNxGjVWY2s56^;a%R28xkAMFU^tkt-i*}hVfGDRA`fC;%h@rscNP1T+lqza@UKe%TL zCRY_I%Frva(gU;CS%eSB5wvn0J+$}}$x?PuT8q5m#_*lWT`oP>JM78WJE`1wWf^hnJ>-{q96^ zkVFNcBDIdItE=#f@UGnvY-WmWMk-+_6rkHotg8_<7J)Hvjy0vhQ_(U*GX+;eHGVqC zNa_6nfnDFNHPu!#rtDWWzC#I~(b|w7>p|H!K=D|F5G?}mCQ1!jz-m?>{r0Ie=CI_M zgSL1h^EOGi7IDae4y?`=3dm&m2Ot?HY68LK27cY@CHeYWRnk z&t1%7(c1{J+-I=|RE?=(vBdkMGDMO=aztzbrs@o}>!j)OXn^t;-LXHmKl#dYEKhTE zS}yZv@QILA_LeJwNgS$gn^ysD$1E*y15}SD3>PNh!*L7dEM7KCiyM91M_uS*DWSME zKW2xdGY#IgECQD_V`Unw+Xod#b$dm(!S1eIgo^noKZLw|&6_bdmHNoGiEr@5rOT$MM-w;g)_(laIqNNK z8;2TpOO3I|7-YG1T)&ihKjy$f3QE1iDSB1IkW49d7x%e2&S&p}B*{kCQ~QGQwXnDJ zub%41Uk1fDeLfVGVSi}QH&@ICFIG2Ul2vO{pgD!M<*=Lm~#(QMZhm<;=#IU!d@KKf%ko?xdxkaU&+7do*RJLa*0 z!+z{N;Ld^M;IUF?j?C%W5hA;jg()qvb>9_9GE%At0DNSq4O&H+7FmP0 z$_J2pjeUS?dNrOfgDK;FJoq;DQ{-pGN{FbeFbaH|s6zgJ94@Sdz-tt7aZ9jMPnj9Y zAqohxCD7s$4Uu_sbXkjbh4GrzsoVg~0))v-#ON%mU|k+7pgyB68T(+=gB1tpCGFH# zau)OU@sVywmSfYSNekPT`o{2DQ=Q!Ix3hP?tc0^HI{qD2nr^mrSIz9>JlW79i&b`q zmB(NBo|IYWcNuK4alR3~%^yBM$kc|l$KT1p?y7yi#6j# zT9oyQ=50oO&9IVQi3Nue^@nf$l5*yJZci4NwZI$>8bh~UH(o9i^Y z-TOWJoGrrkT8_+f=p2krd&GXown$&{B_o*euOv>FOre!ff$*=~R~f(P?Nt_lkRL9rE!Xz?sGizLsnpjN*D1o$h6;`sO^~AJ%EFbuo@?p9=UVq(c z_tRWJdDY2LkuhY_x^Cr#bE6%o|B!?>aCkxi|5tbWn37R#>e`47W~c$Gp1>P}*~gd) zx?%^Bks`+Il^&M>DSdAFm0DT7y;IaaRS^iz#W%+3~oDVzYIng4iQG}CugdcCq zdp@N90bn~SpFr!d|dmS!iP=voY41< z@$>MEh3a4IjYGE+xHanH+@udr6(1>lqFf8M>dME98}LR0*sNTYV+=d`L!v7bn#aS! z!`*j+ZJC=Fa*2Jl%1cN$^7PH|2r$d`8QMQI{hwV5zj;oRc>ctO@$(e_NhMao$N+o8 zeA>8`|L3-$ikMG>8kEDB!mYo<_EyN?n$!h0&JepEqiTTgp_q9=667 z45j}-t3fjP0w$&a*;8c<^o)4W*@d2zf8e*oy7?U9Y^^ZHNX=HQfkasAall*tyw}67 zUiG5GN#H0bHUV|(DOfX+)8If$bQ!?#K<)(^&rep-4Mu4&oH0alBrY=zA%2r-BPAIt z`O+#iYibzOxu;-Vb6u29DOO19PWtJfv_Q7T`_EnNK|%m7WXO<0#*|9fnl&&tjw=$ zwM>5~B;Gbf*fZH(b<-dIbM5(FZYFNw8^RAlZR?WDayZQe-eTuJi}5koR~D1fZT+jz z4oDMcctFkG;%~Cjs_t30^5+CO@1DP&;d@AV@e)v$S6yRMcJeEI-XvOQrtehfnT?gg zm*2c2e5d(cDm;W<&cEr6}r*tMF$zRBosh5pHZ&YWmXPr*Qw0O_ePPEkTqB|ArO0x(3?f zQ=6wRV^6D1)CH=TvG<#aJm^a?F1Ww8VlEaMAdL5$#1W=(rT31K+xJZY?ZF^>IY9e+ zi9|%*Ur@6#;OjB%Fh9{6?Y~-xXjTpv8ihinaa$JH-s-!2JNnAKF4fDJ|Id4}$&yA0 zyiKNXQ9ZPo${}TZNGL{d&T*~!MbKJ7!UxLM4Mw_3b&SN>M_*jGXZBT=ax%d(ADMkz>Ol$f`hW4Jv z4}YTUE+tZjwA7Gh;C0X6WvuI4E?E(TP5lk=h}#lvm5tV>hQJ)Sic(?xP4(P`IHw|c z%~OtxwtxigLA zweFUzYDs~&zyv$R>|Nfva?**CR%`4U@vEV<4m<#vO3n&Q@KlJkdA zCC>L|yqjQt?fTgiB?jRh;nYiqEAJ_jT7*PHO3~D%uTtVv1uq4w)%J0lJ+ zcWi6Gw7hU=_mLe+Z9E>r7Fs7$6DezSdnuS_15=lVZ28w`KL2P|=7J*N( zMgFXWFfX<@uf=qWkZ)P@F$*+wysOF6adtjrgp!T|t&irkQV7*@Qc&F#>`}TDVj#mq zR~K}@T1XZljvd?R*55u9tnu{DHBeXo6Hd!CDhNc(G5HYLj=Kbqzv@d&;0q8+8?-U7 z6^pG*lT0uCnHT+SMbCK51@#suB%Uw+sE{z)SGz4E$rkrkw$z9I0<~g z&CowJ%EXKkoz{Q*5J224bb(DT+GWJCR3c1LfPwF?swi1meHf*|sl)NMMMdgqZ_7K9 zRdpj-82ue+gUz2a76i2UTD2JQ(10A_+Fd>Loh!bygdyVJJ+6%3y69w@d2Pm3PW;9n zM!6;qsqXCF|IPG0Me!<{AxZjPaWX(v&Hh?F)9Hop+tYzek%npRbLw2a4$23^PCKI& z0$DwT$CgI|;th!L&hQ2ALYN)Dbe+l(yXDC?M$|*sO&c|Fx`prZNdz2YYxgr=q|=+@ z#k`61`tS3S%^RRS^k+4pv*K$Yn^Kk~!K~4SF|UI3B!N(vb!4J$2}U9Ysg$Z&@u&j7 z7SURpV^gMD<;Jj0qxwiykd1?vE~4g=!K{=yK2VfE^Qrjthr7e1FsZ$yJ8gQFbWpB_ zI&18^p3^0mGd?dbsiKJO6Y2-qud!pK?_Mb0UODi};8|Of?U6fh%G~^IE&oMuAr~PkR2tTV?3pJ9K1j$Ei(IY_PEL z(Hk;7#;=Q*zbzCz#DTmjB(MTGaOZal-s;>4SqiolY58KtOAQL38s|42lvsttXLHQd z+*wenY%x=VgeZ@xCLv#n%+3|j<~Y{#Nb`PAPg9c%!kktRp0rAC35Vr-jcE~U3ehz@ z&I`g|U`bNX-7m&dNh&%6AUmJ++-Z@D^VPQyUnEN$9uS=ALB3fl|w1HVco9L)Xdmpa!Jh zJCi(};oUbt+d%BB^hGhjH^THXOTadkTdpgT=xK-nZ61}2!jRRcl|v;|%{{s=QkFr4 zh>K5yYIK}^T=Z{!Be*6CdIgz_oA4=a_bv*M54rA+e0pi8@4)GooxzlpuWt;ky`ZOf z$i-DOxX(2%o7CU?9F`Ig5mki);FA?8>l)7Yr3~u5wH7Mjh!>nj^~F@6eg@r%q*S}7 zqqorceUnmhxS=UiIkZ4jY5e^HBE%XRvMo@DE+h=if3`cT4ol@`WAzU=Gc3M)*T@*+ zadtn&=Iss8TJS(P{0f`k8z_UD#n2W4N;;9r44#C|{?_T0+(FKF6>LTWqExJH6U9p< z94w_dmkckSEmvgS7YKf(Q#JCYtdXjlCd>9qvBRQmg2xEv!)X?Q#IQb|bfbrNT@L@r zA_tC)hW4dZ?^D|lFu^Q?fifEo?bG~iQ9J-3AC4~#A-(mc-!rd}tU~3Z(7k-YY}J1A zDcK*ob1H}KF2zh_n!z6R=l0yy#w0=I>27T;dY^t@9&Nux7HsC(y$w4(o$$5zPAr}! zl3OPjfw}=&M-%fafv^bz5gwfRXzN@waM9xM<#l%y9}oh<1ws)3O}xcz#o4JT$A>={ zQ6e1A42khbMXkI7rxabmXl#5*Q@KtIE|UN~m)F`FvQU+JmLYAxBz@{GKF@|g!7Nlo zaP~`OE@ypNeY#Gx37PH*`g+et9W`Hf|Dv`{+DEr6<<^b%v`j7;-7vvSKmV~9*gOsx zOE93-`*X7e_Xx!B;mExD=YEkx2{nh=@T}xv!}qk-eqXkx_Jn0M?i3E`9Is}3Pu-8z zb2(7q{IJ|q)UTLIhLR{M4O}xkAx^U=jQXn7?T1Kg|B0L9Agy7V7B$N;)7bV z?-7EfT0GEPd#8t%fzp@ER;kQk8U6xib6n7;Qfi`no9X2OJAr2%n4pUnN;w^?=U@0) zf4~jMHehBa7t4JuF)SFWDl~xW)rpM3)09zEjNm@PkV^b=)GYuk?KF((QAIW%^jnZY)2+NWEA>++fsG)!km} zfc(tNzyg7sj3zZtVWTBlb3!V7PF2Q}{PJyG3zxL>t1#sz@;j=_)B8@;iG;Kb3p%iS z&CrcEYHEGOUF`3BGRK`Zc{OEYPH^}p)Vg5D!p`=Uee2;=l*6sh=qMXZ(UcPuF9s*f z{w|Vig$|JjT>@F16u#UnXlw{K?@=dbaX(qfc$g}8k$JKUqiJ5dz)l#W>O_~V4J5$% zU7lLsD$A;l(>I^{L1bCaXW+aNtF5Oi?pFuTvRx0=vlJanJqp+-njXrp?}%9CQQNch zWw`r{uIoW06lT62NbSz?NOXywdfx3iTAR93Wh8LQJ4=K&{v3`DBTJ#~*Q>Wh^p`z4 zZv3IO;9l$&t`m<;wcaz;Vw0wh4#4PI{%WHsVUB~iZC}3z*riP*<#SC>L~JQcz-Wjf zZf?2F>pmoZRhVUv9K_ACYD3z>r9Hhy$o^8Fy4{ZX!m0qSyGj>y6|74|9R1An!Lf^8 z@al2~s02L3IuMq1-!tH&qbHG+Kq$Qo*S`)as)JOJh2)d1WKB2Gm>EvhQ zRnMo=za95A|0G7p?Z*UNSZFKVH@T`VjC5&Ed&Ax)JN!uHF7r@|1EkfqY(ctLz>8|= zZyySct>nJI2G4wBz41@d9<8#^~Z;cv8z+Z1c^r%qnT@^Bbh(R+aDULLTOq0c z<4?i`UA&n*Et-rFY%s2z(P(8f%)alioai*a$lwmA$gf>tHAWVAE9B^tGiz8DUoWLYdQC^Z}$J~ z0-9?IXN8c?E~g61NmMa(N)7|FqD-P)y-hfh2^Dj8PR0*TQRQ_KOPdX3?-F?@`i|44 zQf$Z(2}(HA{UP%+LG85FowlU9?skW5$EVMpDIdIg8jp?hSC!aDKN@vU{$Cn-_B>%_r%q$rlT{S`67kZ{nJ~`7KEu0 z-5!256h!)z2lKj=mL4ubO&c6^e;lC`XPEl=&BY`QJ1q$@=4W_KQQAK8M`vf}zs3ac zvg{=rbdr#*1jPKYC&Y{!<@@sd jpJw#G41NPNfjwklANJCVM->1>uAj1S{+D(BpBDcwB^3D_ literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Alert_3.mp3 b/sound/pixelui-sounds/notifications-alerts/Alert_3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0ab6c8daea5fd4dbafb9525229498542d379b955 GIT binary patch literal 24912 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Alert_4.mp3 b/sound/pixelui-sounds/notifications-alerts/Alert_4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c5c70c5a9007e192fc4cb50183c6858bb7d417ad GIT binary patch literal 12791 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 au3(l}bAlR;CY;*nVzd7L*#G}}SN{i$@y~Ps literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Alert_5.mp3 b/sound/pixelui-sounds/notifications-alerts/Alert_5.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..25520e70610618d9e9bfcf4ea35d57abbd819e84 GIT binary patch literal 7151 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 O??=x6>nQ$O8p04E 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 P1|FaC|C0H?l;nQ^lPXyk literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Notification_3.mp3 b/sound/pixelui-sounds/notifications-alerts/Notification_3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..6460cb2d321b4190a05e03430fe5c7a9d98c75f8 GIT binary patch literal 19486 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Notification_4.mp3 b/sound/pixelui-sounds/notifications-alerts/Notification_4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..fe4c619a1b0293f08fcc824c1b5f55f5804b85eb GIT binary patch literal 13216 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Notification_6.mp3 b/sound/pixelui-sounds/notifications-alerts/Notification_6.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..3ea05ed530818d907b6a49bfb5f5e4c77b0a841d GIT binary patch literal 36204 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Notification_7.mp3 b/sound/pixelui-sounds/notifications-alerts/Notification_7.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c26d22329618ff476e5839704a03353fde19dcbd GIT binary patch literal 27427 zcmbrlWn5c9)9@XF2Py7u#hqepaV_rN;_g;`asO9D^C&WRc62fIur+hA{GWT>|K059!q02#?(F#AcUnHa z(^kvVNkvsd8AQYV)OdI$|EKfV|JUJp!NdE1N4R+eDQpA;Y8{~h7xlN9>j5s;RG z7Vjeu&g0jqID6Py*_uDj&Dn`Y@V^s5dz5HNDXaZI2!h8EYf~2oOLzCTE)J$XW~S!$ z|4&NvD3x(Cceb!~vZhfpbu)Ez2R;1`|NT7Zqx=a>Q&~;&KVbjm;TGcmA24n{S>gYk z;-i$8k55YQe+T}5c0gL1nlg{b&mJeDWa?!lAjHYb&B?>f{W$jD2Hc8w{HUE2MZDVKe z;P~|X^5*X0>B}D{Y5q7#K7pr;|277c|MYD6I%RCp|6KsLYCRwjx<|A&zXc2-ftG!n zsv5NND54R_pW8U^B*8>MM1cL+pNG^HUQkgK`=yV7$}iB05`20-m}ZlqLxmMtuNdRJyfL0 zK>Mi^IU3hrdmd|I0nb}XD>w=YL`OoWNgLhKj6calvMvvRQ_yX{pZL&GUnsClcv}SA z76&h0od5vv^NhD9n&6?HJ<2BTQdpk`qb7hos|L8$=s^Zyw9^_IUBF1KbIZ9e5-;Nt z!ca)*M54h2>Cw4fZgv`IBVvvU-Ui-Wsg5nJ{C`s)q&1Gd33*V_%-9!RHnmj&S1&5_ z{s0d+%GR|%Kedu8wRn^N)?jikTr$}PPKfhDG%rN+dMq|ScS}wkkCtF@b$@3$$7O6G z#U=JQ<&Ip)^4}{jEqWosVLnXC=oS63W|wj5O4pom<~*=#rxs#;HqPl25Gn}s6`ykXt2g7Gv@91v4SAdb zp}wuG8Q~Sk-DU9fG*hzAeOb_#qB__YhO?qm%kxRM56#S2&iBXGP*tc0Bk$C=Yd^yQ+e5O|#=Y6q92r+>tWK2gymK`}*6q=X?l#=&%co2R37Ozjt zamiid(KF4lld^Hb35d8)U|@l#wP{E|I7shluD|_9Lt0nD6~m`pzEoSbJ%czk@4tIk zx**|kueq$TRABd22<+}kam($Cbm*jss!Uv8B#*UP*Dt3O)^bC3WWyaIi1T3b=NPE9 zf;vDB2Xwms*M`r54_Ed<)t}-&`TI&;IUppMlDJ0iqTHNmBA=Ih9SY9C$hrh`*#%}J z(I;FAbSw-;;lX61-51DjWA%%NzJB{y`vty(pa%JIIj~kcV@y*>e-dg__yM?x{dup_ znysC0m^$Q9Mw*OqWdjfR*`xM1I@cv}_lMlRT zN1t@>Uv*~RB(RHz-B?cp!qk7i#sf2B%(OJjzo>4y8MU>&DR}i@YAP6?kULIFK6DQ* zL6diIB|P-{D`m~#UsU;bBTXT3%rr4)hA#s(`6Z9)RHvc_&|+sV3d3x(UKS}$V|^a7 zi@z#Pdt3JnTZjOEn�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 b1Hb{8YB-$8MFs#6{(X!j`X8|SUrqc!WQ9XP literal 0 HcmV?d00001 From b1b1622af0f420921779dbaafeeefd2d9a9b484f Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:06:17 +0100 Subject: [PATCH 015/155] feat: More sounds --- lua/pixelui/core/cl_sounds.lua | 24 +++++++++++++++++ lua/pixelui/elements/cl_frame.lua | 2 ++ lua/pixelui/elements/cl_navbar.lua | 2 ++ lua/pixelui/elements/cl_notification.lua | 34 ++++++++++++------------ lua/pixelui/elements/cl_sidebar.lua | 3 +++ 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/lua/pixelui/core/cl_sounds.lua b/lua/pixelui/core/cl_sounds.lua index 97e37b5..b2f234c 100644 --- a/lua/pixelui/core/cl_sounds.lua +++ b/lua/pixelui/core/cl_sounds.lua @@ -25,4 +25,28 @@ do PIXEL.PlaySound("buttons-navigation", "Collapse") end end + + function PIXEL.PlayNotify() + PIXEL.PlaySound("notifications-alerts", "Alert_2") + end + + local tabSounds = { + [1] = "Tab_1", + [2] = "Tab_2", + [3] = "Tab_3" + } + + function PIXEL.PlayChangeTab() + local randSound = math.random(1, 3) + PIXEL.PlaySound("buttons-navigation", tabSounds[randSound]) + end + + function PIXEL.PlayCancel() + PIXEL.PlaySound("errors-cancel", "Cancel_2") + end + + function PIXEL.PlayError(num) + if not num then num = 1 end + PIXEL.PlaySound("errors-cancel", "Cancel_" .. num) + end end \ No newline at end of file diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index ffdd2d2..b78844b 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -201,6 +201,8 @@ function PANEL:PerformLayout(w, h) end function PANEL:Open() + PIXEL.PlayButtonSound() + self:SetVisible(false) self:SetAlpha(0) self:SetVisible(true) self:AlphaTo(255, .1, 0) diff --git a/lua/pixelui/elements/cl_navbar.lua b/lua/pixelui/elements/cl_navbar.lua index b775f0c..481c5d7 100644 --- a/lua/pixelui/elements/cl_navbar.lua +++ b/lua/pixelui/elements/cl_navbar.lua @@ -27,6 +27,7 @@ function PANEL:Init() self:SetName("N/A") self:SetColor(PIXEL.Colors.Primary) self:SetClicky(false) + self:SetSounds(false) self.NormalCol = PIXEL.Colors.PrimaryText self.HoverCol = PIXEL.Colors.SecondaryText @@ -95,6 +96,7 @@ end function PANEL:SelectItem(id) local item = self.Items[id] if not item then return end + PIXEL.PlayChangeTab() if self.SelectedItem and self.SelectedItem == id then return end self.SelectedItem = id diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua index 401261c..7b4e7e3 100644 --- a/lua/pixelui/elements/cl_notification.lua +++ b/lua/pixelui/elements/cl_notification.lua @@ -1,7 +1,8 @@ local sc = PIXEL.Scale local Notices = {} -local notifAmount = 0 +local notifyAmount = 0 + surface.CreateFont("PIXEL.NotifyFont", { font = "Open Sans Bold", size = 25, @@ -11,22 +12,24 @@ surface.CreateFont("PIXEL.NotifyFont", { function PIXEL.Notify(text, type, length) + local ply = LocalPlayer() + if not ply.NotifyAmount then ply.NotifyAmount = 0 end + ply.NotifyAmount = ply.NotifyAmount + 1 local parent = nil if ( GetOverlayPanel ) then parent = GetOverlayPanel() end - local notif = vgui.Create("PIXEL.Notification", parent) notif:SetLength(math.max(length, 0)) notif:SetText(text) + table.insert(Notices, notif) - if notifAmount > 0 then - notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200) - (sc(50) * notifAmount)) + if ply.NotifyAmount > 0 then + notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200) - (sc(50) * ply.NotifyAmount)) else notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200)) end - table.insert(Notices, notif) end -hook.Add("Initialize", "NotificationOverride", function() +hook.Add("Initialize", "PIXEL.NotificationOverride", function() local oldNotification = notification.AddLegacy function notification.AddLegacy(text, type, length) @@ -42,8 +45,7 @@ local PANEL = {} function PANEL:SetText(txt) self.NotifyText = txt - surface.SetFont("PIXEL.NotifyFont") - self:SetWide(surface.GetTextSize(txt) + sc(25)) + self:SetWide(PIXEL.GetTextSize(txt, "PIXEL.NotifyFont") + sc(25)) end function PANEL:SetLength(sec) @@ -56,7 +58,6 @@ function PANEL:SetLength(sec) end function PANEL:Init() - notifAmount = notifAmount + 1 self:SetTall(sc(40)) self:SetWide(sc(40)) self.NotifyText = "" @@ -79,27 +80,26 @@ function PANEL:Paint(w, h) PIXEL.DrawSimpleText(self.NotifyText, "PIXEL.NotifyFont", w / 2, h / 2 - sc(1), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end -function PANEL:SetProgress(frac) -end - -function PANEL:KillSelf() -end - function PANEL:Open() self:SetAlpha(0) self:SetVisible(true) self:AlphaTo(255, .1, 0) + PIXEL.PlayNotify() end function PANEL:Close() + local ply = LocalPlayer() self:AlphaTo(0, .1, 0, function(anim, pnl) if not IsValid(pnl) then return end pnl:SetVisible(false) pnl:Remove() end) - notifAmount = notifAmount - 1 + ply.NotifyAmount = ply.NotifyAmount - 1 end +function PANEL:SetProgress(frac) end + +function PANEL:KillSelf() end -vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") \ No newline at end of file +vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 9cb2fe7..cb939e8 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -28,6 +28,7 @@ function PANEL:Init() self:SetName("N/A") self:SetDrawOutline(true) self:SetClicky(false) + self:SetSounds(false) self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) @@ -134,6 +135,8 @@ function PANEL:SelectItem(id) local item = self.Items[id] if not item then return end + PIXEL.PlayChangeTab() + if self.SelectedItem and self.SelectedItem == id then return end self.SelectedItem = id From 052978d5ef3b4c62e031714775b20fe1ab07edc6 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:18:42 +0100 Subject: [PATCH 016/155] feat: even more ui sounds --- lua/pixelui/core/cl_sounds.lua | 15 ++++++++++++++- lua/pixelui/elements/cl_notification.lua | 17 ++++++++++++++++- lua/pixelui/elements/cl_text_entry_internal.lua | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/core/cl_sounds.lua b/lua/pixelui/core/cl_sounds.lua index b2f234c..b5e2967 100644 --- a/lua/pixelui/core/cl_sounds.lua +++ b/lua/pixelui/core/cl_sounds.lua @@ -17,6 +17,9 @@ do PIXEL.PlaySound("buttons-navigation", buttonSounds[randSound]) end + function PIXEL.PlayKeyType() + PIXEL.PlayButtonSound() + end function PIXEL.PlayExpand(type) if type == "open" then @@ -47,6 +50,16 @@ do function PIXEL.PlayError(num) if not num then num = 1 end - PIXEL.PlaySound("errors-cancel", "Cancel_" .. num) + PIXEL.PlaySound("errors-cancel", "Error_" .. num) + end + + function PIXEL.PlayComplete(num) + if not num then num = 1 end + PIXEL.PlaySound("complete-success", "Complete_" .. num) + end + + function PIXEL.PlaySuccess(num) + if not num then num = 1 end + PIXEL.PlaySound("complete-success", "Success_" .. num) end end \ No newline at end of file diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua index 7b4e7e3..2c15b54 100644 --- a/lua/pixelui/elements/cl_notification.lua +++ b/lua/pixelui/elements/cl_notification.lua @@ -20,6 +20,7 @@ function PIXEL.Notify(text, type, length) local notif = vgui.Create("PIXEL.Notification", parent) notif:SetLength(math.max(length, 0)) notif:SetText(text) + notif:SetType(type) table.insert(Notices, notif) if ply.NotifyAmount > 0 then @@ -48,6 +49,21 @@ function PANEL:SetText(txt) self:SetWide(PIXEL.GetTextSize(txt, "PIXEL.NotifyFont") + sc(25)) end +function PANEL:SetType(type) + self.NotifyType = type + if type == NOTIFY_GENERIC then + PIXEL.PlayNotify() + elseif type == NOTIFY_ERROR then + PIXEL.PlayError(1) + elseif type == NOTIFY_UNDO then + PIXEL.PlayError(2) + elseif type == NOTIFY_HINT then + PIXEL.PlaySuccess(1) + elseif type == NOTIFY_CLEANUP then + PIXEL.PlayError(5) + end +end + function PANEL:SetLength(sec) sec = sec + .2 self.Length = sec @@ -84,7 +100,6 @@ function PANEL:Open() self:SetAlpha(0) self:SetVisible(true) self:AlphaTo(255, .1, 0) - PIXEL.PlayNotify() end function PANEL:Close() diff --git a/lua/pixelui/elements/cl_text_entry_internal.lua b/lua/pixelui/elements/cl_text_entry_internal.lua index 231da93..1001150 100644 --- a/lua/pixelui/elements/cl_text_entry_internal.lua +++ b/lua/pixelui/elements/cl_text_entry_internal.lua @@ -138,6 +138,7 @@ function PANEL:UpdateFromMenu() end function PANEL:OnTextChanged(noMenuRemoval) + PIXEL.PlayKeyType() self.HistoryPos = 0 if self:GetUpdateOnType() then From f3be36b09e0c04044ba293e8b52aae92cc6691ac Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:20:56 +0100 Subject: [PATCH 017/155] refactor: disabling sounds --- lua/pixelui/core/cl_sounds.lua | 2 ++ lua/pixelui/core/{sh_confetti.lua => sv_confetti.lua} | 9 +-------- lua/pixelui/sh_config.lua | 5 +++++ 3 files changed, 8 insertions(+), 8 deletions(-) rename lua/pixelui/core/{sh_confetti.lua => sv_confetti.lua} (75%) diff --git a/lua/pixelui/core/cl_sounds.lua b/lua/pixelui/core/cl_sounds.lua index b5e2967..c9ea43c 100644 --- a/lua/pixelui/core/cl_sounds.lua +++ b/lua/pixelui/core/cl_sounds.lua @@ -1,5 +1,7 @@ +PIXEL = PIXEL or {} do function PIXEL.PlaySound(type, sound) + if PIXEL.DisableUISounds then return end local soundPath = "pixelui-sounds/" .. type .. "/" .. sound .. ".mp3" if not file.Exists("sound/" .. soundPath, "GAME") then print(soundPath, "bad") return end diff --git a/lua/pixelui/core/sh_confetti.lua b/lua/pixelui/core/sv_confetti.lua similarity index 75% rename from lua/pixelui/core/sh_confetti.lua rename to lua/pixelui/core/sv_confetti.lua index 30398fb..91b00b7 100644 --- a/lua/pixelui/core/sh_confetti.lua +++ b/lua/pixelui/core/sv_confetti.lua @@ -1,4 +1,4 @@ -if SERVER then +do util.AddNetworkString("PIXEL.SpawnConfetti") util.PrecacheSound("pixel_confetti.mp3") function PIXEL.SpawnConfetti(ply) @@ -11,11 +11,4 @@ if SERVER then net.Receive("PIXEL.SpawnConfetti", function(_, ply) PIXEL.SpawnConfetti(ply) end) -end - -if CLIENT then - function PIXEL.SpawnConfetti() - net.Start("PIXEL.SpawnConfetti") - net.SendToServer() - end end \ No newline at end of file diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index f5c0ec8..bc10dd2 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -34,6 +34,11 @@ PIXEL.OverrideDermaMenus = 0 ]] PIXEL.DisableNotification = false +--[[ + Should we disable The UI Sounds? +]] +PIXEL.DisableUISounds = false + --[[ The Imgur ID of the progress image you want to appear when Imgur content is loading. ]] From dc624d7b64d71649c9a09a2cfeb93cad12fd7764 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:25:05 +0100 Subject: [PATCH 018/155] refactor: remove useless code --- lua/pixelui/core/sv_confetti.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lua/pixelui/core/sv_confetti.lua b/lua/pixelui/core/sv_confetti.lua index 91b00b7..bfcfba5 100644 --- a/lua/pixelui/core/sv_confetti.lua +++ b/lua/pixelui/core/sv_confetti.lua @@ -7,8 +7,4 @@ do util.Effect("pixel_confetti", effectData) sound.Play("pixelui-sounds/pixel_confetti.mp3", ply:GetPos()) end - - net.Receive("PIXEL.SpawnConfetti", function(_, ply) - PIXEL.SpawnConfetti(ply) - end) end \ No newline at end of file From 446dd5bdfbdf2457dad3fbc0a1ec4fb8c9804034 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:33:53 +0100 Subject: [PATCH 019/155] refactor: update autorun info --- lua/autorun/sh_pixelui_loader.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 39d85d6..0b8e657 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -56,16 +56,16 @@ hook.Run("PIXEL.UI.FullyLoaded") if CLIENT then return end -resource.AddWorkshop("2468112758") +resource.AddWorkshop("2825396224") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://raw.githubusercontent.com/TomDotBat/pixel-ui/master/VERSION", function(body) + http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) - MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/TomDotBat/pixel-ui/releases\n") + MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") MsgC(red, "New version: " .. body .. "\n") return From 06e5f2a38ab64f349d3a43d72465d623bd9b7d22 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 25 Jun 2022 00:32:22 +0100 Subject: [PATCH 020/155] feat: Feature showcase menu --- lua/pixelui/elements/cl_text_button.lua | 4 +- lua/pixelui/test/cl_menu.lua | 84 +++++++++++++++++++++++ lua/pixelui/test/pages/cl_avatar.lua | 31 +++++++++ lua/pixelui/test/pages/cl_buttons.lua | 72 +++++++++++++++++++ lua/pixelui/test/pages/cl_navigation.lua | 21 ++++++ lua/pixelui/test/pages/cl_other.lua | 42 ++++++++++++ lua/pixelui/test/pages/cl_scrollpanel.lua | 23 +++++++ lua/pixelui/test/pages/cl_text.lua | 34 +++++++++ 8 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 lua/pixelui/test/cl_menu.lua create mode 100644 lua/pixelui/test/pages/cl_avatar.lua create mode 100644 lua/pixelui/test/pages/cl_buttons.lua create mode 100644 lua/pixelui/test/pages/cl_navigation.lua create mode 100644 lua/pixelui/test/pages/cl_other.lua create mode 100644 lua/pixelui/test/pages/cl_scrollpanel.lua create mode 100644 lua/pixelui/test/pages/cl_text.lua diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index 2ae6d63..2bf3243 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -51,7 +51,9 @@ function PANEL:PaintExtra(w, h) return end - if self:GetClicky() then + if self.ClickyMove and self:GetClicky() then + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2 - PIXEL.Scale(2)) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + elseif self:GetClicky() then PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(2), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) else PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) diff --git a/lua/pixelui/test/cl_menu.lua b/lua/pixelui/test/cl_menu.lua new file mode 100644 index 0000000..8c54147 --- /dev/null +++ b/lua/pixelui/test/cl_menu.lua @@ -0,0 +1,84 @@ +PIXEL = PIXEL or {} +local PANEL = {} + +function PANEL:Init() + self:SetSize(PIXEL.Scale(900), PIXEL.Scale(550)) + self:Center() + self:MakePopup() + self:SetTitle("PIXEL Test") + + self.Sidebar = self:CreateSidebar("PIXEL.Test.Avatar", "8bKjn4t") + + self.Sidebar:AddItem("PIXEL.Test.Avatar", "Avatar", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Avatar") + end) + self.Sidebar:AddItem("PIXEL.Test.Buttons", "Buttons", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Buttons") + end) + self.Sidebar:AddItem("PIXEL.Test.Navigation", "Navigation", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Navigation") + end) + self.Sidebar:AddItem("PIXEL.Test.ScrollPanel", "ScrollPanel", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.ScrollPanel") + end) + self.Sidebar:AddItem("PIXEL.Test.Text", "Text", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Text") + end) + self.Sidebar:AddItem("PIXEL.Test.Other", "Other", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Other") + end) +end + +function PANEL:ChangeTab(panel) + if not self.SideBar:IsMouseInputEnabled() then return end + + if not IsValid(self.ContentPanel) then + self.ContentPanel = vgui.Create(panel, self) + self.ContentPanel:Dock(FILL) + self.ContentPanel:InvalidateLayout(true) + + function self.ContentPanel.Think(s) + if not self.DragThink then return end + if self:DragThink(self) then return end + if self:SizeThink(self, s) then return end + self:SetCursor("arrow") + + if self.y < 0 then + self:SetPos(self.x, 0) + end + end + + function self.ContentPanel.OnMousePressed() + self:OnMousePressed() + end + + function self.ContentPanel.OnMouseReleased() + self:OnMouseReleased() + end + + return + end + + self.SideBar:SetMouseInputEnabled(false) + + self.ContentPanel:AlphaTo(0, .15, 0, function(anim, pnl) + self.ContentPanel:Remove() + self.ContentPanel = vgui.Create(panel, self) + self.ContentPanel:Dock(FILL) + self.ContentPanel:InvalidateLayout(true) + + self.ContentPanel:AlphaTo(255, .15, 0, function(anim2, pnl2) + self.SideBar:SetMouseInputEnabled(true) + end) + end) +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.Main", PANEL, "PIXEL.Frame") + +concommand.Add("pixel_test", function() + vgui.Create("PIXEL.Test.Main") +end) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_avatar.lua b/lua/pixelui/test/pages/cl_avatar.lua new file mode 100644 index 0000000..41ced19 --- /dev/null +++ b/lua/pixelui/test/pages/cl_avatar.lua @@ -0,0 +1,31 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} +PIXEL.GenerateFont(50) + +function PANEL:Init() + self.Avatar = vgui.Create("PIXEL.Avatar", self) + self.Avatar:SetPlayer(LocalPlayer(), sc(200)) + self.Avatar:SetRounding(sc(8)) + self.Avatar:SetDrawOnTop(true) + self.Avatar:SetSize(sc(200), sc(200)) + self.Avatar:SetPos(sc(250), sc(100)) + + self.Label = vgui.Create("PIXEL.Label", self) + self.Label:SetText("Hey " .. LocalPlayer():Nick() .. "!") + self.Label:SetWide(sc(500)) + self.Label:SetTall(sc(100)) + self.Label:SetFont("PIXEL.Font.Size50") + self.Label:SetPos(sc(230), sc(300)) + + +end + +function PANEL:PaintMore(w,h) + +end + +function PANEL:LayoutContent(w,h) +end + +vgui.Register("PIXEL.Test.Avatar", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_buttons.lua b/lua/pixelui/test/pages/cl_buttons.lua new file mode 100644 index 0000000..9f2ec89 --- /dev/null +++ b/lua/pixelui/test/pages/cl_buttons.lua @@ -0,0 +1,72 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + + +function PANEL:Init() + self.Button = vgui.Create("PIXEL.Button", self) + self.Button:Dock(TOP) + self.Button:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.Button:SetTall(sc(50)) + self.Button.DoClick = function() + notification.AddLegacy("Normal Button!", NOTIFY_GENERIC, 5) + end + + self.ClickyButton = vgui.Create("PIXEL.Button", self) + self.ClickyButton:Dock(TOP) + self.ClickyButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.ClickyButton:SetTall(sc(50)) + self.ClickyButton:SetClicky(true) + self.ClickyButton.DoClick = function() + notification.AddLegacy("Normal Clicky Button!", NOTIFY_GENERIC, 5) + end + + self.ClickyTextButton = vgui.Create("PIXEL.TextButton", self) + self.ClickyTextButton:Dock(TOP) + self.ClickyTextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.ClickyTextButton:SetTall(sc(50)) + self.ClickyTextButton:SetText("Clicky Button!") + self.ClickyTextButton.DoClick = function() + notification.AddLegacy("Clicky Text Button!", NOTIFY_GENERIC, 5) + end + + self.TextButton = vgui.Create("PIXEL.TextButton", self) + self.TextButton:Dock(TOP) + self.TextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.TextButton:SetTall(sc(50)) + self.TextButton:SetText("Non Clicky Button!") + self.TextButton:SetClicky(false) + self.TextButton.DoClick = function() + notification.AddLegacy("Non Clicky Text button!", NOTIFY_GENERIC, 5) + end + + self.NoSoundButton = vgui.Create("PIXEL.TextButton", self) + self.NoSoundButton:Dock(TOP) + self.NoSoundButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.NoSoundButton:SetTall(sc(50)) + self.NoSoundButton:SetText("No Sound Clicky Button!") + self.NoSoundButton:SetSounds(false) + self.NoSoundButton.DoClick = function() + notification.AddLegacy("No Sound Button!", NOTIFY_GENERIC, 5) + end + + + self.ImgurButton = vgui.Create("PIXEL.ImgurButton", self) + self.ImgurButton:Dock(TOP) + self.ImgurButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.ImgurButton:SetSize(sc(50), sc(50)) + self.ImgurButton:SetImgurID("8bKjn4t") + self.ImgurButton:SetNormalColor(PIXEL.Colors.PrimaryText) + self.ImgurButton:SetHoverColor(PIXEL.Colors.Negative) + self.ImgurButton:SetClickColor(PIXEL.Colors.Positive) + self.ImgurButton:SetDisabledColor(PIXEL.Colors.DisabledText) + self.ImgurButton.DoClick = function() + notification.AddLegacy("Imgur Button!", NOTIFY_GENERIC, 5) + end +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.Buttons", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_navigation.lua b/lua/pixelui/test/pages/cl_navigation.lua new file mode 100644 index 0000000..c3b1aa9 --- /dev/null +++ b/lua/pixelui/test/pages/cl_navigation.lua @@ -0,0 +1,21 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + +function PANEL:Init() + self.Navbar = vgui.Create("PIXEL.Navbar", self) + self.Navbar:Dock(TOP) + self.Navbar:SetTall(sc(50)) + self.Navbar:AddItem("test1", "Test 1", function() notification.AddLegacy("Clicked 1!", NOTIFY_GENERIC, 5) end, 1, PIXEL.Colors.Gold) + self.Navbar:AddItem("test2", "Test 2", function() notification.AddLegacy("Clicked 2!", NOTIFY_GENERIC, 5) end, 2, PIXEL.Colors.Diamond) + self.Navbar:AddItem("test3", "Test 3", function() notification.AddLegacy("Clicked 3!", NOTIFY_GENERIC, 5) end, 3, PIXEL.Colors.Silver) + self.Navbar:AddItem("test4", "Test 4", function() notification.AddLegacy("Clicked 4!", NOTIFY_GENERIC, 5) end, 4, PIXEL.Colors.Bronze) + self.Navbar:AddItem("test5", "Test 5", function() notification.AddLegacy("Clicked 5!", NOTIFY_GENERIC, 5) end, 5, PIXEL.Colors.Primary) + + +end + +function PANEL:PaintMore(w,h) +end + +vgui.Register("PIXEL.Test.Navigation", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_other.lua b/lua/pixelui/test/pages/cl_other.lua new file mode 100644 index 0000000..1553641 --- /dev/null +++ b/lua/pixelui/test/pages/cl_other.lua @@ -0,0 +1,42 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + +PIXEL.GenerateFont(25) + +function PANEL:Init() + self.Category = vgui.Create("PIXEL.Category", self) + self.Category:Dock(TOP) + self.Category:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.Category:SetTitle("Categorys!") + + self.Slider = vgui.Create("PIXEL.Slider", self) + self.Slider:Dock(TOP) + self.Slider:DockMargin(sc(50), sc(10), sc(50), sc(10)) + + self.LabelledCheckbox = vgui.Create("PIXEL.LabelledCheckbox", self) + self.LabelledCheckbox:Dock(TOP) + self.LabelledCheckbox:DockMargin(sc(50), sc(10), sc(50), sc(10)) + self.LabelledCheckbox:SetText("Labelled Checkbox!") + self.LabelledCheckbox:SetFont("PIXEL.Font.Size25") + + self.ComboBox = vgui.Create("PIXEL.ComboBox", self) + self.ComboBox:Dock(TOP) + self.ComboBox:DockMargin(sc(50), sc(10), sc(50), sc(10)) + self.ComboBox:SetSizeToText(false) + self.ComboBox:AddChoice("Choice 1", "Choice 1", "Choice 1") + self.ComboBox:AddChoice("Choice 2", "Choice 2", "Choice 2") + self.ComboBox:AddChoice("Choice 3", "Choice 3", "Choice 3") + self.ComboBox:AddChoice("Choice 4", "Choice 4", "Choice 4") + self.ComboBox:AddChoice("Choice 5", "Choice 5", "Choice 5") + + self.ColorPicker = vgui.Create("PIXEL.ColorPicker", self) + self.ColorPicker:Dock(FILL) + self.ColorPicker:DockMargin(sc(50), sc(10), sc(50), sc(10)) +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.Other", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_scrollpanel.lua b/lua/pixelui/test/pages/cl_scrollpanel.lua new file mode 100644 index 0000000..35c7c59 --- /dev/null +++ b/lua/pixelui/test/pages/cl_scrollpanel.lua @@ -0,0 +1,23 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + +function PANEL:Init() + self.ScrollPanel = vgui.Create("PIXEL.ScrollPanel", self) + self.ScrollPanel:Dock(FILL) + self.ScrollPanel:DockMargin(0, 0, 0, 0) + + for i = 0, 250 do + self.ClickyTextButton = vgui.Create("PIXEL.TextButton", self.ScrollPanel) + self.ClickyTextButton:Dock(TOP) + self.ClickyTextButton:DockMargin(sc(5), sc(5), sc(5), sc(5)) + self.ClickyTextButton:SetTall(sc(50)) + self.ClickyTextButton:SetText("Clicky Button!") + end +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.ScrollPanel", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_text.lua b/lua/pixelui/test/pages/cl_text.lua new file mode 100644 index 0000000..5eae5a7 --- /dev/null +++ b/lua/pixelui/test/pages/cl_text.lua @@ -0,0 +1,34 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + +function PANEL:Init() + self.TextEntry = vgui.Create("PIXEL.TextEntry", self) + self.TextEntry:Dock(TOP) + self.TextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) + self.TextEntry:SetTall(sc(35)) + self.TextEntry:SetPlaceholderText("Placeholder Text!") + + self.BadValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) + self.BadValidatedTextEntry:Dock(TOP) + self.BadValidatedTextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) + self.BadValidatedTextEntry:SetPlaceholderText("Bad Text!") + + function self.BadValidatedTextEntry:IsTextValid(text) + return false, "Bad Text!" + end + + self.GoodValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) + self.GoodValidatedTextEntry:Dock(TOP) + self.GoodValidatedTextEntry:DockMargin(sc(20), sc(0), sc(20), sc(20)) + self.GoodValidatedTextEntry:SetPlaceholderText("Good Text!") + function self.GoodValidatedTextEntry:IsTextValid(text) + return true, "Good Text!" + end +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.Text", PANEL) \ No newline at end of file From f324e311e3b79c42f007230892760b30b95b118e Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 25 Jun 2022 12:52:27 +0100 Subject: [PATCH 021/155] stuff --- .github/workflows/retype-action.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/retype-action.yml diff --git a/.github/workflows/retype-action.yml b/.github/workflows/retype-action.yml new file mode 100644 index 0000000..5d4c449 --- /dev/null +++ b/.github/workflows/retype-action.yml @@ -0,0 +1,21 @@ +name: Publish Retype powered website to GitHub Pages +on: + workflow_dispatch: + push: + branches: + - wiki + +jobs: + publish: + name: Publish to retype branch + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: retypeapp/action-build@latest + + - uses: retypeapp/action-github-pages@latest + with: + update-branch: true \ No newline at end of file From 5dc7942e9ca9346eebe70abf7767a07e4c7102f4 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 25 Jun 2022 12:54:31 +0100 Subject: [PATCH 022/155] Revert "stuff" This reverts commit f324e311e3b79c42f007230892760b30b95b118e. --- .github/workflows/retype-action.yml | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 .github/workflows/retype-action.yml diff --git a/.github/workflows/retype-action.yml b/.github/workflows/retype-action.yml deleted file mode 100644 index 5d4c449..0000000 --- a/.github/workflows/retype-action.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Publish Retype powered website to GitHub Pages -on: - workflow_dispatch: - push: - branches: - - wiki - -jobs: - publish: - name: Publish to retype branch - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - uses: retypeapp/action-build@latest - - - uses: retypeapp/action-github-pages@latest - with: - update-branch: true \ No newline at end of file From 5303fba95604c092150459e07c4b3d1790e87bb4 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 25 Jun 2022 17:31:59 +0100 Subject: [PATCH 023/155] refactor: change text position --- lua/pixelui/elements/cl_text_button.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index 2bf3243..f727f2c 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -52,9 +52,9 @@ function PANEL:PaintExtra(w, h) end if self.ClickyMove and self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2 - PIXEL.Scale(2)) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2 - PIXEL.Scale(4)) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) elseif self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(2), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(4), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) else PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) end From 2eceb3d77ba149197facfaa34f8b832ae3509d06 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 26 Jun 2022 15:05:58 +0100 Subject: [PATCH 024/155] feat: Allow servers to have custom themes without breaking shit --- lua/autorun/sh_pixelui_loader.lua | 23 ++++ lua/pixelui/cl_themes.lua | 30 +++++ lua/pixelui/core/cl_color.lua | 4 + lua/pixelui/core/cl_theme.lua | 52 ++++++++ lua/pixelui/core/cl_themes.lua | 149 ++++++++++++++++++++++ lua/pixelui/core/sh_theme.lua | 52 -------- lua/pixelui/elements/cl_button.lua | 26 ---- lua/pixelui/elements/cl_notification.lua | 2 +- lua/pixelui/panels/cl_themeeditor.lua | 30 ++++- lua/pixelui/sh_config.lua | 152 +---------------------- 10 files changed, 285 insertions(+), 235 deletions(-) create mode 100644 lua/pixelui/cl_themes.lua create mode 100644 lua/pixelui/core/cl_theme.lua create mode 100644 lua/pixelui/core/cl_themes.lua delete mode 100644 lua/pixelui/core/sh_theme.lua diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 0b8e657..56ffcca 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -20,6 +20,29 @@ PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} PIXEL.UI.Version = "1.2.3" +PIXEL.Colors = { + Background = Color(22, 22, 22), + Header = Color(28, 28, 28), + SecondaryHeader = Color(15, 15, 15), + Scroller = Color(61, 61, 61), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(220, 220, 220), + DisabledText = Color(40, 40, 40), + + Primary = Color(77, 79, 199), + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + function PIXEL.LoadDirectory(path) local files, folders = file.Find(path .. "/*", "LUA") diff --git a/lua/pixelui/cl_themes.lua b/lua/pixelui/cl_themes.lua new file mode 100644 index 0000000..690f18b --- /dev/null +++ b/lua/pixelui/cl_themes.lua @@ -0,0 +1,30 @@ +PIXEL.Themes = PIXEL.Themes or {} + +--[[ + Want to make custom themes for your server? + Here is a basic example of how to do it: +]] +--[[ +PIXEL.Themes["Your Theme Name"] = { + Background = Color(22, 22, 22), -- UI Background Color + Header = Color(28, 28, 28), -- UI Header Color + SecondaryHeader = Color(43, 43, 43), -- UI Secondary Header Color + Scroller = Color(61, 61, 61), -- UI Scroller Color + + PrimaryText = Color(255, 255, 255), -- UI Primary Text Color + SecondaryText = Color(220, 220, 220), -- UI Secondary Text Color + DisabledText = Color(40, 40, 40), -- UI Disabled Text Color + + Primary = Color(74, 61, 255), -- Primary Server Color + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} +]] diff --git a/lua/pixelui/core/cl_color.lua b/lua/pixelui/core/cl_color.lua index f4f7de6..62c2bed 100644 --- a/lua/pixelui/core/cl_color.lua +++ b/lua/pixelui/core/cl_color.lua @@ -150,6 +150,10 @@ function PIXEL.IsColorEqualTo(from, to) return from.r == to.r and from.g == to.g and from.b == to.b and from.a == to.a end +function PIXEL.SetColorTransparency(color, transparency) + return Color(color.r, color.g, color.b, transparency) +end + local colorMeta = FindMetaTable("Color") colorMeta.Copy = PIXEL.CopyColor colorMeta.IsLight = PIXEL.IsColorLight diff --git a/lua/pixelui/core/cl_theme.lua b/lua/pixelui/core/cl_theme.lua new file mode 100644 index 0000000..6a76494 --- /dev/null +++ b/lua/pixelui/core/cl_theme.lua @@ -0,0 +1,52 @@ +if not file.Exists("pixel/themes/", "DATA") then + file.CreateDir("pixel/themes/") +end + +function PIXEL.SetTheme(theme, cross) + print(theme, cross) + if not cross then + local ip = game.GetIPAddress() + ip = ip:gsub(":", "-") + ip = string.Replace(ip, ".", "_") + + file.CreateDir("pixel/themes/" .. ip .. "/") + file.Write("pixel/themes/" .. ip .. "/theme.txt", theme) + else + file.Write("pixel/themes/theme.txt", theme) + end + + if PIXEL.Themes[theme] then + PIXEL.Colors = PIXEL.Themes[theme] + local ply = LocalPlayer() + ply.PIXELTheme = theme + else + PIXEL.Colors = PIXEL.Themes["Dark"] + return false + end +end + +hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() + local ply = LocalPlayer() + local ip = game.GetIPAddress() + ip = ip:gsub(":", "-") + ip = string.Replace(ip, ".", "_") + if file.Exists("pixel/themes/" .. ip .. "/theme.txt", "DATA") then + local theme = file.Read("pixel/" .. ip .. "/theme.txt", "DATA") + PIXEL.Colors = PIXEL.Themes[theme] + ply.PIXELTheme = theme + return + end + + if not file.Exists("pixel/themes/theme.txt", "DATA") then + PIXEL.Colors = PIXEL.Themes["Dark"] + return + end + + local theme = file.Read("pixel/theme.txt", "DATA") + PIXEL.Colors = PIXEL.Themes[theme] + ply.PIXELTheme = theme +end) + +concommand.Add("pixel_reset_theme", function(ply, cmd, args) + PIXEL.Colors = PIXEL.Themes["Dark"] +end) \ No newline at end of file diff --git a/lua/pixelui/core/cl_themes.lua b/lua/pixelui/core/cl_themes.lua new file mode 100644 index 0000000..874e28a --- /dev/null +++ b/lua/pixelui/core/cl_themes.lua @@ -0,0 +1,149 @@ +PIXEL = PIXEL or {} +PIXEL.Themes = PIXEL.Themes or {} +PIXEL.DefaultThemes = PIXEL.DefaultThemes or { + "Dark", "Light", "GitHubDark", "NightOwl", "DiscordDark", "DiscordLight" +} + +PIXEL.Themes["Dark"] = { + included = true, + Background = Color(22, 22, 22), + Header = Color(28, 28, 28), + SecondaryHeader = Color(43, 43, 43), + Scroller = Color(61, 61, 61), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(220, 220, 220), + DisabledText = Color(40, 40, 40), + + Primary = Color(74, 61, 255), + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["Light"] = { + included = true, + Background = PIXEL.HexToColor("#F7F8FA"), + Header = PIXEL.HexToColor("#edf1f5"), + SecondaryHeader = PIXEL.HexToColor("#DFE1E4"), + Scroller = PIXEL.HexToColor("#edf1f5"), + + PrimaryText = PIXEL.HexToColor("#292D31"), + SecondaryText = PIXEL.HexToColor("#808080"), + DisabledText = PIXEL.HexToColor("#9ba0a3"), + + Primary = Color(74, 61, 255), + Disabled = PIXEL.HexToColor("#9ba0a3"), + Positive = PIXEL.HexToColor("#79CB60"), + Negative = PIXEL.HexToColor("#d73a49"), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["GitHubDark"] = { + included = true, + Background = PIXEL.HexToColor("#24292e"), + Header = PIXEL.HexToColor("#2f363d"), + SecondaryHeader = PIXEL.HexToColor("#2b3036"), + Scroller = PIXEL.HexToColor("#2f363d"), + + PrimaryText = Color(74, 61, 255), + SecondaryText = PIXEL.HexToColor("#c9d1d9"), + DisabledText = PIXEL.HexToColor("#39414a"), + + Primary = PIXEL.HexToColor("#b392f0"), + Disabled = PIXEL.HexToColor("#6a737d"), + Positive = PIXEL.HexToColor("#85e89d"), + Negative = PIXEL.HexToColor("#f97583"), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["NightOwl"] = { + included = true, + Background = PIXEL.HexToColor("#011627"), -- Background + Header = PIXEL.HexToColor("#0b2942"), -- Seccond Background + SecondaryHeader = PIXEL.HexToColor("#13344f"), -- Active + Scroller = PIXEL.HexToColor("#0b2942"), -- Seccond Background + + PrimaryText = PIXEL.HexToColor("#FBFBFB"), -- Text + SecondaryText = PIXEL.HexToColor("#d9d9d9"), -- Buttons + DisabledText = PIXEL.HexToColor("#697098"), -- Disabled + + Primary = Color(74, 61, 255), + Disabled = PIXEL.HexToColor("#697098"), -- Disabled + Positive = PIXEL.HexToColor("#addb67"), -- Green + Negative = PIXEL.HexToColor("#ff6363"), -- Red + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["DiscordDark"] = { + included = true, + Background = Color(54, 57, 63), + Header = Color(47, 49, 54), + SecondaryHeader = Color(51, 54, 59), + Scroller = Color(32, 34, 37), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(185, 187, 190), + DisabledText = Color(40, 40, 40), + + Primary = Color(88, 101, 242), + Disabled = Color(114, 118, 125), + Positive = Color(87, 242, 135), + Negative = Color(237, 66, 69), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["DiscordLight"] = { + included = true, + Background = Color(255, 255, 255), + Header = Color(242, 243, 245), + SecondaryHeader = Color(220, 223, 227), + Scroller = Color(204, 204, 204), + + PrimaryText = Color(6, 6, 7), + SecondaryText = Color(79, 86, 96), + DisabledText = Color(79, 86, 96), + + Primary = Color(88, 101, 242), + Disabled = Color(79, 86, 96), + Positive = Color(87, 242, 135), + Negative = Color(237, 66, 69), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} \ No newline at end of file diff --git a/lua/pixelui/core/sh_theme.lua b/lua/pixelui/core/sh_theme.lua deleted file mode 100644 index 5bb9ca5..0000000 --- a/lua/pixelui/core/sh_theme.lua +++ /dev/null @@ -1,52 +0,0 @@ -PIXEL.Colors = { - Background = Color(22, 22, 22), - Header = Color(28, 28, 28), - SecondaryHeader = Color(15, 15, 15), - Scroller = Color(61, 61, 61), - - PrimaryText = Color(255, 255, 255), - SecondaryText = Color(220, 220, 220), - DisabledText = Color(40, 40, 40), - - Primary = Color(77, 79, 199), - Disabled = Color(180, 180, 180), - Positive = Color(68, 235, 124), - Negative = Color(235, 68, 68), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes = PIXEL.Themes or {} - -function PIXEL.SetTheme(theme) - file.Write("pixel/theme.txt", theme) - - if PIXEL.Themes[theme] then - PIXEL.Colors = PIXEL.Themes[theme] - if CLIENT then - local ply = LocalPlayer() - ply.PIXELTheme = theme - end - else - PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] - return false - end -end - -hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() - if !file.Exists("pixel/theme.txt", "DATA") then - PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] - return - end - local theme = file.Read("pixel/theme.txt", "DATA") - PIXEL.Colors = PIXEL.Themes[theme] -end) - -concommand.Add("pixel_reset_theme", function(ply, cmd, args) - PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] -end) \ No newline at end of file diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index 4529e55..a4ec336 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -177,29 +177,3 @@ function PANEL:DoRightClick() end function PANEL:DoMiddleClick() end vgui.Register("PIXEL.Button", PANEL, "Panel") - -concommand.Add("test", function() - local pnl = vgui.Create("PIXEL.Frame") - pnl:SetTitle("Test") - pnl:SetSize(650, 350) - pnl:Center() - local btn1 = pnl:Add("PIXEL.Button") - btn1:SetClicky(true) - btn1:SetSize(480, 200) - btn1:SetPos(10, 50) - - local btn2 = pnl:Add("PIXEL.Button") - btn2:SetClicky(true) - btn2:SetSize(100, 25) - btn2:SetPos(10, 275) - - local btn3 = pnl:Add("PIXEL.Button") - btn3:SetClicky(true) - btn3:SetSize(50, 200) - btn3:SetPos(525, 50) - - local btn4 = pnl:Add("PIXEL.Button") - btn4:SetClicky(true) - btn4:SetSize(300, 30) - btn4:SetPos(125, 275) -end) \ No newline at end of file diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua index 2c15b54..857f00d 100644 --- a/lua/pixelui/elements/cl_notification.lua +++ b/lua/pixelui/elements/cl_notification.lua @@ -91,7 +91,7 @@ function PANEL:Paint(w, h) local shouldDraw = not (LocalPlayer and IsValid(LocalPlayer()) and IsValid(LocalPlayer():GetActiveWeapon()) and LocalPlayer():GetActiveWeapon():GetClass() == "gmod_camera") if not shouldDraw then return end - PIXEL.DrawRoundedBoxEx(sc(6), sc(5), 0, w, h, Color(0, 0, 0, 200), false, true, false, true) + PIXEL.DrawRoundedBoxEx(sc(6), sc(5), 0, w, h, PIXEL.SetColorTransparency(PIXEL.Colors.Background, 200), false, true, false, true) PIXEL.DrawRoundedBoxEx(sc(6), 0, 0, sc(5), h, PIXEL.Colors.Primary, true, false, true, false) PIXEL.DrawSimpleText(self.NotifyText, "PIXEL.NotifyFont", w / 2, h / 2 - sc(1), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end diff --git a/lua/pixelui/panels/cl_themeeditor.lua b/lua/pixelui/panels/cl_themeeditor.lua index b846a2e..46a2396 100644 --- a/lua/pixelui/panels/cl_themeeditor.lua +++ b/lua/pixelui/panels/cl_themeeditor.lua @@ -1,8 +1,8 @@ local PANEL = {} local sc = PIXEL.Scale - +PIXEL.GenerateFont(18) function PANEL:Init() - self:SetSize(sc(200), sc(175)) + self:SetSize(sc(200), sc(200)) self:MakePopup() self:Center() @@ -11,7 +11,7 @@ function PANEL:Init() local panW, panH = self:GetSize() self.DropDown = self:Add("PIXEL.ComboBox") - self.DropDown:SetPos((panW / 2) - (self.DropDown:GetWide() / 2), panH / 2 - sc(15)) + self.DropDown:SetPos((panW / 2) - (self.DropDown:GetWide() / 2), panH / 2 - sc(35)) self.DropDown:SetSizeToText(false) for k, v in pairs(PIXEL.Themes) do @@ -19,9 +19,29 @@ function PANEL:Init() end self.DropDown:SetValue(LocalPlayer().PIXELTheme) - local themeSelected + + self.SaveCross = self:Add("PIXEL.LabelledCheckbox") + self.SaveCross:SetPos((panW / 2) - (self.SaveCross:GetWide() / 2) - sc(50), panH / 2 + sc(10)) + self.SaveCross:SetText("Save Across Servers?") + self.SaveCross:SetFont("PIXEL.Font.Size18") + local crossServer = false + if not table.HasValue(PIXEL.DefaultThemes, LocalPlayer().PIXELTheme) then + self.SaveCross.Checkbox:SetEnabled(false) + crossServer = false + end + + + local themeSelected = LocalPlayer().PIXELTheme + function self.DropDown:OnSelect(index, text, data) themeSelected = data + if PIXEL.Themes[themeSelected].included then + self:GetParent().SaveCross.Checkbox:SetEnabled(true) + crossServer = true + else + self:GetParent().SaveCross.Checkbox:SetEnabled(false) + crossServer = false + end end self.Submit = self:Add("PIXEL.TextButton") @@ -31,7 +51,7 @@ function PANEL:Init() self.Submit:SetText("Submit") self.Submit.DoClick = function() - PIXEL.SetTheme(themeSelected) + PIXEL.SetTheme(themeSelected, crossServer) self:Close() notification.AddLegacy("PIXELUI: Theme changed to " .. themeSelected, 0, 3) end diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index bc10dd2..f156014 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -1,8 +1,3 @@ -function HexColor(hex, alpha) - hex = hex:gsub("#","") - return Color ( tonumber("0x" .. hex:sub(1,2)), tonumber("0x" .. hex:sub(3,4)), tonumber("0x" .. hex:sub(5,6)), alpha or 255 ) -end - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -42,149 +37,4 @@ PIXEL.DisableUISounds = false --[[ The Imgur ID of the progress image you want to appear when Imgur content is loading. ]] -PIXEL.ProgressImageID = "635PPvg" - ---[[ - Colour definitions. -]] - -PIXEL.DefaultTheme = "Dark" - -PIXEL.Themes = PIXEL.Themes or {} -- do not touch -PIXEL.Themes["Dark"] = { - Background = Color(22, 22, 22), - Header = Color(28, 28, 28), - SecondaryHeader = Color(43, 43, 43), - Scroller = Color(61, 61, 61), - - PrimaryText = Color(255, 255, 255), - SecondaryText = Color(220, 220, 220), - DisabledText = Color(40, 40, 40), - - Primary = Color(74, 61, 255), - Disabled = Color(180, 180, 180), - Positive = Color(68, 235, 124), - Negative = Color(235, 68, 68), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["Light"] = { - Background = HexColor("#F7F8FA"), - Header = HexColor("#edf1f5"), - SecondaryHeader = HexColor("#DFE1E4"), - Scroller = HexColor("#edf1f5"), - - PrimaryText = HexColor("#292D31"), - SecondaryText = HexColor("#808080"), - DisabledText = HexColor("#9ba0a3"), - - Primary = Color(74, 61, 255), - Disabled = HexColor("#9ba0a3"), - Positive = HexColor("#79CB60"), - Negative = HexColor("#d73a49"), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["GitHubDark"] = { - Background = HexColor("#24292e"), - Header = HexColor("#2f363d"), - SecondaryHeader = HexColor("#2b3036"), - Scroller = HexColor("#2f363d"), - - PrimaryText = Color(74, 61, 255), - SecondaryText = HexColor("#c9d1d9"), - DisabledText = HexColor("#39414a"), - - Primary = HexColor("#b392f0"), - Disabled = HexColor("#6a737d"), - Positive = HexColor("#85e89d"), - Negative = HexColor("#f97583"), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["NightOwl"] = { - Background = HexColor("#011627"), -- Background - Header = HexColor("#0b2942"), -- Seccond Background - SecondaryHeader = HexColor("#13344f"), -- Active - Scroller = HexColor("#0b2942"), -- Seccond Background - - PrimaryText = HexColor("#FBFBFB"), -- Text - SecondaryText = HexColor("#d9d9d9"), -- Buttons - DisabledText = HexColor("#697098"), -- Disabled - - Primary = Color(74, 61, 255), - Disabled = HexColor("#697098"), -- Disabled - Positive = HexColor("#addb67"), -- Green - Negative = HexColor("#ff6363"), -- Red - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["DiscordDark"] = { - Background = Color(54, 57, 63), - Header = Color(47, 49, 54), - SecondaryHeader = Color(51, 54, 59), - Scroller = Color(32, 34, 37), - - PrimaryText = Color(255, 255, 255), - SecondaryText = Color(185, 187, 190), - DisabledText = Color(40, 40, 40), - - Primary = Color(88, 101, 242), - Disabled = Color(114, 118, 125), - Positive = Color(87, 242, 135), - Negative = Color(237, 66, 69), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["DiscordLight"] = { - Background = Color(255, 255, 255), - Header = Color(242, 243, 245), - SecondaryHeader = Color(220, 223, 227), - Scroller = Color(204, 204, 204), - - PrimaryText = Color(6, 6, 7), - SecondaryText = Color(79, 86, 96), - DisabledText = Color(79, 86, 96), - - Primary = Color(88, 101, 242), - Disabled = Color(79, 86, 96), - Positive = Color(87, 242, 135), - Negative = Color(237, 66, 69), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} \ No newline at end of file +PIXEL.ProgressImageID = "635PPvg" \ No newline at end of file From b8a22dfb990ebd5a5b1369cf54268532fac21087 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 27 Jun 2022 15:37:44 +0100 Subject: [PATCH 025/155] update version --- VERSION | 2 +- lua/autorun/sh_pixelui_loader.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index e8ea05d..589268e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.4 +1.3.0 \ No newline at end of file diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 56ffcca..6eeec74 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -18,7 +18,7 @@ along with this program. If not, see . PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} -PIXEL.UI.Version = "1.2.3" +PIXEL.UI.Version = "1.3.0" PIXEL.Colors = { Background = Color(22, 22, 22), From 36755e048de1b0920d694435b7a6fb3595c2b122 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Jun 2022 17:56:58 +0100 Subject: [PATCH 026/155] better theming styff --- lua/pixelui/core/{ => themes}/cl_theme.lua | 24 ++++++++++++++++----- lua/pixelui/core/{ => themes}/cl_themes.lua | 0 lua/pixelui/core/themes/sh_themes.lua | 22 +++++++++++++++++++ lua/pixelui/elements/cl_sidebar.lua | 3 ++- lua/pixelui/elements/cl_text_entry.lua | 5 ++++- 5 files changed, 47 insertions(+), 7 deletions(-) rename lua/pixelui/core/{ => themes}/cl_theme.lua (71%) rename lua/pixelui/core/{ => themes}/cl_themes.lua (100%) create mode 100644 lua/pixelui/core/themes/sh_themes.lua diff --git a/lua/pixelui/core/cl_theme.lua b/lua/pixelui/core/themes/cl_theme.lua similarity index 71% rename from lua/pixelui/core/cl_theme.lua rename to lua/pixelui/core/themes/cl_theme.lua index 6a76494..0eabf2e 100644 --- a/lua/pixelui/core/cl_theme.lua +++ b/lua/pixelui/core/themes/cl_theme.lua @@ -3,7 +3,6 @@ if not file.Exists("pixel/themes/", "DATA") then end function PIXEL.SetTheme(theme, cross) - print(theme, cross) if not cross then local ip = game.GetIPAddress() ip = ip:gsub(":", "-") @@ -25,26 +24,41 @@ function PIXEL.SetTheme(theme, cross) end end -hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() +local function setJoinTheme() local ply = LocalPlayer() local ip = game.GetIPAddress() ip = ip:gsub(":", "-") ip = string.Replace(ip, ".", "_") if file.Exists("pixel/themes/" .. ip .. "/theme.txt", "DATA") then - local theme = file.Read("pixel/" .. ip .. "/theme.txt", "DATA") + local theme = file.Read("pixel/themes/" .. ip .. "/theme.txt", "DATA") + if theme == "" then theme = "Dark" end + if not PIXEL.Themes[theme] then + ply.PIXELTheme = "Dark" + PIXEL.Colors = PIXEL.Themes["Dark"] + return + end + PIXEL.Colors = PIXEL.Themes[theme] ply.PIXELTheme = theme return end - if not file.Exists("pixel/themes/theme.txt", "DATA") then + if not file.Exists("pixel/themes/theme.txt", "DATA") then return end + + local theme = file.Read("pixel/theme.txt", "DATA") + if theme == "" then theme = "Dark" end + if not PIXEL.Themes[theme] then + ply.PIXELTheme = "Dark" PIXEL.Colors = PIXEL.Themes["Dark"] return end - local theme = file.Read("pixel/theme.txt", "DATA") PIXEL.Colors = PIXEL.Themes[theme] ply.PIXELTheme = theme +end + +hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() + setJoinTheme() end) concommand.Add("pixel_reset_theme", function(ply, cmd, args) diff --git a/lua/pixelui/core/cl_themes.lua b/lua/pixelui/core/themes/cl_themes.lua similarity index 100% rename from lua/pixelui/core/cl_themes.lua rename to lua/pixelui/core/themes/cl_themes.lua diff --git a/lua/pixelui/core/themes/sh_themes.lua b/lua/pixelui/core/themes/sh_themes.lua new file mode 100644 index 0000000..0e0aa17 --- /dev/null +++ b/lua/pixelui/core/themes/sh_themes.lua @@ -0,0 +1,22 @@ +PIXEL.Colors = { + Background = Color(22, 22, 22), + Header = Color(28, 28, 28), + SecondaryHeader = Color(15, 15, 15), + Scroller = Color(61, 61, 61), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(220, 220, 220), + DisabledText = Color(40, 40, 40), + + Primary = Color(77, 79, 199), + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} \ No newline at end of file diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index cb939e8..3103f2e 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -80,6 +80,7 @@ AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "ImgurScale", "ImgurScale", FORCE_NUMBER) AccessorFunc(PANEL, "ImgurOffset", "ImgurOffset", FORCE_NUMBER) AccessorFunc(PANEL, "ButtonOffset", "ButtonOffset", FORCE_NUMBER) +AccessorFunc(PANEL, "ButtonBtmOffset", "ButtonBtmOffset", FORCE_NUMBER) function PANEL:Init() self.Items = {} @@ -151,7 +152,7 @@ end function PANEL:PerformLayout(w, h) local sideSpacing = PIXEL.Scale(7) local topSpacing = PIXEL.Scale(7) - self:DockPadding(sideSpacing, self:GetImgurID() and w * self:GetImgurScale() + self:GetImgurOffset() + self:GetButtonOffset() + topSpacing * 2 or topSpacing, sideSpacing, topSpacing) + self:DockPadding(sideSpacing, self:GetImgurID() and w * self:GetImgurScale() + self:GetImgurOffset() + self:GetButtonOffset() + topSpacing * 2 or topSpacing, sideSpacing, self:GetButtonBtmOffset() or topSpacing) self.Scroller:Dock(FILL) self.Scroller:GetCanvas():DockPadding(0, 0, self.Scroller.VBar.Enabled and sideSpacing or 0, 0) diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index c14cf77..6d5a9f8 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -41,7 +41,10 @@ end function PANEL:Paint(w, h) if not self:IsEnabled() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.DisabledCol) - PIXEL.DrawSimpleText("Disabled", "UI.TextEntry", PIXEL.Scale(4), h / 2, PIXEL.Colors.SecondaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + end + + if not self:IsEnabled() and self:GetValue() == "" then + PIXEL.DrawSimpleText(self:GetPlaceholderText() or "", "UI.TextEntry", PIXEL.Scale(10), h / 2, self.PlaceholderTextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) return end From 5183fa761385f17db76fc707aa86eff5f2d7e664 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 2 Jul 2022 19:49:15 +0100 Subject: [PATCH 027/155] remove notifications because broken --- VERSION | 2 +- lua/autorun/sh_pixelui_loader.lua | 2 +- lua/pixelui/elements/cl_notification.lua | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 589268e..6261a05 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.0 \ No newline at end of file +1.3.1 \ No newline at end of file diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 6eeec74..a81ca41 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -18,7 +18,7 @@ along with this program. If not, see . PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} -PIXEL.UI.Version = "1.3.0" +PIXEL.UI.Version = "1.3.1" PIXEL.Colors = { Background = Color(22, 22, 22), diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua index 857f00d..18737d1 100644 --- a/lua/pixelui/elements/cl_notification.lua +++ b/lua/pixelui/elements/cl_notification.lua @@ -2,7 +2,7 @@ local sc = PIXEL.Scale local Notices = {} local notifyAmount = 0 - +--[[ surface.CreateFont("PIXEL.NotifyFont", { font = "Open Sans Bold", size = 25, @@ -118,3 +118,4 @@ function PANEL:SetProgress(frac) end function PANEL:KillSelf() end vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") +--]] \ No newline at end of file From e0da099284403fe6574d7520b5d1092557fcb3bd Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 15 Aug 2022 10:55:19 +0100 Subject: [PATCH 028/155] refactor: Add back function to support old addons --- lua/pixelui/elements/cl_avatar.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_avatar.lua b/lua/pixelui/elements/cl_avatar.lua index 9106286..bea7c24 100644 --- a/lua/pixelui/elements/cl_avatar.lua +++ b/lua/pixelui/elements/cl_avatar.lua @@ -1,6 +1,7 @@ local PANEL = {} AccessorFunc(PANEL, "Rounding", "Rounding", FORCE_NUMBER) +AccessorFunc(PANEL, "MaskSize", "MaskSize", FORCE_NUMBER) function PANEL:Init() self.Avatar = vgui.Create("AvatarImage", self) @@ -35,7 +36,7 @@ function PANEL:Paint(w, h) render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NEVER) render.SetStencilReferenceValue(1) - PIXEL.DrawFullRoundedBox(self:GetRounding(), 0, 0, w, h, color_white) + PIXEL.DrawFullRoundedBox(self:GetRounding() or self:GetMaskSize(), 0, 0, w, h, color_white) render.SetStencilFailOperation(STENCILOPERATION_ZERO) render.SetStencilPassOperation(STENCILOPERATION_REPLACE) From 3c1bd2d2faffde0917edc11e74c3e1fe698efa2d Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 13:57:41 +0100 Subject: [PATCH 029/155] refactor: move some files around --- lua/pixelui/{panels => menus}/cl_themeeditor.lua | 0 lua/pixelui/{ => menus}/test/cl_menu.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_avatar.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_buttons.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_navigation.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_other.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_scrollpanel.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_text.lua | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename lua/pixelui/{panels => menus}/cl_themeeditor.lua (100%) rename lua/pixelui/{ => menus}/test/cl_menu.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_avatar.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_buttons.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_navigation.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_other.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_scrollpanel.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_text.lua (100%) diff --git a/lua/pixelui/panels/cl_themeeditor.lua b/lua/pixelui/menus/cl_themeeditor.lua similarity index 100% rename from lua/pixelui/panels/cl_themeeditor.lua rename to lua/pixelui/menus/cl_themeeditor.lua diff --git a/lua/pixelui/test/cl_menu.lua b/lua/pixelui/menus/test/cl_menu.lua similarity index 100% rename from lua/pixelui/test/cl_menu.lua rename to lua/pixelui/menus/test/cl_menu.lua diff --git a/lua/pixelui/test/pages/cl_avatar.lua b/lua/pixelui/menus/test/pages/cl_avatar.lua similarity index 100% rename from lua/pixelui/test/pages/cl_avatar.lua rename to lua/pixelui/menus/test/pages/cl_avatar.lua diff --git a/lua/pixelui/test/pages/cl_buttons.lua b/lua/pixelui/menus/test/pages/cl_buttons.lua similarity index 100% rename from lua/pixelui/test/pages/cl_buttons.lua rename to lua/pixelui/menus/test/pages/cl_buttons.lua diff --git a/lua/pixelui/test/pages/cl_navigation.lua b/lua/pixelui/menus/test/pages/cl_navigation.lua similarity index 100% rename from lua/pixelui/test/pages/cl_navigation.lua rename to lua/pixelui/menus/test/pages/cl_navigation.lua diff --git a/lua/pixelui/test/pages/cl_other.lua b/lua/pixelui/menus/test/pages/cl_other.lua similarity index 100% rename from lua/pixelui/test/pages/cl_other.lua rename to lua/pixelui/menus/test/pages/cl_other.lua diff --git a/lua/pixelui/test/pages/cl_scrollpanel.lua b/lua/pixelui/menus/test/pages/cl_scrollpanel.lua similarity index 100% rename from lua/pixelui/test/pages/cl_scrollpanel.lua rename to lua/pixelui/menus/test/pages/cl_scrollpanel.lua diff --git a/lua/pixelui/test/pages/cl_text.lua b/lua/pixelui/menus/test/pages/cl_text.lua similarity index 100% rename from lua/pixelui/test/pages/cl_text.lua rename to lua/pixelui/menus/test/pages/cl_text.lua From 3aa03c6161661e84a82a1031ce29ec832c4bacfc Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 13:57:47 +0100 Subject: [PATCH 030/155] feat: slide out frames --- lua/pixelui/elements/cl_frame.lua | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index b78844b..2f634b2 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -24,6 +24,9 @@ AccessorFunc(PANEL, "MinWidth", "MinWidth", FORCE_NUMBER) AccessorFunc(PANEL, "MinHeight", "MinHeight", FORCE_NUMBER) AccessorFunc(PANEL, "ScreenLock", "ScreenLock", FORCE_BOOL) AccessorFunc(PANEL, "RemoveOnClose", "RemoveOnClose", FORCE_BOOL) +AccessorFunc(PANEL, "SlideOut", "SlideOut", FORCE_BOOL) +AccessorFunc(PANEL, "SlideDirection", "SlideDirection", FORCE_NUMBER) -- 1 = up, 2 = right, 3 = down, 4 = left + AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) @@ -42,6 +45,9 @@ function PANEL:Init() self:Close() end + self:SetSlideOut(true) + self:SetSlideDirection(4) + self.ExtraButtons = {} self:SetTitle("PIXEL Frame") @@ -208,8 +214,29 @@ function PANEL:Open() self:AlphaTo(255, .1, 0) end + function PANEL:Close() - self:AlphaTo(0, .1, 0, function(anim, pnl) + if not self:GetSlideOut() then + self:AlphaTo(0, .1, 0, function(anim, pnl) + if not IsValid(pnl) then return end + pnl:SetVisible(false) + pnl:OnClose() + if pnl:GetRemoveOnClose() then pnl:Remove() end + end) + return + end + + local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() + local slideDirections = { + [1] = {x = (scrw / 2) - (wide / 2), y = -tall, size = function() self:SizeTo(wide, 0, .3, 0, -1) end}, -- up + [2] = {x = scrw, y = posY, size = function() end}, -- right + [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end}, -- down + [4] = {x = -wide, y = posY, size = function() end}, -- left + } + + local direction = self:GetSlideDirection() or 1 + slideDirections[direction].size() + self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, .5, 0, -1, function(anim, pnl) if not IsValid(pnl) then return end pnl:SetVisible(false) pnl:OnClose() From 79f949c525f49631e6c78faa0df8042c2f5965e7 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 13:58:58 +0100 Subject: [PATCH 031/155] a --- lua/pixelui/elements/cl_frame.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 2f634b2..6b9a973 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -228,10 +228,10 @@ function PANEL:Close() local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() local slideDirections = { - [1] = {x = (scrw / 2) - (wide / 2), y = -tall, size = function() self:SizeTo(wide, 0, .3, 0, -1) end}, -- up - [2] = {x = scrw, y = posY, size = function() end}, -- right - [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end}, -- down - [4] = {x = -wide, y = posY, size = function() end}, -- left + [1] = {x = (scrw / 2) - (wide / 2), y = -tall,size = function() self:SizeTo(wide, 0, .3, 0, -1) end},-- up + [2] = {x = scrw,y = posY,size = function() end},-- right + [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end},-- down + [4] = {x = -wide,y = posY,size = function() end},-- left } local direction = self:GetSlideDirection() or 1 From c5a9bdde6e1343315735ee431a4e01c547def91e Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 17:34:08 +0100 Subject: [PATCH 032/155] refactor: stop slide out by default --- lua/pixelui/elements/cl_frame.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 6b9a973..97edc4e 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -45,8 +45,7 @@ function PANEL:Init() self:Close() end - self:SetSlideOut(true) - self:SetSlideDirection(4) + self:SetSlideOut(false) self.ExtraButtons = {} From 55a0cbcec4ccb37281880796365534a3646db935 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 19:39:55 +0100 Subject: [PATCH 033/155] feat: slideTime --- lua/pixelui/elements/cl_frame.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 97edc4e..7d00eab 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -26,6 +26,7 @@ AccessorFunc(PANEL, "ScreenLock", "ScreenLock", FORCE_BOOL) AccessorFunc(PANEL, "RemoveOnClose", "RemoveOnClose", FORCE_BOOL) AccessorFunc(PANEL, "SlideOut", "SlideOut", FORCE_BOOL) AccessorFunc(PANEL, "SlideDirection", "SlideDirection", FORCE_NUMBER) -- 1 = up, 2 = right, 3 = down, 4 = left +AccessorFunc(PANEL, "SlideTime", "SlideTime", FORCE_NUMBER) AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) @@ -45,7 +46,8 @@ function PANEL:Init() self:Close() end - self:SetSlideOut(false) + self:SetSlideOut(true) + self:SetSlideDirection(3) self.ExtraButtons = {} @@ -227,7 +229,7 @@ function PANEL:Close() local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() local slideDirections = { - [1] = {x = (scrw / 2) - (wide / 2), y = -tall,size = function() self:SizeTo(wide, 0, .3, 0, -1) end},-- up + [1] = {x = (scrw / 2) - (wide / 2), y = -tall,size = function() self:SizeTo(wide, 0, (self:GetSlideTime() - 0.2) or .3, 0, -1) end},-- up [2] = {x = scrw,y = posY,size = function() end},-- right [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end},-- down [4] = {x = -wide,y = posY,size = function() end},-- left @@ -235,7 +237,7 @@ function PANEL:Close() local direction = self:GetSlideDirection() or 1 slideDirections[direction].size() - self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, .5, 0, -1, function(anim, pnl) + self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, self:GetSlideTime() or .5, 0, -1, function(anim, pnl) if not IsValid(pnl) then return end pnl:SetVisible(false) pnl:OnClose() From 0274163cf3a083fbc3aa0efa379f6a4681e10e36 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 19:40:09 +0100 Subject: [PATCH 034/155] a --- lua/pixelui/elements/cl_frame.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 7d00eab..9195dfb 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -46,8 +46,7 @@ function PANEL:Init() self:Close() end - self:SetSlideOut(true) - self:SetSlideDirection(3) + self:SetSlideOut(false) self.ExtraButtons = {} From b86500c0ceb61f04070161f00c900bb29d69d761 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 20 Nov 2022 12:33:35 +0000 Subject: [PATCH 035/155] feat: Ability to add icons on PIXEL.Navbar --- lua/pixelui/elements/cl_navbar.lua | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/elements/cl_navbar.lua b/lua/pixelui/elements/cl_navbar.lua index 481c5d7..8cc6074 100644 --- a/lua/pixelui/elements/cl_navbar.lua +++ b/lua/pixelui/elements/cl_navbar.lua @@ -20,6 +20,8 @@ local PANEL = {} AccessorFunc(PANEL, "Name", "Name", FORCE_STRING) AccessorFunc(PANEL, "Color", "Color") +AccessorFunc(PANEL, "ImgurID", "ImgurID") +AccessorFunc(PANEL, "ImgurScale", "ImgurScale") PIXEL.RegisterFont("UI.NavbarItem", "Open Sans SemiBold", 22) @@ -28,6 +30,7 @@ function PANEL:Init() self:SetColor(PIXEL.Colors.Primary) self:SetClicky(false) self:SetSounds(false) + self:SetImgurScale(0.2) self.NormalCol = PIXEL.Colors.PrimaryText self.HoverCol = PIXEL.Colors.SecondaryText @@ -50,6 +53,14 @@ function PANEL:Paint(w, h) local animTime = FrameTime() * 12 self.TextCol = PIXEL.LerpColor(animTime, self.TextCol, textCol) + local imgurID = self:GetImgurID() + if imgurID then + local imageSize = w * self:GetImgurScale() + PIXEL.DrawImgur(0, (self:GetTall() / 2) - (imageSize / 2), imageSize, imageSize, imgurID, color_white) + PIXEL.DrawSimpleText(self:GetName(), "UI.NavbarItem", imageSize + PIXEL.Scale(3), h / 2, self.TextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + return + end + PIXEL.DrawSimpleText(self:GetName(), "UI.NavbarItem", w / 2, h / 2, self.TextCol, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end @@ -67,9 +78,10 @@ function PANEL:Init() self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 10) end -function PANEL:AddItem(id, name, doClick, order, color) +function PANEL:AddItem(id, name, doClick, order, color, imgurID) local btn = vgui.Create("PIXEL.NavbarItem", self) + btn:SetImgurID(imgurID) btn:SetName(name:upper()) btn:SetZPos(order or table.Count(self.Items) + 1) btn:SetColor((IsColor(color) and color) or PIXEL.Colors.Primary) @@ -112,7 +124,7 @@ end function PANEL:PerformLayout(w, h) for k,v in pairs(self.Items) do v:Dock(LEFT) - v:SetWide(v:GetItemSize() + PIXEL.Scale(30)) + v:SetWide(v:GetItemSize() + PIXEL.Scale(50)) end end @@ -137,4 +149,4 @@ function PANEL:Paint(w, h) surface.DrawRect(self.SelectionX + 2, h - selectorH, self.SelectionW - 4, selectorH / 2) end -vgui.Register("PIXEL.Navbar", PANEL, "Panel") \ No newline at end of file +vgui.Register("PIXEL.Navbar", PANEL, "Panel") From fcb6f92005fcfcff1547ae7977dc8506b8ecfa10 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 20 Nov 2022 12:43:40 +0000 Subject: [PATCH 036/155] a --- lua/autorun/sh_pixelui_loader.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index a81ca41..42b4529 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -66,11 +66,15 @@ function PIXEL.LoadDirectory(path) return files, folders end -function PIXEL.LoadDirectoryRecursive(basePath) +function PIXEL.LoadDirectoryRecursive(basePath, onLoad) local _, folders = PIXEL.LoadDirectory(basePath) for _, folderName in ipairs(folders) do PIXEL.LoadDirectoryRecursive(basePath .. "/" .. folderName) end + + if onLoad and isfunction(onLoad) then + onLoad() + end end PIXEL.LoadDirectoryRecursive("pixelui") @@ -84,11 +88,11 @@ resource.AddWorkshop("2825396224") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) + http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pulsar-lib/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) - MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") + MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pulsar-lib/releases/latest\n") MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") MsgC(red, "New version: " .. body .. "\n") return From f6d5e7cfa0679f38d7e730c125e250a2fa537dbc Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 21 Nov 2022 18:50:44 +0000 Subject: [PATCH 037/155] feat: add PIXEL.OldAvatar to fix addons having wrong corner sizes --- lua/autorun/sh_pixelui_loader.lua | 5 ++ lua/pixelui/elements/cl_avatar.lua | 75 +++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 42b4529..affac19 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -43,6 +43,11 @@ PIXEL.Colors = { Transparent = Color(0, 0, 0, 0) } + +function PIXEL.Warn(...) + MsgC(PIXEL.Colors.Gold, "[PIXEL UI - Warning] ", PIXEL.Colors.Negative, ..., "\n") +end + function PIXEL.LoadDirectory(path) local files, folders = file.Find(path .. "/*", "LUA") diff --git a/lua/pixelui/elements/cl_avatar.lua b/lua/pixelui/elements/cl_avatar.lua index bea7c24..90a0d96 100644 --- a/lua/pixelui/elements/cl_avatar.lua +++ b/lua/pixelui/elements/cl_avatar.lua @@ -52,4 +52,77 @@ function PANEL:Paint(w, h) render.ClearStencil() end -vgui.Register("PIXEL.Avatar", PANEL, "Panel") \ No newline at end of file +vgui.Register("PIXEL.Avatar", PANEL, "Panel") + + +-- old avatar + +PANEL = {} + +AccessorFunc(PANEL, "MaskSize", "MaskSize", FORCE_NUMBER) + +function PANEL:Init() + PIXEL.Warn("Please update to using PIXEL.Avatar instead of using PIXEL.OldAvatar! This panel is deprecated and may be removed in a future release.") + self.Avatar = vgui.Create("AvatarImage", self) + self.Avatar:SetPaintedManually(true) + + self.CirclePoly = {} + self:SetMaskSize(1) +end + +function PANEL:PerformLayout(w, h) + self.Avatar:SetSize(w, h) + + self.CirclePoly = {} + local maskSize = self:GetMaskSize() + + local t = 0 + for i = 1, 360 do + t = math.rad(i * 720) / 720 + self.CirclePoly[i] = {x = w / 2 + math.cos(t) * maskSize, y = h / 2 + math.sin(t) * maskSize} + end +end + +function PANEL:SetPlayer(ply, size) + self.Avatar:SetPlayer(ply, size) +end + +function PANEL:SetSteamID(id, size) + self.Avatar:SetSteamID(id, size) +end + +local render = render +local surface = surface +local whiteTexture = surface.GetTextureID("vgui/white") +function PANEL:Paint(w, h) + render.ClearStencil() + render.SetStencilEnable(true) + + render.SetStencilWriteMask(1) + render.SetStencilTestMask(1) + + render.SetStencilFailOperation(STENCILOPERATION_REPLACE) + render.SetStencilPassOperation(STENCILOPERATION_ZERO) + render.SetStencilZFailOperation(STENCILOPERATION_ZERO) + render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NEVER) + render.SetStencilReferenceValue(1) + + surface.SetTexture(whiteTexture) + surface.SetDrawColor(255, 255, 255, 255) + surface.DrawPoly(self.CirclePoly) + + render.SetStencilFailOperation(STENCILOPERATION_ZERO) + render.SetStencilPassOperation(STENCILOPERATION_REPLACE) + render.SetStencilZFailOperation(STENCILOPERATION_ZERO) + render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL) + render.SetStencilReferenceValue(1) + + self.Avatar:SetPaintedManually(false) + self.Avatar:PaintManual() + self.Avatar:SetPaintedManually(true) + + render.SetStencilEnable(false) + render.ClearStencil() +end + +vgui.Register("PIXEL.OldAvatar", PANEL, "Panel") From 8feaefdde95929113bbc1469cdbaf3c30e6bbd49 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 7 Dec 2022 23:07:01 +0000 Subject: [PATCH 038/155] fix: Theme changer font errors --- lua/pixelui/menus/cl_themeeditor.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/menus/cl_themeeditor.lua b/lua/pixelui/menus/cl_themeeditor.lua index 46a2396..9f5d4da 100644 --- a/lua/pixelui/menus/cl_themeeditor.lua +++ b/lua/pixelui/menus/cl_themeeditor.lua @@ -1,6 +1,8 @@ local PANEL = {} local sc = PIXEL.Scale PIXEL.GenerateFont(18) +PIXEL.GenerateFont(20) + function PANEL:Init() self:SetSize(sc(200), sc(200)) self:MakePopup() @@ -58,7 +60,7 @@ function PANEL:Init() end function PANEL:PaintOver(w, h) - PIXEL.DrawSimpleText("Select new theme:", "Lyth_Pulsar.Font.Size20", w / 2, self.DropDown:GetY() - sc(15), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText("Select new theme:", "PIXEL.Font.Size20", w / 2, self.DropDown:GetY() - sc(15), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end vgui.Register("PIXELUI.ThemeChanger", PANEL, "PIXEL.Frame") @@ -71,4 +73,4 @@ concommand.Add("pixel_change_theme", function() ThemeChanger:Close() ThemeChanger = vgui.Create("PIXELUI.ThemeChanger") end -end) \ No newline at end of file +end) From 8e8f4f58cc6b2c47cee6b904f3dcef22930e425e Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 19 Dec 2022 19:50:00 +0000 Subject: [PATCH 039/155] pro scaling optimisations --- lua/pixelui/core/cl_scaling.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/core/cl_scaling.lua b/lua/pixelui/core/cl_scaling.lua index fc28391..534f703 100644 --- a/lua/pixelui/core/cl_scaling.lua +++ b/lua/pixelui/core/cl_scaling.lua @@ -16,10 +16,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ]] -local scrH = ScrH -local max = math.max +local scrH = scrH or ScrH() function PIXEL.Scale(value) - return max(value * (scrH() / 1080), 1) + return value * (scrH / 1080) end local constants = {} @@ -37,4 +36,5 @@ hook.Add("OnScreenSizeChanged", "PIXEL.UI.UpdateScaledConstants", function() for varName, size in pairs(constants) do scaledConstants[varName] = PIXEL.Scale(size) end + scrH = ScrH() end) From 1cfb060925b2bba2c76a71a8e8f9b357334023fa Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:17:39 +0000 Subject: [PATCH 040/155] feat: Color Override for overheads --- lua/pixelui/drawing/cl_overheads.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lua/pixelui/drawing/cl_overheads.lua b/lua/pixelui/drawing/cl_overheads.lua index 795940a..cc9ab8c 100644 --- a/lua/pixelui/drawing/cl_overheads.lua +++ b/lua/pixelui/drawing/cl_overheads.lua @@ -28,7 +28,7 @@ local disableClipping = DisableClipping local start3d2d, end3d2d = cam.Start3D2D, cam.End3D2D local Icon = icon -local function drawOverhead(ent, pos, text, ang, scale) +local function drawOverhead(ent, pos, text, ang, scale, col) if ang then ang = ent:LocalToWorldAngles(ang) else @@ -47,12 +47,12 @@ local function drawOverhead(ent, pos, text, ang, scale) start3d2d(pos, ang, scale or 0.05) if not Icon then - PIXEL.DrawRoundedBox(12, x, y, w, h, PIXEL.Colors.Primary) + PIXEL.DrawRoundedBox(12, x, y, w, h, col or PIXEL.Colors.Primary) PIXEL.DrawText(text, "UI.Overhead", 0, y + 1, PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER) else x = x - 40 PIXEL.DrawRoundedBox(12, x, y, h, h, PIXEL.Colors.Primary) - PIXEL.DrawRoundedBoxEx(12, x + (h - 12), y + h - 20, w + 15, 20, PIXEL.Colors.Primary, false, false, false, true) + PIXEL.DrawRoundedBoxEx(12, x + (h - 12), y + h - 20, w + 15, 20, col or PIXEL.Colors.Primary, false, false, false, true) PIXEL.DrawText(text, "UI.Overhead", x + h + 15, y + 8, PIXEL.Colors.PrimaryText) PIXEL.DrawImgur(x + 10, y + 10, h - 20, h - 20, Icon, color_white) end @@ -62,7 +62,7 @@ local function drawOverhead(ent, pos, text, ang, scale) end local entOffset = 2 -function PIXEL.DrawEntOverhead(ent, text, angleOverride, posOverride, scaleOverride) +function PIXEL.DrawEntOverhead(ent, text, angleOverride, posOverride, scaleOverride, colOverride) if checkDistance(ent) then return end if posOverride then @@ -73,12 +73,12 @@ function PIXEL.DrawEntOverhead(ent, text, angleOverride, posOverride, scaleOverr local pos = ent:OBBMaxs() pos:SetUnpacked(0, 0, pos[3] + entOffset) - drawOverhead(ent, ent:LocalToWorld(pos), text, angleOverride, scaleOverride) + drawOverhead(ent, ent:LocalToWorld(pos), text, angleOverride, scaleOverride, colOverride) end local eyeOffset = Vector(0, 0, 7) local fallbackOffset = Vector(0, 0, 73) -function PIXEL.DrawNPCOverhead(ent, text, angleOverride, offsetOverride, scaleOverride) +function PIXEL.DrawNPCOverhead(ent, text, angleOverride, offsetOverride, scaleOverride, colOverride) if checkDistance(ent) then return end local eyeId = ent:LookupAttachment("eyes") @@ -91,7 +91,7 @@ function PIXEL.DrawNPCOverhead(ent, text, angleOverride, offsetOverride, scaleOv end end - drawOverhead(ent, ent:GetPos() + fallbackOffset, text, angleOverride, scaleOverride) + drawOverhead(ent, ent:GetPos() + fallbackOffset, text, angleOverride, scaleOverride, colOverride) end function PIXEL.EnableIconOverheads(new) From e86d31147bb3ae793911c262a305083c49092942 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:52:45 +0100 Subject: [PATCH 041/155] feat: OnOpen and OnClose functions for combo boxes --- lua/pixelui/elements/cl_combo_box.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_combo_box.lua b/lua/pixelui/elements/cl_combo_box.lua index 77df52e..17950bd 100644 --- a/lua/pixelui/elements/cl_combo_box.lua +++ b/lua/pixelui/elements/cl_combo_box.lua @@ -48,6 +48,7 @@ function PANEL:Clear() if not self.Menu then return end self.Menu:Remove() + self:OnClose() self.Menu = nil end @@ -131,8 +132,9 @@ end function PANEL:OpenMenu(pControlOpener) if pControlOpener and pControlOpener == self.TextEntry then return end - PIXEL.PlayExpand("open") if #self.Choices == 0 then return end + PIXEL.PlayExpand("open") + self:OnOpen() if IsValid(self.Menu) then self.Menu:Remove() @@ -174,6 +176,7 @@ function PANEL:OpenMenu(pControlOpener) self.Menu.OnRemove = function(s) if not IsValid(self) then return end PIXEL.PlayExpand("close") + self:OnClose() self:SetToggle(false) end end @@ -181,6 +184,7 @@ end function PANEL:CloseMenu() if not IsValid(self.Menu) then return end self.Menu:Remove() + self:OnClose() end function PANEL:CheckConVarChanges() @@ -205,6 +209,12 @@ function PANEL:DoClick() if not self:IsMenuOpen() then self:OpenMenu() end end +function PANEL:OnOpen() +end + +function PANEL:OnClose() +end + function PANEL:PaintOver(w, h) local dropBtnSize = PIXEL.Scale(8) PIXEL.DrawImgur(w - dropBtnSize - PIXEL.Scale(8), h / 2 - dropBtnSize / 2, dropBtnSize, dropBtnSize, "30Bvuwi", PIXEL.Colors.PrimaryText) From e2f7a0a3856079f9dad526bf7db54b37add3857f Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:53:06 +0100 Subject: [PATCH 042/155] feat: function to stop scrolling in scrollpanel? --- lua/pixelui/elements/cl_scrollpanel.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lua/pixelui/elements/cl_scrollpanel.lua b/lua/pixelui/elements/cl_scrollpanel.lua index 9928287..539b45e 100644 --- a/lua/pixelui/elements/cl_scrollpanel.lua +++ b/lua/pixelui/elements/cl_scrollpanel.lua @@ -22,8 +22,11 @@ AccessorFunc(PANEL, "Padding", "Padding") AccessorFunc(PANEL, "Canvas", "Canvas") AccessorFunc(PANEL, "ScrollbarLeft", "ScrollbarLeftSide") AccessorFunc(PANEL, "BarDockShouldOffset", "BarDockShouldOffset", FORCE_BOOL) +AccessorFunc(PANEL, "CanScroll", "CanScroll", FORCE_BOOL) function PANEL:Init() + self:SetCanScroll(true) + self.Canvas = vgui.Create("Panel", self) self.Canvas.OnMousePressed = function(s, code) s:GetParent():OnMousePressed(code) end self.Canvas:SetMouseInputEnabled(true) @@ -122,6 +125,8 @@ function PANEL:Think() end function PANEL:OnMouseWheeled(delta) + if not self:GetCanScroll() then return end + if (delta > 0 and self.VBar.Scroll <= self.VBar.CanvasSize * 0.005) or (delta < 0 and self.VBar.Scroll >= self.VBar.CanvasSize * 0.995) then self.ScrollDelta = self.ScrollDelta + delta / 10 From 2c368233a46a5fd4c9301a5a09036e3515ceaaaa Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:53:31 +0100 Subject: [PATCH 043/155] Update updater url --- lua/autorun/sh_pixelui_loader.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index affac19..7dd9b82 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -93,11 +93,11 @@ resource.AddWorkshop("2825396224") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pulsar-lib/master/VERSION", function(body) + http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) - MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pulsar-lib/releases/latest\n") + MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") MsgC(red, "New version: " .. body .. "\n") return From 9683ffb9f0ba482aece6730c5f9af9d80c3798b0 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:57:23 +0100 Subject: [PATCH 044/155] Update VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6261a05..1892b92 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.1 \ No newline at end of file +1.3.2 From 2005d868dc8d6cc1661c5e2b073534226ccaf787 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 23 Apr 2023 01:31:17 +0100 Subject: [PATCH 045/155] feat: better readme --- README.md | 11 +++++++++++ pixelui.png | Bin 0 -> 8314 bytes 2 files changed, 11 insertions(+) create mode 100644 README.md create mode 100644 pixelui.png diff --git a/README.md b/README.md new file mode 100644 index 0000000..766c46e --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +![](./pixelui.png) + +### A **modern**, **optimised** UI library to replace derma and other slow built in Garry's Mod functions. + +## Example Projects +- [PIXEL Karts](https://github.com/TomDotBat/pixel-karts) +- [PIXEL HUD](https://github.com/TomDotBat/pixel-hud) +- [PIXEL F4](https://github.com/TomDotBat/pixel-f4) +- [PIXEL Item Lab](https://github.com/TomDotBat/pixel-itemlab) +- [PIXEL Defences](https://github.com/TomDotBat/pixel-defences) +- [PIXEL Spawn Protection](https://github.com/TomDotBat/pixel-spawn-protection) diff --git a/pixelui.png b/pixelui.png new file mode 100644 index 0000000000000000000000000000000000000000..190b741c5bdfa3e2ca337a9004518f552d5363c5 GIT binary patch literal 8314 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 literal 0 HcmV?d00001 From 3387be02b169653de64c236ca9efdd6e2e488c0e Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:11:46 +0100 Subject: [PATCH 046/155] fix: TextButton text being offset when ClickyButton --- lua/pixelui/elements/cl_text_button.lua | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index f727f2c..9f7c770 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,14 +14,11 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) AccessorFunc(PANEL, "TextSpacing", "TextSpacing", FORCE_NUMBER) AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) - PIXEL.RegisterFont("UI.TextButton", "Open Sans SemiBold", 20) function PANEL:Init() @@ -30,11 +26,9 @@ function PANEL:Init() self:SetTextAlign(TEXT_ALIGN_CENTER) self:SetTextSpacing(PIXEL.Scale(6)) self:SetFont("UI.TextButton") - self:SetSize(PIXEL.Scale(100), PIXEL.Scale(30)) self:SetClicky(true) self:SetSounds(true) - end function PANEL:SizeToText() @@ -48,13 +42,14 @@ function PANEL:PaintExtra(w, h) if not self:IsEnabled() then PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.DisabledText, textAlign, TEXT_ALIGN_CENTER) + return end if self.ClickyMove and self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2 - PIXEL.Scale(4)) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) elseif self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(4), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) else PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) end From 41070ed5769c23de6efcd7ce4a8e5531141d12a4 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:12:04 +0100 Subject: [PATCH 047/155] =?UTF-8?q?=E2=9C=A8=20feat:=20Mini=20Sidebar=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_mini_sidebar.lua | 166 +++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 lua/pixelui/elements/cl_mini_sidebar.lua diff --git a/lua/pixelui/elements/cl_mini_sidebar.lua b/lua/pixelui/elements/cl_mini_sidebar.lua new file mode 100644 index 0000000..39010b8 --- /dev/null +++ b/lua/pixelui/elements/cl_mini_sidebar.lua @@ -0,0 +1,166 @@ + +--[[ +PIXEL UI +Copyright (C) 2021 Tom O'Sullivan (Tom.bat) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +]] + +local PANEL = {} + +AccessorFunc(PANEL, "Name", "Name", FORCE_STRING) +AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) +AccessorFunc(PANEL, "DrawOutline", "DrawOutline", FORCE_BOOL) + +PIXEL.RegisterFont("SidebarItem", "Rubik", 19) + +function PANEL:Init() + self:SetName("N/A") + self:SetDrawOutline(true) + self:SetClicky(false) + self:SetSounds(false) + self:SetTooltip(self:GetName() or "N/A") + + self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) + self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) + self.BackgroundHoverCol = ColorAlpha(PIXEL.Colors.Scroller, 80) +end + +function PANEL:Paint(w, h) + local textCol = PIXEL.Colors.SecondaryText + local backgroundCol = PIXEL.Colors.Transparent + local hoverLineCol = PIXEL.Colors.Transparent + + if self:IsHovered() then + textCol = PIXEL.Colors.PrimaryText + backgroundCol = self.BackgroundHoverCol + hoverLineCol = PIXEL.Colors.Primary + end + + if self:IsDown() or self:GetToggle() then + textCol = PIXEL.Colors.PrimaryText + backgroundCol = self.BackgroundHoverCol + hoverLineCol = PIXEL.Colors.Primary + end + + local animTime = FrameTime() * 12 + self.TextCol = PIXEL.LerpColor(animTime, self.TextCol, textCol) + self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) + + if self:GetDrawOutline() then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverLineCol, PIXEL.Scale(1)) + end + + local imgurID = self:GetImgurID() + local iconSize = h * .65 + PIXEL.DrawImgur(PIXEL.Scale(9), (h - iconSize) / 2 + PIXEL.Scale(1), iconSize, iconSize, imgurID, Color(255,255,255)) +end + +vgui.Register("PIXEL.SidebarItem", PANEL, "PIXEL.Button") + +PANEL = {} + +AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) +AccessorFunc(PANEL, "ImgurScale", "ImgurScale", FORCE_NUMBER) +AccessorFunc(PANEL, "ImgurOffset", "ImgurOffset", FORCE_NUMBER) +AccessorFunc(PANEL, "ButtonOffset", "ButtonOffset", FORCE_NUMBER) +AccessorFunc(PANEL, "ButtonBtmOffset", "ButtonBtmOffset", FORCE_NUMBER) + +function PANEL:Init() + self.Items = {} + + self.Scroller = vgui.Create("PIXEL.ScrollPanel", self) + self.Scroller:SetBarDockShouldOffset(true) + self.Scroller.LayoutContent = function(s, w, h) + local spacing = PIXEL.Scale(8) + local height = PIXEL.Scale(36) + for k,v in pairs(self.Items) do + v:SetTall(height) + v:Dock(TOP) + v:DockMargin(0, 0, 0, spacing) + end + end + + self:SetImgurScale(.6) + self:SetImgurOffset(0) + self:SetButtonOffset(0) + + self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Header) +end + +function PANEL:AddItem(id, name, imgurID, doClick, order) + local btn = vgui.Create("PIXEL.SidebarItem", self.Scroller) + + btn:SetZPos(order or table.Count(self.Items) + 1) + btn:SetName(name) + if imgurID then btn:SetImgurID(imgurID) end + btn.Function = doClick + + btn.DoClick = function(s) + self:SelectItem(id) + end + + self.Items[id] = btn + + return btn +end + +function PANEL:RemoveItem(id) + local item = self.Items[id] + if not item then return end + + item:Remove() + self.Items[id] = nil + + if self.SelectedItem != id then return end + self:SelectItem(next(self.Items)) +end + +function PANEL:SelectItem(id) + local item = self.Items[id] + if not item then return end + + PIXEL.PlayChangeTab() + + if self.SelectedItem and self.SelectedItem == id then return end + self.SelectedItem = id + + for k,v in pairs(self.Items) do + v:SetToggle(false) + end + + item:SetToggle(true) + item.Function(item) +end + +function PANEL:PerformLayout(w, h) + local sideSpacing = PIXEL.Scale(7) + local topSpacing = PIXEL.Scale(7) + self:DockPadding(sideSpacing, self:GetImgurID() and w * self:GetImgurScale() + self:GetImgurOffset() + self:GetButtonOffset() + topSpacing * 2 or topSpacing, sideSpacing, self:GetButtonBtmOffset() or topSpacing) + + self.Scroller:Dock(FILL) + self.Scroller:GetCanvas():DockPadding(0, 0, self.Scroller.VBar.Enabled and sideSpacing or 0, 0) +end + +function PANEL:Paint(w, h) + PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), 0, 0, w, h, self.BackgroundCol, false, false, true) + + local imgurID = self:GetImgurID() + if imgurID then + local imageSize = w * self:GetImgurScale() + PIXEL.DrawImgur((w - imageSize) / 2, imageSize / 2 - (imageSize / 3), imageSize, imageSize, imgurID, color_white) + end +end + +vgui.Register("PIXEL.MiniSidebar", PANEL, "Panel") From b032928470d5db216a07b169d4574550d7a0366b Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 17:18:06 +0100 Subject: [PATCH 048/155] stuff --- lua/autorun/sh_pixelui_loader.lua | 99 +++--- lua/pixelui/core/themes/cl_themes.lua | 43 +-- lua/pixelui/core/themes/sh_themes.lua | 19 +- lua/pixelui/elements/cl_button.lua | 263 +++++++-------- lua/pixelui/elements/cl_category.lua | 46 +-- lua/pixelui/elements/cl_check_box.lua | 9 +- lua/pixelui/elements/cl_frame.lua | 432 ++++++++++++++----------- lua/pixelui/elements/cl_sidebar.lua | 38 +-- lua/pixelui/elements/cl_text_entry.lua | 141 +++++--- lua/pixelui/menus/test/cl_menu.lua | 148 +++++---- 10 files changed, 657 insertions(+), 581 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 7dd9b82..9409b3b 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,7 +14,6 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} PIXEL.UI.Version = "1.3.1" @@ -25,82 +23,79 @@ PIXEL.Colors = { Header = Color(28, 28, 28), SecondaryHeader = Color(15, 15, 15), Scroller = Color(61, 61, 61), - + -- PrimaryText = Color(255, 255, 255), SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - - Primary = Color(77, 79, 199), + -- + Primary = Color(2, 153, 204), Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), Negative = Color(235, 68, 68), - + -- Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - + -- Transparent = Color(0, 0, 0, 0) } - function PIXEL.Warn(...) MsgC(PIXEL.Colors.Gold, "[PIXEL UI - Warning] ", PIXEL.Colors.Negative, ..., "\n") end function PIXEL.LoadDirectory(path) - local files, folders = file.Find(path .. "/*", "LUA") - - for _, fileName in ipairs(files) do - local filePath = path .. "/" .. fileName - - if CLIENT then - include(filePath) - else - if fileName:StartWith("cl_") then - AddCSLuaFile(filePath) - elseif fileName:StartWith("sh_") then - AddCSLuaFile(filePath) - include(filePath) - else - include(filePath) - end - end - end - - return files, folders + local files, folders = file.Find(path .. "/*", "LUA") + + for _, fileName in ipairs(files) do + local filePath = path .. "/" .. fileName + + if CLIENT then + include(filePath) + else + if fileName:StartWith("cl_") then + AddCSLuaFile(filePath) + elseif fileName:StartWith("sh_") then + AddCSLuaFile(filePath) + include(filePath) + else + include(filePath) + end + end + end + + return files, folders end function PIXEL.LoadDirectoryRecursive(basePath, onLoad) - local _, folders = PIXEL.LoadDirectory(basePath) - for _, folderName in ipairs(folders) do - PIXEL.LoadDirectoryRecursive(basePath .. "/" .. folderName) - end - - if onLoad and isfunction(onLoad) then - onLoad() - end + local _, folders = PIXEL.LoadDirectory(basePath) + + for _, folderName in ipairs(folders) do + PIXEL.LoadDirectoryRecursive(basePath .. "/" .. folderName) + end + + if onLoad and isfunction(onLoad) then + onLoad() + end end PIXEL.LoadDirectoryRecursive("pixelui") - hook.Run("PIXEL.UI.FullyLoaded") - if CLIENT then return end - resource.AddWorkshop("2825396224") hook.Add("Think", "PIXEL.UI.VersionChecker", function() - hook.Remove("Think", "PIXEL.UI.VersionChecker") - - http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) - if PIXEL.UI.Version ~= string.Trim(body) then - local red = Color(192, 27, 27) - - MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") - MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") - MsgC(red, "New version: " .. body .. "\n") - return - end - end) -end) + hook.Remove("Think", "PIXEL.UI.VersionChecker") + + http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) + if PIXEL.UI.Version ~= string.Trim(body) then + local red = Color(192, 27, 27) + MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") + MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") + MsgC(red, "New version: " .. body .. "\n") + + return + end + end) +end) \ No newline at end of file diff --git a/lua/pixelui/core/themes/cl_themes.lua b/lua/pixelui/core/themes/cl_themes.lua index 874e28a..a279f23 100644 --- a/lua/pixelui/core/themes/cl_themes.lua +++ b/lua/pixelui/core/themes/cl_themes.lua @@ -1,8 +1,7 @@ PIXEL = PIXEL or {} PIXEL.Themes = PIXEL.Themes or {} -PIXEL.DefaultThemes = PIXEL.DefaultThemes or { - "Dark", "Light", "GitHubDark", "NightOwl", "DiscordDark", "DiscordLight" -} + +PIXEL.DefaultThemes = PIXEL.DefaultThemes or {"Dark", "Light", "GitHubDark", "NightOwl", "DiscordDark", "DiscordLight"} PIXEL.Themes["Dark"] = { included = true, @@ -10,21 +9,17 @@ PIXEL.Themes["Dark"] = { Header = Color(28, 28, 28), SecondaryHeader = Color(43, 43, 43), Scroller = Color(61, 61, 61), - PrimaryText = Color(255, 255, 255), SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - - Primary = Color(74, 61, 255), + Primary = Color(2, 153, 204), Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), Negative = Color(235, 68, 68), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -34,21 +29,17 @@ PIXEL.Themes["Light"] = { Header = PIXEL.HexToColor("#edf1f5"), SecondaryHeader = PIXEL.HexToColor("#DFE1E4"), Scroller = PIXEL.HexToColor("#edf1f5"), - PrimaryText = PIXEL.HexToColor("#292D31"), SecondaryText = PIXEL.HexToColor("#808080"), DisabledText = PIXEL.HexToColor("#9ba0a3"), - - Primary = Color(74, 61, 255), + Primary = Color(2, 153, 204), Disabled = PIXEL.HexToColor("#9ba0a3"), Positive = PIXEL.HexToColor("#79CB60"), Negative = PIXEL.HexToColor("#d73a49"), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -58,21 +49,17 @@ PIXEL.Themes["GitHubDark"] = { Header = PIXEL.HexToColor("#2f363d"), SecondaryHeader = PIXEL.HexToColor("#2b3036"), Scroller = PIXEL.HexToColor("#2f363d"), - - PrimaryText = Color(74, 61, 255), + PrimaryText = Color(255, 255, 255), SecondaryText = PIXEL.HexToColor("#c9d1d9"), DisabledText = PIXEL.HexToColor("#39414a"), - - Primary = PIXEL.HexToColor("#b392f0"), + Primary = Color(2, 153, 204), Disabled = PIXEL.HexToColor("#6a737d"), Positive = PIXEL.HexToColor("#85e89d"), Negative = PIXEL.HexToColor("#f97583"), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -82,21 +69,17 @@ PIXEL.Themes["NightOwl"] = { Header = PIXEL.HexToColor("#0b2942"), -- Seccond Background SecondaryHeader = PIXEL.HexToColor("#13344f"), -- Active Scroller = PIXEL.HexToColor("#0b2942"), -- Seccond Background - PrimaryText = PIXEL.HexToColor("#FBFBFB"), -- Text SecondaryText = PIXEL.HexToColor("#d9d9d9"), -- Buttons DisabledText = PIXEL.HexToColor("#697098"), -- Disabled - - Primary = Color(74, 61, 255), + Primary = Color(2, 153, 204), Disabled = PIXEL.HexToColor("#697098"), -- Disabled Positive = PIXEL.HexToColor("#addb67"), -- Green Negative = PIXEL.HexToColor("#ff6363"), -- Red - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -106,21 +89,17 @@ PIXEL.Themes["DiscordDark"] = { Header = Color(47, 49, 54), SecondaryHeader = Color(51, 54, 59), Scroller = Color(32, 34, 37), - PrimaryText = Color(255, 255, 255), SecondaryText = Color(185, 187, 190), DisabledText = Color(40, 40, 40), - - Primary = Color(88, 101, 242), + Primary = Color(2, 153, 204), Disabled = Color(114, 118, 125), Positive = Color(87, 242, 135), Negative = Color(237, 66, 69), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -130,20 +109,16 @@ PIXEL.Themes["DiscordLight"] = { Header = Color(242, 243, 245), SecondaryHeader = Color(220, 223, 227), Scroller = Color(204, 204, 204), - PrimaryText = Color(6, 6, 7), SecondaryText = Color(79, 86, 96), DisabledText = Color(79, 86, 96), - - Primary = Color(88, 101, 242), + Primary = Color(2, 153, 204), Disabled = Color(79, 86, 96), Positive = Color(87, 242, 135), Negative = Color(237, 66, 69), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } \ No newline at end of file diff --git a/lua/pixelui/core/themes/sh_themes.lua b/lua/pixelui/core/themes/sh_themes.lua index 0e0aa17..fe28098 100644 --- a/lua/pixelui/core/themes/sh_themes.lua +++ b/lua/pixelui/core/themes/sh_themes.lua @@ -1,22 +1,23 @@ PIXEL.Colors = { - Background = Color(22, 22, 22), - Header = Color(28, 28, 28), - SecondaryHeader = Color(15, 15, 15), + Background = Color(31, 31, 31), + Header = Color(40, 41, 42), + SecondaryHeader = Color(45, 47, 49), Scroller = Color(61, 61, 61), - + Outline = Color(55, 56, 57), + -- PrimaryText = Color(255, 255, 255), SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - - Primary = Color(77, 79, 199), + -- + Primary = Color(66, 133, 244), + -- Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), - Negative = Color(235, 68, 68), - + Negative = Color(179, 38, 30), + -- Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } \ No newline at end of file diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index a4ec336..f886d8d 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,165 +14,167 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "IsToggle", "IsToggle", FORCE_BOOL) AccessorFunc(PANEL, "Toggle", "Toggle", FORCE_BOOL) AccessorFunc(PANEL, "Clicky", "Clicky", FORCE_BOOL) AccessorFunc(PANEL, "Sounds", "Sounds", FORCE_BOOL) - function PANEL:Init() - self:SetIsToggle(false) - self:SetToggle(false) - self:SetMouseInputEnabled(true) - - self:SetCursor("hand") - self:SetClicky(false) - self:SetSounds(true) - - local btnSize = PIXEL.Scale(30) - self:SetSize(btnSize, btnSize) - - self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) - self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) - self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) - self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) - self.ClickyCol = PIXEL.OffsetColor(self.NormalCol, -35) - - self.BackgroundCol = self.NormalCol - self.BackgroundClickyCol = self.ClickyCol - - self.ClickyScale = PIXEL.Scale(3) - self.Clicky = self:GetClicky() - self.ClickyMove = false + self:SetIsToggle(false) + self:SetToggle(false) + self:SetMouseInputEnabled(true) + self:SetCursor("hand") + self:SetClicky(false) + self:SetSounds(true) + local btnSize = PIXEL.Scale(30) + self:SetSize(btnSize, btnSize) + self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) + self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) + self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) + self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) + self.ClickyCol = PIXEL.OffsetColor(self.NormalCol, -35) + self.BackgroundCol = self.NormalCol + self.BackgroundClickyCol = self.ClickyCol + self.ClickyScale = PIXEL.Scale(3) + self.Clicky = self:GetClicky() + self.ClickyMove = false end function PANEL:PerformLayout() - local tall = self:GetTall() - - if tall > 75 then - self.ClickyScale = self:GetTall() / 25 - elseif tall > 50 then - self.ClickyScale = self:GetTall() / 17 - elseif tall > 25 then - self.ClickyScale = self:GetTall() / 10 - elseif tall > 15 then - self.ClickyScale = self:GetTall() / 5 - end + local tall = self:GetTall() + + if tall > 75 then + self.ClickyScale = self:GetTall() / 25 + elseif tall > 50 then + self.ClickyScale = self:GetTall() / 17 + elseif tall > 25 then + self.ClickyScale = self:GetTall() / 10 + elseif tall > 15 then + self.ClickyScale = self:GetTall() / 5 + end end function PANEL:DoToggle(...) - if not self:GetIsToggle() then return end - - self:SetToggle(not self:GetToggle()) - self:OnToggled(self:GetToggle(), ...) + if not self:GetIsToggle() then return end + self:SetToggle(not self:GetToggle()) + self:OnToggled(self:GetToggle(), ...) end local localPly -function PANEL:OnMousePressed(mouseCode) - if not self:IsEnabled() then return end - self.ClickyMove = true - if self:GetSounds() then - PIXEL.PlayButtonSound() - end - - if not localPly then - localPly = LocalPlayer() - end - - if self:IsSelectable() and mouseCode == MOUSE_LEFT and (input.IsShiftDown() or input.IsControlDown()) and not (localPly:KeyDown(IN_FORWARD) or localPly:KeyDown(IN_BACK) or localPly:KeyDown(IN_MOVELEFT) or localPly:KeyDown(IN_MOVERIGHT)) then - return self:StartBoxSelection() - end - - self:MouseCapture(true) - self.Depressed = true - self:OnPressed(mouseCode) - self:DragMousePress(mouseCode) +function PANEL:OnMousePressed(mouseCode) + if not self:IsEnabled() then return end + self.ClickyMove = true + + if self:GetSounds() then + PIXEL.PlayButtonSound() + end + + if not localPly then + localPly = LocalPlayer() + end + + if self:IsSelectable() and mouseCode == MOUSE_LEFT and (input.IsShiftDown() or input.IsControlDown()) and not (localPly:KeyDown(IN_FORWARD) or localPly:KeyDown(IN_BACK) or localPly:KeyDown(IN_MOVELEFT) or localPly:KeyDown(IN_MOVERIGHT)) then return self:StartBoxSelection() end + self:MouseCapture(true) + self.Depressed = true + self:OnPressed(mouseCode) + self:DragMousePress(mouseCode) end function PANEL:OnMouseReleased(mouseCode) - self:MouseCapture(false) - - if not self:IsEnabled() then return end - if not self.Depressed and dragndrop.m_DraggingMain ~= self then return end - - self.ClickyMove = false - - if self.Depressed then - self.Depressed = nil - self:OnReleased(mouseCode) - end + self:MouseCapture(false) + if not self:IsEnabled() then return end + if not self.Depressed and dragndrop.m_DraggingMain ~= self then return end + self.ClickyMove = false + + if self.Depressed then + self.Depressed = nil + self:OnReleased(mouseCode) + end + + if self:DragMouseRelease(mouseCode) then return end + + if self:IsSelectable() and mouseCode == MOUSE_LEFT then + local canvas = self:GetSelectionCanvas() + + if canvas then + canvas:UnselectAll() + end + end + + if not self.Hovered then return end + self.Depressed = true + + if mouseCode == MOUSE_RIGHT then + self:DoRightClick() + elseif mouseCode == MOUSE_LEFT then + self:DoClick() + elseif mouseCode == MOUSE_MIDDLE then + self:DoMiddleClick() + end + + self.Depressed = nil +end - if self:DragMouseRelease(mouseCode) then - return - end +function PANEL:PaintExtra(w, h) +end - if self:IsSelectable() and mouseCode == MOUSE_LEFT then - local canvas = self:GetSelectionCanvas() - if canvas then - canvas:UnselectAll() - end - end +function PANEL:Paint(w, h) + if not self:IsEnabled() then + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h, self.DisabledCol) + self:PaintExtra(w, h) + + return + end + + local bgCol = self.NormalCol + + if self:IsDown() or self:GetToggle() then + bgCol = self.ClickedCol + elseif self:IsHovered() and not self.Clicky then + bgCol = self.HoverCol + end + + if not self.Clicky then + self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) + end + + if not self:GetClicky() then + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h, self.BackgroundCol) + else + if self.ClickyMove then + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) + else + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h, self.ClickyCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h - self.ClickyScale, self.BackgroundCol) + end + end + + self:PaintExtra(w, h) +end - if not self.Hovered then return end +function PANEL:IsDown() + return self.Depressed +end - self.Depressed = true +function PANEL:OnPressed(mouseCode) +end - if mouseCode == MOUSE_RIGHT then - self:DoRightClick() - elseif mouseCode == MOUSE_LEFT then - self:DoClick() - elseif mouseCode == MOUSE_MIDDLE then - self:DoMiddleClick() - end +function PANEL:OnReleased(mouseCode) +end - self.Depressed = nil +function PANEL:OnToggled(enabled) end -function PANEL:PaintExtra(w, h) end +function PANEL:DoClick(...) + self:DoToggle(...) +end -function PANEL:Paint(w, h) - if not self:IsEnabled() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.DisabledCol) - self:PaintExtra(w, h) - return - end - - local bgCol = self.NormalCol - - if self:IsDown() or self:GetToggle() then - bgCol = self.ClickedCol - elseif self:IsHovered() and not self.Clicky then - bgCol = self.HoverCol - end - - if not self.Clicky then - self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) - end - - if not self:GetClicky() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) - else - if self.ClickyMove then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) - else - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.ClickyCol) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h - self.ClickyScale, self.BackgroundCol) - end - end - - self:PaintExtra(w, h) +function PANEL:DoRightClick() end -function PANEL:IsDown() return self.Depressed end -function PANEL:OnPressed(mouseCode) end -function PANEL:OnReleased(mouseCode) end -function PANEL:OnToggled(enabled) end -function PANEL:DoClick(...) self:DoToggle(...) end -function PANEL:DoRightClick() end -function PANEL:DoMiddleClick() end +function PANEL:DoMiddleClick() +end -vgui.Register("PIXEL.Button", PANEL, "Panel") +vgui.Register("PIXEL.Button", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_category.lua b/lua/pixelui/elements/cl_category.lua index 6cedbb5..dde3cf2 100644 --- a/lua/pixelui/elements/cl_category.lua +++ b/lua/pixelui/elements/cl_category.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,11 +14,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) - PIXEL.RegisterFont("UI.CategoryHeader", "Open Sans Bold", 19) function PANEL:Init() @@ -33,20 +29,17 @@ function PANEL:DoClick() end local lerp = Lerp + function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) PIXEL.DrawSimpleText(self.Title, "UI.CategoryHeader", PIXEL.Scale(10), h / 2, PIXEL.Colors.PrimaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) - self.ArrowRotation = lerp(FrameTime() * 10, self.ArrowRotation, self:GetParent():GetExpanded() and 0 or 90) - local arrowSize = h * .45 PIXEL.DrawImgurRotated(w - h * .3 - PIXEL.Scale(4), h / 2, arrowSize, arrowSize, self.ArrowRotation, "30Bvuwi", PIXEL.Colors.PrimaryText) end vgui.Register("PIXEL.CategoryHeader", PANEL, "PIXEL.Button") - PANEL = {} - AccessorFunc(PANEL, "m_bSizeExpanded", "Expanded", FORCE_BOOL) AccessorFunc(PANEL, "m_iContentHeight", "StartHeight") AccessorFunc(PANEL, "m_fAnimTime", "AnimTime") @@ -56,20 +49,17 @@ AccessorFunc(PANEL, "m_pList", "List") function PANEL:Init() self.Header = vgui.Create("PIXEL.CategoryHeader", self) - self:SetTitle("PIXEL Category") - self:SetExpanded(true) self:SetMouseInputEnabled(true) - self:SetAnimTime(0.2) self.SlideAnimation = Derma_Anim("Anim", self, self.AnimSlide) - self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 2) end function PANEL:UnselectAll() local children = self:GetChildren() + for k, v in pairs(children) do if v.SetSelected then v:SetSelected(false) @@ -93,7 +83,6 @@ function PANEL:SetContents(contents) self.Contents = contents self.Contents:SetParent(self) self.Contents:Dock(FILL) - local margin = PIXEL.Scale(8) self.Contents:DockMargin(margin, margin, margin, margin) @@ -120,21 +109,24 @@ end function PANEL:Toggle() self:SetExpanded(not self:GetExpanded()) - self.SlideAnimation:Start(self:GetAnimTime(), {From = self:GetTall()}) + self.SlideAnimation:Start(self:GetAnimTime(), { + From = self:GetTall() + }) self:InvalidateLayout(true) - self:OnToggle(self:GetExpanded()) end -function PANEL:OnToggle(expanded) end +function PANEL:OnToggle(expanded) +end function PANEL:DoExpansion(b) if self:GetExpanded() == b then return end self:Toggle() end -function PANEL:LayoutContent(w, h) end +function PANEL:LayoutContent(w, h) +end function PANEL:PerformLayout(w, h) self.Header:Dock(TOP) @@ -150,20 +142,26 @@ function PANEL:PerformLayout(w, h) end if self:GetExpanded() then - if IsValid(self.Contents) and #self.Contents:GetChildren() > 0 then self.Contents:SizeToChildren(false, true) end + if IsValid(self.Contents) and #self.Contents:GetChildren() > 0 then + self.Contents:SizeToChildren(false, true) + end + self:SizeToChildren(false, true) else - if IsValid(self.Contents) and not self.OldHeight then self.OldHeight = self.Contents:GetTall() end + if IsValid(self.Contents) and not self.OldHeight then + self.OldHeight = self.Contents:GetTall() + end + self:SetTall(self.Header:GetTall()) end self.SlideAnimation:Run() - self:LayoutContent(w, h) end function PANEL:OnMousePressed(mcode) if not self:GetParent().OnMousePressed then return end + return self:GetParent():OnMousePressed(mcode) end @@ -174,6 +172,7 @@ function PANEL:AnimSlide(anim, delta, data) if anim.Started then if not IsValid(self.Contents) and (self.OldHeight or 0) < self.Header:GetTall() then self.OldHeight = 0 + for id, pnl in pairs(self:GetChildren()) do self.OldHeight = self.OldHeight + pnl:GetTall() end @@ -186,11 +185,12 @@ function PANEL:AnimSlide(anim, delta, data) end end - if IsValid(self.Contents) then self.Contents:SetVisible(true) end + if IsValid(self.Contents) then + self.Contents:SetVisible(true) + end self:GetParent():InvalidateLayout() self:GetParent():GetParent():InvalidateLayout() - self:SetTall(Lerp(delta, data.From, data.To)) end diff --git a/lua/pixelui/elements/cl_check_box.lua b/lua/pixelui/elements/cl_check_box.lua index 518253e..7f08ac3 100644 --- a/lua/pixelui/elements/cl_check_box.lua +++ b/lua/pixelui/elements/cl_check_box.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,24 +14,18 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} function PANEL:Init() self:SetIsToggle(true) - local boxSize = PIXEL.Scale(20) self:SetSize(boxSize, boxSize) - self:SetImgurID("YvG7VI6") - self:SetNormalColor(PIXEL.Colors.Transparent) self:SetHoverColor(PIXEL.Colors.PrimaryText) self:SetClickColor(PIXEL.Colors.PrimaryText) self:SetDisabledColor(PIXEL.Colors.Transparent) - self:SetImageSize(.8) - self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Primary) end @@ -40,6 +33,7 @@ function PANEL:PaintBackground(w, h) if not self:IsEnabled() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Disabled) self:PaintExtra(w, h) + return end @@ -51,7 +45,6 @@ function PANEL:PaintBackground(w, h) local animTime = FrameTime() * 12 self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, bgCol) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) end diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 9195dfb..27dd902 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,9 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "Draggable", "Draggable", FORCE_BOOL) AccessorFunc(PANEL, "Sizable", "Sizable", FORCE_BOOL) AccessorFunc(PANEL, "MinWidth", "MinWidth", FORCE_NUMBER) @@ -27,245 +24,296 @@ AccessorFunc(PANEL, "RemoveOnClose", "RemoveOnClose", FORCE_BOOL) AccessorFunc(PANEL, "SlideOut", "SlideOut", FORCE_BOOL) AccessorFunc(PANEL, "SlideDirection", "SlideDirection", FORCE_NUMBER) -- 1 = up, 2 = right, 3 = down, 4 = left AccessorFunc(PANEL, "SlideTime", "SlideTime", FORCE_NUMBER) - - AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) - PIXEL.RegisterFont("UI.FrameTitle", "Open Sans Bold", 22) function PANEL:Init() - self.CloseButton = vgui.Create("PIXEL.ImgurButton", self) - self.CloseButton:SetImgurID("z1uAU0b") - self.CloseButton:SetNormalColor(PIXEL.Colors.PrimaryText) - self.CloseButton:SetHoverColor(PIXEL.Colors.Negative) - self.CloseButton:SetClickColor(PIXEL.Colors.Negative) - self.CloseButton:SetDisabledColor(PIXEL.Colors.DisabledText) + self.CloseButton = vgui.Create("PIXEL.ImgurButton", self) + self.CloseButton:SetImgurID("z1uAU0b") + self.CloseButton:SetNormalColor(PIXEL.Colors.PrimaryText) + self.CloseButton:SetHoverColor(PIXEL.Colors.Negative) + self.CloseButton:SetClickColor(PIXEL.Colors.Negative) + self.CloseButton:SetDisabledColor(PIXEL.Colors.DisabledText) + + self.CloseButton.DoClick = function(s) + self:Close() + end + + self:SetSlideOut(false) + self.ExtraButtons = {} + self:SetTitle("PIXEL Frame") + self:SetDraggable(true) + self:SetScreenLock(true) + self:SetRemoveOnClose(true) + local size = PIXEL.Scale(200) + self:SetMinWidth(size) + self:SetMinHeight(size) + local oldMakePopup = self.MakePopup + + function self:MakePopup() + oldMakePopup(self) + self:Open() + end +end - self.CloseButton.DoClick = function(s) - self:Close() - end +function PANEL:DragThink(targetPanel, hoverPanel) + local scrw, scrh = ScrW(), ScrH() + local mousex, mousey = math.Clamp(gui.MouseX(), 1, scrw - 1), math.Clamp(gui.MouseY(), 1, scrh - 1) - self:SetSlideOut(false) + if targetPanel.Dragging then + local x = mousex - targetPanel.Dragging[1] + local y = mousey - targetPanel.Dragging[2] - self.ExtraButtons = {} + if targetPanel:GetScreenLock() then + x = math.Clamp(x, 0, scrw - targetPanel:GetWide()) + y = math.Clamp(y, 0, scrh - targetPanel:GetTall()) + end - self:SetTitle("PIXEL Frame") + targetPanel:SetPos(x, y) + end - self:SetDraggable(true) - self:SetScreenLock(true) - self:SetRemoveOnClose(true) + local _, screenY = targetPanel:LocalToScreen(0, 0) - local size = PIXEL.Scale(200) - self:SetMinWidth(size) - self:SetMinHeight(size) + if (hoverPanel or targetPanel).Hovered and targetPanel:GetDraggable() and mousey < (screenY + PIXEL.Scale(30)) then + targetPanel:SetCursor("sizeall") - local oldMakePopup = self.MakePopup - function self:MakePopup() - oldMakePopup(self) - self:Open() - end -end - -function PANEL:DragThink(targetPanel, hoverPanel) - local scrw, scrh = ScrW(), ScrH() - local mousex, mousey = math.Clamp(gui.MouseX(), 1, scrw - 1), math.Clamp(gui.MouseY(), 1, scrh - 1) - - if targetPanel.Dragging then - local x = mousex - targetPanel.Dragging[1] - local y = mousey - targetPanel.Dragging[2] - - if targetPanel:GetScreenLock() then - x = math.Clamp(x, 0, scrw - targetPanel:GetWide()) - y = math.Clamp(y, 0, scrh - targetPanel:GetTall()) - end - - targetPanel:SetPos(x, y) - end - - local _, screenY = targetPanel:LocalToScreen(0, 0) - if (hoverPanel or targetPanel).Hovered and targetPanel:GetDraggable() and mousey < (screenY + PIXEL.Scale(30)) then - targetPanel:SetCursor("sizeall") - return true - end + return true + end end function PANEL:SizeThink(targetPanel, hoverPanel) - local scrw, scrh = ScrW(), ScrH() - local mousex, mousey = math.Clamp(gui.MouseX(), 1, scrw - 1), math.Clamp(gui.MouseY(), 1, scrh - 1) - - if targetPanel.Sizing then - local x = mousex - targetPanel.Sizing[1] - local y = mousey - targetPanel.Sizing[2] - local px, py = targetPanel:GetPos() - - local screenLock = self:GetScreenLock() - if x < targetPanel.MinWidth then x = targetPanel.MinWidth elseif x > scrw - px and screenLock then x = scrw - px end - if y < targetPanel.MinHeight then y = targetPanel.MinHeight elseif y > scrh - py and screenLock then y = scrh - py end - - targetPanel:SetSize(x, y) - targetPanel:SetCursor("sizenwse") - return true - end - - local screenX, screenY = targetPanel:LocalToScreen(0, 0) - if (hoverPanel or targetPanel).Hovered and targetPanel.Sizable and mousex > (screenX + targetPanel:GetWide() - PIXEL.Scale(20)) and mousey > (screenY + targetPanel:GetTall() - PIXEL.Scale(20)) then - (hoverPanel or targetPanel):SetCursor("sizenwse") - return true - end + local scrw, scrh = ScrW(), ScrH() + local mousex, mousey = math.Clamp(gui.MouseX(), 1, scrw - 1), math.Clamp(gui.MouseY(), 1, scrh - 1) + + if targetPanel.Sizing then + local x = mousex - targetPanel.Sizing[1] + local y = mousey - targetPanel.Sizing[2] + local px, py = targetPanel:GetPos() + local screenLock = self:GetScreenLock() + + if x < targetPanel.MinWidth then + x = targetPanel.MinWidth + elseif x > scrw - px and screenLock then + x = scrw - px + end + + if y < targetPanel.MinHeight then + y = targetPanel.MinHeight + elseif y > scrh - py and screenLock then + y = scrh - py + end + + targetPanel:SetSize(x, y) + targetPanel:SetCursor("sizenwse") + + return true + end + + local screenX, screenY = targetPanel:LocalToScreen(0, 0) + + if (hoverPanel or targetPanel).Hovered and targetPanel.Sizable and mousex > (screenX + targetPanel:GetWide() - PIXEL.Scale(20)) and mousey > (screenY + targetPanel:GetTall() - PIXEL.Scale(20)) then + (hoverPanel or targetPanel):SetCursor("sizenwse") + + return true + end end function PANEL:Think() - if self:DragThink(self) then return end - if self:SizeThink(self) then return end + if self:DragThink(self) then return end + if self:SizeThink(self) then return end + self:SetCursor("arrow") - self:SetCursor("arrow") - - if self.y < 0 then - self:SetPos(self.x, 0) - end + if self.y < 0 then + self:SetPos(self.x, 0) + end end function PANEL:OnMousePressed() - local screenX, screenY = self:LocalToScreen(0, 0) - local mouseX, mouseY = gui.MouseX(), gui.MouseY() - - if self.Sizable and mouseX > (screenX + self:GetWide() - PIXEL.Scale(30)) and mouseY > (screenY + self:GetTall() - PIXEL.Scale(30)) then - self.Sizing = {mouseX - self:GetWide(), mouseY - self:GetTall()} - self:MouseCapture(true) - return - end - - if self:GetDraggable() and mouseY < (screenY + PIXEL.Scale(30)) then - self.Dragging = {mouseX - self.x, mouseY - self.y} - self:MouseCapture(true) - return - end + local screenX, screenY = self:LocalToScreen(0, 0) + local mouseX, mouseY = gui.MouseX(), gui.MouseY() + + if self.Sizable and mouseX > (screenX + self:GetWide() - PIXEL.Scale(30)) and mouseY > (screenY + self:GetTall() - PIXEL.Scale(30)) then + self.Sizing = {mouseX - self:GetWide(), mouseY - self:GetTall()} + + self:MouseCapture(true) + + return + end + + if self:GetDraggable() and mouseY < (screenY + PIXEL.Scale(30)) then + self.Dragging = {mouseX - self.x, mouseY - self.y} + + self:MouseCapture(true) + + return + end end function PANEL:OnMouseReleased() - self.Dragging = nil - self.Sizing = nil - self:MouseCapture(false) + self.Dragging = nil + self.Sizing = nil + self:MouseCapture(false) end function PANEL:CreateSidebar(defaultItem, imgurID, imgurScale, imgurYOffset, buttonYOffset) - if IsValid(self.SideBar) then return end - self.SideBar = vgui.Create("PIXEL.Sidebar", self) - - if defaultItem then - timer.Simple(0, function() - if not IsValid(self.SideBar) then return end - self.SideBar:SelectItem(defaultItem) - end) - end - - if imgurID then self.SideBar:SetImgurID(imgurID) end - if imgurScale then self.SideBar:SetImgurScale(imgurScale) end - if imgurYOffset then self.SideBar:SetImgurOffset(imgurYOffset) end - if buttonYOffset then self.SideBar:SetButtonOffset(buttonYOffset) end - - return self.SideBar + if IsValid(self.SideBar) then return end + self.SideBar = vgui.Create("PIXEL.Sidebar", self) + + if defaultItem then + timer.Simple(0, function() + if not IsValid(self.SideBar) then return end + self.SideBar:SelectItem(defaultItem) + end) + end + + if imgurID then + self.SideBar:SetImgurID(imgurID) + end + + if imgurScale then + self.SideBar:SetImgurScale(imgurScale) + end + + if imgurYOffset then + self.SideBar:SetImgurOffset(imgurYOffset) + end + + if buttonYOffset then + self.SideBar:SetButtonOffset(buttonYOffset) + end + + return self.SideBar end function PANEL:AddHeaderButton(elem, size) - elem.HeaderIconSize = size or .45 - return table.insert(self.ExtraButtons, elem) + elem.HeaderIconSize = size or .45 + + return table.insert(self.ExtraButtons, elem) end -function PANEL:LayoutContent(w, h) end +function PANEL:LayoutContent(w, h) +end function PANEL:PerformLayout(w, h) - local headerH = PIXEL.Scale(30) - local btnPad = PIXEL.Scale(6) - local btnSpacing = PIXEL.Scale(6) - - if IsValid(self.CloseButton) then - local btnSize = headerH * .45 - self.CloseButton:SetSize(btnSize, btnSize) - self.CloseButton:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) - - btnPad = btnPad + btnSize + btnSpacing - end - - for _, btn in ipairs(self.ExtraButtons) do - local btnSize = headerH * btn.HeaderIconSize - btn:SetSize(btnSize, btnSize) - btn:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) - btnPad = btnPad + btnSize + btnSpacing - end - - if IsValid(self.SideBar) then - self.SideBar:SetPos(0, headerH) - self.SideBar:SetSize(PIXEL.Scale(200), h - headerH) - end - - local padding = PIXEL.Scale(6) - self:DockPadding(self.SideBar and PIXEL.Scale(200) + padding or padding, headerH + padding, padding, padding) - - self:LayoutContent(w, h) + local headerH = PIXEL.Scale(30) + local btnPad = PIXEL.Scale(6) + local btnSpacing = PIXEL.Scale(6) + + if IsValid(self.CloseButton) then + local btnSize = headerH * .45 + self.CloseButton:SetSize(btnSize, btnSize) + self.CloseButton:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) + btnPad = btnPad + btnSize + btnSpacing + end + + for _, btn in ipairs(self.ExtraButtons) do + local btnSize = headerH * btn.HeaderIconSize + btn:SetSize(btnSize, btnSize) + btn:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) + btnPad = btnPad + btnSize + btnSpacing + end + + if IsValid(self.SideBar) then + self.SideBar:SetPos(0, headerH) + self.SideBar:SetSize(PIXEL.Scale(200), h - headerH) + end + + local padding = PIXEL.Scale(6) + self:DockPadding(self.SideBar and PIXEL.Scale(200) + padding or padding, headerH + padding, padding, padding) + self:LayoutContent(w, h) end function PANEL:Open() - PIXEL.PlayButtonSound() - self:SetVisible(false) - self:SetAlpha(0) - self:SetVisible(true) - self:AlphaTo(255, .1, 0) + PIXEL.PlayButtonSound() + self:SetVisible(false) + self:SetAlpha(0) + self:SetVisible(true) + self:AlphaTo(255, .1, 0) end - function PANEL:Close() - if not self:GetSlideOut() then - self:AlphaTo(0, .1, 0, function(anim, pnl) - if not IsValid(pnl) then return end - pnl:SetVisible(false) - pnl:OnClose() - if pnl:GetRemoveOnClose() then pnl:Remove() end - end) - return - end - - local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() - local slideDirections = { - [1] = {x = (scrw / 2) - (wide / 2), y = -tall,size = function() self:SizeTo(wide, 0, (self:GetSlideTime() - 0.2) or .3, 0, -1) end},-- up - [2] = {x = scrw,y = posY,size = function() end},-- right - [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end},-- down - [4] = {x = -wide,y = posY,size = function() end},-- left - } - - local direction = self:GetSlideDirection() or 1 - slideDirections[direction].size() - self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, self:GetSlideTime() or .5, 0, -1, function(anim, pnl) - if not IsValid(pnl) then return end - pnl:SetVisible(false) - pnl:OnClose() - if pnl:GetRemoveOnClose() then pnl:Remove() end - end) + if not self:GetSlideOut() then + self:AlphaTo(0, .1, 0, function(anim, pnl) + if not IsValid(pnl) then return end + pnl:SetVisible(false) + pnl:OnClose() + + if pnl:GetRemoveOnClose() then + pnl:Remove() + end + end) + + return + end + + local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() + + local slideDirections = { + [1] = { + x = (scrw / 2) - (wide / 2), + y = -tall, + size = function() + self:SizeTo(wide, 0, (self:GetSlideTime() - 0.2) or .3, 0, -1) + end + }, -- up + [2] = { + x = scrw, + y = posY, + size = function() end + }, -- right + [3] = { + x = (scrw / 2) - (wide / 2), + y = scrh + tall, + size = function() end + }, -- down + [4] = { + x = -wide, + y = posY, + size = function() end + }, -- left + + } + + local direction = self:GetSlideDirection() or 1 + slideDirections[direction].size() + + self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, self:GetSlideTime() or .5, 0, -1, function(anim, pnl) + if not IsValid(pnl) then return end + pnl:SetVisible(false) + pnl:OnClose() + + if pnl:GetRemoveOnClose() then + pnl:Remove() + end + end) end -function PANEL:OnClose() end +function PANEL:OnClose() +end function PANEL:PaintHeader(x, y, w, h) - PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), x, y, w, h, PIXEL.Colors.Header, true, true) + PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), x, y, w, h, PIXEL.Colors.Header, true, true) + local imgurID = self:GetImgurID() - local imgurID = self:GetImgurID() - if imgurID then - local iconSize = h * .6 - PIXEL.DrawImgur(PIXEL.Scale(6), x + (h - iconSize) / 2, y + iconSize, iconSize, imgurID, color_white) - PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(12) + iconSize, y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) - return - end + if imgurID then + local iconSize = h * .6 + PIXEL.DrawImgur(PIXEL.Scale(6), x + (h - iconSize) / 2, y + iconSize, iconSize, imgurID, color_white) + PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(12) + iconSize, y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) - PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(8), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) + return + end + + PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(8), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) end -function PANEL:PaintMore(w,h) end +function PANEL:PaintMore(w, h) +end function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Background) - self:PaintHeader(0, 0, w, PIXEL.Scale(30)) - self:PaintMore(w, h) + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Background) + self:PaintHeader(0, 0, w, PIXEL.Scale(30)) + self:PaintMore(w, h) end -vgui.Register("PIXEL.Frame", PANEL, "EditablePanel") +vgui.Register("PIXEL.Frame", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 3103f2e..a3b3b67 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,13 +14,10 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "Name", "Name", FORCE_STRING) AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "DrawOutline", "DrawOutline", FORCE_BOOL) - PIXEL.RegisterFont("SidebarItem", "Open Sans Bold", 19) function PANEL:Init() @@ -29,7 +25,6 @@ function PANEL:Init() self:SetDrawOutline(true) self:SetClicky(false) self:SetSounds(false) - self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) self.BackgroundHoverCol = ColorAlpha(PIXEL.Colors.Scroller, 80) @@ -62,10 +57,12 @@ function PANEL:Paint(w, h) end local imgurID = self:GetImgurID() + if imgurID then local iconSize = h * .65 - PIXEL.DrawImgur(PIXEL.Scale(10), (h - iconSize) / 2, iconSize, iconSize, imgurID, Color(255,255,255)) + PIXEL.DrawImgur(PIXEL.Scale(10), (h - iconSize) / 2, iconSize, iconSize, imgurID, Color(255, 255, 255)) PIXEL.DrawSimpleText(self:GetName(), "SidebarItem", PIXEL.Scale(20) + iconSize, h / 2, self.TextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + return end @@ -73,9 +70,7 @@ function PANEL:Paint(w, h) end vgui.Register("PIXEL.SidebarItem", PANEL, "PIXEL.Button") - PANEL = {} - AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "ImgurScale", "ImgurScale", FORCE_NUMBER) AccessorFunc(PANEL, "ImgurOffset", "ImgurOffset", FORCE_NUMBER) @@ -84,13 +79,14 @@ AccessorFunc(PANEL, "ButtonBtmOffset", "ButtonBtmOffset", FORCE_NUMBER) function PANEL:Init() self.Items = {} - self.Scroller = vgui.Create("PIXEL.ScrollPanel", self) self.Scroller:SetBarDockShouldOffset(true) + self.Scroller.LayoutContent = function(s, w, h) local spacing = PIXEL.Scale(8) local height = PIXEL.Scale(35) - for k,v in pairs(self.Items) do + + for k, v in pairs(self.Items) do v:SetTall(height) v:Dock(TOP) v:DockMargin(0, 0, 0, spacing) @@ -100,16 +96,18 @@ function PANEL:Init() self:SetImgurScale(.6) self:SetImgurOffset(0) self:SetButtonOffset(0) - self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Header) end function PANEL:AddItem(id, name, imgurID, doClick, order) local btn = vgui.Create("PIXEL.SidebarItem", self.Scroller) - btn:SetZPos(order or table.Count(self.Items) + 1) btn:SetName(name) - if imgurID then btn:SetImgurID(imgurID) end + + if imgurID then + btn:SetImgurID(imgurID) + end + btn.Function = doClick btn.DoClick = function(s) @@ -124,24 +122,20 @@ end function PANEL:RemoveItem(id) local item = self.Items[id] if not item then return end - item:Remove() self.Items[id] = nil - - if self.SelectedItem != id then return end + if self.SelectedItem ~= id then return end self:SelectItem(next(self.Items)) end function PANEL:SelectItem(id) local item = self.Items[id] if not item then return end - PIXEL.PlayChangeTab() - if self.SelectedItem and self.SelectedItem == id then return end self.SelectedItem = id - for k,v in pairs(self.Items) do + for k, v in pairs(self.Items) do v:SetToggle(false) end @@ -153,19 +147,19 @@ function PANEL:PerformLayout(w, h) local sideSpacing = PIXEL.Scale(7) local topSpacing = PIXEL.Scale(7) self:DockPadding(sideSpacing, self:GetImgurID() and w * self:GetImgurScale() + self:GetImgurOffset() + self:GetButtonOffset() + topSpacing * 2 or topSpacing, sideSpacing, self:GetButtonBtmOffset() or topSpacing) - self.Scroller:Dock(FILL) self.Scroller:GetCanvas():DockPadding(0, 0, self.Scroller.VBar.Enabled and sideSpacing or 0, 0) end function PANEL:Paint(w, h) PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), 0, 0, w, h, self.BackgroundCol, false, false, true) - + PIXEL.DrawRoundedBox(0, 0, 0, w, PIXEL.Scale(1), PIXEL.Colors.Outline) local imgurID = self:GetImgurID() + if imgurID then local imageSize = w * self:GetImgurScale() PIXEL.DrawImgur((w - imageSize) / 2, self:GetImgurOffset() + PIXEL.Scale(15), imageSize, imageSize, imgurID, color_white) end end -vgui.Register("PIXEL.Sidebar", PANEL, "Panel") +vgui.Register("PIXEL.Sidebar", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 6d5a9f8..20a8f33 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,25 +14,19 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - - local PANEL = {} function PANEL:Init() self.TextEntry = vgui.Create("PIXEL.TextEntryInternal", self) - self.PlaceholderTextCol = PIXEL.OffsetColor(PIXEL.Colors.SecondaryText, -110) - self.DisabledCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 6) self.FocusedOutlineCol = PIXEL.Colors.PrimaryText - self.OutlineCol = PIXEL.OffsetColor(PIXEL.Colors.Scroller, 10) self.InnerOutlineCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) end function PANEL:PerformLayout(w, h) self.TextEntry:Dock(FILL) - local xPad, yPad = PIXEL.Scale(4), PIXEL.Scale(8) self:DockPadding(xPad, yPad, xPad, yPad) end @@ -45,6 +38,7 @@ function PANEL:Paint(w, h) if not self:IsEnabled() and self:GetValue() == "" then PIXEL.DrawSimpleText(self:GetPlaceholderText() or "", "UI.TextEntry", PIXEL.Scale(10), h / 2, self.PlaceholderTextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + return end @@ -54,7 +48,6 @@ function PANEL:Paint(w, h) local outlineThickness = PIXEL.Scale(1) PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(2), 0, 0, w, h, self.OutlineCol, outlineThickness) - local col = PIXEL.Colors.Transparent if self:IsEditing() then @@ -66,55 +59,123 @@ function PANEL:Paint(w, h) end self.InnerOutlineCol = PIXEL.LerpColor(FrameTime() * 8, self.InnerOutlineCol, col) - PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(2), outlineThickness, outlineThickness, w - outlineThickness * 2, h - outlineThickness * 2, self.InnerOutlineCol, PIXEL.Scale(1)) end -function PANEL:OnChange() end -function PANEL:OnValueChange(value) end +function PANEL:OnChange() +end + +function PANEL:OnValueChange(value) +end + +function PANEL:IsEnabled() + return self.TextEntry:IsEnabled() +end + +function PANEL:SetEnabled(enabled) + self.TextEntry:SetEnabled(enabled) +end + +function PANEL:GetValue() + return self.TextEntry:GetValue() +end + +function PANEL:SetValue(value) + self.TextEntry:SetValue(value) +end + +function PANEL:IsMultiline() + return self.TextEntry:IsMultiline() +end + +function PANEL:SetMultiline(isMultiline) + self.TextEntry:SetMultiline(isMultiline) +end + +function PANEL:IsEditing() + return self.TextEntry:IsEditing() +end + +function PANEL:GetEnterAllowed() + return self.TextEntry:GetEnterAllowed() +end + +function PANEL:SetEnterAllowed(allow) + self.TextEntry:SetEnterAllowed(allow) +end + +function PANEL:GetUpdateOnType() + return self.TextEntry:GetUpdateOnType() +end + +function PANEL:SetUpdateOnType(enabled) + self.TextEntry:SetUpdateOnType(enabled) +end -function PANEL:IsEnabled() return self.TextEntry:IsEnabled() end -function PANEL:SetEnabled(enabled) self.TextEntry:SetEnabled(enabled) end +function PANEL:GetNumeric() + return self.TextEntry:GetNumeric() +end + +function PANEL:SetNumeric(enabled) + self.TextEntry:SetNumeric(enabled) +end + +function PANEL:GetHistoryEnabled() + return self.TextEntry:GetHistoryEnabled() +end + +function PANEL:SetHistoryEnabled(enabled) + self.TextEntry:SetHistoryEnabled(enabled) +end -function PANEL:GetValue() return self.TextEntry:GetValue() end -function PANEL:SetValue(value) self.TextEntry:SetValue(value) end +function PANEL:GetTabbingDisabled() + return self.TextEntry:GetTabbingDisabled() +end -function PANEL:IsMultiline() return self.TextEntry:IsMultiline() end -function PANEL:SetMultiline(isMultiline) self.TextEntry:SetMultiline(isMultiline) end +function PANEL:SetTabbingDisabled(disabled) + self.TextEntry:SetTabbingDisabled(disabled) +end -function PANEL:IsEditing() return self.TextEntry:IsEditing() end +function PANEL:GetPlaceholderText() + return self.TextEntry:GetPlaceholderText() +end -function PANEL:GetEnterAllowed() return self.TextEntry:GetEnterAllowed() end -function PANEL:SetEnterAllowed(allow) self.TextEntry:SetEnterAllowed(allow) end +function PANEL:SetPlaceholderText(text) + self.TextEntry:SetPlaceholderText(text) +end -function PANEL:GetUpdateOnType() return self.TextEntry:GetUpdateOnType() end -function PANEL:SetUpdateOnType(enabled) self.TextEntry:SetUpdateOnType(enabled) end +function PANEL:GetInt() + return self.TextEntry:GetInt() +end -function PANEL:GetNumeric() return self.TextEntry:GetNumeric() end -function PANEL:SetNumeric(enabled) self.TextEntry:SetNumeric(enabled) end +function PANEL:GetFloat() + return self.TextEntry:GetFloat() +end -function PANEL:GetHistoryEnabled() return self.TextEntry:GetHistoryEnabled() end -function PANEL:SetHistoryEnabled(enabled) self.TextEntry:SetHistoryEnabled(enabled) end +function PANEL:IsEditing() + return self.TextEntry:IsEditing() +end -function PANEL:GetTabbingDisabled() return self.TextEntry:GetTabbingDisabled() end -function PANEL:SetTabbingDisabled(disabled) self.TextEntry:SetTabbingDisabled(disabled) end +function PANEL:SetEditable(enabled) + self.TextEntry:SetEditable(enabled) +end -function PANEL:GetPlaceholderText() return self.TextEntry:GetPlaceholderText() end -function PANEL:SetPlaceholderText(text) self.TextEntry:SetPlaceholderText(text) end +function PANEL:AllowInput(value) +end -function PANEL:GetInt() return self.TextEntry:GetInt() end -function PANEL:GetFloat() return self.TextEntry:GetFloat() end +function PANEL:GetAutoComplete(txt) +end -function PANEL:IsEditing() return self.TextEntry:IsEditing() end -function PANEL:SetEditable(enabled) self.TextEntry:SetEditable(enabled) end +function PANEL:OnKeyCode(code) +end -function PANEL:AllowInput(value) end -function PANEL:GetAutoComplete(txt) end +function PANEL:OnEnter() +end -function PANEL:OnKeyCode(code) end -function PANEL:OnEnter() end +function PANEL:OnGetFocus() +end -function PANEL:OnGetFocus() end -function PANEL:OnLoseFocus() end +function PANEL:OnLoseFocus() +end vgui.Register("PIXEL.TextEntry", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/menus/test/cl_menu.lua b/lua/pixelui/menus/test/cl_menu.lua index 8c54147..0c2e3f2 100644 --- a/lua/pixelui/menus/test/cl_menu.lua +++ b/lua/pixelui/menus/test/cl_menu.lua @@ -2,83 +2,91 @@ PIXEL = PIXEL or {} local PANEL = {} function PANEL:Init() - self:SetSize(PIXEL.Scale(900), PIXEL.Scale(550)) - self:Center() - self:MakePopup() - self:SetTitle("PIXEL Test") - - self.Sidebar = self:CreateSidebar("PIXEL.Test.Avatar", "8bKjn4t") - - self.Sidebar:AddItem("PIXEL.Test.Avatar", "Avatar", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Avatar") - end) - self.Sidebar:AddItem("PIXEL.Test.Buttons", "Buttons", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Buttons") - end) - self.Sidebar:AddItem("PIXEL.Test.Navigation", "Navigation", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Navigation") - end) - self.Sidebar:AddItem("PIXEL.Test.ScrollPanel", "ScrollPanel", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.ScrollPanel") - end) - self.Sidebar:AddItem("PIXEL.Test.Text", "Text", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Text") - end) - self.Sidebar:AddItem("PIXEL.Test.Other", "Other", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Other") - end) + self:SetSize(PIXEL.Scale(900), PIXEL.Scale(550)) + self:Center() + self:MakePopup() + self:SetTitle("PIXEL Test") + self.Sidebar = self:CreateSidebar("PIXEL.Test.Avatar", "8bKjn4t") + + self.Sidebar:AddItem("PIXEL.Test.Avatar", "Avatar", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Avatar") + end) + + self.Sidebar:AddItem("PIXEL.Test.Buttons", "Buttons", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Buttons") + end) + + self.Sidebar:AddItem("PIXEL.Test.Navigation", "Navigation", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Navigation") + end) + + self.Sidebar:AddItem("PIXEL.Test.ScrollPanel", "ScrollPanel", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.ScrollPanel") + end) + + self.Sidebar:AddItem("PIXEL.Test.Text", "Text", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Text") + end) + + self.Sidebar:AddItem("PIXEL.Test.Other", "Other", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Other") + end) end function PANEL:ChangeTab(panel) - if not self.SideBar:IsMouseInputEnabled() then return end - - if not IsValid(self.ContentPanel) then - self.ContentPanel = vgui.Create(panel, self) - self.ContentPanel:Dock(FILL) - self.ContentPanel:InvalidateLayout(true) - - function self.ContentPanel.Think(s) - if not self.DragThink then return end - if self:DragThink(self) then return end - if self:SizeThink(self, s) then return end - self:SetCursor("arrow") - - if self.y < 0 then - self:SetPos(self.x, 0) - end - end - - function self.ContentPanel.OnMousePressed() - self:OnMousePressed() - end - - function self.ContentPanel.OnMouseReleased() - self:OnMouseReleased() - end - - return - end - - self.SideBar:SetMouseInputEnabled(false) - - self.ContentPanel:AlphaTo(0, .15, 0, function(anim, pnl) - self.ContentPanel:Remove() - self.ContentPanel = vgui.Create(panel, self) - self.ContentPanel:Dock(FILL) - self.ContentPanel:InvalidateLayout(true) - - self.ContentPanel:AlphaTo(255, .15, 0, function(anim2, pnl2) - self.SideBar:SetMouseInputEnabled(true) - end) - end) + if not self.SideBar:IsMouseInputEnabled() then return end + + if not IsValid(self.ContentPanel) then + self.ContentPanel = vgui.Create(panel, self) + self.ContentPanel:Dock(FILL) + self.ContentPanel:InvalidateLayout(true) + + function self.ContentPanel.Think(s) + if not self.DragThink then return end + if self:DragThink(self) then return end + if self:SizeThink(self, s) then return end + self:SetCursor("arrow") + + if self.y < 0 then + self:SetPos(self.x, 0) + end + end + + function self.ContentPanel.OnMousePressed() + self:OnMousePressed() + end + + function self.ContentPanel.OnMouseReleased() + self:OnMouseReleased() + end + + return + end + + self.SideBar:SetMouseInputEnabled(false) + + self.ContentPanel:AlphaTo(0, .15, 0, function(anim, pnl) + self.ContentPanel:Remove() + self.ContentPanel = vgui.Create(panel, self) + self.ContentPanel:Dock(FILL) + self.ContentPanel:InvalidateLayout(true) + + self.ContentPanel:AlphaTo(255, .15, 0, function(anim2, pnl2) + self.SideBar:SetMouseInputEnabled(true) + end) + end) end -function PANEL:PaintMore(w,h) - +function PANEL:PaintMore(w, h) end vgui.Register("PIXEL.Test.Main", PANEL, "PIXEL.Frame") concommand.Add("pixel_test", function() - vgui.Create("PIXEL.Test.Main") -end) \ No newline at end of file + PIXEL.TestFrame = vgui.Create("PIXEL.Test.Main") +end) + +if IsValid(PIXEL.TestFrame) then + PIXEL.TestFrame:Remove() + PIXEL.TestFrame = vgui.Create("PIXEL.Test.Main") +end \ No newline at end of file From 941c7f6c4d07a3e403b7cae91645e7de99e81281 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 21:01:16 +0100 Subject: [PATCH 049/155] =?UTF-8?q?=F0=9F=92=84=20New=20button=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_button.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index f886d8d..22613e1 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -141,13 +141,13 @@ function PANEL:Paint(w, h) end if not self:GetClicky() then - PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) else if self.ClickyMove then - PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) else - PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h, self.ClickyCol) - PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h - self.ClickyScale, self.BackgroundCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.ClickyCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h - self.ClickyScale, self.BackgroundCol) end end From 3853b8634b4e68342f0f29505f96c3175f0bf06d Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 21:01:27 +0100 Subject: [PATCH 050/155] =?UTF-8?q?=F0=9F=92=84=20New=20category=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_category.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/elements/cl_category.lua b/lua/pixelui/elements/cl_category.lua index dde3cf2..409d99f 100644 --- a/lua/pixelui/elements/cl_category.lua +++ b/lua/pixelui/elements/cl_category.lua @@ -16,12 +16,12 @@ along with this program. If not, see . ]] local PANEL = {} AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) -PIXEL.RegisterFont("UI.CategoryHeader", "Open Sans Bold", 19) +PIXEL.RegisterFont("UI.CategoryHeader", "Rubik", 19, 600) function PANEL:Init() self.ArrowRotation = 0 self:SetClicky(false) - self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 6) + self.BackgroundCol = PIXEL.Colors.Header end function PANEL:DoClick() @@ -130,7 +130,7 @@ end function PANEL:PerformLayout(w, h) self.Header:Dock(TOP) - self.Header:SetTall(PIXEL.Scale(26)) + self.Header:SetTall(PIXEL.Scale(30)) if IsValid(self.Contents) then if self:GetExpanded() then From 0e6fcc46d946fc2ac394d4e24251bcb02cd11614 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 21:01:36 +0100 Subject: [PATCH 051/155] =?UTF-8?q?=F0=9F=92=84=20New=20checkbox=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_check_box.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/elements/cl_check_box.lua b/lua/pixelui/elements/cl_check_box.lua index 7f08ac3..e6c4814 100644 --- a/lua/pixelui/elements/cl_check_box.lua +++ b/lua/pixelui/elements/cl_check_box.lua @@ -25,13 +25,13 @@ function PANEL:Init() self:SetHoverColor(PIXEL.Colors.PrimaryText) self:SetClickColor(PIXEL.Colors.PrimaryText) self:SetDisabledColor(PIXEL.Colors.Transparent) - self:SetImageSize(.8) + self:SetImageSize(.6) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Primary) end function PANEL:PaintBackground(w, h) if not self:IsEnabled() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Disabled) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, PIXEL.Colors.Disabled) self:PaintExtra(w, h) return @@ -45,7 +45,7 @@ function PANEL:PaintBackground(w, h) local animTime = FrameTime() * 12 self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, bgCol) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) end vgui.Register("PIXEL.Checkbox", PANEL, "PIXEL.ImgurButton") \ No newline at end of file From 593c09ae16f8a95b6a532738d3e46483d94d1baa Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 21:01:48 +0100 Subject: [PATCH 052/155] =?UTF-8?q?=F0=9F=92=84=20New=20frame=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_frame.lua | 85 +++++++++++++++++-------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 27dd902..4e26385 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -26,7 +26,7 @@ AccessorFunc(PANEL, "SlideDirection", "SlideDirection", FORCE_NUMBER) -- 1 = up, AccessorFunc(PANEL, "SlideTime", "SlideTime", FORCE_NUMBER) AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) -PIXEL.RegisterFont("UI.FrameTitle", "Open Sans Bold", 22) +PIXEL.RegisterFont("UI.FrameTitle", "Rubik", 20, 700) function PANEL:Init() self.CloseButton = vgui.Create("PIXEL.ImgurButton", self) @@ -35,6 +35,8 @@ function PANEL:Init() self.CloseButton:SetHoverColor(PIXEL.Colors.Negative) self.CloseButton:SetClickColor(PIXEL.Colors.Negative) self.CloseButton:SetDisabledColor(PIXEL.Colors.DisabledText) + self.CloseButton:SetFrameEnabled(true) + self.CloseButton:SetRounded(PIXEL.Scale(8)) self.CloseButton.DoClick = function(s) self:Close() @@ -195,35 +197,6 @@ end function PANEL:LayoutContent(w, h) end -function PANEL:PerformLayout(w, h) - local headerH = PIXEL.Scale(30) - local btnPad = PIXEL.Scale(6) - local btnSpacing = PIXEL.Scale(6) - - if IsValid(self.CloseButton) then - local btnSize = headerH * .45 - self.CloseButton:SetSize(btnSize, btnSize) - self.CloseButton:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) - btnPad = btnPad + btnSize + btnSpacing - end - - for _, btn in ipairs(self.ExtraButtons) do - local btnSize = headerH * btn.HeaderIconSize - btn:SetSize(btnSize, btnSize) - btn:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) - btnPad = btnPad + btnSize + btnSpacing - end - - if IsValid(self.SideBar) then - self.SideBar:SetPos(0, headerH) - self.SideBar:SetSize(PIXEL.Scale(200), h - headerH) - end - - local padding = PIXEL.Scale(6) - self:DockPadding(self.SideBar and PIXEL.Scale(200) + padding or padding, headerH + padding, padding, padding) - self:LayoutContent(w, h) -end - function PANEL:Open() PIXEL.PlayButtonSound() self:SetVisible(false) @@ -256,25 +229,28 @@ function PANEL:Close() size = function() self:SizeTo(wide, 0, (self:GetSlideTime() - 0.2) or .3, 0, -1) end - }, -- up + }, + -- up [2] = { x = scrw, y = posY, size = function() end - }, -- right + }, + -- right [3] = { x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end - }, -- down + }, + -- down [4] = { x = -wide, y = posY, size = function() end - }, -- left - + }, } + -- left local direction = self:GetSlideDirection() or 1 slideDirections[direction].size() @@ -292,8 +268,37 @@ end function PANEL:OnClose() end +function PANEL:PerformLayout(w, h) + self.HeaderH = PIXEL.Scale(30) + local btnPad = PIXEL.Scale(12) + local btnSpacing = PIXEL.Scale(12) + + if IsValid(self.CloseButton) then + local btnSize = self.HeaderH + self.CloseButton:SetSize(btnSize, btnSize) + self.CloseButton:SetPos(w - btnSize, (self.HeaderH - btnSize) / 2) + btnPad = btnPad + btnSize + btnSpacing + end + + for _, btn in ipairs(self.ExtraButtons) do + local btnSize = self.HeaderH * btn.HeaderIconSize + btn:SetSize(btnSize, btnSize) + btn:SetPos(w - btnSize - btnPad, (self.HeaderH - btnSize) / 2) + btnPad = btnPad + btnSize + btnSpacing + end + + if IsValid(self.SideBar) then + self.SideBar:SetPos(0, self.HeaderH) + self.SideBar:SetSize(PIXEL.Scale(200), h - self.HeaderH) + end + + self.ContentPadding = PIXEL.Scale(8) + self:DockPadding(self.SideBar and PIXEL.Scale(200) or self.ContentPadding, self.HeaderH + self.ContentPadding, self.ContentPadding, self.ContentPadding) + self:LayoutContent(w, h) +end + function PANEL:PaintHeader(x, y, w, h) - PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), x, y, w, h, PIXEL.Colors.Header, true, true) + PIXEL.DrawRoundedBoxEx(PIXEL.Scale(8), x, y, w, h, PIXEL.Colors.Header, true, true) local imgurID = self:GetImgurID() if imgurID then @@ -304,15 +309,17 @@ function PANEL:PaintHeader(x, y, w, h) return end - PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(8), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(12), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP) end function PANEL:PaintMore(w, h) end function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Background) - self:PaintHeader(0, 0, w, PIXEL.Scale(30)) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, PIXEL.Colors.Header) + local contentX, contentY = self.SideBar and PIXEL.Scale(200) or self.ContentPadding, self.HeaderH + self.ContentPadding + PIXEL.DrawRoundedBoxEx(PIXEL.Scale(8), contentX, contentY, w - contentX - self.ContentPadding, h - contentY - self.ContentPadding, PIXEL.Colors.Background, true, true, true, true) + self:PaintHeader(0, 0, w, self.HeaderH) self:PaintMore(w, h) end From 11be4b5839ac6d095724c1ccdd3dbf0d1a714f21 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 21:01:59 +0100 Subject: [PATCH 053/155] =?UTF-8?q?=F0=9F=92=84=20New=20buttons=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_imgur_button.lua | 24 ++++++++++++++++-------- lua/pixelui/elements/cl_text_button.lua | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/lua/pixelui/elements/cl_imgur_button.lua b/lua/pixelui/elements/cl_imgur_button.lua index ff850cf..1a9ac8c 100644 --- a/lua/pixelui/elements/cl_imgur_button.lua +++ b/lua/pixelui/elements/cl_imgur_button.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,45 +14,55 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "ImageSize", "ImageSize", FORCE_NUMBER) AccessorFunc(PANEL, "NormalColor", "NormalColor") AccessorFunc(PANEL, "HoverColor", "HoverColor") AccessorFunc(PANEL, "ClickColor", "ClickColor") AccessorFunc(PANEL, "DisabledColor", "DisabledColor") +AccessorFunc(PANEL, "FrameEnabled", "FrameEnabled") +AccessorFunc(PANEL, "Rounded", "Rounded", FORCE_NUMBER) function PANEL:Init() self.ImageCol = PIXEL.CopyColor(color_white) self:SetImgurID("635PPvg") - self:SetNormalColor(color_white) self:SetHoverColor(color_white) self:SetClickColor(color_white) self:SetDisabledColor(color_white) self:SetClicky(false) - self:SetImageSize(1) + self:SetFrameEnabled(false) end -function PANEL:PaintBackground(w, h) end +function PANEL:PaintBackground(w, h) +end function PANEL:Paint(w, h) self:PaintBackground(w, h) + if self:IsHovered() and self:GetFrameEnabled() then + PIXEL.DrawRoundedBox(self:GetRounded(), 0, 0, w, h, self:GetHoverColor()) + end + local imageSize = h * self:GetImageSize() local imageOffset = (h - imageSize) / 2 + if self:GetFrameEnabled() then + imageSize = imageSize * .45 + imageOffset = (h - imageSize) / 2 + PIXEL.Scale(1) + end + if not self:IsEnabled() then PIXEL.DrawImgur(imageOffset, imageOffset, imageSize, imageSize, self:GetImgurID(), self:GetDisabledColor()) + return end local col = self:GetNormalColor() - if self:IsHovered() then + if self:IsHovered() and not self:GetFrameEnabled() then col = self:GetHoverColor() end @@ -62,7 +71,6 @@ function PANEL:Paint(w, h) end self.ImageCol = PIXEL.LerpColor(FrameTime() * 12, self.ImageCol, col) - PIXEL.DrawImgur(imageOffset, imageOffset, imageSize, imageSize, self:GetImgurID(), self.ImageCol) end diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index 9f7c770..e52fb86 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -19,7 +19,7 @@ AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) AccessorFunc(PANEL, "TextSpacing", "TextSpacing", FORCE_NUMBER) AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) -PIXEL.RegisterFont("UI.TextButton", "Open Sans SemiBold", 20) +PIXEL.RegisterFont("UI.TextButton", "Rubik", 20, 600) function PANEL:Init() self:SetText("Button") From 85ff5b8e2aab8c4650c8a7c2bf837c1be20b0e4c Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 21:02:14 +0100 Subject: [PATCH 054/155] =?UTF-8?q?=F0=9F=92=84=20New=20navigation=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_mini_sidebar.lua | 39 +++++------ lua/pixelui/elements/cl_navbar.lua | 83 ++++++++++-------------- lua/pixelui/elements/cl_sidebar.lua | 34 ++-------- 3 files changed, 56 insertions(+), 100 deletions(-) diff --git a/lua/pixelui/elements/cl_mini_sidebar.lua b/lua/pixelui/elements/cl_mini_sidebar.lua index 39010b8..d37f5a4 100644 --- a/lua/pixelui/elements/cl_mini_sidebar.lua +++ b/lua/pixelui/elements/cl_mini_sidebar.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,13 +14,10 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "Name", "Name", FORCE_STRING) AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "DrawOutline", "DrawOutline", FORCE_BOOL) - PIXEL.RegisterFont("SidebarItem", "Rubik", 19) function PANEL:Init() @@ -30,7 +26,6 @@ function PANEL:Init() self:SetClicky(false) self:SetSounds(false) self:SetTooltip(self:GetName() or "N/A") - self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) self.BackgroundHoverCol = ColorAlpha(PIXEL.Colors.Scroller, 80) @@ -58,19 +53,17 @@ function PANEL:Paint(w, h) self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) if self:GetDrawOutline() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverLineCol, PIXEL.Scale(1)) end local imgurID = self:GetImgurID() - local iconSize = h * .65 - PIXEL.DrawImgur(PIXEL.Scale(9), (h - iconSize) / 2 + PIXEL.Scale(1), iconSize, iconSize, imgurID, Color(255,255,255)) + local iconSize = h * .65 + PIXEL.DrawImgur(PIXEL.Scale(9), (h - iconSize) / 2 + PIXEL.Scale(1), iconSize, iconSize, imgurID, Color(255, 255, 255)) end vgui.Register("PIXEL.SidebarItem", PANEL, "PIXEL.Button") - PANEL = {} - AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "ImgurScale", "ImgurScale", FORCE_NUMBER) AccessorFunc(PANEL, "ImgurOffset", "ImgurOffset", FORCE_NUMBER) @@ -79,13 +72,14 @@ AccessorFunc(PANEL, "ButtonBtmOffset", "ButtonBtmOffset", FORCE_NUMBER) function PANEL:Init() self.Items = {} - self.Scroller = vgui.Create("PIXEL.ScrollPanel", self) self.Scroller:SetBarDockShouldOffset(true) + self.Scroller.LayoutContent = function(s, w, h) local spacing = PIXEL.Scale(8) local height = PIXEL.Scale(36) - for k,v in pairs(self.Items) do + + for k, v in pairs(self.Items) do v:SetTall(height) v:Dock(TOP) v:DockMargin(0, 0, 0, spacing) @@ -95,16 +89,18 @@ function PANEL:Init() self:SetImgurScale(.6) self:SetImgurOffset(0) self:SetButtonOffset(0) - self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Header) end function PANEL:AddItem(id, name, imgurID, doClick, order) local btn = vgui.Create("PIXEL.SidebarItem", self.Scroller) - btn:SetZPos(order or table.Count(self.Items) + 1) btn:SetName(name) - if imgurID then btn:SetImgurID(imgurID) end + + if imgurID then + btn:SetImgurID(imgurID) + end + btn.Function = doClick btn.DoClick = function(s) @@ -119,24 +115,20 @@ end function PANEL:RemoveItem(id) local item = self.Items[id] if not item then return end - item:Remove() self.Items[id] = nil - - if self.SelectedItem != id then return end + if self.SelectedItem ~= id then return end self:SelectItem(next(self.Items)) end function PANEL:SelectItem(id) local item = self.Items[id] if not item then return end - PIXEL.PlayChangeTab() - if self.SelectedItem and self.SelectedItem == id then return end self.SelectedItem = id - for k,v in pairs(self.Items) do + for k, v in pairs(self.Items) do v:SetToggle(false) end @@ -148,19 +140,18 @@ function PANEL:PerformLayout(w, h) local sideSpacing = PIXEL.Scale(7) local topSpacing = PIXEL.Scale(7) self:DockPadding(sideSpacing, self:GetImgurID() and w * self:GetImgurScale() + self:GetImgurOffset() + self:GetButtonOffset() + topSpacing * 2 or topSpacing, sideSpacing, self:GetButtonBtmOffset() or topSpacing) - self.Scroller:Dock(FILL) self.Scroller:GetCanvas():DockPadding(0, 0, self.Scroller.VBar.Enabled and sideSpacing or 0, 0) end function PANEL:Paint(w, h) PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), 0, 0, w, h, self.BackgroundCol, false, false, true) - local imgurID = self:GetImgurID() + if imgurID then local imageSize = w * self:GetImgurScale() PIXEL.DrawImgur((w - imageSize) / 2, imageSize / 2 - (imageSize / 3), imageSize, imageSize, imgurID, color_white) end end -vgui.Register("PIXEL.MiniSidebar", PANEL, "Panel") +vgui.Register("PIXEL.MiniSidebar", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_navbar.lua b/lua/pixelui/elements/cl_navbar.lua index 8cc6074..cf8e5f5 100644 --- a/lua/pixelui/elements/cl_navbar.lua +++ b/lua/pixelui/elements/cl_navbar.lua @@ -1,29 +1,15 @@ - ---[[ -PIXEL UI -Copyright (C) 2021 Tom O'Sullivan (Tom.bat) - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -]] - local PANEL = {} - AccessorFunc(PANEL, "Name", "Name", FORCE_STRING) -AccessorFunc(PANEL, "Color", "Color") AccessorFunc(PANEL, "ImgurID", "ImgurID") AccessorFunc(PANEL, "ImgurScale", "ImgurScale") +AccessorFunc(PANEL, "Selected", "Selected", FORCE_BOOL) +PIXEL.RegisterFont("UI.NavbarItem", "Rubik", 22, 600) -PIXEL.RegisterFont("UI.NavbarItem", "Open Sans SemiBold", 22) +function PANEL:SetColor(col) + self.BackgroundCol = PIXEL.Colors.Transparent + self.BackgroundHoverCol = ColorAlpha(col, 40) + self.BackgroundSelectCol = ColorAlpha(col, 80) +end function PANEL:Init() self:SetName("N/A") @@ -31,58 +17,65 @@ function PANEL:Init() self:SetClicky(false) self:SetSounds(false) self:SetImgurScale(0.2) - self.NormalCol = PIXEL.Colors.PrimaryText self.HoverCol = PIXEL.Colors.SecondaryText - self.TextCol = PIXEL.CopyColor(self.NormalCol) + self.BackgroundCol = PIXEL.Colors.Transparent + self.BackgroundHoverCol = ColorAlpha(PIXEL.Colors.Primary, 40) + self.BackgroundSelectCol = ColorAlpha(PIXEL.Colors.Primary, 80) end function PANEL:GetItemSize() PIXEL.SetFont("UI.NavbarItem") + return PIXEL.GetTextSize(self:GetName()) end function PANEL:Paint(w, h) local textCol = self.NormalCol + local backgroundCol = self.BackgroundCol if self:IsHovered() then textCol = self.HoverCol + backgroundCol = self.BackgroundHoverCol + end + + if self:IsDown() or self:GetToggle() then + backgroundCol = self.BackgroundSelectCol end local animTime = FrameTime() * 12 self.TextCol = PIXEL.LerpColor(animTime, self.TextCol, textCol) - local imgurID = self:GetImgurID() + if imgurID then local imageSize = w * self:GetImgurScale() PIXEL.DrawImgur(0, (self:GetTall() / 2) - (imageSize / 2), imageSize, imageSize, imgurID, color_white) PIXEL.DrawSimpleText(self:GetName(), "UI.NavbarItem", imageSize + PIXEL.Scale(3), h / 2, self.TextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + return end + local boxW, boxH = w - PIXEL.Scale(16), h - PIXEL.Scale(16) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), PIXEL.Scale(8), PIXEL.Scale(8), boxW, boxH, backgroundCol) PIXEL.DrawSimpleText(self:GetName(), "UI.NavbarItem", w / 2, h / 2, self.TextCol, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end vgui.Register("PIXEL.NavbarItem", PANEL, "PIXEL.Button") - PANEL = {} function PANEL:Init() self.Items = {} - self.SelectionX = 0 self.SelectionW = 0 self.SelectionColor = Color(0, 0, 0) - - self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 10) + self.BackgroundCol = PIXEL.Colors.Header end function PANEL:AddItem(id, name, doClick, order, color, imgurID) local btn = vgui.Create("PIXEL.NavbarItem", self) - btn:SetImgurID(imgurID) - btn:SetName(name:upper()) + btn:SetName(name) btn:SetZPos(order or table.Count(self.Items) + 1) btn:SetColor((IsColor(color) and color) or PIXEL.Colors.Primary) btn.Function = doClick @@ -97,56 +90,48 @@ end function PANEL:RemoveItem(id) local item = self.Items[id] if not item then return end - item:Remove() self.Items[id] = nil - - if self.SelectedItem != id then return end + if self.SelectedItem ~= id then return end self:SelectItem(next(self.Items)) end function PANEL:SelectItem(id) local item = self.Items[id] if not item then return end - PIXEL.PlayChangeTab() - if self.SelectedItem and self.SelectedItem == id then return end + item:SetSelected(false) self.SelectedItem = id + PIXEL.PlayChangeTab() - for k,v in pairs(self.Items) do + for k, v in pairs(self.Items) do v:SetToggle(false) end item:SetToggle(true) item.Function(item) + item:SetSelected(true) end function PANEL:PerformLayout(w, h) - for k,v in pairs(self.Items) do + self:DockMargin(PIXEL.Scale(8), PIXEL.Scale(8), PIXEL.Scale(8), PIXEL.Scale(8)) + + for k, v in pairs(self.Items) do v:Dock(LEFT) v:SetWide(v:GetItemSize() + PIXEL.Scale(50)) end end function PANEL:Paint(w, h) - surface.SetDrawColor(self.BackgroundCol) - surface.DrawRect(0, 0, w, h) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) if not self.SelectedItem then self.SelectionX = Lerp(FrameTime() * 10, self.SelectionX, 0) self.SelectionW = Lerp(FrameTime() * 10, self.SelectionX, 0) self.SelectionColor = PIXEL.LerpColor(FrameTime() * 10, self.SelectionColor, PIXEL.Colors.Primary) + return end - - local selectedItem = self.Items[self.SelectedItem] - self.SelectionX = Lerp(FrameTime() * 10, self.SelectionX, selectedItem.x) - self.SelectionW = Lerp(FrameTime() * 10, self.SelectionW, selectedItem:GetWide()) - self.SelectionColor = PIXEL.LerpColor(FrameTime() * 10, self.SelectionColor, selectedItem:GetColor()) - - local selectorH = PIXEL.Scale(6) - surface.SetDrawColor(self.SelectionColor) - surface.DrawRect(self.SelectionX + 2, h - selectorH, self.SelectionW - 4, selectorH / 2) end -vgui.Register("PIXEL.Navbar", PANEL, "Panel") +vgui.Register("PIXEL.Navbar", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index a3b3b67..3b49cf4 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -1,24 +1,8 @@ ---[[ -PIXEL UI -Copyright (C) 2021 Tom O'Sullivan (Tom.bat) - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -]] local PANEL = {} AccessorFunc(PANEL, "Name", "Name", FORCE_STRING) AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "DrawOutline", "DrawOutline", FORCE_BOOL) -PIXEL.RegisterFont("SidebarItem", "Open Sans Bold", 19) +PIXEL.RegisterFont("SidebarItem", "Rubik", 19, 600) function PANEL:Init() self:SetName("N/A") @@ -27,24 +11,22 @@ function PANEL:Init() self:SetSounds(false) self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) - self.BackgroundHoverCol = ColorAlpha(PIXEL.Colors.Scroller, 80) + self.BackgroundHoverCol = ColorAlpha(PIXEL.Colors.Primary, 40) + self.BackgroundSelectCol = ColorAlpha(PIXEL.Colors.Primary, 80) end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent - local hoverLineCol = PIXEL.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - hoverLineCol = PIXEL.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText - backgroundCol = self.BackgroundHoverCol - hoverLineCol = PIXEL.Colors.Primary + backgroundCol = self.BackgroundSelectCol end local animTime = FrameTime() * 12 @@ -52,8 +34,7 @@ function PANEL:Paint(w, h) self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) if self:GetDrawOutline() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) - PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverLineCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, backgroundCol, PIXEL.Scale(1)) end local imgurID = self:GetImgurID() @@ -61,7 +42,7 @@ function PANEL:Paint(w, h) if imgurID then local iconSize = h * .65 PIXEL.DrawImgur(PIXEL.Scale(10), (h - iconSize) / 2, iconSize, iconSize, imgurID, Color(255, 255, 255)) - PIXEL.DrawSimpleText(self:GetName(), "SidebarItem", PIXEL.Scale(20) + iconSize, h / 2, self.TextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetName(), "SidebarItem", PIXEL.Scale(15) + iconSize, h / 2, self.TextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) return end @@ -153,11 +134,10 @@ end function PANEL:Paint(w, h) PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), 0, 0, w, h, self.BackgroundCol, false, false, true) - PIXEL.DrawRoundedBox(0, 0, 0, w, PIXEL.Scale(1), PIXEL.Colors.Outline) local imgurID = self:GetImgurID() if imgurID then - local imageSize = w * self:GetImgurScale() + local imageSize = w * self:GetImgurScale() * .9 PIXEL.DrawImgur((w - imageSize) / 2, self:GetImgurOffset() + PIXEL.Scale(15), imageSize, imageSize, imgurID, color_white) end end From 80a1bd005c25afac8a7d1fea561168c2f0e78f25 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 21:02:23 +0100 Subject: [PATCH 055/155] =?UTF-8?q?=F0=9F=92=84=20other=20style=20shit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_label.lua | 9 +- lua/pixelui/elements/cl_menu.lua | 78 ++-- lua/pixelui/elements/cl_menu_option.lua | 36 +- lua/pixelui/elements/cl_notification.lua | 121 ----- lua/pixelui/elements/cl_property_sheet.lua | 442 +++++++++--------- lua/pixelui/elements/cl_slider.lua | 41 +- lua/pixelui/elements/cl_text_entry.lua | 6 +- .../elements/cl_text_entry_internal.lua | 59 +-- .../menus/test/pages/cl_navigation.lua | 25 +- 9 files changed, 356 insertions(+), 461 deletions(-) delete mode 100644 lua/pixelui/elements/cl_notification.lua diff --git a/lua/pixelui/elements/cl_label.lua b/lua/pixelui/elements/cl_label.lua index 74a0536..af7e797 100644 --- a/lua/pixelui/elements/cl_label.lua +++ b/lua/pixelui/elements/cl_label.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,9 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) @@ -26,8 +23,7 @@ AccessorFunc(PANEL, "Ellipses", "Ellipses", FORCE_BOOL) AccessorFunc(PANEL, "AutoHeight", "AutoHeight", FORCE_BOOL) AccessorFunc(PANEL, "AutoWidth", "AutoWidth", FORCE_BOOL) AccessorFunc(PANEL, "AutoWrap", "AutoWrap", FORCE_BOOL) - -PIXEL.RegisterFont("UI.Label", "Open Sans SemiBold", 14) +PIXEL.RegisterFont("UI.Label", "Rubik", 14) function PANEL:Init() self:SetText("Label") @@ -43,6 +39,7 @@ end function PANEL:CalculateSize() PIXEL.SetFont(self:GetFont()) + return PIXEL.GetTextSize(self:GetText()) end @@ -68,9 +65,11 @@ function PANEL:Paint(w, h) if align == TEXT_ALIGN_CENTER then PIXEL.DrawText(text, self:GetFont(), w / 2, 0, self:GetTextColor(), TEXT_ALIGN_CENTER) + return elseif align == TEXT_ALIGN_RIGHT then PIXEL.DrawText(text, self:GetFont(), w, 0, self:GetTextColor(), TEXT_ALIGN_RIGHT) + return end diff --git a/lua/pixelui/elements/cl_menu.lua b/lua/pixelui/elements/cl_menu.lua index 1161ea6..ae65742 100644 --- a/lua/pixelui/elements/cl_menu.lua +++ b/lua/pixelui/elements/cl_menu.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,9 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "m_bBorder", "DrawBorder") AccessorFunc(PANEL, "m_bDeleteSelf", "DeleteSelf") AccessorFunc(PANEL, "m_iMinimumWidth", "MinimumWidth") @@ -34,11 +31,8 @@ function PANEL:Init() self:SetMaxHeight(ScrH() * 0.3) self:SetDeleteSelf(true) self:SetBarDockShouldOffset(true) - self:SetPadding(0) - self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 10) - RegisterDermaMenuForClose(self) end @@ -51,7 +45,10 @@ function PANEL:AddOption(strText, funcFunction) local pnl = vgui.Create("PIXEL.MenuOption", self) pnl:SetMenu(self) pnl:SetText(strText) - if funcFunction then pnl.DoClick = funcFunction end + + if funcFunction then + pnl.DoClick = funcFunction + end self:AddPanel(pnl) @@ -62,12 +59,14 @@ function PANEL:AddCVar(strText, convar, on, off, funcFunction) local pnl = vgui.Create("PIXEL.MenuOptionCVar", self) pnl:SetMenu(self) pnl:SetText(strText) - if funcFunction then pnl.DoClick = funcFunction end + + if funcFunction then + pnl.DoClick = funcFunction + end pnl:SetConVar(convar) pnl:SetValueOn(on) pnl:SetValueOff(off) - self:AddPanel(pnl) return pnl @@ -75,11 +74,10 @@ end function PANEL:AddSpacer(text, func) local pnl = vgui.Create("Panel", self) - local spacerCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 6) + pnl.Paint = function(p, w, h) - surface.SetDrawColor(spacerCol) - surface.DrawRect(0, 0, w, h) + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, spacerCol) end pnl:SetTall(PIXEL.Scale(3)) @@ -91,9 +89,11 @@ end function PANEL:AddSubMenu(strText, funcFunction) local pnl = vgui.Create("PIXEL.MenuOption", self) local subMenu = pnl:AddSubMenu(strText, funcFunction) - pnl:SetText(strText) - if funcFunction then pnl.DoClick = funcFunction end + + if funcFunction then + pnl.DoClick = funcFunction + end self:AddPanel(pnl) @@ -102,6 +102,7 @@ end function PANEL:Hide() local openmenu = self:GetOpenSubMenu() + if openmenu then openmenu:Hide() end @@ -112,17 +113,15 @@ end function PANEL:OpenSubMenu(item, menu) local openmenu = self:GetOpenSubMenu() + if IsValid(openmenu) and openmenu:IsVisible() then if menu and openmenu == menu then return end - self:CloseSubMenu(openmenu) end if not IsValid(menu) then return end - local x, y = item:LocalToScreen(self:GetWide(), 0) menu:Open(x, y, false, item) - self:SetOpenSubMenu(menu) end @@ -141,29 +140,27 @@ end function PANEL:LayoutContent(w, h) w = self:GetMinimumWidth() - local children = self:GetCanvas():GetChildren() + for k, pnl in pairs(children) do pnl:InvalidateLayout(true) w = math.max(w, pnl:GetWide()) end self:SetWide(w) - local y = 0 + for k, pnl in pairs(children) do pnl:SetWide(w) pnl:SetPos(0, y) pnl:InvalidateLayout(true) - y = y + pnl:GetTall() end y = math.min(y, self:GetMaxHeight()) - self:SetTall(y) - local overlap = select(2, self:LocalToScreen(0, y)) - ScrH() + if overlap > 0 then self:SetPos(self:GetPos(), select(2, self:GetPos()) - overlap) end @@ -171,38 +168,48 @@ end function PANEL:Open(x, y, skipanimation, ownerpanel) RegisterDermaMenuForClose(self) - local maunal = x and y x = x or gui.MouseX() y = y or gui.MouseY() - local ownerHeight = 0 - if ownerpanel then ownerHeight = ownerpanel:GetTall() end - self:InvalidateLayout(true) + if ownerpanel then + ownerHeight = ownerpanel:GetTall() + end + self:InvalidateLayout(true) local w, h = self:GetWide(), self:GetTall() - self:SetSize(w, h) - if y + h > ScrH() then y = ((maunal and ScrH()) or (y + ownerHeight)) - h end - if x + w > ScrW() then x = ((maunal and ScrW()) or x) - w end - if y < 1 then y = 1 end - if x < 1 then x = 1 end + if y + h > ScrH() then + y = ((maunal and ScrH()) or (y + ownerHeight)) - h + end - self:SetPos(x, y) + if x + w > ScrW() then + x = ((maunal and ScrW()) or x) - w + end + + if y < 1 then + y = 1 + end + + if x < 1 then + x = 1 + end + self:SetPos(x, y) self:MakePopup() self:SetVisible(true) self:SetKeyboardInputEnabled(false) - self.DrawTall = PIXEL.Scale(0) local children = self:GetCanvas():GetChildren() local childTall = children[1]:GetTall() local childCount = 1 + for k, v in pairs(children) do v:Hide(false) end + timer.Create("PIXEL.Menu.Open", 0.025, self:ChildCount(), function() if not IsValid(self) then return end self.DrawTall = self.DrawTall + childTall @@ -216,14 +223,15 @@ function PANEL:Open(x, y, skipanimation, ownerpanel) end function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, self.DrawTall, self.BackgroundCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, self.DrawTall, self.BackgroundCol) end function PANEL:OptionSelectedInternal(option) self:OptionSelected(option, option:GetText()) end -function PANEL:OptionSelected(option, text) end +function PANEL:OptionSelected(option, text) +end function PANEL:ClearHighlights() for k, pnl in pairs(self:GetCanvas():GetChildren()) do diff --git a/lua/pixelui/elements/cl_menu_option.lua b/lua/pixelui/elements/cl_menu_option.lua index dfad5e6..3e1d0cd 100644 --- a/lua/pixelui/elements/cl_menu_option.lua +++ b/lua/pixelui/elements/cl_menu_option.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,22 +14,19 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "m_pMenu", "Menu") AccessorFunc(PANEL, "m_bChecked", "Checked") AccessorFunc(PANEL, "m_bCheckable", "IsCheckable") - AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) - -PIXEL.RegisterFont("UI.MenuOption", "Open Sans SemiBold", 18) +PIXEL.RegisterFont("UI.MenuOption", "Rubik", 18, 600) function PANEL:Hide() self.Hidden = true end + function PANEL:Show() self.Hidden = false end @@ -40,14 +36,13 @@ function PANEL:Init() self:SetFont("UI.MenuOption") self:SetChecked(false) self:SetClicky(false) - self.NormalCol = PIXEL.Colors.Transparent self.HoverCol = PIXEL.Colors.Scroller - self.BackgroundCol = PIXEL.CopyColor(self.NormalCol) end -function PANEL:SetIcon() end +function PANEL:SetIcon() +end function PANEL:SetSubMenu(menu) self.SubMenu = menu @@ -57,7 +52,6 @@ function PANEL:AddSubMenu() local subMenu = vgui.Create("PIXEL.Menu", self) subMenu:SetVisible(false) subMenu:SetParent(self) - self:SetSubMenu(subMenu) return subMenu @@ -65,24 +59,24 @@ end function PANEL:OnCursorEntered() local parent = self.ParentMenu - if not IsValid(parent) then parent = self:GetParent() end - if not IsValid(parent) then return end + if not IsValid(parent) then + parent = self:GetParent() + end + + if not IsValid(parent) then return end if not parent.OpenSubMenu then return end parent:OpenSubMenu(self, self.SubMenu) end -function PANEL:OnCursorExited() end +function PANEL:OnCursorExited() +end function PANEL:Paint(w, h) if self.Hidden then return end self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, self:IsHovered() and self.HoverCol or self.NormalCol) - - surface.SetDrawColor(self.BackgroundCol) - surface.DrawRect(0, 0, w, h) - + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), PIXEL.Scale(14), h / 2, PIXEL.Colors.PrimaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) - if not self.SubMenu then return end local dropBtnSize = PIXEL.Scale(8) PIXEL.DrawImgur(w - dropBtnSize - PIXEL.Scale(6), h / 2 - dropBtnSize / 2, dropBtnSize, dropBtnSize, "gXg3U6X", PIXEL.Colors.PrimaryText) @@ -118,10 +112,12 @@ function PANEL:ToggleCheck() self:OnChecked(self:GetChecked()) end -function PANEL:OnChecked(enabled) end +function PANEL:OnChecked(enabled) +end function PANEL:CalculateWidth() PIXEL.SetFont(self:GetFont()) + return PIXEL.GetTextSize(self:GetText()) + PIXEL.Scale(34) end @@ -130,9 +126,7 @@ function PANEL:PerformLayout(w, h) end vgui.Register("PIXEL.MenuOption", PANEL, "PIXEL.Button") - PANEL = {} - AccessorFunc(PANEL, "ConVar", "ConVar") AccessorFunc(PANEL, "ValueOn", "ValueOn") AccessorFunc(PANEL, "ValueOff", "ValueOff") diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua deleted file mode 100644 index 18737d1..0000000 --- a/lua/pixelui/elements/cl_notification.lua +++ /dev/null @@ -1,121 +0,0 @@ - -local sc = PIXEL.Scale -local Notices = {} -local notifyAmount = 0 ---[[ -surface.CreateFont("PIXEL.NotifyFont", { - font = "Open Sans Bold", - size = 25, - weight = 500, - antialias = true, -}) - - -function PIXEL.Notify(text, type, length) - local ply = LocalPlayer() - if not ply.NotifyAmount then ply.NotifyAmount = 0 end - ply.NotifyAmount = ply.NotifyAmount + 1 - local parent = nil - if ( GetOverlayPanel ) then parent = GetOverlayPanel() end - local notif = vgui.Create("PIXEL.Notification", parent) - notif:SetLength(math.max(length, 0)) - notif:SetText(text) - notif:SetType(type) - table.insert(Notices, notif) - - if ply.NotifyAmount > 0 then - notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200) - (sc(50) * ply.NotifyAmount)) - else - notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200)) - end -end - -hook.Add("Initialize", "PIXEL.NotificationOverride", function() - local oldNotification = notification.AddLegacy - - function notification.AddLegacy(text, type, length) - if PIXEL.DisableNotification then - oldNotification(text, type, length) - else - PIXEL.Notify(text, type, length) - end - end -end) - -local PANEL = {} - -function PANEL:SetText(txt) - self.NotifyText = txt - self:SetWide(PIXEL.GetTextSize(txt, "PIXEL.NotifyFont") + sc(25)) -end - -function PANEL:SetType(type) - self.NotifyType = type - if type == NOTIFY_GENERIC then - PIXEL.PlayNotify() - elseif type == NOTIFY_ERROR then - PIXEL.PlayError(1) - elseif type == NOTIFY_UNDO then - PIXEL.PlayError(2) - elseif type == NOTIFY_HINT then - PIXEL.PlaySuccess(1) - elseif type == NOTIFY_CLEANUP then - PIXEL.PlayError(5) - end -end - -function PANEL:SetLength(sec) - sec = sec + .2 - self.Length = sec - - timer.Simple(sec, function() - self:Close() - end) -end - -function PANEL:Init() - self:SetTall(sc(40)) - self:SetWide(sc(40)) - self.NotifyText = "" - self:SetVisible(false) - self:Open() -end - -function PANEL:SizeToContents() -end - -function PANEL:SetLegacyType() -end - -function PANEL:Paint(w, h) - local shouldDraw = not (LocalPlayer and IsValid(LocalPlayer()) and IsValid(LocalPlayer():GetActiveWeapon()) and LocalPlayer():GetActiveWeapon():GetClass() == "gmod_camera") - if not shouldDraw then return end - - PIXEL.DrawRoundedBoxEx(sc(6), sc(5), 0, w, h, PIXEL.SetColorTransparency(PIXEL.Colors.Background, 200), false, true, false, true) - PIXEL.DrawRoundedBoxEx(sc(6), 0, 0, sc(5), h, PIXEL.Colors.Primary, true, false, true, false) - PIXEL.DrawSimpleText(self.NotifyText, "PIXEL.NotifyFont", w / 2, h / 2 - sc(1), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) -end - -function PANEL:Open() - self:SetAlpha(0) - self:SetVisible(true) - self:AlphaTo(255, .1, 0) -end - -function PANEL:Close() - local ply = LocalPlayer() - self:AlphaTo(0, .1, 0, function(anim, pnl) - if not IsValid(pnl) then return end - pnl:SetVisible(false) - pnl:Remove() - end) - - ply.NotifyAmount = ply.NotifyAmount - 1 -end - -function PANEL:SetProgress(frac) end - -function PANEL:KillSelf() end - -vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") ---]] \ No newline at end of file diff --git a/lua/pixelui/elements/cl_property_sheet.lua b/lua/pixelui/elements/cl_property_sheet.lua index ba744f7..bdc3c28 100644 --- a/lua/pixelui/elements/cl_property_sheet.lua +++ b/lua/pixelui/elements/cl_property_sheet.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,311 +14,300 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "m_sText", "Text") AccessorFunc(PANEL, "m_pPropertySheet", "PropertySheet") AccessorFunc(PANEL, "m_pPanel", "Panel") - -PIXEL.RegisterFont("UI.Tab", "Open Sans Bold", 16) +PIXEL.RegisterFont("UI.Tab", "Rubik", 16) function PANEL:Init() - self:SetClicky(false) - self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, -4) - self.SelectedCol = PIXEL.Colors.Primary - self.UnselectedTextCol = PIXEL.Colors.SecondaryText - self.SelectedTextCol = PIXEL.Colors.PrimaryText - - self.Color = PIXEL.CopyColor(self.BackgroundCol) - self.TextColor = PIXEL.CopyColor(self.UnselectedTextCol) + self:SetClicky(false) + self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, -4) + self.SelectedCol = PIXEL.Colors.Primary + self.UnselectedTextCol = PIXEL.Colors.SecondaryText + self.SelectedTextCol = PIXEL.Colors.PrimaryText + self.Color = PIXEL.CopyColor(self.BackgroundCol) + self.TextColor = PIXEL.CopyColor(self.UnselectedTextCol) end function PANEL:Setup(text, propertySheet, panel) - self:SetText(text) - self:SetPropertySheet(propertySheet) - self:SetPanel(panel) - - PIXEL.SetFont("UI.Tab") - self:SetWide(PIXEL.GetTextSize(text) + PIXEL.Scale(16)) + self:SetText(text) + self:SetPropertySheet(propertySheet) + self:SetPanel(panel) + PIXEL.SetFont("UI.Tab") + self:SetWide(PIXEL.GetTextSize(text) + PIXEL.Scale(16)) end function PANEL:IsActive() - return self:GetPropertySheet():GetActiveTab() == self + return self:GetPropertySheet():GetActiveTab() == self end function PANEL:DoClick() - self:GetPropertySheet():SetActiveTab(self) + self:GetPropertySheet():SetActiveTab(self) end function PANEL:GetTabHeight() - return PIXEL.Scale(24) + return PIXEL.Scale(24) end function PANEL:DragHoverClick(hoverTime) - self:DoClick() + self:DoClick() end function PANEL:DoRightClick() - if not IsValid(self:GetPropertySheet()) then return end + if not IsValid(self:GetPropertySheet()) then return end + local tabs = vgui.Create("PIXEL.Menu", self) - local tabs = vgui.Create("PIXEL.Menu", self) + for k, v in pairs(self:GetPropertySheet().Items) do + if not v or not IsValid(v.Tab) or not v.Tab:IsVisible() then continue end - for k, v in pairs(self:GetPropertySheet().Items) do - if not v or not IsValid(v.Tab) or not v.Tab:IsVisible() then continue end + tabs:AddOption(v.Tab:GetText(), function() + if not v or not IsValid(v.Tab) or not IsValid(self:GetPropertySheet()) or not IsValid(self:GetPropertySheet().tabScroller) then return end + v.Tab:DoClick() + self:GetPropertySheet().tabScroller:ScrollToChild(v.Tab) + end) + end - tabs:AddOption(v.Tab:GetText(), function() - if not v or not IsValid(v.Tab) or not IsValid(self:GetPropertySheet()) or not IsValid(self:GetPropertySheet().tabScroller) then return end - v.Tab:DoClick() - self:GetPropertySheet().tabScroller:ScrollToChild(v.Tab) - end) - end - - tabs:Open() + tabs:Open() end function PANEL:Paint(w, h) - self.Color = PIXEL.LerpColor(FrameTime() * 12, self.Color, (self:IsActive() or self:IsHovered()) and self.SelectedCol or self.BackgroundCol) - self.TextColor = PIXEL.LerpColor(FrameTime() * 12, self.TextColor, (self:IsActive() or self:IsHovered()) and self.SelectedTextCol or self.UnselectedTextCol) - - PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), 0, 0, w, h, self.Color, true, true) - PIXEL.DrawSimpleText(self:GetText(), "UI.Tab", w * .5, h * .5, self.TextColor, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) + self.Color = PIXEL.LerpColor(FrameTime() * 12, self.Color, (self:IsActive() or self:IsHovered()) and self.SelectedCol or self.BackgroundCol) + self.TextColor = PIXEL.LerpColor(FrameTime() * 12, self.TextColor, (self:IsActive() or self:IsHovered()) and self.SelectedTextCol or self.UnselectedTextCol) + PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), 0, 0, w, h, self.Color, true, true) + PIXEL.DrawSimpleText(self:GetText(), "UI.Tab", w * .5, h * .5, self.TextColor, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end vgui.Register("PIXEL.Tab", PANEL, "PIXEL.Button") - - PANEL = {} - AccessorFunc(PANEL, "m_pActiveTab", "ActiveTab") AccessorFunc(PANEL, "m_iPadding", "Padding") AccessorFunc(PANEL, "m_fFadeTime", "FadeTime") function PANEL:Init() - self.tabScroller = vgui.Create("DHorizontalScroller", self) - self.tabScroller:SetOverlap(PIXEL.Scale(5)) - self.tabScroller:Dock(TOP) - self.tabScroller:DockMargin(PIXEL.Scale(3), 0, PIXEL.Scale(3), 0) - - self:SetFadeTime(0.1) - self:SetPadding(PIXEL.Scale(8)) - - self.animFade = Derma_Anim("Fade", self, self.CrossFade) - - self.Items = {} - - self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 2) + self.tabScroller = vgui.Create("DHorizontalScroller", self) + self.tabScroller:SetOverlap(PIXEL.Scale(5)) + self.tabScroller:Dock(TOP) + self.tabScroller:DockMargin(PIXEL.Scale(3), 0, PIXEL.Scale(3), 0) + self:SetFadeTime(0.1) + self:SetPadding(PIXEL.Scale(8)) + self.animFade = Derma_Anim("Fade", self, self.CrossFade) + self.Items = {} + self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 2) end function PANEL:AddSheet(label, panel, material, noStretchX, noStretchY, tooltip) - if not IsValid(panel) then - ErrorNoHalt("PIXEL.PropertySheet:AddSheet tried to add invalid panel!") - debug.Trace() - return - end - - local sheet = {} - - sheet.Name = label - - sheet.Tab = vgui.Create("PIXEL.Tab", self) - sheet.Tab:SetTooltip(tooltip) - sheet.Tab:Setup(label, self, panel, material) - - sheet.Panel = panel - sheet.Panel.NoStretchX = noStretchX - sheet.Panel.NoStretchY = noStretchY - sheet.Panel:SetPos(self:GetPadding(), PIXEL.Scale(24) + self:GetPadding()) - sheet.Panel:SetVisible(false) - - panel:SetParent(self) - - table.insert(self.Items, sheet) - - if not self:GetActiveTab() then - self:SetActiveTab(sheet.Tab) - sheet.Panel:SetVisible(true) - end - - self.tabScroller:AddPanel(sheet.Tab) - - return sheet + if not IsValid(panel) then + ErrorNoHalt("PIXEL.PropertySheet:AddSheet tried to add invalid panel!") + debug.Trace() + + return + end + + local sheet = {} + sheet.Name = label + sheet.Tab = vgui.Create("PIXEL.Tab", self) + sheet.Tab:SetTooltip(tooltip) + sheet.Tab:Setup(label, self, panel, material) + sheet.Panel = panel + sheet.Panel.NoStretchX = noStretchX + sheet.Panel.NoStretchY = noStretchY + sheet.Panel:SetPos(self:GetPadding(), PIXEL.Scale(24) + self:GetPadding()) + sheet.Panel:SetVisible(false) + panel:SetParent(self) + table.insert(self.Items, sheet) + + if not self:GetActiveTab() then + self:SetActiveTab(sheet.Tab) + sheet.Panel:SetVisible(true) + end + + self.tabScroller:AddPanel(sheet.Tab) + + return sheet end function PANEL:SetActiveTab(active) - if not IsValid(active) or self.m_pActiveTab == active then return end - - if IsValid(self.m_pActiveTab) then - self:OnActiveTabChanged(self.m_pActiveTab, active) - - if self:GetFadeTime() > 0 then - self.animFade:Start(self:GetFadeTime(), {OldTab = self.m_pActiveTab, NewTab = active}) - else - self.m_pActiveTab:GetPanel():SetVisible(false) - end - end - - self.m_pActiveTab = active - self:InvalidateLayout() + if not IsValid(active) or self.m_pActiveTab == active then return end + + if IsValid(self.m_pActiveTab) then + self:OnActiveTabChanged(self.m_pActiveTab, active) + + if self:GetFadeTime() > 0 then + self.animFade:Start(self:GetFadeTime(), { + OldTab = self.m_pActiveTab, + NewTab = active + }) + else + self.m_pActiveTab:GetPanel():SetVisible(false) + end + end + + self.m_pActiveTab = active + self:InvalidateLayout() end -function PANEL:OnActiveTabChanged(old, new) end +function PANEL:OnActiveTabChanged(old, new) +end function PANEL:Think() - self.animFade:Run() + self.animFade:Run() end function PANEL:GetItems() - return self.Items + return self.Items end function PANEL:CrossFade(anim, delta, data) - if not data or not IsValid(data.OldTab) or not IsValid(data.NewTab) then return end - - local old = data.OldTab:GetPanel() - local new = data.NewTab:GetPanel() - - if not IsValid(old) and not IsValid(new) then return end - - if anim.Finished then - if IsValid(old) then - old:SetAlpha(255) - old:SetZPos(0) - old:SetVisible(false) - end - - if IsValid(new) then - new:SetAlpha(255) - new:SetZPos(0) - new:SetVisible(true) - end - - return - end - - if anim.Started then - if IsValid(old) then - old:SetAlpha(255) - old:SetZPos(0) - end - - if IsValid(new) then - new:SetAlpha(0) - new:SetZPos(1) - end - end - - if IsValid(old) then - old:SetVisible(true) - if not IsValid(new) then old:SetAlpha(255 * (1 - delta)) end - end - - if IsValid(new) then - new:SetVisible(true) - new:SetAlpha(255 * delta) - end + if not data or not IsValid(data.OldTab) or not IsValid(data.NewTab) then return end + local old = data.OldTab:GetPanel() + local new = data.NewTab:GetPanel() + if not IsValid(old) and not IsValid(new) then return end + + if anim.Finished then + if IsValid(old) then + old:SetAlpha(255) + old:SetZPos(0) + old:SetVisible(false) + end + + if IsValid(new) then + new:SetAlpha(255) + new:SetZPos(0) + new:SetVisible(true) + end + + return + end + + if anim.Started then + if IsValid(old) then + old:SetAlpha(255) + old:SetZPos(0) + end + + if IsValid(new) then + new:SetAlpha(0) + new:SetZPos(1) + end + end + + if IsValid(old) then + old:SetVisible(true) + + if not IsValid(new) then + old:SetAlpha(255 * (1 - delta)) + end + end + + if IsValid(new) then + new:SetVisible(true) + new:SetAlpha(255 * delta) + end end function PANEL:PerformLayout() - local activeTab = self:GetActiveTab() - local padding = self:GetPadding() - - if not IsValid(activeTab) then return end - - activeTab:InvalidateLayout(true) - - self.tabScroller:SetTall(activeTab:GetTall()) - - local activePanel = activeTab:GetPanel() - - for k, v in pairs(self.Items) do - if v.Tab:GetPanel() == activePanel then - if IsValid(v.Tab:GetPanel()) then v.Tab:GetPanel():SetVisible(true) end - v.Tab:SetZPos(100) - else - if IsValid(v.Tab:GetPanel()) then v.Tab:GetPanel():SetVisible(false) end - v.Tab:SetZPos(1) - end - end - - if IsValid(activePanel) then - if not activePanel.NoStretchX then - activePanel:SetWide(self:GetWide() - padding * 2) - else - activePanel:CenterHorizontal() - end - - if not activePanel.NoStretchY then - local _, y = activePanel:GetPos() - activePanel:SetTall(self:GetTall() - y - padding) - else - activePanel:CenterVertical() - end - - activePanel:InvalidateLayout() - end - - self.animFade:Run() + local activeTab = self:GetActiveTab() + local padding = self:GetPadding() + if not IsValid(activeTab) then return end + activeTab:InvalidateLayout(true) + self.tabScroller:SetTall(activeTab:GetTall()) + local activePanel = activeTab:GetPanel() + + for k, v in pairs(self.Items) do + if v.Tab:GetPanel() == activePanel then + if IsValid(v.Tab:GetPanel()) then + v.Tab:GetPanel():SetVisible(true) + end + + v.Tab:SetZPos(100) + else + if IsValid(v.Tab:GetPanel()) then + v.Tab:GetPanel():SetVisible(false) + end + + v.Tab:SetZPos(1) + end + end + + if IsValid(activePanel) then + if not activePanel.NoStretchX then + activePanel:SetWide(self:GetWide() - padding * 2) + else + activePanel:CenterHorizontal() + end + + if not activePanel.NoStretchY then + local _, y = activePanel:GetPos() + activePanel:SetTall(self:GetTall() - y - padding) + else + activePanel:CenterVertical() + end + + activePanel:InvalidateLayout() + end + + self.animFade:Run() end function PANEL:SizeToContentWidth() - local wide = 0 + local wide = 0 - for k, v in pairs(self.Items) do - if IsValid(v.Panel) then - v.Panel:InvalidateLayout(true) - wide = math.max(wide, v.Panel:GetWide() + self:GetPadding() * 2) - end - end + for k, v in pairs(self.Items) do + if IsValid(v.Panel) then + v.Panel:InvalidateLayout(true) + wide = math.max(wide, v.Panel:GetWide() + self:GetPadding() * 2) + end + end - self:SetWide(wide) + self:SetWide(wide) end function PANEL:SwitchToName(name) - for k, v in pairs(self.Items) do - if v.Name == name then - v.Tab:DoClick() - return true - end - end - - return false + for k, v in pairs(self.Items) do + if v.Name == name then + v.Tab:DoClick() + + return true + end + end + + return false end function PANEL:CloseTab(tab, removePanelToo) - for k, v in pairs(self.Items) do - if v.Tab ~= tab then continue end - table.remove(self.Items, k) - end + for k, v in pairs(self.Items) do + if v.Tab ~= tab then continue end + table.remove(self.Items, k) + end - for k, v in pairs(self.tabScroller.Panels) do - if v ~= tab then continue end - table.remove(self.tabScroller.Panels, k) - end + for k, v in pairs(self.tabScroller.Panels) do + if v ~= tab then continue end + table.remove(self.tabScroller.Panels, k) + end - self.tabScroller:InvalidateLayout(true) + self.tabScroller:InvalidateLayout(true) - if tab == self:GetActiveTab() then - self.m_pActiveTab = self.Items[#self.Items].Tab - end + if tab == self:GetActiveTab() then + self.m_pActiveTab = self.Items[#self.Items].Tab + end - local pnl = tab:GetPanel() - if removePanelToo then - pnl:Remove() - end + local pnl = tab:GetPanel() - tab:Remove() + if removePanelToo then + pnl:Remove() + end - self:InvalidateLayout(true) + tab:Remove() + self:InvalidateLayout(true) - return pnl + return pnl end function PANEL:Paint(w, h) - local activeTab = self:GetActiveTab() - local offset = activeTab and activeTab:GetTall() or 0 - - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, offset, w, h - offset, self.BackgroundCol) + local activeTab = self:GetActiveTab() + local offset = activeTab and activeTab:GetTall() or 0 + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, offset, w, h - offset, self.BackgroundCol) end vgui.Register("PIXEL.PropertySheet", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_slider.lua b/lua/pixelui/elements/cl_slider.lua index d5ddae0..6a725d6 100644 --- a/lua/pixelui/elements/cl_slider.lua +++ b/lua/pixelui/elements/cl_slider.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,49 +14,59 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} function PANEL:Init() self:SetClicky(false) self.Fraction = 0 - - self.Grip = vgui.Create("PIXEL.ImgurButton", self) + self.Grip = vgui.Create("PIXEL.Button", self) self.Grip:NoClipping(true) + self.Grip:SetMouseInputEnabled(true) + self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) + self.HoverCol = PIXEL.OffsetColor(PIXEL.Colors.Primary, -15) + local currentCol = self.NormalCol - self.Grip:SetImgurID("E8QbV5i") - self.Grip:SetNormalColor(PIXEL.CopyColor(PIXEL.Colors.Primary)) - self.Grip:SetHoverColor(PIXEL.OffsetColor(PIXEL.Colors.Primary, -15)) - self.Grip:SetClickColor(PIXEL.OffsetColor(PIXEL.Colors.Primary, 15)) + self.Grip.Paint = function(s, w, h) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, currentCol) + end + + self.Grip.Think = function(s) + if s:IsHovered() then + currentCol = self.HoverCol + s:SetCursor("sizewe") + else + currentCol = self.NormalCol + s:SetCursor("arrow") + end + end self.Grip.OnCursorMoved = function(pnl, x, y) if not pnl.Depressed then return end - x, y = pnl:LocalToScreen(x, y) x = self:ScreenToLocal(x, y) - self.Fraction = math.Clamp(x / self:GetWide(), 0, 1) - self:OnValueChanged(self.Fraction) self:InvalidateLayout() end - self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 20) - self.FillCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 10) + self.BackgroundCol = PIXEL.Colors.Header + self.FillCol = PIXEL.OffsetColor(PIXEL.Colors.Header, 5) end function PANEL:OnMousePressed() local w = self:GetWide() - self.Fraction = math.Clamp(self:CursorPos() / w, 0, 1) self:OnValueChanged(self.Fraction) self:InvalidateLayout() + self.Grip:RequestFocus() + print(self.Grip:HasFocus()) end -function PANEL:OnValueChanged(fraction) end +function PANEL:OnValueChanged(fraction) +end function PANEL:Paint(w, h) - local rounding = h * .5 + local rounding = PIXEL.Scale(8) PIXEL.DrawRoundedBox(rounding, 0, 0, w, h, self.BackgroundCol) PIXEL.DrawRoundedBox(rounding, 0, 0, self.Fraction * w, h, self.FillCol) end diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 20a8f33..1a60b5d 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -33,7 +33,7 @@ end function PANEL:Paint(w, h) if not self:IsEnabled() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.DisabledCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.DisabledCol) end if not self:IsEnabled() and self:GetValue() == "" then @@ -47,7 +47,7 @@ function PANEL:Paint(w, h) end local outlineThickness = PIXEL.Scale(1) - PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(2), 0, 0, w, h, self.OutlineCol, outlineThickness) + PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.OutlineCol, outlineThickness) local col = PIXEL.Colors.Transparent if self:IsEditing() then @@ -59,7 +59,7 @@ function PANEL:Paint(w, h) end self.InnerOutlineCol = PIXEL.LerpColor(FrameTime() * 8, self.InnerOutlineCol, col) - PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(2), outlineThickness, outlineThickness, w - outlineThickness * 2, h - outlineThickness * 2, self.InnerOutlineCol, PIXEL.Scale(1)) + PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(4), outlineThickness, outlineThickness, w - outlineThickness * 2, h - outlineThickness * 2, self.InnerOutlineCol, PIXEL.Scale(1)) end function PANEL:OnChange() diff --git a/lua/pixelui/elements/cl_text_entry_internal.lua b/lua/pixelui/elements/cl_text_entry_internal.lua index 1001150..dd35775 100644 --- a/lua/pixelui/elements/cl_text_entry_internal.lua +++ b/lua/pixelui/elements/cl_text_entry_internal.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,37 +14,28 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} - AccessorFunc(PANEL, "m_bAllowEnter", "EnterAllowed", FORCE_BOOL) AccessorFunc(PANEL, "m_bUpdateOnType", "UpdateOnType", FORCE_BOOL) AccessorFunc(PANEL, "m_bNumeric", "Numeric", FORCE_BOOL) AccessorFunc(PANEL, "m_bHistory", "HistoryEnabled", FORCE_BOOL) AccessorFunc(PANEL, "m_bDisableTabbing", "TabbingDisabled", FORCE_BOOL) AccessorFunc(PANEL, "m_txtPlaceholder", "PlaceholderText", FORCE_STRING) - Derma_Install_Convar_Functions(PANEL) - -PIXEL.RegisterFont("UI.TextEntry", "Open Sans SemiBold", 18) +PIXEL.RegisterFont("UI.TextEntry", "Rubik", 18) function PANEL:Init() self:SetHistoryEnabled(false) self.History = {} self.HistoryPos = 0 - self:SetPaintBorderEnabled(false) self:SetPaintBackgroundEnabled(false) - self:SetEnterAllowed(true) self:SetUpdateOnType(false) self:SetNumeric(false) self:SetAllowNonAsciiCharacters(true) - self:SetTall(PIXEL.Scale(34)) - self.m_bLoseFocusOnClickAway = true - self:SetCursor("beam") self:SetFontInternal(PIXEL.GetRealFont("UI.TextEntry")) end @@ -58,7 +48,9 @@ function PANEL:OnKeyCodeTyped(code) self:OnKeyCode(code) if code == KEY_ENTER and not self:IsMultiline() and self:GetEnterAllowed() then - if IsValid(self.Menu) then self.Menu:Remove() end + if IsValid(self.Menu) then + self.Menu:Remove() + end self:FocusNext() self:OnEnter() @@ -82,7 +74,9 @@ function PANEL:OnKeyCode(code) local parent = self:GetParent() if not parent then return end - if parent.OnKeyCode then parent:OnKeyCode() end + if parent.OnKeyCode then + parent:OnKeyCode() + end end function PANEL:UpdateFromHistory() @@ -98,6 +92,7 @@ function PANEL:UpdateFromHistory() end local text = self.History[pos] + if not text then text = "" end @@ -122,14 +117,15 @@ function PANEL:UpdateFromMenu() end local item = self.Menu:GetChild(pos) + if not item then self:SetText("") self.HistoryPos = pos + return end self.Menu:HighlightItem(item) - local txt = item:GetText() self:SetText(txt) self:SetCaretPos(txt:len()) @@ -163,7 +159,9 @@ function PANEL:OnChange() local parent = self:GetParent() if not parent then return end - if parent.OnChange then parent:OnChange() end + if parent.OnChange then + parent:OnChange() + end end function PANEL:OpenAutoComplete(tab) @@ -193,11 +191,12 @@ end function PANEL:OnEnter() self:UpdateConvarValue() self:OnValueChange(self:GetText()) - local parent = self:GetParent() if not parent then return end - if parent.OnEnter then parent:OnEnter() end + if parent.OnEnter then + parent:OnEnter() + end end function PANEL:UpdateConvarValue() @@ -210,7 +209,6 @@ end function PANEL:SetValue(value) if self:IsEditing() then return end - self:SetText(value) self:OnValueChange(value) self:SetCaretPos(self:GetCaretPos()) @@ -220,10 +218,13 @@ function PANEL:OnValueChange(value) local parent = self:GetParent() if not parent then return end - if parent.OnValueChange then parent:OnValueChange(value) end + if parent.OnValueChange then + parent:OnValueChange(value) + end end local numericChars = "1234567890.-" + function PANEL:CheckNumeric(value) if not self:GetNumeric() then return false end if not string.find(numericChars, value, 1, true) then return true end @@ -233,11 +234,12 @@ end function PANEL:AllowInput(value) if self:CheckNumeric(value) then return true end - local parent = self:GetParent() if not parent then return end - if parent.AllowInput then parent:AllowInput() end + if parent.AllowInput then + parent:AllowInput() + end end function PANEL:SetEditable(enabled) @@ -247,21 +249,23 @@ end function PANEL:OnGetFocus() hook.Run("OnTextEntryGetFocus", self) - local parent = self:GetParent() if not parent then return end - if parent.OnGetFocus then parent:OnGetFocus() end + if parent.OnGetFocus then + parent:OnGetFocus() + end end function PANEL:OnLoseFocus() self:UpdateConvarValue() hook.Call("OnTextEntryLoseFocus", nil, self) - local parent = self:GetParent() if not parent then return end - if parent.OnLoseFocus then parent:OnLoseFocus() end + if parent.OnLoseFocus then + parent:OnLoseFocus() + end end function PANEL:OnMousePressed(mcode) @@ -270,7 +274,6 @@ end function PANEL:AddHistory(txt) if not txt or txt == "" then return end - table.RemoveByValue(self.History, txt) table.insert(self.History, txt) end @@ -279,7 +282,9 @@ function PANEL:GetAutoComplete(txt) local parent = self:GetParent() if not parent then return end - if parent.GetAutoComplete then parent:GetAutoComplete() end + if parent.GetAutoComplete then + parent:GetAutoComplete() + end end function PANEL:GetInt() diff --git a/lua/pixelui/menus/test/pages/cl_navigation.lua b/lua/pixelui/menus/test/pages/cl_navigation.lua index c3b1aa9..085ef19 100644 --- a/lua/pixelui/menus/test/pages/cl_navigation.lua +++ b/lua/pixelui/menus/test/pages/cl_navigation.lua @@ -6,16 +6,29 @@ function PANEL:Init() self.Navbar = vgui.Create("PIXEL.Navbar", self) self.Navbar:Dock(TOP) self.Navbar:SetTall(sc(50)) - self.Navbar:AddItem("test1", "Test 1", function() notification.AddLegacy("Clicked 1!", NOTIFY_GENERIC, 5) end, 1, PIXEL.Colors.Gold) - self.Navbar:AddItem("test2", "Test 2", function() notification.AddLegacy("Clicked 2!", NOTIFY_GENERIC, 5) end, 2, PIXEL.Colors.Diamond) - self.Navbar:AddItem("test3", "Test 3", function() notification.AddLegacy("Clicked 3!", NOTIFY_GENERIC, 5) end, 3, PIXEL.Colors.Silver) - self.Navbar:AddItem("test4", "Test 4", function() notification.AddLegacy("Clicked 4!", NOTIFY_GENERIC, 5) end, 4, PIXEL.Colors.Bronze) - self.Navbar:AddItem("test5", "Test 5", function() notification.AddLegacy("Clicked 5!", NOTIFY_GENERIC, 5) end, 5, PIXEL.Colors.Primary) + self.Navbar:AddItem("test1", "Test 1", function() + notification.AddLegacy("Clicked 1!", NOTIFY_GENERIC, 5) + end, 1, PIXEL.Colors.Gold) + self.Navbar:AddItem("test2", "Test 2", function() + notification.AddLegacy("Clicked 2!", NOTIFY_GENERIC, 5) + end, 2, PIXEL.Colors.Diamond) + + self.Navbar:AddItem("test3", "Test 3", function() + notification.AddLegacy("Clicked 3!", NOTIFY_GENERIC, 5) + end, 3, PIXEL.Colors.Silver) + + self.Navbar:AddItem("test4", "Test 4", function() + notification.AddLegacy("Clicked 4!", NOTIFY_GENERIC, 5) + end, 4, PIXEL.Colors.Bronze) + + self.Navbar:AddItem("test5", "Test 5", function() + notification.AddLegacy("Clicked 5!", NOTIFY_GENERIC, 5) + end, 5, PIXEL.Colors.Primary) end -function PANEL:PaintMore(w,h) +function PANEL:PaintMore(w, h) end vgui.Register("PIXEL.Test.Navigation", PANEL) \ No newline at end of file From 96c2395940936494653b1bc228ca49bc6102c4c3 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 28 Apr 2023 16:01:50 +0100 Subject: [PATCH 056/155] feat: :GetTextValid function --- lua/pixelui/elements/cl_validated_text_entry.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lua/pixelui/elements/cl_validated_text_entry.lua b/lua/pixelui/elements/cl_validated_text_entry.lua index ed7277f..4ccefaf 100644 --- a/lua/pixelui/elements/cl_validated_text_entry.lua +++ b/lua/pixelui/elements/cl_validated_text_entry.lua @@ -38,11 +38,13 @@ function PANEL:Init() if valid then self.Message:SetText(message or "") self.Message:SetTextColor(PIXEL.Colors.Positive) + self.TextValid = true s.OverrideCol = PIXEL.Colors.Positive else self.Message:SetText(message or "") self.Message:SetTextColor(PIXEL.Colors.Negative) + self.TextValid = false s.OverrideCol = PIXEL.Colors.Negative end @@ -57,6 +59,10 @@ function PANEL:IsTextValid(text) return false, "This is invalid text lol" end +function PANEL:GetTextValid() + return self.TextValid or true +end + function PANEL:OnValidate(valid, message) end function PANEL:PerformLayout(w, h) From 8ddbfcf113b54a0226f8aeb1318e3d4dc591b084 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 28 Apr 2023 16:02:41 +0100 Subject: [PATCH 057/155] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Frame=20header=20?= =?UTF-8?q?icons=20being=20in=20wrong=20position?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/core/themes/sh_themes.lua | 2 +- lua/pixelui/elements/cl_frame.lua | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lua/pixelui/core/themes/sh_themes.lua b/lua/pixelui/core/themes/sh_themes.lua index fe28098..bd03b73 100644 --- a/lua/pixelui/core/themes/sh_themes.lua +++ b/lua/pixelui/core/themes/sh_themes.lua @@ -1,7 +1,7 @@ PIXEL.Colors = { Background = Color(31, 31, 31), Header = Color(40, 41, 42), - SecondaryHeader = Color(45, 47, 49), + SecondaryHeader = Color(35, 37, 39), Scroller = Color(61, 61, 61), Outline = Color(55, 56, 57), -- diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 4e26385..a0e43b2 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -270,8 +270,8 @@ end function PANEL:PerformLayout(w, h) self.HeaderH = PIXEL.Scale(30) - local btnPad = PIXEL.Scale(12) - local btnSpacing = PIXEL.Scale(12) + local btnPad = PIXEL.Scale(6) + local btnSpacing = PIXEL.Scale(6) if IsValid(self.CloseButton) then local btnSize = self.HeaderH @@ -281,9 +281,9 @@ function PANEL:PerformLayout(w, h) end for _, btn in ipairs(self.ExtraButtons) do - local btnSize = self.HeaderH * btn.HeaderIconSize + local btnSize = self.HeaderH * (.6 or btn.HeaderIconSize) btn:SetSize(btnSize, btnSize) - btn:SetPos(w - btnSize - btnPad, (self.HeaderH - btnSize) / 2) + btn:SetPos(w - btnSize - btnPad, (self.HeaderH / 2) - (btnSize / 2)) btnPad = btnPad + btnSize + btnSpacing end From 772e90bcdff83778d762796f13aa07b7c17f2724 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 29 Apr 2023 22:56:59 +0100 Subject: [PATCH 058/155] =?UTF-8?q?=E2=9C=A8=20feat:=20Step=20Counter=20el?= =?UTF-8?q?ement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_step_counter.lua | 94 ++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 lua/pixelui/elements/cl_step_counter.lua diff --git a/lua/pixelui/elements/cl_step_counter.lua b/lua/pixelui/elements/cl_step_counter.lua new file mode 100644 index 0000000..1bb9558 --- /dev/null +++ b/lua/pixelui/elements/cl_step_counter.lua @@ -0,0 +1,94 @@ +local PANEL = {} + +PIXEL.RegisterFont("StepCounterStep", "Rubik", 19, 700) + +AccessorFunc(PANEL, "Step", "Step", FORCE_NUMBER) +AccessorFunc(PANEL, "Enabled", "Enabled", FORCE_BOOL) + +function PANEL:Init() + self.BackgroundCol = PIXEL.Colors.Header + self.EnabledCol = PIXEL.Colors.Primary + self.TextCol = PIXEL.Colors.SecondaryText +end + +function PANEL:Paint(w, h) + local backgroundCol = self.BackgroundCol + if self:GetEnabled() then + backgroundCol = self.EnabledCol + end + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, backgroundCol) + PIXEL.DrawSimpleText(self:GetStep(), "StepCounterStep", w / 2, h / 2, self.TextCol, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) +end + +vgui.Register("PIXEL.StepCounterStep", PANEL, "EditablePanel") + +-- + +PANEL = {} + +PIXEL.RegisterFont("StepCounterTitle", "Rubik", 24, 700) + + +AccessorFunc(PANEL, "StepCount", "StepCount", FORCE_NUMBER) +AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) + +function PANEL:SetStepCount(count) + self.StepCount = count + for i = 1, self:GetStepCount() do + self.Steps[i] = vgui.Create("PIXEL.StepCounterStep", self) + self.Steps[i]:SetStep(i) + if i <= 3 then + self.Steps[i]:SetEnabled(true) + end + end + + self:InvalidateLayout(true) +end + +function PANEL:Init() + self:SetTitle("PIXEL Step Counter") + + self.Steps = {} +end + +function PANEL:Paint(w, h) + for k, v in ipairs(self.Steps) do + local nextStep = self.Steps[k + 1] + if not nextStep then continue end + local startX = v:GetX() + v:GetWide()| + local width = endX - startX + local tall = PIXEL.Scale(4) + local yPos = v:GetY() + (v:GetTall() / 2) - (tall / 2) + local backgroundCol = PIXEL.Colors.Header + if nextStep:GetEnabled() then + backgroundCol = PIXEL.Colors.Primary + end + PIXEL.DrawRoundedBox(0, startX, yPos, width, tall, backgroundCol) + end + + if self:GetTitle() then + PIXEL.DrawSimpleText(self:GetTitle(), "StepCounterTitle", w / 2, 0, PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP) + end +end + +function PANEL:PerformLayout(w, h) + local steps = self:GetStepCount() + local stepSize = PIXEL.Scale(38) + local allStepWidth = stepSize * steps + local space = (w - allStepWidth) / (steps - 1) + for k, v in ipairs(self.Steps) do + v:SetSize(stepSize, stepSize) + v:SetX((k - 1) * (stepSize + space)) + if self:GetTitle() then + v:SetY(PIXEL.Scale(35)) + end + end +end + +vgui.Register("PIXEL.StepCounter", PANEL, "EditablePanel") + +if IsValid(PIXEL.TestFrame) then + PIXEL.TestFrame:Remove() +end + +PIXEL.TestFrame = vgui.Create("PIXEL.Test.Main") \ No newline at end of file From 40460ef2cd8324931b8efec3300a55f96a42b271 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 29 Apr 2023 22:57:30 +0100 Subject: [PATCH 059/155] =?UTF-8?q?=E2=9C=A8=20feat:=20GetTextValid=20func?= =?UTF-8?q?tion=20on=20ValidatedTextEntry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../elements/cl_validated_text_entry.lua | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/lua/pixelui/elements/cl_validated_text_entry.lua b/lua/pixelui/elements/cl_validated_text_entry.lua index ed7277f..5073950 100644 --- a/lua/pixelui/elements/cl_validated_text_entry.lua +++ b/lua/pixelui/elements/cl_validated_text_entry.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,7 +14,6 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local PANEL = {} function PANEL:Init() @@ -25,54 +23,66 @@ function PANEL:Init() self.TextEntry.OnChange = function(s) local text = s:GetValue() + if text == "" then self.Message:SetText("") s.OverrideCol = nil + return end local valid, message = self:IsTextValid(text) - self:OnValidate(valid, message) if valid then self.Message:SetText(message or "") self.Message:SetTextColor(PIXEL.Colors.Positive) - + self.TextValid = true s.OverrideCol = PIXEL.Colors.Positive else self.Message:SetText(message or "") self.Message:SetTextColor(PIXEL.Colors.Negative) - + self.TextValid = false s.OverrideCol = PIXEL.Colors.Negative end end end function PANEL:IsTextValid(text) - if text == "test" then - return true - end + if text == "test" then return true end return false, "This is invalid text lol" end -function PANEL:OnValidate(valid, message) end +function PANEL:GetTextValid() + return self.TextValid +end + +function PANEL:OnValidate(valid, message) +end function PANEL:PerformLayout(w, h) self.TextEntry:SetTall(PIXEL.Scale(34)) self.TextEntry:Dock(TOP) - self.Message:Dock(TOP) self.Message:DockMargin(PIXEL.Scale(4), PIXEL.Scale(5), 0, 0) - self:SizeToChildren(false, true) end -function PANEL:SetValue(text) self.TextEntry:SetValue(text) end -function PANEL:GetValue() return self.TextEntry:GetValue() end +function PANEL:SetValue(text) + self.TextEntry:SetValue(text) +end -function PANEL:SetPlaceholderText(text) self.TextEntry:SetPlaceholderText(text) end -function PANEL:GetPlaceholderText() return self.TextEntry:GetPlaceholderText() end +function PANEL:GetValue() + return self.TextEntry:GetValue() +end + +function PANEL:SetPlaceholderText(text) + self.TextEntry:SetPlaceholderText(text) +end + +function PANEL:GetPlaceholderText() + return self.TextEntry:GetPlaceholderText() +end vgui.Register("PIXEL.ValidatedTextEntry", PANEL, "Panel") \ No newline at end of file From 208131784dd378879dd1de6be472891b3fa84de4 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 29 Apr 2023 23:36:53 +0100 Subject: [PATCH 060/155] =?UTF-8?q?=F0=9F=90=9B=20fix:=20TextEntryInternal?= =?UTF-8?q?=20not=20passing=20value=20to=20parent=20AllowInput?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_text_entry.lua | 4 ++++ lua/pixelui/elements/cl_text_entry_internal.lua | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 1a60b5d..7942298 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -26,11 +26,15 @@ function PANEL:Init() end function PANEL:PerformLayout(w, h) + self:LayoutContent(w, h) self.TextEntry:Dock(FILL) local xPad, yPad = PIXEL.Scale(4), PIXEL.Scale(8) self:DockPadding(xPad, yPad, xPad, yPad) end +function PANEL:LayoutContent(w, h) +end + function PANEL:Paint(w, h) if not self:IsEnabled() then PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.DisabledCol) diff --git a/lua/pixelui/elements/cl_text_entry_internal.lua b/lua/pixelui/elements/cl_text_entry_internal.lua index dd35775..98d0a17 100644 --- a/lua/pixelui/elements/cl_text_entry_internal.lua +++ b/lua/pixelui/elements/cl_text_entry_internal.lua @@ -238,7 +238,7 @@ function PANEL:AllowInput(value) if not parent then return end if parent.AllowInput then - parent:AllowInput() + parent:AllowInput(value) end end From c31d9520ef9a7d5f130c8c81916280fd80f9e1b9 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 30 Apr 2023 13:50:57 +0100 Subject: [PATCH 061/155] =?UTF-8?q?=E2=9C=A8=20feat:=20PIXEL.NumberWang?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_number_wang.lua | 91 +++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 lua/pixelui/elements/cl_number_wang.lua diff --git a/lua/pixelui/elements/cl_number_wang.lua b/lua/pixelui/elements/cl_number_wang.lua new file mode 100644 index 0000000..5139f98 --- /dev/null +++ b/lua/pixelui/elements/cl_number_wang.lua @@ -0,0 +1,91 @@ +local PANEL = {} + +AccessorFunc(PANEL, "HideWang", "HideWang", FORCE_BOOL) +AccessorFunc(PANEL, "Interval", "Interval", FORCE_NUMBER) +AccessorFunc(PANEL, "Min", "Min", FORCE_NUMBER) +AccessorFunc(PANEL, "Max", "Max", FORCE_NUMBER) + +function PANEL:Init() + self:SetHideWang(false) + self:SetNumeric(true) + self:SetInterval(1) + self:SetValue(1) + self:SetMin(1) + self:SetMax(100) + self:SetHistoryEnabled(false) + self:SetUpdateOnType(true) + self.UpButton = self:Add("PIXEL.ImgurButton") + self.UpButton:SetImgurID("RD7dJ7x") + self.UpButton.DoClick = function(s) + local current = tonumber(self:GetValue()) + if not current then current = self:GetMin() or 0 end + local interval = self:GetInterval() or 1 + local new = current + interval + if (new > self:GetMax()) or (new < self:GetMin()) then + new = current + end + self:SetValue(new) + end + + self.DownButton = self:Add("PIXEL.ImgurButton") + self.DownButton:SetImgurID("Y9Dqinn") + self.DownButton.DoClick = function(s) + local current = tonumber(self:GetValue()) + if not current then current = self:GetMin() or 0 end + local interval = self:GetInterval() or 1 + local new = current - interval + if (new > self:GetMax()) or (new < self:GetMin()) then + new = current + end + self:SetValue(new) + end + + function self:AllowInput() + local value = self:GetValue() + value = tonumber(value) + if not value then + value = self:GetMin() or 0 + end + if (value > self:GetMax()) then + self.TextEntry:SetText(self:GetMax()) + return true + end + + if (value < self:GetMin()) then + self.TextEntry:SetText(self:GetMin()) + return true + end + return false + end + + function self:OnValueChange() + local value = self:GetValue() + if not value then value = self:GetMin() or 0 end + value = tonumber(value) + if (value > self:GetMax()) then + self.TextEntry:SetText(self:GetMax()) + elseif (value < self:GetMin()) then + self.TextEntry:SetText(self:GetMin()) + end + end +end + +function PANEL:LayoutContent(w, h) + if self:GetHideWang() then + self.UpButton:SetVisible(false) + self.DownButton:SetVisible(false) + end + local height = (h / 4) + self.UpButton:SetSize(height, height) + self.UpButton:SetPos(w - height - PIXEL.Scale(10), (h / 2) - height) + + self.DownButton:SetSize(height, height) + self.DownButton:SetPos(w - height - PIXEL.Scale(10), h - self.UpButton:GetY() - height) + + local zPos = self:GetZPos() + self.UpButton:SetZPos(zPos + 1) + self.DownButton:SetZPos(zPos + 1) +end + + +vgui.Register("PIXEL.NumberWang", PANEL, "PIXEL.TextEntry") \ No newline at end of file From 76a853f040729c626c3f5efb3b2eef4d7cdbadd3 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 30 Apr 2023 22:14:48 +0100 Subject: [PATCH 062/155] fix: The corners shenanigans --- lua/pixelui/elements/cl_button.lua | 8 ++++---- lua/pixelui/elements/cl_category.lua | 2 +- lua/pixelui/elements/cl_check_box.lua | 4 ++-- lua/pixelui/elements/cl_frame.lua | 6 +++--- lua/pixelui/elements/cl_menu.lua | 2 +- lua/pixelui/elements/cl_menu_option.lua | 2 +- lua/pixelui/elements/cl_mini_sidebar.lua | 2 +- lua/pixelui/elements/cl_navbar.lua | 4 ++-- lua/pixelui/elements/cl_sidebar.lua | 2 +- lua/pixelui/elements/cl_slider.lua | 2 +- lua/pixelui/elements/cl_step_counter.lua | 13 ++++--------- lua/pixelui/elements/cl_text_entry.lua | 2 +- .../elements/cl_text_entry_internal.lua | 2 +- lua/pixelui/menus/test/cl_menu.lua | 5 ----- lua/pixelui/menus/test/pages/cl_other.lua | 18 ++++++++---------- 15 files changed, 31 insertions(+), 43 deletions(-) diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index 22613e1..fa052e7 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -141,13 +141,13 @@ function PANEL:Paint(w, h) end if not self:GetClicky() then - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol) else if self.ClickyMove then - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) else - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.ClickyCol) - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h - self.ClickyScale, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.ClickyCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h - self.ClickyScale, self.BackgroundCol) end end diff --git a/lua/pixelui/elements/cl_category.lua b/lua/pixelui/elements/cl_category.lua index 409d99f..5e0b459 100644 --- a/lua/pixelui/elements/cl_category.lua +++ b/lua/pixelui/elements/cl_category.lua @@ -31,7 +31,7 @@ end local lerp = Lerp function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol) PIXEL.DrawSimpleText(self.Title, "UI.CategoryHeader", PIXEL.Scale(10), h / 2, PIXEL.Colors.PrimaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) self.ArrowRotation = lerp(FrameTime() * 10, self.ArrowRotation, self:GetParent():GetExpanded() and 0 or 90) local arrowSize = h * .45 diff --git a/lua/pixelui/elements/cl_check_box.lua b/lua/pixelui/elements/cl_check_box.lua index e6c4814..7014487 100644 --- a/lua/pixelui/elements/cl_check_box.lua +++ b/lua/pixelui/elements/cl_check_box.lua @@ -31,7 +31,7 @@ end function PANEL:PaintBackground(w, h) if not self:IsEnabled() then - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, PIXEL.Colors.Disabled) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, PIXEL.Colors.Disabled) self:PaintExtra(w, h) return @@ -45,7 +45,7 @@ function PANEL:PaintBackground(w, h) local animTime = FrameTime() * 12 self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, bgCol) - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol) end vgui.Register("PIXEL.Checkbox", PANEL, "PIXEL.ImgurButton") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index a0e43b2..1921a2e 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -36,7 +36,7 @@ function PANEL:Init() self.CloseButton:SetClickColor(PIXEL.Colors.Negative) self.CloseButton:SetDisabledColor(PIXEL.Colors.DisabledText) self.CloseButton:SetFrameEnabled(true) - self.CloseButton:SetRounded(PIXEL.Scale(8)) + self.CloseButton:SetRounded(8) self.CloseButton.DoClick = function(s) self:Close() @@ -316,9 +316,9 @@ function PANEL:PaintMore(w, h) end function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, PIXEL.Colors.Header) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, PIXEL.Colors.Header) local contentX, contentY = self.SideBar and PIXEL.Scale(200) or self.ContentPadding, self.HeaderH + self.ContentPadding - PIXEL.DrawRoundedBoxEx(PIXEL.Scale(8), contentX, contentY, w - contentX - self.ContentPadding, h - contentY - self.ContentPadding, PIXEL.Colors.Background, true, true, true, true) + PIXEL.DrawRoundedBoxEx(8, contentX, contentY, w - contentX - self.ContentPadding, h - contentY - self.ContentPadding, PIXEL.Colors.Background, true, true, true, true) self:PaintHeader(0, 0, w, self.HeaderH) self:PaintMore(w, h) end diff --git a/lua/pixelui/elements/cl_menu.lua b/lua/pixelui/elements/cl_menu.lua index ae65742..37e77ef 100644 --- a/lua/pixelui/elements/cl_menu.lua +++ b/lua/pixelui/elements/cl_menu.lua @@ -223,7 +223,7 @@ function PANEL:Open(x, y, skipanimation, ownerpanel) end function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, self.DrawTall, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, self.DrawTall, self.BackgroundCol) end function PANEL:OptionSelectedInternal(option) diff --git a/lua/pixelui/elements/cl_menu_option.lua b/lua/pixelui/elements/cl_menu_option.lua index 3e1d0cd..3b09240 100644 --- a/lua/pixelui/elements/cl_menu_option.lua +++ b/lua/pixelui/elements/cl_menu_option.lua @@ -75,7 +75,7 @@ end function PANEL:Paint(w, h) if self.Hidden then return end self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, self:IsHovered() and self.HoverCol or self.NormalCol) - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol) PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), PIXEL.Scale(14), h / 2, PIXEL.Colors.PrimaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) if not self.SubMenu then return end local dropBtnSize = PIXEL.Scale(8) diff --git a/lua/pixelui/elements/cl_mini_sidebar.lua b/lua/pixelui/elements/cl_mini_sidebar.lua index d37f5a4..78ed208 100644 --- a/lua/pixelui/elements/cl_mini_sidebar.lua +++ b/lua/pixelui/elements/cl_mini_sidebar.lua @@ -53,7 +53,7 @@ function PANEL:Paint(w, h) self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) if self:GetDrawOutline() then - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverLineCol, PIXEL.Scale(1)) end diff --git a/lua/pixelui/elements/cl_navbar.lua b/lua/pixelui/elements/cl_navbar.lua index cf8e5f5..f34ade5 100644 --- a/lua/pixelui/elements/cl_navbar.lua +++ b/lua/pixelui/elements/cl_navbar.lua @@ -57,7 +57,7 @@ function PANEL:Paint(w, h) end local boxW, boxH = w - PIXEL.Scale(16), h - PIXEL.Scale(16) - PIXEL.DrawRoundedBox(PIXEL.Scale(8), PIXEL.Scale(8), PIXEL.Scale(8), boxW, boxH, backgroundCol) + PIXEL.DrawRoundedBox(8, PIXEL.Scale(8), PIXEL.Scale(8), boxW, boxH, backgroundCol) PIXEL.DrawSimpleText(self:GetName(), "UI.NavbarItem", w / 2, h / 2, self.TextCol, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end @@ -123,7 +123,7 @@ function PANEL:PerformLayout(w, h) end function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol) if not self.SelectedItem then self.SelectionX = Lerp(FrameTime() * 10, self.SelectionX, 0) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 3b49cf4..77573a9 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -34,7 +34,7 @@ function PANEL:Paint(w, h) self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) if self:GetDrawOutline() then - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, backgroundCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, backgroundCol, PIXEL.Scale(1)) end local imgurID = self:GetImgurID() diff --git a/lua/pixelui/elements/cl_slider.lua b/lua/pixelui/elements/cl_slider.lua index 6a725d6..bca7876 100644 --- a/lua/pixelui/elements/cl_slider.lua +++ b/lua/pixelui/elements/cl_slider.lua @@ -27,7 +27,7 @@ function PANEL:Init() local currentCol = self.NormalCol self.Grip.Paint = function(s, w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, currentCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, currentCol) end self.Grip.Think = function(s) diff --git a/lua/pixelui/elements/cl_step_counter.lua b/lua/pixelui/elements/cl_step_counter.lua index 1bb9558..2e1945c 100644 --- a/lua/pixelui/elements/cl_step_counter.lua +++ b/lua/pixelui/elements/cl_step_counter.lua @@ -16,7 +16,7 @@ function PANEL:Paint(w, h) if self:GetEnabled() then backgroundCol = self.EnabledCol end - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, backgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, backgroundCol) PIXEL.DrawSimpleText(self:GetStep(), "StepCounterStep", w / 2, h / 2, self.TextCol, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end @@ -55,7 +55,8 @@ function PANEL:Paint(w, h) for k, v in ipairs(self.Steps) do local nextStep = self.Steps[k + 1] if not nextStep then continue end - local startX = v:GetX() + v:GetWide()| + local startX = v:GetX() + v:GetWide() + local endX = nextStep:GetX() local width = endX - startX local tall = PIXEL.Scale(4) local yPos = v:GetY() + (v:GetTall() / 2) - (tall / 2) @@ -85,10 +86,4 @@ function PANEL:PerformLayout(w, h) end end -vgui.Register("PIXEL.StepCounter", PANEL, "EditablePanel") - -if IsValid(PIXEL.TestFrame) then - PIXEL.TestFrame:Remove() -end - -PIXEL.TestFrame = vgui.Create("PIXEL.Test.Main") \ No newline at end of file +vgui.Register("PIXEL.StepCounter", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 7942298..4c0200c 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -37,7 +37,7 @@ end function PANEL:Paint(w, h) if not self:IsEnabled() then - PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.DisabledCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.DisabledCol) end if not self:IsEnabled() and self:GetValue() == "" then diff --git a/lua/pixelui/elements/cl_text_entry_internal.lua b/lua/pixelui/elements/cl_text_entry_internal.lua index 98d0a17..083ab1c 100644 --- a/lua/pixelui/elements/cl_text_entry_internal.lua +++ b/lua/pixelui/elements/cl_text_entry_internal.lua @@ -238,7 +238,7 @@ function PANEL:AllowInput(value) if not parent then return end if parent.AllowInput then - parent:AllowInput(value) + if parent:AllowInput(value) then return true end end end diff --git a/lua/pixelui/menus/test/cl_menu.lua b/lua/pixelui/menus/test/cl_menu.lua index 0c2e3f2..efeed27 100644 --- a/lua/pixelui/menus/test/cl_menu.lua +++ b/lua/pixelui/menus/test/cl_menu.lua @@ -85,8 +85,3 @@ vgui.Register("PIXEL.Test.Main", PANEL, "PIXEL.Frame") concommand.Add("pixel_test", function() PIXEL.TestFrame = vgui.Create("PIXEL.Test.Main") end) - -if IsValid(PIXEL.TestFrame) then - PIXEL.TestFrame:Remove() - PIXEL.TestFrame = vgui.Create("PIXEL.Test.Main") -end \ No newline at end of file diff --git a/lua/pixelui/menus/test/pages/cl_other.lua b/lua/pixelui/menus/test/pages/cl_other.lua index 1553641..a7a39e0 100644 --- a/lua/pixelui/menus/test/pages/cl_other.lua +++ b/lua/pixelui/menus/test/pages/cl_other.lua @@ -1,7 +1,6 @@ PIXEL = PIXEL or {} local sc = PIXEL.Scale local PANEL = {} - PIXEL.GenerateFont(25) function PANEL:Init() @@ -9,17 +8,14 @@ function PANEL:Init() self.Category:Dock(TOP) self.Category:DockMargin(sc(10), sc(10), sc(10), sc(10)) self.Category:SetTitle("Categorys!") - self.Slider = vgui.Create("PIXEL.Slider", self) self.Slider:Dock(TOP) self.Slider:DockMargin(sc(50), sc(10), sc(50), sc(10)) - self.LabelledCheckbox = vgui.Create("PIXEL.LabelledCheckbox", self) self.LabelledCheckbox:Dock(TOP) self.LabelledCheckbox:DockMargin(sc(50), sc(10), sc(50), sc(10)) self.LabelledCheckbox:SetText("Labelled Checkbox!") self.LabelledCheckbox:SetFont("PIXEL.Font.Size25") - self.ComboBox = vgui.Create("PIXEL.ComboBox", self) self.ComboBox:Dock(TOP) self.ComboBox:DockMargin(sc(50), sc(10), sc(50), sc(10)) @@ -29,14 +25,16 @@ function PANEL:Init() self.ComboBox:AddChoice("Choice 3", "Choice 3", "Choice 3") self.ComboBox:AddChoice("Choice 4", "Choice 4", "Choice 4") self.ComboBox:AddChoice("Choice 5", "Choice 5", "Choice 5") - - self.ColorPicker = vgui.Create("PIXEL.ColorPicker", self) - self.ColorPicker:Dock(FILL) - self.ColorPicker:DockMargin(sc(50), sc(10), sc(50), sc(10)) + -- self.ColorPicker = vgui.Create("PIXEL.NumberWang", self) + -- self.ColorPicker:Dock(TOP) + -- self.ColorPicker:SetTall(PIXEL.Scale(40)) + self.StepCounter = vgui.Create("PIXEL.StepCounter", self) + self.StepCounter:Dock(FILL) + self.StepCounter:DockMargin(sc(50), sc(10), sc(50), sc(10)) + self.StepCounter:SetStepCount(8) end -function PANEL:PaintMore(w,h) - +function PANEL:PaintMore(w, h) end vgui.Register("PIXEL.Test.Other", PANEL) \ No newline at end of file From e078e475ad3c41e938648c6874cc0fa69c223e63 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:50:55 +0100 Subject: [PATCH 063/155] =?UTF-8?q?=F0=9F=9A=9A=20Rename=20NumberWang=20to?= =?UTF-8?q?=20NumberEntry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{cl_number_wang.lua => cl_number_entry.lua} | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) rename lua/pixelui/elements/{cl_number_wang.lua => cl_number_entry.lua} (90%) diff --git a/lua/pixelui/elements/cl_number_wang.lua b/lua/pixelui/elements/cl_number_entry.lua similarity index 90% rename from lua/pixelui/elements/cl_number_wang.lua rename to lua/pixelui/elements/cl_number_entry.lua index 5139f98..bfdb845 100644 --- a/lua/pixelui/elements/cl_number_wang.lua +++ b/lua/pixelui/elements/cl_number_entry.lua @@ -60,13 +60,18 @@ function PANEL:Init() function self:OnValueChange() local value = self:GetValue() - if not value then value = self:GetMin() or 0 end value = tonumber(value) + if not value then value = self:GetMin() or 0 end + if (value > self:GetMax()) then self.TextEntry:SetText(self:GetMax()) elseif (value < self:GetMin()) then self.TextEntry:SetText(self:GetMin()) end + self:OnValueChanged(value) + end + + function self:OnValueChanged() end end @@ -77,10 +82,10 @@ function PANEL:LayoutContent(w, h) end local height = (h / 4) self.UpButton:SetSize(height, height) - self.UpButton:SetPos(w - height - PIXEL.Scale(10), (h / 2) - height) + self.UpButton:SetPos(w - height - (h / 4), (h / 2) - height) self.DownButton:SetSize(height, height) - self.DownButton:SetPos(w - height - PIXEL.Scale(10), h - self.UpButton:GetY() - height) + self.DownButton:SetPos(w - height - (h / 4), h - self.UpButton:GetY() - height) local zPos = self:GetZPos() self.UpButton:SetZPos(zPos + 1) @@ -88,4 +93,4 @@ function PANEL:LayoutContent(w, h) end -vgui.Register("PIXEL.NumberWang", PANEL, "PIXEL.TextEntry") \ No newline at end of file +vgui.Register("PIXEL.NumberEntry", PANEL, "PIXEL.TextEntry") \ No newline at end of file From ff809f1b64a35cd1e672fb956afafb6e115c984d Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:51:26 +0100 Subject: [PATCH 064/155] =?UTF-8?q?=E2=9E=95=20Add=20gradients=20library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/libraries/cl_gradient.lua | 100 ++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 lua/pixelui/libraries/cl_gradient.lua diff --git a/lua/pixelui/libraries/cl_gradient.lua b/lua/pixelui/libraries/cl_gradient.lua new file mode 100644 index 0000000..55a8095 --- /dev/null +++ b/lua/pixelui/libraries/cl_gradient.lua @@ -0,0 +1,100 @@ +-- https://github.com/Bo98/garrysmod-util/blob/master/lua/autorun/client/gradient.lua + +-- Gradient helper functions +-- By Bo Anderson +-- Licensed under Mozilla Public License v2.0 + +--[[ +Test scripts: + lua_run_cl hook.Add("HUDPaint", "test", function() PIXEL.DrawSimpleLinearGradient(100, 200, 100, 100, Color(255, 0, 0), Color(255, 255, 0), false) PIXEL.DrawSimpleLinearGradient(250, 200, 100, 100, Color(0, 255, 0), Color(0, 0, 255), true) end) + lua_run_cl hook.Add("HUDPaint", "test2", function() PIXEL.DrawSimpleLinearGradient(100, 350, 100, 100, Color(255, 255, 255), Color(0, 0, 0), true) PIXEL.DrawSimpleLinearGradient(250, 350, 100, 100, Color(0, 0, 0, 255), Color(0, 0, 0, 0), false) end) + lua_run_cl hook.Add("HUDPaint", "test3", function() PIXEL.DrawLinearGradient(100, 500, 100, 100, { {offset = 0, color = Color(255, 0, 0)}, {offset = 0.5, color = Color(255, 255, 255)}, {offset = 1, color = Color(0, 255, 0)} }, false) end) + lua_run_cl hook.Add("HUDPaint", "test4", function() PIXEL.DrawLinearGradient(250, 500, 100, 100, { {offset = 0, color = Color(0, 0, 255)}, {offset = 0.5, color = Color(255, 255, 0)}, {offset = 1, color = Color(255, 0, 0)} }, true) end) +]] + +local mat_white = Material("vgui/white") +PIXEL = PIXEL or {} + +function PIXEL.DrawSimpleLinearGradient(x, y, w, h, startColor, endColor, horizontal) + PIXEL.DrawLinearGradient(x, y, w, h, { {offset = 0, color = startColor}, {offset = 1, color = endColor} }, horizontal) +end + +--[[ +The stops argument is a table of GradientStop structures. + +Example: + PIXEL.LinearGradient(0, 0, 100, 100, { + {offset = 0, color = Color(255, 0, 0)}, + {offset = 0.5, color = Color(255, 255, 0)}, + {offset = 1, color = Color(255, 0, 0)} + }, false) + +== GradientStop structure == + +Field | Type | Description +------ | ------ | --------------------------------------------------------------------------------------- +offset | number | Where along the gradient should this stop occur, scaling from 0 (beginning) to 1 (end). +color | table | Color structure of what color this stop should be. +]] +function PIXEL.DrawLinearGradient(x, y, w, h, stops, horizontal) + if #stops == 0 then + return + elseif #stops == 1 then + surface.SetDrawColor(stops[1].color) + surface.DrawRect(x, y, w, h) + return + end + + table.SortByMember(stops, "offset", true) + + render.SetMaterial(mat_white) + mesh.Begin(MATERIAL_QUADS, #stops - 1) + for i = 1, #stops - 1 do + local offset1 = math.Clamp(stops[i].offset, 0, 1) + local offset2 = math.Clamp(stops[i + 1].offset, 0, 1) + if offset1 == offset2 then continue end + + local deltaX1, deltaY1, deltaX2, deltaY2 + + local color1 = stops[i].color + local color2 = stops[i + 1].color + + local r1, g1, b1, a1 = color1.r, color1.g, color1.b, color1.a + local r2, g2, b2, a2 + local r3, g3, b3, a3 = color2.r, color2.g, color2.b, color2.a + local r4, g4, b4, a4 + + if horizontal then + r2, g2, b2, a2 = r3, g3, b3, a3 + r4, g4, b4, a4 = r1, g1, b1, a1 + deltaX1 = offset1 * w + deltaY1 = 0 + deltaX2 = offset2 * w + deltaY2 = h + else + r2, g2, b2, a2 = r1, g1, b1, a1 + r4, g4, b4, a4 = r3, g3, b3, a3 + deltaX1 = 0 + deltaY1 = offset1 * h + deltaX2 = w + deltaY2 = offset2 * h + end + + mesh.Color(r1, g1, b1, a1) + mesh.Position(Vector(x + deltaX1, y + deltaY1)) + mesh.AdvanceVertex() + + mesh.Color(r2, g2, b2, a2) + mesh.Position(Vector(x + deltaX2, y + deltaY1)) + mesh.AdvanceVertex() + + mesh.Color(r3, g3, b3, a3) + mesh.Position(Vector(x + deltaX2, y + deltaY2)) + mesh.AdvanceVertex() + + mesh.Color(r4, g4, b4, a4) + mesh.Position(Vector(x + deltaX1, y + deltaY2)) + mesh.AdvanceVertex() + end + mesh.End() +end \ No newline at end of file From cdc45bc4c47a457607851b536912e3ee37e6c72b Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:51:45 +0100 Subject: [PATCH 065/155] =?UTF-8?q?=E2=9C=A8=20feat:=20DrawFilledArc=20fun?= =?UTF-8?q?ction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/libraries/cl_arc.lua | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lua/pixelui/libraries/cl_arc.lua b/lua/pixelui/libraries/cl_arc.lua index 8811c62..8590979 100644 --- a/lua/pixelui/libraries/cl_arc.lua +++ b/lua/pixelui/libraries/cl_arc.lua @@ -23,6 +23,10 @@ along with this program. If not, see . -- radius is the total radius of the outside edge to the center. -- cx, cy are the x,y coordinates of the center of the arc. -- roughness determines how many triangles are drawn. Number between 1-360; 2 or 3 is a good number. + +PIXEL = PIXEL or {} + + function PIXEL.DrawUncachedArc(cx, cy, radius, thickness, startang, endang, roughness, color) surface.SetDrawColor(color) PIXEL.DrawArc(PIXEL.PrecacheArc(cx, cy, radius, thickness, startang, endang, roughness)) @@ -100,4 +104,21 @@ function PIXEL.DrawArc(arc) for k, v in ipairs(arc) do surface.DrawPoly(v) end +end + +-- https://github.com/Threebow/tdlib/blob/master/tdlib.lua#L39 +function PIXEL.DrawFilledArc(x, y, ang, p, rad, color, seg) + seg = seg or 80 + ang = (-ang) + 180 + local circle = {} + + table.insert(circle, {x = x, y = y}) + for i = 0, seg do + local a = math.rad((i / seg) * -p + ang) + table.insert(circle, {x = x + math.sin(a) * rad, y = y + math.cos(a) * rad}) + end + + surface.SetDrawColor(color) + draw.NoTexture() + surface.DrawPoly(circle) end \ No newline at end of file From 50b7325d6bdcc01ea0444ab32d7f4eaa605e2b4f Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:51:55 +0100 Subject: [PATCH 066/155] =?UTF-8?q?=E2=9C=A8=20feat:=20Masking=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/libraries/cl_masks.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 lua/pixelui/libraries/cl_masks.lua diff --git a/lua/pixelui/libraries/cl_masks.lua b/lua/pixelui/libraries/cl_masks.lua new file mode 100644 index 0000000..4ae1296 --- /dev/null +++ b/lua/pixelui/libraries/cl_masks.lua @@ -0,0 +1,24 @@ +PIXEL = PIXEL or {} + +function PIXEL.Mask(maskFunc, drawFunc) + render.ClearStencil() + render.SetStencilEnable(true) + + render.SetStencilWriteMask(1) + render.SetStencilTestMask(1) + + render.SetStencilFailOperation(STENCILOPERATION_REPLACE) + render.SetStencilPassOperation(STENCILOPERATION_ZERO) + render.SetStencilZFailOperation(STENCILOPERATION_ZERO) + render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NEVER) + render.SetStencilReferenceValue(1) + maskFunc() + render.SetStencilFailOperation(STENCILOPERATION_ZERO) + render.SetStencilPassOperation(STENCILOPERATION_REPLACE) + render.SetStencilZFailOperation(STENCILOPERATION_ZERO) + render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL) + render.SetStencilReferenceValue(1) + drawFunc() + render.SetStencilEnable(false) + render.ClearStencil() +end \ No newline at end of file From a74f7dd3d587e8a704d893f267699bf7efc66653 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:52:50 +0100 Subject: [PATCH 067/155] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20Improv?= =?UTF-8?q?e=20DrawFullRoundedBox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/drawing/cl_rounded_box.lua | 304 +++++++++++++++++-------- 1 file changed, 204 insertions(+), 100 deletions(-) diff --git a/lua/pixelui/drawing/cl_rounded_box.lua b/lua/pixelui/drawing/cl_rounded_box.lua index daeab63..ef1eae4 100644 --- a/lua/pixelui/drawing/cl_rounded_box.lua +++ b/lua/pixelui/drawing/cl_rounded_box.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,132 +14,237 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local cornerTex8 = surface.GetTextureID("gui/corner8") local cornerTex16 = surface.GetTextureID("gui/corner16") local cornerTex32 = surface.GetTextureID("gui/corner32") local cornerTex64 = surface.GetTextureID("gui/corner64") local cornerTex512 = surface.GetTextureID("gui/corner512") - local round = math.Round local min = math.min local floor = math.floor - local setDrawColor = surface.SetDrawColor local drawRect = surface.DrawRect local drawTexturedRectUV = surface.DrawTexturedRectUV local setTexture = surface.SetTexture function PIXEL.DrawRoundedBoxEx(borderSize, x, y, w, h, col, topLeft, topRight, bottomLeft, bottomRight) - setDrawColor(col.r, col.g, col.b, col.a) - - if borderSize <= 0 then - drawRect(x, y, w, h) - return - end - - x = round(x) - y = round(y) - w = round(w) - h = round(h) - borderSize = min(round(borderSize), floor(w / 2)) - - drawRect(x + borderSize, y, w - borderSize * 2, h) - drawRect(x, y + borderSize, borderSize, h - borderSize * 2) - drawRect(x + w - borderSize, y + borderSize, borderSize, h - borderSize * 2) - - local tex = cornerTex8 - if borderSize > 8 then tex = cornerTex16 end - if borderSize > 16 then tex = cornerTex32 end - if borderSize > 32 then tex = cornerTex64 end - if borderSize > 64 then tex = cornerTex512 end - - setTexture(tex) - - if topLeft then - drawTexturedRectUV(x, y, borderSize, borderSize, 0, 0, 1, 1) - else - drawRect(x, y, borderSize, borderSize) - end - - if topRight then - drawTexturedRectUV(x + w - borderSize, y, borderSize, borderSize, 1, 0, 0, 1) - else - drawRect(x + w - borderSize, y, borderSize, borderSize) - end - - if bottomLeft then - drawTexturedRectUV(x, y + h -borderSize, borderSize, borderSize, 0, 1, 1, 0) - else - drawRect(x, y + h - borderSize, borderSize, borderSize) - end - - if bottomRight then - drawTexturedRectUV(x + w - borderSize, y + h - borderSize, borderSize, borderSize, 1, 1, 0, 0) - else - drawRect(x + w - borderSize, y + h - borderSize, borderSize, borderSize) - end + setDrawColor(col.r, col.g, col.b, col.a) + + if borderSize <= 0 then + drawRect(x, y, w, h) + + return + end + + x = round(x) + y = round(y) + w = round(w) + h = round(h) + borderSize = min(round(borderSize), floor(w / 2)) + drawRect(x + borderSize, y, w - borderSize * 2, h) + drawRect(x, y + borderSize, borderSize, h - borderSize * 2) + drawRect(x + w - borderSize, y + borderSize, borderSize, h - borderSize * 2) + local tex = cornerTex8 + + if borderSize > 8 then + tex = cornerTex16 + end + + if borderSize > 16 then + tex = cornerTex32 + end + + if borderSize > 32 then + tex = cornerTex64 + end + + if borderSize > 64 then + tex = cornerTex512 + end + + setTexture(tex) + + if topLeft then + drawTexturedRectUV(x, y, borderSize, borderSize, 0, 0, 1, 1) + else + drawRect(x, y, borderSize, borderSize) + end + + if topRight then + drawTexturedRectUV(x + w - borderSize, y, borderSize, borderSize, 1, 0, 0, 1) + else + drawRect(x + w - borderSize, y, borderSize, borderSize) + end + + if bottomLeft then + drawTexturedRectUV(x, y + h - borderSize, borderSize, borderSize, 0, 1, 1, 0) + else + drawRect(x, y + h - borderSize, borderSize, borderSize) + end + + if bottomRight then + drawTexturedRectUV(x + w - borderSize, y + h - borderSize, borderSize, borderSize, 1, 1, 0, 0) + else + drawRect(x + w - borderSize, y + h - borderSize, borderSize, borderSize) + end end local drawRoundedBoxEx = PIXEL.DrawRoundedBoxEx + function PIXEL.DrawRoundedBox(borderSize, x, y, w, h, col) - return drawRoundedBoxEx(borderSize, x, y, w, h, col, true, true, true, true) + return drawRoundedBoxEx(borderSize, x, y, w, h, col, true, true, true, true) end local roundedBoxCache = {} local whiteTexture = surface.GetTextureID("vgui/white") - local drawPoly = surface.DrawPoly -function PIXEL.DrawFullRoundedBoxEx(borderSize, x, y, w, h, col, tl, tr, bl, br) - setDrawColor(col.r, col.g, col.b, col.a) - - if borderSize <= 0 then - drawRect(x, y, w, h) - return - end - - local fullRight = x + w - local fullBottom = y + h - - local left, right = x + borderSize, fullRight - borderSize - local top, bottom = y + borderSize, fullBottom - borderSize - - local halfBorder = borderSize * .7 - - local cacheName = borderSize .. x .. y .. w .. h - local cache = roundedBoxCache[cacheName] - if not cache then - cache = { - {x = right, y = y}, --Top Right - {x = right + halfBorder, y = top - halfBorder}, - {x = fullRight, y = top}, - - {x = fullRight, y = bottom}, --Bottom Right - {x = right + halfBorder, y = bottom + halfBorder}, - {x = right, y = fullBottom}, - - {x = left, y = fullBottom}, --Bottom Left - {x = left - halfBorder, y = bottom + halfBorder}, - {x = x, y = bottom}, - - {x = x, y = top}, --Top Left - {x = left - halfBorder, y = top - halfBorder}, - {x = left, y = y} - } - - roundedBoxCache[cacheName] = cache - end +function PIXEL.DrawFullRoundedBoxExLegacy(borderSize, x, y, w, h, col, tl, tr, bl, br) + setDrawColor(col.r, col.g, col.b, col.a) + + if borderSize <= 0 then + drawRect(x, y, w, h) + + return + end + + local fullRight = x + w + local fullBottom = y + h + local left, right = x + borderSize, fullRight - borderSize + local top, bottom = y + borderSize, fullBottom - borderSize + local halfBorder = borderSize * .7 + local cacheName = borderSize .. x .. y .. w .. h + local cache = roundedBoxCache[cacheName] + + if not cache then + cache = { + { + x = right, + y = y + }, --Top Right + { + x = right + halfBorder, + y = top - halfBorder + }, + { + x = fullRight, + y = top + }, + { + x = fullRight, + y = bottom + }, --Bottom Right + { + x = right + halfBorder, + y = bottom + halfBorder + }, + { + x = right, + y = fullBottom + }, + { + x = left, + y = fullBottom + }, --Bottom Left + { + x = left - halfBorder, + y = bottom + halfBorder + }, + { + x = x, + y = bottom + }, + { + x = x, + y = top + }, --Top Left + { + x = left - halfBorder, + y = top - halfBorder + }, + { + x = left, + y = y + } + } + + roundedBoxCache[cacheName] = cache + end + + setTexture(whiteTexture) + drawPoly(cache) + + if not tl then + drawRect(x, y, borderSize, borderSize) + end + + if not tr then + drawRect(x + w - borderSize, y, borderSize, borderSize) + end + + if not bl then + drawRect(x, y + h - borderSize, borderSize, borderSize) + end + + if not br then + drawRect(x + w - borderSize, y + h - borderSize, borderSize, borderSize) + end +end - setTexture(whiteTexture) - drawPoly(cache) +function PIXEL.DrawFullRoundedBoxLegacy(borderSize, x, y, w, h, col) + return PIXEL.DrawFullRoundedBoxExLegacy(borderSize, x, y, w, h, col, true, true, true, true) +end - if not tl then drawRect(x, y, borderSize, borderSize) end - if not tr then drawRect(x + w - borderSize, y, borderSize, borderSize) end - if not bl then drawRect(x, y + h - borderSize, borderSize, borderSize) end - if not br then drawRect(x + w - borderSize, y + h - borderSize, borderSize, borderSize) end +-- new shit, thx xeninui for making me realise i can do this +function PIXEL.DrawFullRoundedBoxEx(borderSize, x, y, w, h, col, topLeft, topRight, bottomLeft, bottomRight) + setDrawColor(col.r, col.g, col.b, col.a) + + if borderSize <= 0 then + drawRect(x, y, w, h) + + return + end + + x = round(x) + y = round(y) + w = round(w) + h = round(h) + borderSize = min(round(borderSize), floor(w / 2)) + drawRect(x + borderSize, y, w - borderSize * 2, h) + drawRect(x, y + borderSize, borderSize, h - borderSize * 2) + drawRect(x + w - borderSize, y + borderSize, borderSize, h - borderSize * 2) + + if topLeft then + PIXEL.DrawFilledArc(x + borderSize, y + borderSize, 270, 90, borderSize, col, borderSize) + else + setDrawColor(col) + drawRect(x, y, borderSize, borderSize) + end + + if topRight then + PIXEL.DrawFilledArc(x + w - borderSize, y + borderSize, 0, 90, borderSize, col, borderSize) + else + setDrawColor(col) + drawRect(x + w - borderSize, y, borderSize, borderSize) + end + + if bottomLeft then + PIXEL.DrawFilledArc(x + borderSize, y + h - borderSize, 180, 90, borderSize, col, borderSize) + else + setDrawColor(col) + drawRect(x, y + h - borderSize, borderSize, borderSize) + end + + if bottomRight then + PIXEL.DrawFilledArc(x + w - borderSize, y + h - borderSize, 90, 90, borderSize, col, borderSize) + else + setDrawColor(col) + drawRect(x + w - borderSize, y + h - borderSize, borderSize, borderSize) + end end +local drawFullRoundedBoxEx = PIXEL.DrawFullRoundedBoxEx + function PIXEL.DrawFullRoundedBox(borderSize, x, y, w, h, col) - return PIXEL.DrawFullRoundedBoxEx(borderSize, x, y, w, h, col, true, true, true, true) + return drawFullRoundedBoxEx(borderSize, x, y, w, h, col, true, true, true, true) end \ No newline at end of file From 4a9a495e8d3dba102b02ea4d214d025f02b616e3 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:53:02 +0100 Subject: [PATCH 068/155] =?UTF-8?q?=E2=9C=A8=20feat:=20PIXEL.Image=20eleme?= =?UTF-8?q?nt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_image.lua | 140 ++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 lua/pixelui/elements/cl_image.lua diff --git a/lua/pixelui/elements/cl_image.lua b/lua/pixelui/elements/cl_image.lua new file mode 100644 index 0000000..e7e4443 --- /dev/null +++ b/lua/pixelui/elements/cl_image.lua @@ -0,0 +1,140 @@ +local PANEL = {} +AccessorFunc(PANEL, "Material", "Material") +AccessorFunc(PANEL, "ImageColor", "ImageColor") +AccessorFunc(PANEL, "KeepAspect", "KeepAspect") +AccessorFunc(PANEL, "MatName", "MatName") +AccessorFunc(PANEL, "FailsafeMatName", "FailsafeMatName") + +local find = string.find + +function PANEL:Init() + self:SetImageColor(color_white) + self:SetMouseInputEnabled(false) + self:SetKeyboardInputEnabled(false) + self:SetKeepAspect(false) + self.ImageName = "" + self.ActualWidth = 10 + self.ActualHeight = 10 +end + +function PANEL:SetOnViewMaterial(materialName, failsafeMatName) + self:SetMatName(materialName) + self:SetFailsafeMatName(failsafeMatName) + self.ImageName = materialName +end + +function PANEL:Unloaded() + return self.MatName ~= nil +end + +function PANEL:LoadMaterial() + if not self:Unloaded() then return end + self:DoLoadMaterial() + self:SetMatName(nil) +end + +function PANEL:DoLoadMaterial() + local mat = Material(self:GetMatName()) + if mat:IsError() then + if self:GetFailsafeMatName() then + mat = Material(self:GetFailsafeMatName()) + else + return + end + end + self:SetMaterial(mat) + self:FixVertexLitMaterial() + self:InvalidateParent() +end + +function PANEL:SetMaterial(material) + if isstring(material) then + self:SetImage(material) + return + end + self.Material = material + if not self.Material then return end + local tex = self.Material:GetTexture("$basetexture") + if tex then + self.ActualWidth = tex:Width() + self.ActualHeight = tex:Height() + else + self.ActualWidth = self.Material:Width() + self.ActualHeight = self.Material:Height() + end +end + + +function PANEL:SetImage(image, imageBackup) + if imageBackup and not file.Exists("materials/" .. image .. ".vmt", "GAME") and not file.Exists("materials/" .. image, "GAME") then + image = imageBackup + end + self.ImageName = image + local mat = Material(image) + self:SetMaterial(mat) + self:FixVertexLitMaterial() +end + +function PANEL:GetImage() + return self.ImageName +end + +function PANEL:FixVertexLitMaterial() + local mat = self:GetMaterial() + local image = mat:GetName() + if find(mat:GetShader(), "VertexLitGeneric") or find(mat:GetShader(), "Cable") then + local t = mat:GetString("$basetexture") + if t then + local params = {} + params["$basetexture"] = t + params["$vertexcolor"] = 1 + params["$vertexalpha"] = 1 + mat = CreateMaterial(image .. "_DImage", "UnlitGeneric", params) + end + end + self:SetMaterial(mat) +end + +function PANEL:SizeToContents(image) + self:SetSize(self.ActualWidth, self.ActualHeight) +end + +local drawTexturedRect = surface.DrawTexturedRect +local setMaterial = surface.SetMaterial +local setDrawColor = surface.SetDrawColor + +function PANEL:Paint() + local x, y = 0, 0 + local dw, dh = self:GetWide(), self:GetTall() + self:LoadMaterial() + if not self.Material then return true end + setMaterial(self.Material) + setDrawColor(self.ImageColor.r, self.ImageColor.g, self.ImageColor.b, self.ImageColor.a) + + if self:GetKeepAspect() then + local w = self.ActualWidth + local h = self.ActualHeight + + if w > dw and h > dh then + if w > dw then + w = dw + elseif h > dh then + h = dh + end + elseif w < dw and h < dh then + if w < dw then + w = dw + elseif h < dh then + h = dh + end + end + + local OffX = (dw - w) * 0.5 + local OffY = (dh - h) * 0.5 + drawTexturedRect(OffX + x, OffY + y, w, h) + end + + drawTexturedRect(x, y, dw, dh) +end + +vgui.Register("PIXEL.Image", PANEL, "EditablePanel") \ No newline at end of file From 67bb2046f972faf407193b90d5b115e7836acecc Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:53:53 +0100 Subject: [PATCH 069/155] =?UTF-8?q?=E2=9C=A8=20feat:=20Allow=20changing=20?= =?UTF-8?q?font=20for=20TextEntry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_text_entry.lua | 17 ++++++++++++++--- lua/pixelui/elements/cl_text_entry_internal.lua | 10 ++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 4c0200c..3be5deb 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -14,8 +14,19 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] + local PANEL = {} +AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) + +function PANEL:SetFont(font, isPixel) + if isPixel then + self.TextEntry:SetFont(font, isPixel) + else + self.TextEntry:SetFont(font, isPixel) + end +end + function PANEL:Init() self.TextEntry = vgui.Create("PIXEL.TextEntryInternal", self) self.PlaceholderTextCol = PIXEL.OffsetColor(PIXEL.Colors.SecondaryText, -110) @@ -37,7 +48,7 @@ end function PANEL:Paint(w, h) if not self:IsEnabled() then - PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.DisabledCol) + PIXEL.DrawRoundedBox(4, 0, 0, w, h, self.DisabledCol) end if not self:IsEnabled() and self:GetValue() == "" then @@ -51,7 +62,7 @@ function PANEL:Paint(w, h) end local outlineThickness = PIXEL.Scale(1) - PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.OutlineCol, outlineThickness) + PIXEL.DrawFullOutlinedRoundedBox(8, 0, 0, w, h, self.OutlineCol, outlineThickness) local col = PIXEL.Colors.Transparent if self:IsEditing() then @@ -63,7 +74,7 @@ function PANEL:Paint(w, h) end self.InnerOutlineCol = PIXEL.LerpColor(FrameTime() * 8, self.InnerOutlineCol, col) - PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(4), outlineThickness, outlineThickness, w - outlineThickness * 2, h - outlineThickness * 2, self.InnerOutlineCol, PIXEL.Scale(1)) + PIXEL.DrawFullOutlinedRoundedBox(8, outlineThickness, outlineThickness, w - outlineThickness * 2, h - outlineThickness * 2, self.InnerOutlineCol, outlineThickness) end function PANEL:OnChange() diff --git a/lua/pixelui/elements/cl_text_entry_internal.lua b/lua/pixelui/elements/cl_text_entry_internal.lua index 083ab1c..ec6e43a 100644 --- a/lua/pixelui/elements/cl_text_entry_internal.lua +++ b/lua/pixelui/elements/cl_text_entry_internal.lua @@ -21,9 +21,19 @@ AccessorFunc(PANEL, "m_bNumeric", "Numeric", FORCE_BOOL) AccessorFunc(PANEL, "m_bHistory", "HistoryEnabled", FORCE_BOOL) AccessorFunc(PANEL, "m_bDisableTabbing", "TabbingDisabled", FORCE_BOOL) AccessorFunc(PANEL, "m_txtPlaceholder", "PlaceholderText", FORCE_STRING) +AccessorFunc(PANEL, "m_txtFont", "Font", FORCE_STRING) Derma_Install_Convar_Functions(PANEL) PIXEL.RegisterFont("UI.TextEntry", "Rubik", 18) +function PANEL:SetFont(font, isPixel) + if isPixel then + self:SetFontInternal(PIXEL.GetRealFont(font)) + else + self:SetFontInternal(font) + end +end + + function PANEL:Init() self:SetHistoryEnabled(false) self.History = {} From 04628c9577511383f2a1217309c91bf4761aa137 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:54:07 +0100 Subject: [PATCH 070/155] add a space? --- lua/pixelui/elements/cl_text_button.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index e52fb86..c20ee40 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -19,6 +19,7 @@ AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) AccessorFunc(PANEL, "TextSpacing", "TextSpacing", FORCE_NUMBER) AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) + PIXEL.RegisterFont("UI.TextButton", "Rubik", 20, 600) function PANEL:Init() From 024dace3b7e6bb4884f3507cef1feb5cba8fa04e Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:54:38 +0100 Subject: [PATCH 071/155] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Remove=20print=20f?= =?UTF-8?q?rom=20PIXEL.Slider?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_slider.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_slider.lua b/lua/pixelui/elements/cl_slider.lua index bca7876..828df91 100644 --- a/lua/pixelui/elements/cl_slider.lua +++ b/lua/pixelui/elements/cl_slider.lua @@ -59,7 +59,6 @@ function PANEL:OnMousePressed() self:OnValueChanged(self.Fraction) self:InvalidateLayout() self.Grip:RequestFocus() - print(self.Grip:HasFocus()) end function PANEL:OnValueChanged(fraction) @@ -78,4 +77,7 @@ function PANEL:PerformLayout(w, h) self.Grip:SetPos((self.Fraction * w) - (gripSize * .5), -offset) end +function PANEL:LayoutContent() +end + vgui.Register("PIXEL.Slider", PANEL, "PIXEL.Button") \ No newline at end of file From 0100b0ae9e92263df7a0ccfce722900277966901 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 14:54:53 +0100 Subject: [PATCH 072/155] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Change=20default?= =?UTF-8?q?=20height=20of=20PIXEL.StepCounter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_step_counter.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lua/pixelui/elements/cl_step_counter.lua b/lua/pixelui/elements/cl_step_counter.lua index 2e1945c..3dbd94f 100644 --- a/lua/pixelui/elements/cl_step_counter.lua +++ b/lua/pixelui/elements/cl_step_counter.lua @@ -6,6 +6,8 @@ AccessorFunc(PANEL, "Step", "Step", FORCE_NUMBER) AccessorFunc(PANEL, "Enabled", "Enabled", FORCE_BOOL) function PANEL:Init() + self:SetTall(PIXEL.Scale(90)) + self.BackgroundCol = PIXEL.Colors.Header self.EnabledCol = PIXEL.Colors.Primary self.TextCol = PIXEL.Colors.SecondaryText From bac3a27df2c193af647bb1aa4823c9981f259b07 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 22:11:27 +0100 Subject: [PATCH 073/155] =?UTF-8?q?=F0=9F=92=84=20Make=20TextEntry=20outli?= =?UTF-8?q?ne=20actualy=20good?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_text_entry.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 3be5deb..4051fb2 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -74,7 +74,7 @@ function PANEL:Paint(w, h) end self.InnerOutlineCol = PIXEL.LerpColor(FrameTime() * 8, self.InnerOutlineCol, col) - PIXEL.DrawFullOutlinedRoundedBox(8, outlineThickness, outlineThickness, w - outlineThickness * 2, h - outlineThickness * 2, self.InnerOutlineCol, outlineThickness) + PIXEL.DrawFullOutlinedRoundedBox(8, 0, 0, w, h, self.InnerOutlineCol, outlineThickness) end function PANEL:OnChange() From d6bb5c3ce85333e201f92faa3764e66cd7d21672 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 22:11:45 +0100 Subject: [PATCH 074/155] =?UTF-8?q?=E2=9C=A8=20feat:=20RGB=20color=20picke?= =?UTF-8?q?r=20bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_rgb_picker.lua | 95 ++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 lua/pixelui/elements/cl_rgb_picker.lua diff --git a/lua/pixelui/elements/cl_rgb_picker.lua b/lua/pixelui/elements/cl_rgb_picker.lua new file mode 100644 index 0000000..e0b8201 --- /dev/null +++ b/lua/pixelui/elements/cl_rgb_picker.lua @@ -0,0 +1,95 @@ +local PANEL = {} +local floor = math.floor +local clamp = math.Clamp +local colToHSV, HSVToCol = ColorToHSV, HSVToColor +local scale = PIXEL.Scale +AccessorFunc(PANEL, "RGBValue", "RGB") + +function PANEL:Init() + self:SetRGB(color_white) + self.LastX = 0 + self.Steps = {} +end + +function PANEL:PerformLayout(w, h) + self.Steps = {} + self.Times = 360 -- The max number that the hue can be + + for i = 0, self.Times do + local step = (1 / self.Times) * i + local color = HSVToCol(i, 1, 1) + + self.Steps[i] = { + offset = step, + color = color + } + end +end + +function PANEL:GetPosColor(value) + local position = floor(value * self.Times) + local color = self.Steps[position].color + + return color +end + +function PANEL:GetColorPos(color) + local h, _, _ = colToHSV(color) + local pos = floor((h * self:GetWide()) / self.Times) + return pos +end + +function PANEL:OnCursorMoved(x, y) + if not input.IsMouseDown(MOUSE_LEFT) then return end + local wide = x / self:GetWide() + local value = clamp(wide, 0, 1) + local col = self:GetPosColor(value) + + if col then + self.RGBValue = col + self.RGBValue.a = 255 + self:OnChange(self.RGBValue) + end + + self.LastX = x +end + +function PANEL:OnChange(col) +end + +function PANEL:OnMousePressed() + self:MouseCapture(true) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:OnMouseReleased() + self:MouseCapture(false) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:Paint(w, h) + local x, y = self:LocalToScreen() + local wh + + PIXEL.Mask(function() + PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) + end, function() + PIXEL.DrawLinearGradient(x, y, w, h, self.Steps, true) + end) + + local newX = self.LastX + + if newX < (h / 2) then + newX = (h / 2) + end + + if newX > w - (h / 2) then + newX = w - (h / 2) + end + + PIXEL.DrawFullRoundedBox(8, newX - (h / 2), 0, h, h, color_white) + x, y, wh = newX + scale(3), scale(3), h - scale(6) + PIXEL.DrawFullRoundedBox(4, x - (h / 2), y, wh, wh, self:GetRGB()) +end + +vgui.Register("PIXEL.RGBPicker", PANEL, "EditablePanel") \ No newline at end of file From 05765a12834ce0367952f978b9ba8159999a445b Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 22:12:00 +0100 Subject: [PATCH 075/155] =?UTF-8?q?=E2=9C=A8=20feat:=20Color=20Cube?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_color_cube.lua | 124 +++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 lua/pixelui/elements/cl_color_cube.lua diff --git a/lua/pixelui/elements/cl_color_cube.lua b/lua/pixelui/elements/cl_color_cube.lua new file mode 100644 index 0000000..de57b4b --- /dev/null +++ b/lua/pixelui/elements/cl_color_cube.lua @@ -0,0 +1,124 @@ +local PANEL = {} +local floor = math.floor +AccessorFunc(PANEL, "Hue", "Hue") +AccessorFunc(PANEL, "BaseRGB", "BaseRGB") +AccessorFunc(PANEL, "RGB", "RGB") +AccessorFunc(PANEL, "SlideX", "SlideX") +AccessorFunc(PANEL, "SlideY", "SlideY") + +function PANEL:Init() + self.BackgroundSat = vgui.Create("PIXEL.Image", self) + self.BackgroundSat:SetImage("vgui/gradient-r") + self.BackgroundSat:Dock(FILL) + + self.BackgroundValue = vgui.Create("PIXEL.Image", self) + self.BackgroundValue:Dock(FILL) + self.BackgroundValue:SetImage("vgui/gradient-d") + self.BackgroundValue:SetImageColor(color_black) + + self:SetBaseRGB(Color(255, 0, 0)) + self:SetRGB(Color(255, 0, 0)) + self:SetColor(Color(255, 0, 0)) + + self.LastX = 0 + self.LastY = 0 +end + +function PANEL:OnCursorMoved(x, y) + if not input.IsMouseDown(MOUSE_LEFT) then return end + local panelWide, panelTall = self:GetSize() + local wide = x / panelWide + local tall = y / panelTall + self.LastX = floor(wide * panelWide) + self.LastY = floor(tall * panelTall) + + self:TranslateValues(x, y) +end + +function PANEL:LayoutContent(w, h) + self.BackgroundSat:SetZPos(-9) + self.BackgroundValue:SetZPos(-8) +end + +function PANEL:Paint(w, h) + PIXEL.Mask( + function() + PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) + end, + function() + PIXEL.DrawRoundedBox(0, 0, 0, w, h, Color(self.BaseRGB.r, self.BaseRGB.g, self.BaseRGB.b, 255)) + PIXEL.DrawOutlinedBox(0, 0, w, h, 1, Color(0, 0, 0, 250)) + end + ) +end + +function PANEL:PaintOver(w, h) + local scale = PIXEL.Scale(20) + local newX = self.LastX + local newY = self.LastY + local x, y, wh + + if newX < (scale / 2) then + newX = (scale / 2) + end + + if newX > w - (scale / 2) then + newX = w - (scale / 2) + end + + if newY < (scale / 2) then + newY = (scale / 2) + end + + if newY > h - (scale / 2) then + newY = h - (scale / 2) + end + + newX = newX - (scale / 2) + newY = newY - (scale / 2) + + PIXEL.DrawFullRoundedBox(8, newX, newY, scale, scale, color_white) + x, y, wh = newX + PIXEL.Scale(3), newY + PIXEL.Scale(3), scale - PIXEL.Scale(6) + PIXEL.DrawFullRoundedBox(4, x, y, wh, wh, self:GetRGB()) +end + +function PANEL:TranslateValues(x, y) + self:UpdateColor(x, y) + self:OnUserChanged(self.RGB) + + return x, y +end + +function PANEL:UpdateColor(x, y) + x = x or self:GetSlideX() or 0 + y = y or self:GetSlideY() or 0 + + local value = 1 - math.Clamp(y / self:GetTall(), 0, 1) + local saturation = 1 - math.Clamp(x / self:GetWide(), 0, 1) + local h = ColorToHSV(self.BaseRGB) + + local color = HSVToColor(h, saturation, value) + + self:SetRGB(color) +end + +function PANEL:OnUserChanged() +end + +function PANEL:SetColor(color) + local h, s, v = ColorToHSV(color) + + self:SetBaseRGB(HSVToColor(h, 1, 1)) + + self:SetSlideY(1 - v) + self:SetSlideX(1 - s) + + self:UpdateColor() +end + +function PANEL:SetBaseRGB(color) + self.BaseRGB = color + self:UpdateColor() +end + +vgui.Register("PIXEL.ColorCube", PANEL, "EditablePanel") \ No newline at end of file From e2f5d906dea90da56c819b1928c310b213f52d27 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 22:12:16 +0100 Subject: [PATCH 076/155] =?UTF-8?q?=E2=9C=A8=20feat:=20Alpha=20bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_alpha_bar.lua | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 lua/pixelui/elements/cl_alpha_bar.lua diff --git a/lua/pixelui/elements/cl_alpha_bar.lua b/lua/pixelui/elements/cl_alpha_bar.lua new file mode 100644 index 0000000..c48d3af --- /dev/null +++ b/lua/pixelui/elements/cl_alpha_bar.lua @@ -0,0 +1,70 @@ +local PANEL = {} +local clamp = math.Clamp +local floor = math.floor +AccessorFunc(PANEL, "Value", "Value") +AccessorFunc(PANEL, "Alpha", "Alpha") +AccessorFunc(PANEL, "BarColor", "BarColor") + +function PANEL:Init() + self:SetBarColor(color_white) + self:SetSize(PIXEL.Scale(26), PIXEL.Scale(26)) + self:SetValue(1) + self:SetAlpha(255) + self.LastX = 0 +end + +function PANEL:OnCursorMoved(x, y) + if not input.IsMouseDown(MOUSE_LEFT) then return end + + local wide = x / self:GetWide() + local value = 1 - clamp(wide, 0, 1) + + self.LastX = floor(wide * self:GetWide()) + + self:SetValue(value) + self:OnChange(value) + self:SetAlpha(floor(value * 255)) +end + +function PANEL:OnMousePressed() + self:MouseCapture(true) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:OnMouseReleased() + self:MouseCapture(false) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:OnChange(alpha) +end + +function PANEL:Paint(w, h) + local x, y = self:LocalToScreen() + local wh + + PIXEL.Mask(function() + PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) + end, function() + PIXEL.DrawSimpleLinearGradient(x, y, w, h, self:GetBarColor(), Color(200, 200, 200, 0), true) + end) + + local newX = self.LastX + + if newX < (h / 2) then + newX = (h / 2) + end + + if newX > w - (h / 2) then + newX = w - (h / 2) + end + + + PIXEL.DrawFullRoundedBox(8, newX - (h / 2), 0, h, h, color_white) + x, y, wh = newX + PIXEL.Scale(3), PIXEL.Scale(3), h - PIXEL.Scale(6) + local barColor = self:GetBarColor() + local r, g, b, a = barColor.r, barColor.g, barColor.b, self:GetAlpha() + PIXEL.DrawFullRoundedBox(4, x - (h / 2), y, wh, wh, Color(r, g, b, a)) +end + +vgui.Register("PIXEL.AlphaBar", PANEL, "EditablePanel") \ No newline at end of file From 1bd8bf036425d7942b89aee4b0e3a39f763fedb3 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 22:12:26 +0100 Subject: [PATCH 077/155] =?UTF-8?q?=E2=9C=A8=20outlined=20box=20shit=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/drawing/cl_outlined_box.lua | 180 ++++++++++++++++++------ 1 file changed, 134 insertions(+), 46 deletions(-) diff --git a/lua/pixelui/drawing/cl_outlined_box.lua b/lua/pixelui/drawing/cl_outlined_box.lua index 3fb039e..1d28039 100644 --- a/lua/pixelui/drawing/cl_outlined_box.lua +++ b/lua/pixelui/drawing/cl_outlined_box.lua @@ -1,4 +1,3 @@ - --[[ PIXEL UI Copyright (C) 2021 Tom O'Sullivan (Tom.bat) @@ -15,12 +14,12 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ]] - local setDrawColor = surface.SetDrawColor local drawOutlinedRect = surface.DrawOutlinedRect function PIXEL.DrawOutlinedBox(x, y, w, h, thickness, col) setDrawColor(col.r, col.g, col.b, col.a) + for i = 0, thickness - 1 do drawOutlinedRect(x + i, y + i, w - i * 2, h - i * 2) end @@ -30,75 +29,139 @@ local ipairs = ipairs local setTexture = surface.SetTexture local drawPoly = surface.DrawPoly local drawRect = surface.DrawRect - local roundedBoxCache = {} local whiteTexture = surface.GetTextureID("vgui/white") function PIXEL.DrawOutlinedRoundedBox(borderSize, x, y, w, h, col, thickness) thickness = thickness or 1 - setDrawColor(col.r, col.g, col.b, col.a) if borderSize <= 0 then PIXEL.DrawOutlinedBox(x, y, w, h, thickness, col) + return end local fullRight = x + w local fullBottom = y + h - local left, right = x + borderSize, fullRight - borderSize local top, bottom = y + borderSize, fullBottom - borderSize - local halfBorder = borderSize * .6 - local width, height = w - borderSize * 2, h - borderSize * 2 - drawRect(x, top, thickness, height) --Left drawRect(x + w - thickness, top, thickness, height) --Right drawRect(left, y, width, thickness) --Top drawRect(left, y + h - thickness, width, thickness) --Bottom - local cacheName = borderSize .. x .. y .. w .. h .. thickness local cache = roundedBoxCache[cacheName] + if not cache then cache = { - { --Top Right - {x = right, y = y}, --Outer - {x = right + halfBorder, y = top - halfBorder}, - {x = fullRight, y = top}, - - {x = fullRight - thickness, y = top}, --Inner - {x = right + halfBorder - thickness, y = top - halfBorder + thickness}, - {x = right, y = y + thickness} - }, - { --Bottom Right - {x = fullRight, y = bottom}, --Outer - {x = right + halfBorder, y = bottom + halfBorder}, - {x = right, y = fullBottom}, - - {x = right, y = fullBottom - thickness}, --Inner - {x = right + halfBorder - thickness, y = bottom + halfBorder - thickness}, - {x = fullRight - thickness, y = bottom} - }, - { --Bottom Left - {x = left, y = fullBottom}, --Outer - {x = left - halfBorder, y = bottom + halfBorder}, - {x = x, y = bottom}, - - {x = x + thickness, y = bottom}, --Inner - {x = left - halfBorder + thickness, y = bottom + halfBorder - thickness}, - {x = left, y = fullBottom - thickness}, - }, - { --Top Left - {x = x, y = top}, --Outer - {x = left - halfBorder, y = top - halfBorder}, - {x = left, y = y}, - - {x = left, y = y + thickness}, --Inner - {x = left - halfBorder + thickness, y = top - halfBorder + thickness}, - {x = x + thickness, y = top} - } + { + { + x = right, + y = y + }, --Outer + { + x = right + halfBorder, + y = top - halfBorder + }, + { + x = fullRight, + y = top + }, + { + x = fullRight - thickness, + y = top + }, --Inner + { + x = right + halfBorder - thickness, + y = top - halfBorder + thickness + }, + { + x = right, + y = y + thickness + } + }, --Top Right + { + { + x = fullRight, + y = bottom + }, --Outer + { + x = right + halfBorder, + y = bottom + halfBorder + }, + { + x = right, + y = fullBottom + }, + { + x = right, + y = fullBottom - thickness + }, --Inner + { + x = right + halfBorder - thickness, + y = bottom + halfBorder - thickness + }, + { + x = fullRight - thickness, + y = bottom + } + }, --Bottom Right + { + { + x = left, + y = fullBottom + }, --Outer + { + x = left - halfBorder, + y = bottom + halfBorder + }, + { + x = x, + y = bottom + }, + { + x = x + thickness, + y = bottom + }, --Inner + { + x = left - halfBorder + thickness, + y = bottom + halfBorder - thickness + }, + { + x = left, + y = fullBottom - thickness + }, + }, --Bottom Left + { + { + x = x, + y = top + }, --Outer + { + x = left - halfBorder, + y = top - halfBorder + }, + { + x = left, + y = y + }, + { + x = left, + y = y + thickness + }, --Inner + { + x = left - halfBorder + thickness, + y = top - halfBorder + thickness + }, + { + x = x + thickness, + y = top + } + } --Top Left + } roundedBoxCache[cacheName] = cache @@ -106,7 +169,32 @@ function PIXEL.DrawOutlinedRoundedBox(borderSize, x, y, w, h, col, thickness) setTexture(whiteTexture) - for k,v in ipairs(cache) do + for k, v in ipairs(cache) do drawPoly(v) end +end + +local round = math.Round +local floor = math.floor +local min = math.min + +function PIXEL.DrawFullOutlinedRoundedBox(borderSize, x, y, w, h, col, thickness) + thickness = thickness or 1 + setDrawColor(col.r, col.g, col.b, col.a) + + if borderSize <= 0 then + drawRect(x, y, w, h) + + return + end + + x = round(x) + y = round(y) + w = round(w) + h = round(h) + thickness = round(thickness) + borderSize = min(round(borderSize), floor(w / 2)) + + PIXEL.DrawRoundedBox(borderSize, x, y, w, h, col) + PIXEL.DrawRoundedBox(borderSize - thickness, x + thickness, y + thickness, w - (thickness * 2), h - (thickness * 2), PIXEL.Colors.Background) end \ No newline at end of file From 91784e3814152e6aa0d45813647f7604a9ec2d75 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 22:14:25 +0100 Subject: [PATCH 078/155] =?UTF-8?q?=E2=9C=A8=20feat:=20Color=20Picker=20V2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_color_picker.lua | 313 ----------------- lua/pixelui/elements/cl_color_picker_v2.lua | 352 ++++++++++++++++++++ 2 files changed, 352 insertions(+), 313 deletions(-) delete mode 100644 lua/pixelui/elements/cl_color_picker.lua create mode 100644 lua/pixelui/elements/cl_color_picker_v2.lua diff --git a/lua/pixelui/elements/cl_color_picker.lua b/lua/pixelui/elements/cl_color_picker.lua deleted file mode 100644 index cccd93d..0000000 --- a/lua/pixelui/elements/cl_color_picker.lua +++ /dev/null @@ -1,313 +0,0 @@ - ---[[ -PIXEL UI -Copyright (C) 2021 Tom O'Sullivan (Tom.bat) - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -]] - -local PANEL = {} - -local gradientMat = Material("nil") -PIXEL.GetImgur("i0xcO1R", function(mat) - gradientMat = mat -end) - -local colorWheelMat = Material("nil") -PIXEL.GetImgur("k5mtok6", function(mat) - colorWheelMat = mat -end) - -local pickerMat = Material("nil") -PIXEL.GetImgur("t0k86qy", function(mat) - pickerMat = mat -end) - -function PANEL:Init() - self.Hue = 0 - self.SmoothHue = 0 - - self.Lightness = 0 - self.Saturation = 0 - - self.TriX = 0 - self.TriY = 0 - - self:UpdateColor() - self:UpdatePositions() -end - -function PANEL:OnChange(color) end - -function PANEL:UpdateColor() - self.Color = PIXEL.HSLToColor(self.Hue, self.Saturation, self.Lightness) - self:OnChange(self.Color) -end - -function PANEL:SetColor(color) - local h, s, l = ColorToHSL(color) - h = h / (360 / 5) - self.Hue = h - self.Saturation = s - self.Lightness = l - - self.Color = color - self:OnChange(color) - - self:UpdatePositions() -end - -function PANEL:UpdatePositions() - local hue = self.Hue - local third = (2 / 3) * math.pi - local sat = self.Saturation - local light = 1 - self.Lightness - - local hX = math.cos(hue) - local hY = math.sin(hue) - local sX = math.cos(hue - third) - local sY = math.sin(hue - third) - local vX = math.cos(hue + third) - local vY = math.sin(hue + third) - - local mX = (sX + vX) / 2 - local mY = (sY + vY) / 2 - local a = (1 - 2 * math.abs(light - 0.5)) * sat - - self.TriX = sX + (vX - sX) * light + (hX - mX) * a - self.TriY = sY + (vY - sY) * light + (hY - mY) * a -end - -function PANEL:Think() - local cursorX, cursorY = self:CursorPos() - local cX, cY = self:GetCenter() - local triangleRadius = self:GetTriangleRadius() - - if not self.Pressed then return end - - local diffX = cursorX - cX - local diffY = cursorY - cY - local rad = math.atan2(diffY, diffX) - - if rad < 0 then - rad = rad + (2 * math.pi) - end - - if self.PressedWheel then - self.Hue = rad - self:UpdatePositions() - self:UpdateColor() - return - end - - local rad0 = (rad + 2 * math.pi - self.Hue) % (2 * math.pi) - local rad1 = rad0 % ((2 / 3) * math.pi) - (math.pi / 3) - local a = 0.5 * triangleRadius - local b = math.tan(rad1) * a - local r = math.sqrt(diffX * diffX + diffY * diffY) - local maxR = math.sqrt(a * a + b * b) - - if r > maxR then - local dx = math.tan(rad1) * r - local rad2 = math.Clamp(math.atan(dx / maxR), -math.pi / 3, math.pi / 3) - rad = rad + (rad2 - rad1) - rad0 = (rad + 2 * math.pi - self.Hue) % (2 * math.pi) - rad1 = rad0 % ((2 / 3) * math.pi) - (math.pi / 3) - b = math.tan(rad1) * a - maxR = math.sqrt(a * a + b * b) - r = maxR - end - - self.TriX = math.cos(rad) * r / triangleRadius - self.TriY = math.sin(rad) * r / triangleRadius - - local triangleSideLen = math.sqrt(3) * triangleRadius - local light = ((math.sin(rad0) * r) / triangleSideLen) + 0.5 - local widthShare = 1.0 - math.abs(light - 0.5) * 2.0 - local saturation = (((math.cos(rad0) * r) + (triangleRadius / 2)) / (1.5 * triangleRadius)) / widthShare - saturation = math.Clamp(saturation, 0, 1) - - self.Lightness = 1 - light - self.Saturation = saturation - - self:UpdateColor() -end - -function PANEL:OnMousePressed() - self:MouseCapture(true) - self.Pressed = true - - local cX, cY = self:GetCenter() - local cursorX, cursorY = self:CursorPos() - local cursor = Vector(cursorX, cursorY) - local center = Vector(cX, cY, 0) - - if cursor:Distance(center) > self:GetTriangleRadius() then - self.PressedWheel = true - return - end - - self.PressedTriangle = true -end - -function PANEL:OnMouseReleased() - self:MouseCapture(false) - self.Pressed = false - self.PressedWheel = false - self.PressedTriangle = false -end - -function PANEL:GetCenter() - return self:GetWide() / 2, self:GetTall() / 2 -end - -function PANEL:GetRadius() - return self:GetTall() / 2 -end - -function PANEL:GetTriangleRadius() - return self:GetRadius() * 0.7 -end - -function PANEL:GetRingThickness() - return self:GetRadius() * 0.2 -end - -function PANEL:GetHueColor() - return PIXEL.HSLToColor(self.Hue, 1, 0.5) -end - -local whiteTexture = surface.GetTextureID("vgui/white") -function PANEL:Paint(w, h) - local cX, cY = self:GetCenter() - local radius = self:GetRadius() - local triangleRadius = self:GetTriangleRadius() - - surface.SetTexture(whiteTexture) - - local triangleAng = self.Hue - local triangleOff = math.pi * 2 / 3 - local vertices = { - { - x = cX + math.cos(triangleAng - triangleOff) * triangleRadius, - y = cY + math.sin(triangleAng - triangleOff) * triangleRadius, - u = 0.5, - v = 0.99 - }, - { - x = cX + math.cos(triangleAng) * triangleRadius, - y = cY + math.sin(triangleAng) * triangleRadius, - u = 0.99, - v = 0.01 - }, - { - x = cX + math.cos(triangleAng + triangleOff * 1) * triangleRadius, - y = cY + math.sin(triangleAng + triangleOff * 1) * triangleRadius, - u = 0.01, - v = 0.01 - } - } - - local col = self:GetHueColor() - surface.SetDrawColor(col) - surface.DrawPoly(vertices) - - surface.SetDrawColor(255, 255, 255, 255) - surface.SetMaterial(gradientMat) - surface.DrawPoly(vertices) - surface.DrawPoly(vertices) - - vertices[1].u = 0.99 - vertices[1].v = 0.01 - - vertices[2].u = 0.01 - vertices[2].v = 0.01 - - vertices[3].u = 0.5 - vertices[3].v = 0.99 - - surface.SetDrawColor(0, 0, 0, 255) - surface.SetMaterial(gradientMat) - surface.DrawPoly(vertices) - - surface.SetDrawColor(255, 255, 255, 255) - surface.SetMaterial(colorWheelMat) - surface.DrawTexturedRect(cX - radius, cY - radius, radius * 2, radius * 2) - - local pickerSize = PIXEL.Scale(5) - local pickerVerts = { - { - x = cX + self.TriX * triangleRadius + pickerSize, - y = cY + self.TriY * triangleRadius + pickerSize, - u = 1, - v = 1 - }, - { - x = cX + self.TriX * triangleRadius - PIXEL.Scale(5), - y = cY + self.TriY * triangleRadius + PIXEL.Scale(5), - u = 0, - v = 1 - }, - { - x = cX + self.TriX * triangleRadius - PIXEL.Scale(5), - y = cY + self.TriY * triangleRadius - PIXEL.Scale(5), - u = 0, - v = 0 - }, - { - x = cX + self.TriX * triangleRadius + pickerSize, - y = cY + self.TriY * triangleRadius - pickerSize, - u = 1, - v = 0 - } - } - - surface.SetDrawColor(255, 255, 255, 255) - surface.SetMaterial(pickerMat) - surface.DrawPoly(pickerVerts) - - local hpX = cX + math.cos(self.Hue) * (radius - self:GetRingThickness() / 2) - local hpY = cY + math.sin(self.Hue) * (radius - self:GetRingThickness() / 2) - local size = PIXEL.Scale(16) - local huePickerVerts = { - { - x = hpX + size / 2, - y = hpY + size / 2, - u = 1, - v = 1 - }, - { - x = hpX - size / 2, - y = hpY + size / 2, - u = 0, - v = 1 - }, - { - x = hpX - size / 2, - y = hpY - size / 2, - u = 0, - v = 0 - }, - { - x = hpX + size / 2, - y = hpY - size / 2, - u = 1, - v = 0 - } - } - surface.SetDrawColor(255, 255, 255, 255) - surface.SetMaterial(pickerMat) - surface.DrawPoly(huePickerVerts) -end - -vgui.Register("PIXEL.ColorPicker", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_color_picker_v2.lua b/lua/pixelui/elements/cl_color_picker_v2.lua new file mode 100644 index 0000000..d03b659 --- /dev/null +++ b/lua/pixelui/elements/cl_color_picker_v2.lua @@ -0,0 +1,352 @@ + +--[[ +PIXEL UI +Copyright (C) 2021 Tom O'Sullivan (Tom.bat) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +]] + +local PANEL = {} +AccessorFunc(PANEL, "ConVarRed", "ConVarR") +AccessorFunc(PANEL, "ConVarGreen", "ConVarG") +AccessorFunc(PANEL, "ConVarBlue", "ConVarBlue") +AccessorFunc(PANEL, "ConVarAlpha", "ConVarAlpha") +AccessorFunc(PANEL, "AlphaBarEnabled", "AlphaBar", FORCE_BOOL) +AccessorFunc(PANEL, "ShowTextEntries", "ShowTextEntries", FORCE_BOOL) +AccessorFunc(PANEL, "Color", "Color") +PIXEL.RegisterFont("UI.ColorPickerWang", "Rubik", 14) + +function PANEL:UpdateRGBEntryValues(panel, num, rgbType) + if panel.Forced then return end + local targetValue = tonumber(num) or 0 + + self:GetColor()[rgbType] = targetValue + + self.ColorCube:SetColor(self:GetColor()) + local pos = self.RGBPicker:GetColorPos(self.ColorCube:GetBaseRGB()) + self.RGBPicker:SetRGB(self.ColorCube:GetBaseRGB()) + self.RGBPicker.LastX = pos + + self:UpdateColor(self:GetColor()) +end + +function PANEL:UpdateNumberEntries(color) + self.RedEntry:SetValue(color.r) + self.GreenEntry:SetValue(color.g) + self.BlueEntry:SetValue(color.b) +end + +function PANEL:Init() + self:SetShowTextEntries(true) + self:SetSize(PIXEL.Scale(256), PIXEL.Scale(230)) + + self.RGBAPanel = vgui.Create("Panel", self) + self.RGBAPanel:Dock(BOTTOM) + self.RGBAPanel:DockMargin(0, PIXEL.Scale(10), 0, PIXEL.Scale(10)) + self.RGBAPanel:SetTall(PIXEL.Scale(35)) + + self.RedEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") + self.RedEntry:SetMin(0) + self.RedEntry:SetMax(255) + self.RedEntry:SetTall(PIXEL.Scale(25)) + self.RedEntry:SetWide(PIXEL.Scale(60)) + self.RedEntry:SetFont("UI.ColorPickerWang", true) + self.RedEntry.OutlineCol = Color(238, 75, 43) + + self.GreenEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") + self.GreenEntry:SetMin(0) + self.GreenEntry:SetMax(255) + self.GreenEntry:SetTall(PIXEL.Scale(25)) + self.GreenEntry:SetWide(PIXEL.Scale(60)) + self.GreenEntry.TextEntry:SetFont("UI.ColorPickerWang", true) + self.GreenEntry.OutlineCol = Color(170, 255, 0) + + self.BlueEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") + self.BlueEntry:SetMin(0) + self.BlueEntry:SetMax(255) + self.BlueEntry:SetTall(PIXEL.Scale(25)) + self.BlueEntry.TextEntry:SetFont("UI.ColorPickerWang", true) + self.BlueEntry.OutlineCol = Color(0, 100, 255) + + self.AlphaEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") + self.AlphaEntry:SetMin(0) + self.AlphaEntry:SetMax(255) + self.AlphaEntry:SetTall(PIXEL.Scale(25)) + self.AlphaEntry:SetWide(PIXEL.Scale(60)) + self.AlphaEntry.TextEntry:SetFont("UI.ColorPickerWang", true) + + self.RGBAPanel.PerformLayout = function(s, w, h) + local boxH = PIXEL.Scale(30) + self.RedEntry:SetTall(boxH) + self.GreenEntry:SetTall(boxH) + self.BlueEntry:SetTall(boxH) + + if self.AlphaBarEnabled then + self.AlphaEntry:SetTall(boxH) + + local boxW = (w / 4) - (PIXEL.Scale(5) * 4) + + self.RedEntry:SetWide(boxW) + self.GreenEntry:SetWide(boxW) + self.BlueEntry:SetWide(boxW) + self.AlphaEntry:SetWide(boxW) + + for i = 1, 4 do + local x = (boxW + PIXEL.Scale(5)) * (i - 1) + + self.RGBAPanel:GetChildren()[i]:SetPos(x, 0) + end + else + local boxW = (w / 3) - (PIXEL.Scale(5) * 2) + + self.RedEntry:SetWide(boxW) + self.GreenEntry:SetWide(boxW) + self.BlueEntry:SetWide(boxW) + + for i = 1, 3 do + local x = (boxW + PIXEL.Scale(5)) * (i - 1) + + self.RGBAPanel:GetChildren()[i]:SetPos(x, 0) + end + end + end + + self.ColorCube = vgui.Create("PIXEL.ColorCube", self) + self.ColorCube:Dock(FILL) + + self.ColorCube.OnUserChanged = function(ctrl, color) + color.a = self:GetColor().a + self:UpdateColor(color) + end + + self.RGBPicker = vgui.Create("PIXEL.RGBPicker", self) + self.RGBPicker:Dock(BOTTOM) + self.RGBPicker:SetTall(PIXEL.Scale(20)) + self.RGBPicker:DockMargin(0, PIXEL.Scale(10), 0, 0) + self.RGBPicker:SetRGB(Color(255, 0, 0)) + + self.RGBPicker.OnChange = function(ctrl, color) + self:SetBaseColor(color) + self:UpdateNumberEntries(color) + end + + self.AlphaBar = vgui.Create("PIXEL.AlphaBar", self) + self.AlphaBar:Dock(BOTTOM) + self.AlphaBar:SetTall(PIXEL.Scale(20)) + self.AlphaBar:DockMargin(0, PIXEL.Scale(10), 0, 0) + + self.AlphaBar.OnChange = function(ctrl, alpha) + self:GetColor().a = math.floor(alpha * 255) + self:UpdateColor(self:GetColor()) + end + + self:SetColor(Color(255, 0, 0, 255)) + + + -- RGB Picker Changes + self.RedEntry.OnValueChanged = function(s, str) + self:UpdateRGBEntryValues(s, str, "r") + end + + self.GreenEntry.OnValueChanged = function(s, str) + self:UpdateRGBEntryValues(s, str, "g") + end + + self.BlueEntry.OnValueChanged = function(s, str) + self:UpdateRGBEntryValues(s, str, "b") + end + + self.AlphaEntry.OnValueChanged = function(s, str) + if s.Forced then return end + local targetValue = tonumber(num) or 0 + + local color = targetValue + self:GetColor()[type] = color + + self.AlphaBar:SetBarColor(ColorAlpha(color, 255)) + self.AlphaBar:SetValue(targetValue / 255) + + self:UpdateColor(color) + end + + self:SetAlphaBar(true) + self:InvalidateLayout() +end + +function PANEL:SetAlphaBar(enabled) + self.AlphaBarEnabled = enabled + + if IsValid(self.AlphaBar) then + self.AlphaBar:SetVisible(enabled) + end + + if IsValid(self.AlphaEntry) then + self.AlphaEntry:SetVisible(enabled) + end + self:InvalidateLayout() +end + +function PANEL:SetShowRGBA(enabled) + self:SetShowTextEntries(enabled) + self.RGBAPanel:SetVisible(enabled) + self:InvalidateLayout() +end + +function PANEL:SetConVarR(cvar) + self.ConVarRed = cvar +end + +function PANEL:SetConVarG(cvar) + self.ConVarGreen = cvar +end + +function PANEL:SetConVarB(cvar) + self.ConVarBlue = cvar +end + +function PANEL:SetConVarA(cvar) + self.ConVarAlpha = cvar + self:SetAlphaBar(cvar ~= nil) +end + +function PANEL:PerformLayout() + local h, s, v = ColorToHSV(self.ColorCube:GetBaseRGB()) + self.RGBPicker.LastY = (PIXEL.Scale(1) - h / PIXEL.Scale(360)) * self.RGBPicker:GetWide() +end + +function PANEL:TranslateValues(x, y) +end + +function PANEL:SetColor(color) + local h, s, v = ColorToHSV(color) + self.RGBPicker.LastY = (PIXEL.Scale(1) - h / PIXEL.Scale(360)) * self.RGBPicker:GetTall() + self.ColorCube:SetColor(color) + self:UpdateColor(color) +end + +function PANEL:SetVector(vec) + self:SetColor(Color(vec.x * 255, vec.y * 255, vec.z * 255, 255)) +end + +function PANEL:SetBaseColor(color) + self.ColorCube:SetBaseRGB(color) + self.ColorCube:TranslateValues() +end + +function PANEL:UpdateConVar(name, key, color) + if not name then return end + + local col = color[key] + RunConsoleCommand(name, tostring(col)) + self["ConVarOld" .. name] = col +end + +function PANEL:UpdateConVars(color) + self.NextConVarCheck = SysTime() + 0.2 + self:UpdateConVar(self.ConVarRed, 'r', color) + self:UpdateConVar(self.ConVarGreen, 'g', color) + self:UpdateConVar(self.ConVarBlue, 'b', color) + self:UpdateConVar(self.ConVarAlpha, 'a', color) +end + +function PANEL:UpdateColor(color) + self.AlphaBar:SetBarColor(ColorAlpha(color, 255)) + self.AlphaBar:SetValue(color.a / 255) + + if color.r ~= self.RedEntry:GetValue() then + self.RedEntry.Forced = true + self.RedEntry:SetValue(color.r) + self.RedEntry.Forced = nil + end + + if color.g ~= self.GreenEntry:GetValue() then + self.GreenEntry.Forced = true + self.GreenEntry:SetValue(color.r) + self.GreenEntry.Forced = nil + end + + if color.b ~= self.BlueEntry:GetValue() then + self.BlueEntry.Forced = true + self.BlueEntry:SetValue(color.r) + self.BlueEntry.Forced = nil + end + + if color.a ~= self.AlphaEntry:GetValue() then + self.AlphaEntry.Forced = true + self.AlphaEntry:SetValue(color.r) + self.AlphaEntry.Forced = nil + end + + self:UpdateConVars(color) + self:ValueChanged(color) + self.Color = color +end + +function PANEL:ValueChanged(color) +end + +function PANEL:GetColor() + self.Color.a = 255 + + if self.AlphaBar:IsVisible() then + self.Color.a = self.AlphaBar:GetAlpha() + end + + return self.Color +end + +function PANEL:GetVector() + local col = self:GetColor() + + return Vector(col.r / 255, col.g / 255, col.b / 255) +end + +function PANEL:Think() + self:ConVarThink() +end + +function PANEL:ConVarThink() + if input.IsMouseDown(MOUSE_LEFT) then return end + + if self.NextConVarCheck > SysTime() then return end + + local r, changed_r = self:DoConVarThink(self.ConVarRed) + local g, changed_g = self:DoConVarThink(self.ConVarGreen) + local b, changed_b = self:DoConVarThink(self.ConVarBlue) + local a, changed_a = 255, false + + if self.ConVarAlpha then + a, changed_a = self:DoConVarThink(self.ConVarAlpha, "a") + end + + if changed_r or changed_g or changed_b or changed_a then + self:SetColor(Color(r, g, b, a)) + end +end + +function PANEL:DoConVarThink(convar) + if not convar then return end + + local value = GetConVar(convar):GetInt() + local oldValue = self["ConVarOld" .. convar] + + if oldValue and value == oldValue then + return oldValue, false + end + + self["ConVarOld" .. convar] = value + + return value, true +end + +vgui.Register("PIXEL.ColorPickerV2", PANEL, "EditablePanel") \ No newline at end of file From d04f2dd3116b1e0fd718520bffe902808dd96612 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 22:14:53 +0100 Subject: [PATCH 079/155] =?UTF-8?q?=F0=9F=93=B8=20Update=20test=20menu=20t?= =?UTF-8?q?o=20show=20new=20elements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/menus/test/pages/cl_other.lua | 41 +++++++++++++++++------ 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/lua/pixelui/menus/test/pages/cl_other.lua b/lua/pixelui/menus/test/pages/cl_other.lua index a7a39e0..79f7813 100644 --- a/lua/pixelui/menus/test/pages/cl_other.lua +++ b/lua/pixelui/menus/test/pages/cl_other.lua @@ -4,37 +4,58 @@ local PANEL = {} PIXEL.GenerateFont(25) function PANEL:Init() - self.Category = vgui.Create("PIXEL.Category", self) + self.ScrollPanel = vgui.Create("PIXEL.ScrollPanel", self) + self.ScrollPanel:Dock(FILL) + + self.Category = vgui.Create("PIXEL.Category", self.ScrollPanel) self.Category:Dock(TOP) self.Category:DockMargin(sc(10), sc(10), sc(10), sc(10)) self.Category:SetTitle("Categorys!") - self.Slider = vgui.Create("PIXEL.Slider", self) + + self.Slider = vgui.Create("PIXEL.Slider", self.ScrollPanel) self.Slider:Dock(TOP) + self.Slider:SetTall(PIXEL.Scale(20)) self.Slider:DockMargin(sc(50), sc(10), sc(50), sc(10)) - self.LabelledCheckbox = vgui.Create("PIXEL.LabelledCheckbox", self) + + self.LabelledCheckbox = vgui.Create("PIXEL.LabelledCheckbox", self.ScrollPanel) self.LabelledCheckbox:Dock(TOP) self.LabelledCheckbox:DockMargin(sc(50), sc(10), sc(50), sc(10)) self.LabelledCheckbox:SetText("Labelled Checkbox!") self.LabelledCheckbox:SetFont("PIXEL.Font.Size25") - self.ComboBox = vgui.Create("PIXEL.ComboBox", self) + + self.ComboBox = vgui.Create("PIXEL.ComboBox", self.ScrollPanel) self.ComboBox:Dock(TOP) self.ComboBox:DockMargin(sc(50), sc(10), sc(50), sc(10)) self.ComboBox:SetSizeToText(false) + self.ComboBox:AddChoice("Choice 1", "Choice 1", "Choice 1") self.ComboBox:AddChoice("Choice 2", "Choice 2", "Choice 2") self.ComboBox:AddChoice("Choice 3", "Choice 3", "Choice 3") self.ComboBox:AddChoice("Choice 4", "Choice 4", "Choice 4") self.ComboBox:AddChoice("Choice 5", "Choice 5", "Choice 5") - -- self.ColorPicker = vgui.Create("PIXEL.NumberWang", self) - -- self.ColorPicker:Dock(TOP) - -- self.ColorPicker:SetTall(PIXEL.Scale(40)) - self.StepCounter = vgui.Create("PIXEL.StepCounter", self) - self.StepCounter:Dock(FILL) - self.StepCounter:DockMargin(sc(50), sc(10), sc(50), sc(10)) + + self.NumberEntry = vgui.Create("PIXEL.NumberEntry", self.ScrollPanel) + self.NumberEntry:Dock(TOP) + self.NumberEntry:SetTall(PIXEL.Scale(40)) + self.NumberEntry:DockMargin(sc(50), sc(10), sc(50), sc(10)) + + self.StepCounter = vgui.Create("PIXEL.StepCounter", self.ScrollPanel) + self.StepCounter:Dock(TOP) self.StepCounter:SetStepCount(8) + self.StepCounter:SetTall(PIXEL.Scale(90)) + self.StepCounter:DockMargin(sc(50), sc(10), sc(50), sc(10)) + + self.ColorPicker = vgui.Create("PIXEL.ColorPickerV2", self.ScrollPanel) + + self.ScrollPanel.LayoutContent = function(s, w, h) + self.ColorPicker:SetSize(w / 2 - PIXEL.Scale(50), w / 2) + self.ColorPicker:SetPos(PIXEL.Scale(50), self.StepCounter:GetY() + self.StepCounter:GetTall() + PIXEL.Scale(10)) + end end function PANEL:PaintMore(w, h) end + + vgui.Register("PIXEL.Test.Other", PANEL) \ No newline at end of file From a3b76d65041e390f239f9a381d986c27d8e2a8bd Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 22:15:42 +0100 Subject: [PATCH 080/155] =?UTF-8?q?=E2=9E=95=20Add=20back=20color=20picker?= =?UTF-8?q?=20v1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_color_picker.lua | 313 +++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 lua/pixelui/elements/cl_color_picker.lua diff --git a/lua/pixelui/elements/cl_color_picker.lua b/lua/pixelui/elements/cl_color_picker.lua new file mode 100644 index 0000000..cccd93d --- /dev/null +++ b/lua/pixelui/elements/cl_color_picker.lua @@ -0,0 +1,313 @@ + +--[[ +PIXEL UI +Copyright (C) 2021 Tom O'Sullivan (Tom.bat) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +]] + +local PANEL = {} + +local gradientMat = Material("nil") +PIXEL.GetImgur("i0xcO1R", function(mat) + gradientMat = mat +end) + +local colorWheelMat = Material("nil") +PIXEL.GetImgur("k5mtok6", function(mat) + colorWheelMat = mat +end) + +local pickerMat = Material("nil") +PIXEL.GetImgur("t0k86qy", function(mat) + pickerMat = mat +end) + +function PANEL:Init() + self.Hue = 0 + self.SmoothHue = 0 + + self.Lightness = 0 + self.Saturation = 0 + + self.TriX = 0 + self.TriY = 0 + + self:UpdateColor() + self:UpdatePositions() +end + +function PANEL:OnChange(color) end + +function PANEL:UpdateColor() + self.Color = PIXEL.HSLToColor(self.Hue, self.Saturation, self.Lightness) + self:OnChange(self.Color) +end + +function PANEL:SetColor(color) + local h, s, l = ColorToHSL(color) + h = h / (360 / 5) + self.Hue = h + self.Saturation = s + self.Lightness = l + + self.Color = color + self:OnChange(color) + + self:UpdatePositions() +end + +function PANEL:UpdatePositions() + local hue = self.Hue + local third = (2 / 3) * math.pi + local sat = self.Saturation + local light = 1 - self.Lightness + + local hX = math.cos(hue) + local hY = math.sin(hue) + local sX = math.cos(hue - third) + local sY = math.sin(hue - third) + local vX = math.cos(hue + third) + local vY = math.sin(hue + third) + + local mX = (sX + vX) / 2 + local mY = (sY + vY) / 2 + local a = (1 - 2 * math.abs(light - 0.5)) * sat + + self.TriX = sX + (vX - sX) * light + (hX - mX) * a + self.TriY = sY + (vY - sY) * light + (hY - mY) * a +end + +function PANEL:Think() + local cursorX, cursorY = self:CursorPos() + local cX, cY = self:GetCenter() + local triangleRadius = self:GetTriangleRadius() + + if not self.Pressed then return end + + local diffX = cursorX - cX + local diffY = cursorY - cY + local rad = math.atan2(diffY, diffX) + + if rad < 0 then + rad = rad + (2 * math.pi) + end + + if self.PressedWheel then + self.Hue = rad + self:UpdatePositions() + self:UpdateColor() + return + end + + local rad0 = (rad + 2 * math.pi - self.Hue) % (2 * math.pi) + local rad1 = rad0 % ((2 / 3) * math.pi) - (math.pi / 3) + local a = 0.5 * triangleRadius + local b = math.tan(rad1) * a + local r = math.sqrt(diffX * diffX + diffY * diffY) + local maxR = math.sqrt(a * a + b * b) + + if r > maxR then + local dx = math.tan(rad1) * r + local rad2 = math.Clamp(math.atan(dx / maxR), -math.pi / 3, math.pi / 3) + rad = rad + (rad2 - rad1) + rad0 = (rad + 2 * math.pi - self.Hue) % (2 * math.pi) + rad1 = rad0 % ((2 / 3) * math.pi) - (math.pi / 3) + b = math.tan(rad1) * a + maxR = math.sqrt(a * a + b * b) + r = maxR + end + + self.TriX = math.cos(rad) * r / triangleRadius + self.TriY = math.sin(rad) * r / triangleRadius + + local triangleSideLen = math.sqrt(3) * triangleRadius + local light = ((math.sin(rad0) * r) / triangleSideLen) + 0.5 + local widthShare = 1.0 - math.abs(light - 0.5) * 2.0 + local saturation = (((math.cos(rad0) * r) + (triangleRadius / 2)) / (1.5 * triangleRadius)) / widthShare + saturation = math.Clamp(saturation, 0, 1) + + self.Lightness = 1 - light + self.Saturation = saturation + + self:UpdateColor() +end + +function PANEL:OnMousePressed() + self:MouseCapture(true) + self.Pressed = true + + local cX, cY = self:GetCenter() + local cursorX, cursorY = self:CursorPos() + local cursor = Vector(cursorX, cursorY) + local center = Vector(cX, cY, 0) + + if cursor:Distance(center) > self:GetTriangleRadius() then + self.PressedWheel = true + return + end + + self.PressedTriangle = true +end + +function PANEL:OnMouseReleased() + self:MouseCapture(false) + self.Pressed = false + self.PressedWheel = false + self.PressedTriangle = false +end + +function PANEL:GetCenter() + return self:GetWide() / 2, self:GetTall() / 2 +end + +function PANEL:GetRadius() + return self:GetTall() / 2 +end + +function PANEL:GetTriangleRadius() + return self:GetRadius() * 0.7 +end + +function PANEL:GetRingThickness() + return self:GetRadius() * 0.2 +end + +function PANEL:GetHueColor() + return PIXEL.HSLToColor(self.Hue, 1, 0.5) +end + +local whiteTexture = surface.GetTextureID("vgui/white") +function PANEL:Paint(w, h) + local cX, cY = self:GetCenter() + local radius = self:GetRadius() + local triangleRadius = self:GetTriangleRadius() + + surface.SetTexture(whiteTexture) + + local triangleAng = self.Hue + local triangleOff = math.pi * 2 / 3 + local vertices = { + { + x = cX + math.cos(triangleAng - triangleOff) * triangleRadius, + y = cY + math.sin(triangleAng - triangleOff) * triangleRadius, + u = 0.5, + v = 0.99 + }, + { + x = cX + math.cos(triangleAng) * triangleRadius, + y = cY + math.sin(triangleAng) * triangleRadius, + u = 0.99, + v = 0.01 + }, + { + x = cX + math.cos(triangleAng + triangleOff * 1) * triangleRadius, + y = cY + math.sin(triangleAng + triangleOff * 1) * triangleRadius, + u = 0.01, + v = 0.01 + } + } + + local col = self:GetHueColor() + surface.SetDrawColor(col) + surface.DrawPoly(vertices) + + surface.SetDrawColor(255, 255, 255, 255) + surface.SetMaterial(gradientMat) + surface.DrawPoly(vertices) + surface.DrawPoly(vertices) + + vertices[1].u = 0.99 + vertices[1].v = 0.01 + + vertices[2].u = 0.01 + vertices[2].v = 0.01 + + vertices[3].u = 0.5 + vertices[3].v = 0.99 + + surface.SetDrawColor(0, 0, 0, 255) + surface.SetMaterial(gradientMat) + surface.DrawPoly(vertices) + + surface.SetDrawColor(255, 255, 255, 255) + surface.SetMaterial(colorWheelMat) + surface.DrawTexturedRect(cX - radius, cY - radius, radius * 2, radius * 2) + + local pickerSize = PIXEL.Scale(5) + local pickerVerts = { + { + x = cX + self.TriX * triangleRadius + pickerSize, + y = cY + self.TriY * triangleRadius + pickerSize, + u = 1, + v = 1 + }, + { + x = cX + self.TriX * triangleRadius - PIXEL.Scale(5), + y = cY + self.TriY * triangleRadius + PIXEL.Scale(5), + u = 0, + v = 1 + }, + { + x = cX + self.TriX * triangleRadius - PIXEL.Scale(5), + y = cY + self.TriY * triangleRadius - PIXEL.Scale(5), + u = 0, + v = 0 + }, + { + x = cX + self.TriX * triangleRadius + pickerSize, + y = cY + self.TriY * triangleRadius - pickerSize, + u = 1, + v = 0 + } + } + + surface.SetDrawColor(255, 255, 255, 255) + surface.SetMaterial(pickerMat) + surface.DrawPoly(pickerVerts) + + local hpX = cX + math.cos(self.Hue) * (radius - self:GetRingThickness() / 2) + local hpY = cY + math.sin(self.Hue) * (radius - self:GetRingThickness() / 2) + local size = PIXEL.Scale(16) + local huePickerVerts = { + { + x = hpX + size / 2, + y = hpY + size / 2, + u = 1, + v = 1 + }, + { + x = hpX - size / 2, + y = hpY + size / 2, + u = 0, + v = 1 + }, + { + x = hpX - size / 2, + y = hpY - size / 2, + u = 0, + v = 0 + }, + { + x = hpX + size / 2, + y = hpY - size / 2, + u = 1, + v = 0 + } + } + surface.SetDrawColor(255, 255, 255, 255) + surface.SetMaterial(pickerMat) + surface.DrawPoly(huePickerVerts) +end + +vgui.Register("PIXEL.ColorPicker", PANEL, "Panel") \ No newline at end of file From 3666e0d32b1cba259348079ddfea8d1a7947e587 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 6 May 2023 22:22:02 +0100 Subject: [PATCH 081/155] =?UTF-8?q?=F0=9F=94=A5=20no=20more=20wangs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_color_picker_v2.lua | 10 +++++----- lua/pixelui/elements/cl_number_entry.lua | 8 +++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lua/pixelui/elements/cl_color_picker_v2.lua b/lua/pixelui/elements/cl_color_picker_v2.lua index d03b659..022ae1f 100644 --- a/lua/pixelui/elements/cl_color_picker_v2.lua +++ b/lua/pixelui/elements/cl_color_picker_v2.lua @@ -24,7 +24,7 @@ AccessorFunc(PANEL, "ConVarAlpha", "ConVarAlpha") AccessorFunc(PANEL, "AlphaBarEnabled", "AlphaBar", FORCE_BOOL) AccessorFunc(PANEL, "ShowTextEntries", "ShowTextEntries", FORCE_BOOL) AccessorFunc(PANEL, "Color", "Color") -PIXEL.RegisterFont("UI.ColorPickerWang", "Rubik", 14) +PIXEL.RegisterFont("UI.ColorPickerNumberEntry", "Rubik", 14) function PANEL:UpdateRGBEntryValues(panel, num, rgbType) if panel.Forced then return end @@ -60,7 +60,7 @@ function PANEL:Init() self.RedEntry:SetMax(255) self.RedEntry:SetTall(PIXEL.Scale(25)) self.RedEntry:SetWide(PIXEL.Scale(60)) - self.RedEntry:SetFont("UI.ColorPickerWang", true) + self.RedEntry:SetFont("UI.ColorPickerNumberEntry", true) self.RedEntry.OutlineCol = Color(238, 75, 43) self.GreenEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") @@ -68,14 +68,14 @@ function PANEL:Init() self.GreenEntry:SetMax(255) self.GreenEntry:SetTall(PIXEL.Scale(25)) self.GreenEntry:SetWide(PIXEL.Scale(60)) - self.GreenEntry.TextEntry:SetFont("UI.ColorPickerWang", true) + self.GreenEntry.TextEntry:SetFont("UI.ColorPickerNumberEntry", true) self.GreenEntry.OutlineCol = Color(170, 255, 0) self.BlueEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") self.BlueEntry:SetMin(0) self.BlueEntry:SetMax(255) self.BlueEntry:SetTall(PIXEL.Scale(25)) - self.BlueEntry.TextEntry:SetFont("UI.ColorPickerWang", true) + self.BlueEntry.TextEntry:SetFont("UI.ColorPickerNumberEntry", true) self.BlueEntry.OutlineCol = Color(0, 100, 255) self.AlphaEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") @@ -83,7 +83,7 @@ function PANEL:Init() self.AlphaEntry:SetMax(255) self.AlphaEntry:SetTall(PIXEL.Scale(25)) self.AlphaEntry:SetWide(PIXEL.Scale(60)) - self.AlphaEntry.TextEntry:SetFont("UI.ColorPickerWang", true) + self.AlphaEntry.TextEntry:SetFont("UI.ColorPickerNumberEntry", true) self.RGBAPanel.PerformLayout = function(s, w, h) local boxH = PIXEL.Scale(30) diff --git a/lua/pixelui/elements/cl_number_entry.lua b/lua/pixelui/elements/cl_number_entry.lua index bfdb845..6f7e125 100644 --- a/lua/pixelui/elements/cl_number_entry.lua +++ b/lua/pixelui/elements/cl_number_entry.lua @@ -1,13 +1,15 @@ local PANEL = {} -AccessorFunc(PANEL, "HideWang", "HideWang", FORCE_BOOL) +AccessorFunc(PANEL, "HideButtons", "HideButtons", FORCE_BOOL) AccessorFunc(PANEL, "Interval", "Interval", FORCE_NUMBER) +AccessorFunc(PANEL, "UseChips", "UseChips", FORCE_BOOL) AccessorFunc(PANEL, "Min", "Min", FORCE_NUMBER) AccessorFunc(PANEL, "Max", "Max", FORCE_NUMBER) function PANEL:Init() - self:SetHideWang(false) + self:SetHideButtons(false) self:SetNumeric(true) + self:SetUseChips(true) self:SetInterval(1) self:SetValue(1) self:SetMin(1) @@ -76,7 +78,7 @@ function PANEL:Init() end function PANEL:LayoutContent(w, h) - if self:GetHideWang() then + if self:GetHideButtons() then self.UpButton:SetVisible(false) self.DownButton:SetVisible(false) end From b691334d268311a55ae417cd33b34c54aca388df Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 17 May 2023 16:35:48 +0100 Subject: [PATCH 082/155] fix: Placeholder text not showing --- lua/pixelui/elements/cl_text_entry.lua | 29 +++++++++++++------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 4051fb2..4fdd51b 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -47,20 +47,6 @@ function PANEL:LayoutContent(w, h) end function PANEL:Paint(w, h) - if not self:IsEnabled() then - PIXEL.DrawRoundedBox(4, 0, 0, w, h, self.DisabledCol) - end - - if not self:IsEnabled() and self:GetValue() == "" then - PIXEL.DrawSimpleText(self:GetPlaceholderText() or "", "UI.TextEntry", PIXEL.Scale(10), h / 2, self.PlaceholderTextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) - - return - end - - if self:GetValue() == "" then - PIXEL.DrawSimpleText(self:GetPlaceholderText() or "", "UI.TextEntry", PIXEL.Scale(10), h / 2, self.PlaceholderTextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) - end - local outlineThickness = PIXEL.Scale(1) PIXEL.DrawFullOutlinedRoundedBox(8, 0, 0, w, h, self.OutlineCol, outlineThickness) local col = PIXEL.Colors.Transparent @@ -75,6 +61,21 @@ function PANEL:Paint(w, h) self.InnerOutlineCol = PIXEL.LerpColor(FrameTime() * 8, self.InnerOutlineCol, col) PIXEL.DrawFullOutlinedRoundedBox(8, 0, 0, w, h, self.InnerOutlineCol, outlineThickness) + + if not self:IsEnabled() then + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.DisabledCol) + return + end + + if not self:IsEnabled() and self:GetValue() == "" then + PIXEL.DrawSimpleText(self:GetPlaceholderText() or "", "UI.TextEntry", PIXEL.Scale(10), h / 2, self.PlaceholderTextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + + return + end + + if self:GetValue() == "" then + PIXEL.DrawSimpleText(self:GetPlaceholderText() or "", "UI.TextEntry", PIXEL.Scale(10), h / 2, self.PlaceholderTextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + end end function PANEL:OnChange() From 691a208670933a2f5f5cfebe530fc8fab278d8a2 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 17 May 2023 16:37:39 +0100 Subject: [PATCH 083/155] random stuff --- lua/pixelui/core/cl_scaling.lua | 2 +- lua/pixelui/elements/cl_number_entry.lua | 2 -- lua/pixelui/menus/test/pages/cl_text.lua | 19 ++++++++----------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/lua/pixelui/core/cl_scaling.lua b/lua/pixelui/core/cl_scaling.lua index 534f703..4b48aa6 100644 --- a/lua/pixelui/core/cl_scaling.lua +++ b/lua/pixelui/core/cl_scaling.lua @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ]] -local scrH = scrH or ScrH() +local scrH = ScrH() function PIXEL.Scale(value) return value * (scrH / 1080) end diff --git a/lua/pixelui/elements/cl_number_entry.lua b/lua/pixelui/elements/cl_number_entry.lua index 6f7e125..17a75f6 100644 --- a/lua/pixelui/elements/cl_number_entry.lua +++ b/lua/pixelui/elements/cl_number_entry.lua @@ -2,14 +2,12 @@ local PANEL = {} AccessorFunc(PANEL, "HideButtons", "HideButtons", FORCE_BOOL) AccessorFunc(PANEL, "Interval", "Interval", FORCE_NUMBER) -AccessorFunc(PANEL, "UseChips", "UseChips", FORCE_BOOL) AccessorFunc(PANEL, "Min", "Min", FORCE_NUMBER) AccessorFunc(PANEL, "Max", "Max", FORCE_NUMBER) function PANEL:Init() self:SetHideButtons(false) self:SetNumeric(true) - self:SetUseChips(true) self:SetInterval(1) self:SetValue(1) self:SetMin(1) diff --git a/lua/pixelui/menus/test/pages/cl_text.lua b/lua/pixelui/menus/test/pages/cl_text.lua index 5eae5a7..b965c28 100644 --- a/lua/pixelui/menus/test/pages/cl_text.lua +++ b/lua/pixelui/menus/test/pages/cl_text.lua @@ -5,30 +5,27 @@ local PANEL = {} function PANEL:Init() self.TextEntry = vgui.Create("PIXEL.TextEntry", self) self.TextEntry:Dock(TOP) - self.TextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) + self.TextEntry:DockMargin(sc(20), sc(20), sc(20), 0) self.TextEntry:SetTall(sc(35)) self.TextEntry:SetPlaceholderText("Placeholder Text!") self.BadValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) self.BadValidatedTextEntry:Dock(TOP) - self.BadValidatedTextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) + self.BadValidatedTextEntry:DockMargin(sc(20), sc(20), sc(20), 0) self.BadValidatedTextEntry:SetPlaceholderText("Bad Text!") function self.BadValidatedTextEntry:IsTextValid(text) - return false, "Bad Text!" - end + return false, "Bad Text!" + end self.GoodValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) self.GoodValidatedTextEntry:Dock(TOP) - self.GoodValidatedTextEntry:DockMargin(sc(20), sc(0), sc(20), sc(20)) + self.GoodValidatedTextEntry:DockMargin(sc(20), sc(0), sc(20), 0) self.GoodValidatedTextEntry:SetPlaceholderText("Good Text!") - function self.GoodValidatedTextEntry:IsTextValid(text) - return true, "Good Text!" - end -end - -function PANEL:PaintMore(w,h) + function self.GoodValidatedTextEntry:IsTextValid(text) + return true, "Good Text!" + end end vgui.Register("PIXEL.Test.Text", PANEL) \ No newline at end of file From bf2334bffde6dbc66359acfc8bed79cd659fcba9 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 17 May 2023 16:37:47 +0100 Subject: [PATCH 084/155] change primary color again --- lua/autorun/sh_pixelui_loader.lua | 2 +- lua/pixelui/core/themes/cl_themes.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 9409b3b..0ef6d4d 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -28,7 +28,7 @@ PIXEL.Colors = { SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), -- - Primary = Color(2, 153, 204), + Primary = Color(43, 157, 203), Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), Negative = Color(235, 68, 68), diff --git a/lua/pixelui/core/themes/cl_themes.lua b/lua/pixelui/core/themes/cl_themes.lua index a279f23..83e174b 100644 --- a/lua/pixelui/core/themes/cl_themes.lua +++ b/lua/pixelui/core/themes/cl_themes.lua @@ -12,7 +12,7 @@ PIXEL.Themes["Dark"] = { PrimaryText = Color(255, 255, 255), SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - Primary = Color(2, 153, 204), + Primary = Color(43, 157, 203), Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), Negative = Color(235, 68, 68), From 6e40f7d7b29487cce0c58f27353376b51c30711d Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 17 May 2023 20:38:50 +0100 Subject: [PATCH 085/155] feat: Make colors actualy be what they should be --- lua/autorun/sh_pixelui_loader.lua | 39 ++++++++++++++------------- lua/pixelui/core/themes/cl_themes.lua | 20 -------------- 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 0ef6d4d..d90d24d 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -18,29 +18,30 @@ PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} PIXEL.UI.Version = "1.3.1" -PIXEL.Colors = { - Background = Color(22, 22, 22), - Header = Color(28, 28, 28), - SecondaryHeader = Color(15, 15, 15), - Scroller = Color(61, 61, 61), - -- +PIXEL.Themes = PIXEL.Themes or {} + +PIXEL.Themes["Dark"] = { + included = true, + Background = Color(29, 29, 29), + Header = Color(34, 34, 34), + SecondaryHeader = Color(47, 47, 47), + Scroller = Color(63, 63, 63), PrimaryText = Color(255, 255, 255), - SecondaryText = Color(220, 220, 220), - DisabledText = Color(40, 40, 40), - -- - Primary = Color(43, 157, 203), - Disabled = Color(180, 180, 180), - Positive = Color(68, 235, 124), - Negative = Color(235, 68, 68), - -- - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - -- + SecondaryText = Color(219, 219, 219), + DisabledText = Color(44, 44, 44), + Primary = Color(86, 86, 255), + Disabled = Color(178, 178, 178), + Positive = Color(0, 168, 107), + Negative = Color(234, 70, 70), + Diamond = Color(184, 242, 255), + Gold = Color(255, 214, 0), + Silver = Color(191, 191, 191), + Bronze = Color(144, 94, 52), Transparent = Color(0, 0, 0, 0) } +PIXEL.Colors = PIXEL.Themes["Dark"] + function PIXEL.Warn(...) MsgC(PIXEL.Colors.Gold, "[PIXEL UI - Warning] ", PIXEL.Colors.Negative, ..., "\n") end diff --git a/lua/pixelui/core/themes/cl_themes.lua b/lua/pixelui/core/themes/cl_themes.lua index 83e174b..ed4b88b 100644 --- a/lua/pixelui/core/themes/cl_themes.lua +++ b/lua/pixelui/core/themes/cl_themes.lua @@ -3,26 +3,6 @@ PIXEL.Themes = PIXEL.Themes or {} PIXEL.DefaultThemes = PIXEL.DefaultThemes or {"Dark", "Light", "GitHubDark", "NightOwl", "DiscordDark", "DiscordLight"} -PIXEL.Themes["Dark"] = { - included = true, - Background = Color(22, 22, 22), - Header = Color(28, 28, 28), - SecondaryHeader = Color(43, 43, 43), - Scroller = Color(61, 61, 61), - PrimaryText = Color(255, 255, 255), - SecondaryText = Color(220, 220, 220), - DisabledText = Color(40, 40, 40), - Primary = Color(43, 157, 203), - Disabled = Color(180, 180, 180), - Positive = Color(68, 235, 124), - Negative = Color(235, 68, 68), - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) -} - PIXEL.Themes["Light"] = { included = true, Background = PIXEL.HexToColor("#F7F8FA"), From cc957c0a20ddfadc05ead1b5ddd01bbf38108527 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 17 May 2023 20:39:08 +0100 Subject: [PATCH 086/155] what the fuck even is this for --- lua/pixelui/elements/cl_labelled_checkbox.lua | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/lua/pixelui/elements/cl_labelled_checkbox.lua b/lua/pixelui/elements/cl_labelled_checkbox.lua index 9a282ed..b55eb81 100644 --- a/lua/pixelui/elements/cl_labelled_checkbox.lua +++ b/lua/pixelui/elements/cl_labelled_checkbox.lua @@ -25,16 +25,9 @@ function PANEL:Init() self:OnToggled(enabled) end - self.LabelHolder = vgui.Create("Panel", self) - self.Label = vgui.Create("PIXEL.Label", self.LabelHolder) + self.Label = vgui.Create("PIXEL.Label", self) self.Label:SetAutoWidth(true) self.Label:SetAutoHeight(true) - - self.LabelHolder.PerformLayout = function(s, w, h) - self.Label:CenterVertical() - s:SizeToChildren(true, true) - self:SizeToChildren(true, true) - end end function PANEL:PerformLayout(w, h) @@ -42,7 +35,7 @@ function PANEL:PerformLayout(w, h) self.Checkbox:SetWide(h) self.Checkbox:DockMargin(0, 0, PIXEL.Scale(6), 0) - self.LabelHolder:Dock(LEFT) + self.Label:SetPos(self.Checkbox:GetWide() + PIXEL.Scale(6), (h / 2) - (self.Label:GetTall() / 2) + 1) end function PANEL:OnToggled(enabled) end From bb778bb2da5b4f525eb5907dbabd48f74c9d9e6e Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 17 May 2023 20:39:15 +0100 Subject: [PATCH 087/155] fix some minor issues --- lua/pixelui/elements/cl_imgur_button.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/elements/cl_imgur_button.lua b/lua/pixelui/elements/cl_imgur_button.lua index 1a9ac8c..f37890b 100644 --- a/lua/pixelui/elements/cl_imgur_button.lua +++ b/lua/pixelui/elements/cl_imgur_button.lua @@ -47,11 +47,11 @@ function PANEL:Paint(w, h) end local imageSize = h * self:GetImageSize() - local imageOffset = (h - imageSize) / 2 + local imageOffset = (h / 2) - (imageSize / 2) if self:GetFrameEnabled() then imageSize = imageSize * .45 - imageOffset = (h - imageSize) / 2 + PIXEL.Scale(1) + imageOffset = (h / 2) - (imageSize / 2) + PIXEL.Scale(1) end if not self:IsEnabled() then From 72d309c327b287dc11973a7cea6d0bd4a9c917cb Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 31 May 2023 18:28:47 +0100 Subject: [PATCH 088/155] feat: Add support for PIXEL.ComboBox icons back --- lua/autorun/sh_pixelui_loader.lua | 2 +- lua/pixelui/elements/cl_button.lua | 40 +++------------------ lua/pixelui/elements/cl_category.lua | 1 - lua/pixelui/elements/cl_combo_box.lua | 11 ++++-- lua/pixelui/elements/cl_imgur_button.lua | 1 - lua/pixelui/elements/cl_menu.lua | 21 +---------- lua/pixelui/elements/cl_menu_option.lua | 24 ++++++------- lua/pixelui/elements/cl_mini_sidebar.lua | 1 - lua/pixelui/elements/cl_navbar.lua | 1 - lua/pixelui/elements/cl_property_sheet.lua | 1 - lua/pixelui/elements/cl_sidebar.lua | 1 - lua/pixelui/elements/cl_slider.lua | 1 - lua/pixelui/elements/cl_text_button.lua | 30 ++++++++++------ lua/pixelui/menus/test/pages/cl_buttons.lua | 19 ---------- 14 files changed, 45 insertions(+), 109 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index d90d24d..1373332 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -29,7 +29,7 @@ PIXEL.Themes["Dark"] = { PrimaryText = Color(255, 255, 255), SecondaryText = Color(219, 219, 219), DisabledText = Color(44, 44, 44), - Primary = Color(86, 86, 255), + Primary = Color(46, 83, 148), Disabled = Color(178, 178, 178), Positive = Color(0, 168, 107), Negative = Color(234, 70, 70), diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index fa052e7..4a3cc97 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -17,7 +17,6 @@ along with this program. If not, see . local PANEL = {} AccessorFunc(PANEL, "IsToggle", "IsToggle", FORCE_BOOL) AccessorFunc(PANEL, "Toggle", "Toggle", FORCE_BOOL) -AccessorFunc(PANEL, "Clicky", "Clicky", FORCE_BOOL) AccessorFunc(PANEL, "Sounds", "Sounds", FORCE_BOOL) function PANEL:Init() @@ -25,7 +24,7 @@ function PANEL:Init() self:SetToggle(false) self:SetMouseInputEnabled(true) self:SetCursor("hand") - self:SetClicky(false) + self:SetSounds(true) local btnSize = PIXEL.Scale(30) self:SetSize(btnSize, btnSize) @@ -33,26 +32,8 @@ function PANEL:Init() self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) - self.ClickyCol = PIXEL.OffsetColor(self.NormalCol, -35) self.BackgroundCol = self.NormalCol - self.BackgroundClickyCol = self.ClickyCol - self.ClickyScale = PIXEL.Scale(3) - self.Clicky = self:GetClicky() - self.ClickyMove = false -end -function PANEL:PerformLayout() - local tall = self:GetTall() - - if tall > 75 then - self.ClickyScale = self:GetTall() / 25 - elseif tall > 50 then - self.ClickyScale = self:GetTall() / 17 - elseif tall > 25 then - self.ClickyScale = self:GetTall() / 10 - elseif tall > 15 then - self.ClickyScale = self:GetTall() / 5 - end end function PANEL:DoToggle(...) @@ -65,7 +46,6 @@ local localPly function PANEL:OnMousePressed(mouseCode) if not self:IsEnabled() then return end - self.ClickyMove = true if self:GetSounds() then PIXEL.PlayButtonSound() @@ -86,7 +66,6 @@ function PANEL:OnMouseReleased(mouseCode) self:MouseCapture(false) if not self:IsEnabled() then return end if not self.Depressed and dragndrop.m_DraggingMain ~= self then return end - self.ClickyMove = false if self.Depressed then self.Depressed = nil @@ -132,24 +111,13 @@ function PANEL:Paint(w, h) if self:IsDown() or self:GetToggle() then bgCol = self.ClickedCol - elseif self:IsHovered() and not self.Clicky then + elseif self:IsHovered() then bgCol = self.HoverCol end - if not self.Clicky then - self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) - end + self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) - if not self:GetClicky() then - PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol) - else - if self.ClickyMove then - PIXEL.DrawRoundedBox(8, 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) - else - PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.ClickyCol) - PIXEL.DrawRoundedBox(8, 0, 0, w, h - self.ClickyScale, self.BackgroundCol) - end - end + PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, self.BackgroundCol) self:PaintExtra(w, h) end diff --git a/lua/pixelui/elements/cl_category.lua b/lua/pixelui/elements/cl_category.lua index 5e0b459..79e9a9a 100644 --- a/lua/pixelui/elements/cl_category.lua +++ b/lua/pixelui/elements/cl_category.lua @@ -20,7 +20,6 @@ PIXEL.RegisterFont("UI.CategoryHeader", "Rubik", 19, 600) function PANEL:Init() self.ArrowRotation = 0 - self:SetClicky(false) self.BackgroundCol = PIXEL.Colors.Header end diff --git a/lua/pixelui/elements/cl_combo_box.lua b/lua/pixelui/elements/cl_combo_box.lua index 17950bd..7573398 100644 --- a/lua/pixelui/elements/cl_combo_box.lua +++ b/lua/pixelui/elements/cl_combo_box.lua @@ -25,7 +25,6 @@ AccessorFunc(PANEL, "m_bDoSort", "SortItems", FORCE_BOOL) function PANEL:Init() self:SetSizeToText(true) - self:SetClicky(false) self:Clear() self:SetTextAlign(TEXT_ALIGN_LEFT) @@ -85,6 +84,13 @@ function PANEL:ChooseOption(value, index) self:SetText(value) self.selected = index + local choicesKey = table.KeyFromValue(self.Choices, value) + + if self.ChoiceIcons[choicesKey] then + self:SetIcon(self.ChoiceIcons[choicesKey]) + else + self:SetIcon(nil) + end self:OnSelect(index, value, self.Data[index]) if not self:GetSizeToText() then return end @@ -206,7 +212,8 @@ function PANEL:SetValue(strValue) end function PANEL:DoClick() - if not self:IsMenuOpen() then self:OpenMenu() end + if self:IsMenuOpen() then return self:CloseMenu() end + self:OpenMenu() end function PANEL:OnOpen() diff --git a/lua/pixelui/elements/cl_imgur_button.lua b/lua/pixelui/elements/cl_imgur_button.lua index f37890b..4d42611 100644 --- a/lua/pixelui/elements/cl_imgur_button.lua +++ b/lua/pixelui/elements/cl_imgur_button.lua @@ -31,7 +31,6 @@ function PANEL:Init() self:SetHoverColor(color_white) self:SetClickColor(color_white) self:SetDisabledColor(color_white) - self:SetClicky(false) self:SetImageSize(1) self:SetFrameEnabled(false) end diff --git a/lua/pixelui/elements/cl_menu.lua b/lua/pixelui/elements/cl_menu.lua index 37e77ef..3c22d75 100644 --- a/lua/pixelui/elements/cl_menu.lua +++ b/lua/pixelui/elements/cl_menu.lua @@ -201,29 +201,10 @@ function PANEL:Open(x, y, skipanimation, ownerpanel) self:MakePopup() self:SetVisible(true) self:SetKeyboardInputEnabled(false) - self.DrawTall = PIXEL.Scale(0) - local children = self:GetCanvas():GetChildren() - local childTall = children[1]:GetTall() - local childCount = 1 - - for k, v in pairs(children) do - v:Hide(false) - end - - timer.Create("PIXEL.Menu.Open", 0.025, self:ChildCount(), function() - if not IsValid(self) then return end - self.DrawTall = self.DrawTall + childTall - children[childCount]:Show(true) - childCount = childCount + 1 - - if self:ChildCount() == childCount then - self.DrawTall = self:GetTall() - end - end) end function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(8, 0, 0, w, self.DrawTall, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol) end function PANEL:OptionSelectedInternal(option) diff --git a/lua/pixelui/elements/cl_menu_option.lua b/lua/pixelui/elements/cl_menu_option.lua index 3b09240..ba2dedf 100644 --- a/lua/pixelui/elements/cl_menu_option.lua +++ b/lua/pixelui/elements/cl_menu_option.lua @@ -21,29 +21,18 @@ AccessorFunc(PANEL, "m_bCheckable", "IsCheckable") AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) +AccessorFunc(PANEL, "Icon", "Icon", FORCE_STRING) PIXEL.RegisterFont("UI.MenuOption", "Rubik", 18, 600) -function PANEL:Hide() - self.Hidden = true -end - -function PANEL:Show() - self.Hidden = false -end - function PANEL:Init() self:SetTextAlign(TEXT_ALIGN_LEFT) self:SetFont("UI.MenuOption") self:SetChecked(false) - self:SetClicky(false) self.NormalCol = PIXEL.Colors.Transparent self.HoverCol = PIXEL.Colors.Scroller self.BackgroundCol = PIXEL.CopyColor(self.NormalCol) end -function PANEL:SetIcon() -end - function PANEL:SetSubMenu(menu) self.SubMenu = menu end @@ -73,10 +62,17 @@ function PANEL:OnCursorExited() end function PANEL:Paint(w, h) - if self.Hidden then return end self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, self:IsHovered() and self.HoverCol or self.NormalCol) PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol) - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), PIXEL.Scale(14), h / 2, PIXEL.Colors.PrimaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + + local iconSize = 0 + if self:GetIcon() then + iconSize = self:GetTall() * .6 + PIXEL.DrawImgur(PIXEL.Scale(8), h / 2 - iconSize / 2, iconSize, iconSize, self:GetIcon(), PIXEL.Colors.PrimaryText) + end + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), PIXEL.Scale(14) + iconSize, h / 2, PIXEL.Colors.PrimaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + + if not self.SubMenu then return end local dropBtnSize = PIXEL.Scale(8) PIXEL.DrawImgur(w - dropBtnSize - PIXEL.Scale(6), h / 2 - dropBtnSize / 2, dropBtnSize, dropBtnSize, "gXg3U6X", PIXEL.Colors.PrimaryText) diff --git a/lua/pixelui/elements/cl_mini_sidebar.lua b/lua/pixelui/elements/cl_mini_sidebar.lua index 78ed208..4947d3b 100644 --- a/lua/pixelui/elements/cl_mini_sidebar.lua +++ b/lua/pixelui/elements/cl_mini_sidebar.lua @@ -23,7 +23,6 @@ PIXEL.RegisterFont("SidebarItem", "Rubik", 19) function PANEL:Init() self:SetName("N/A") self:SetDrawOutline(true) - self:SetClicky(false) self:SetSounds(false) self:SetTooltip(self:GetName() or "N/A") self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) diff --git a/lua/pixelui/elements/cl_navbar.lua b/lua/pixelui/elements/cl_navbar.lua index f34ade5..8f0c7ec 100644 --- a/lua/pixelui/elements/cl_navbar.lua +++ b/lua/pixelui/elements/cl_navbar.lua @@ -14,7 +14,6 @@ end function PANEL:Init() self:SetName("N/A") self:SetColor(PIXEL.Colors.Primary) - self:SetClicky(false) self:SetSounds(false) self:SetImgurScale(0.2) self.NormalCol = PIXEL.Colors.PrimaryText diff --git a/lua/pixelui/elements/cl_property_sheet.lua b/lua/pixelui/elements/cl_property_sheet.lua index bdc3c28..f17951f 100644 --- a/lua/pixelui/elements/cl_property_sheet.lua +++ b/lua/pixelui/elements/cl_property_sheet.lua @@ -21,7 +21,6 @@ AccessorFunc(PANEL, "m_pPanel", "Panel") PIXEL.RegisterFont("UI.Tab", "Rubik", 16) function PANEL:Init() - self:SetClicky(false) self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, -4) self.SelectedCol = PIXEL.Colors.Primary self.UnselectedTextCol = PIXEL.Colors.SecondaryText diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 77573a9..e30e363 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -7,7 +7,6 @@ PIXEL.RegisterFont("SidebarItem", "Rubik", 19, 600) function PANEL:Init() self:SetName("N/A") self:SetDrawOutline(true) - self:SetClicky(false) self:SetSounds(false) self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) diff --git a/lua/pixelui/elements/cl_slider.lua b/lua/pixelui/elements/cl_slider.lua index 828df91..12f0f57 100644 --- a/lua/pixelui/elements/cl_slider.lua +++ b/lua/pixelui/elements/cl_slider.lua @@ -17,7 +17,6 @@ along with this program. If not, see . local PANEL = {} function PANEL:Init() - self:SetClicky(false) self.Fraction = 0 self.Grip = vgui.Create("PIXEL.Button", self) self.Grip:NoClipping(true) diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index c20ee40..e953652 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -19,6 +19,7 @@ AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) AccessorFunc(PANEL, "TextSpacing", "TextSpacing", FORCE_NUMBER) AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) +AccessorFunc(PANEL, "Icon", "Icon") PIXEL.RegisterFont("UI.TextButton", "Rubik", 20, 600) @@ -28,32 +29,41 @@ function PANEL:Init() self:SetTextSpacing(PIXEL.Scale(6)) self:SetFont("UI.TextButton") self:SetSize(PIXEL.Scale(100), PIXEL.Scale(30)) - self:SetClicky(true) self:SetSounds(true) + self:SetIcon(false) end function PANEL:SizeToText() PIXEL.SetFont(self:GetFont()) - self:SetSize(PIXEL.GetTextSize(self:GetText()) + PIXEL.Scale(14), PIXEL.Scale(30)) + + if self:GetIcon() then + local iconSize = self:GetTall() * .6 + self:SetSize(PIXEL.GetTextSize(self:GetText()) + PIXEL.Scale(20) + iconSize, PIXEL.Scale(30)) + return + end + + self:SetSize(PIXEL.GetTextSize(self:GetText()) + PIXEL.Scale(14) , PIXEL.Scale(30)) end function PANEL:PaintExtra(w, h) local textAlign = self:GetTextAlign() local textX = (textAlign == TEXT_ALIGN_CENTER and w / 2) or (textAlign == TEXT_ALIGN_RIGHT and w - self:GetTextSpacing()) or self:GetTextSpacing() + local iconSize = 0 + + if self:GetIcon() then + print("icon", self:GetIcon()) + iconSize = self:GetTall() * .6 + PIXEL.DrawImgur(PIXEL.Scale(8), h / 2 - iconSize / 2, iconSize, iconSize, self:GetIcon(), PIXEL.Colors.PrimaryText) + end + if not self:IsEnabled() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.DisabledText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX + iconSize + PIXEL.Scale(8), h / 2, PIXEL.Colors.DisabledText, textAlign, TEXT_ALIGN_CENTER) return end - if self.ClickyMove and self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) - elseif self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) - else - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) - end + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX + iconSize + PIXEL.Scale(6), h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) end vgui.Register("PIXEL.TextButton", PANEL, "PIXEL.Button") \ No newline at end of file diff --git a/lua/pixelui/menus/test/pages/cl_buttons.lua b/lua/pixelui/menus/test/pages/cl_buttons.lua index 9f2ec89..44e1878 100644 --- a/lua/pixelui/menus/test/pages/cl_buttons.lua +++ b/lua/pixelui/menus/test/pages/cl_buttons.lua @@ -12,30 +12,11 @@ function PANEL:Init() notification.AddLegacy("Normal Button!", NOTIFY_GENERIC, 5) end - self.ClickyButton = vgui.Create("PIXEL.Button", self) - self.ClickyButton:Dock(TOP) - self.ClickyButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.ClickyButton:SetTall(sc(50)) - self.ClickyButton:SetClicky(true) - self.ClickyButton.DoClick = function() - notification.AddLegacy("Normal Clicky Button!", NOTIFY_GENERIC, 5) - end - - self.ClickyTextButton = vgui.Create("PIXEL.TextButton", self) - self.ClickyTextButton:Dock(TOP) - self.ClickyTextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.ClickyTextButton:SetTall(sc(50)) - self.ClickyTextButton:SetText("Clicky Button!") - self.ClickyTextButton.DoClick = function() - notification.AddLegacy("Clicky Text Button!", NOTIFY_GENERIC, 5) - end - self.TextButton = vgui.Create("PIXEL.TextButton", self) self.TextButton:Dock(TOP) self.TextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) self.TextButton:SetTall(sc(50)) self.TextButton:SetText("Non Clicky Button!") - self.TextButton:SetClicky(false) self.TextButton.DoClick = function() notification.AddLegacy("Non Clicky Text button!", NOTIFY_GENERIC, 5) end From de0b952cfe30e4d9fc42f6a93450b8e06d022c70 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:41:42 +0100 Subject: [PATCH 089/155] fix: Text button offset --- lua/pixelui/elements/cl_text_button.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index e953652..7307b3b 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -52,18 +52,18 @@ function PANEL:PaintExtra(w, h) local iconSize = 0 if self:GetIcon() then - print("icon", self:GetIcon()) iconSize = self:GetTall() * .6 PIXEL.DrawImgur(PIXEL.Scale(8), h / 2 - iconSize / 2, iconSize, iconSize, self:GetIcon(), PIXEL.Colors.PrimaryText) + iconSize = iconSize + PIXEL.Scale(6) end if not self:IsEnabled() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX + iconSize + PIXEL.Scale(8), h / 2, PIXEL.Colors.DisabledText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX + iconSize, h / 2, PIXEL.Colors.DisabledText, textAlign, TEXT_ALIGN_CENTER) return end - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX + iconSize + PIXEL.Scale(6), h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX + iconSize, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) end vgui.Register("PIXEL.TextButton", PANEL, "PIXEL.Button") \ No newline at end of file From b419dae5ce97a88e1e7840ff876dc9ee1e589f71 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 13 Jun 2023 15:47:02 +0100 Subject: [PATCH 090/155] more color picker stuff --- lua/pixelui/elements/cl_alpha_bar.lua | 70 ---- lua/pixelui/elements/cl_color_cube.lua | 124 ------ lua/pixelui/elements/cl_color_picker_v2.lua | 352 ------------------ .../elements/color_picker_v2/cl_alpha_bar.lua | 72 ++++ .../color_picker_v2/cl_color_picker_v2.lua | 240 ++++++++++++ .../cl_hue_bar.lua} | 51 +-- .../color_picker_v2/cl_luminosity_bar.lua | 108 ++++++ .../color_picker_v2/cl_saturation_bar.lua | 88 +++++ lua/pixelui/menus/test/pages/cl_other.lua | 3 +- 9 files changed, 539 insertions(+), 569 deletions(-) delete mode 100644 lua/pixelui/elements/cl_alpha_bar.lua delete mode 100644 lua/pixelui/elements/cl_color_cube.lua delete mode 100644 lua/pixelui/elements/cl_color_picker_v2.lua create mode 100644 lua/pixelui/elements/color_picker_v2/cl_alpha_bar.lua create mode 100644 lua/pixelui/elements/color_picker_v2/cl_color_picker_v2.lua rename lua/pixelui/elements/{cl_rgb_picker.lua => color_picker_v2/cl_hue_bar.lua} (61%) create mode 100644 lua/pixelui/elements/color_picker_v2/cl_luminosity_bar.lua create mode 100644 lua/pixelui/elements/color_picker_v2/cl_saturation_bar.lua diff --git a/lua/pixelui/elements/cl_alpha_bar.lua b/lua/pixelui/elements/cl_alpha_bar.lua deleted file mode 100644 index c48d3af..0000000 --- a/lua/pixelui/elements/cl_alpha_bar.lua +++ /dev/null @@ -1,70 +0,0 @@ -local PANEL = {} -local clamp = math.Clamp -local floor = math.floor -AccessorFunc(PANEL, "Value", "Value") -AccessorFunc(PANEL, "Alpha", "Alpha") -AccessorFunc(PANEL, "BarColor", "BarColor") - -function PANEL:Init() - self:SetBarColor(color_white) - self:SetSize(PIXEL.Scale(26), PIXEL.Scale(26)) - self:SetValue(1) - self:SetAlpha(255) - self.LastX = 0 -end - -function PANEL:OnCursorMoved(x, y) - if not input.IsMouseDown(MOUSE_LEFT) then return end - - local wide = x / self:GetWide() - local value = 1 - clamp(wide, 0, 1) - - self.LastX = floor(wide * self:GetWide()) - - self:SetValue(value) - self:OnChange(value) - self:SetAlpha(floor(value * 255)) -end - -function PANEL:OnMousePressed() - self:MouseCapture(true) - self:OnCursorMoved(self:CursorPos()) -end - -function PANEL:OnMouseReleased() - self:MouseCapture(false) - self:OnCursorMoved(self:CursorPos()) -end - -function PANEL:OnChange(alpha) -end - -function PANEL:Paint(w, h) - local x, y = self:LocalToScreen() - local wh - - PIXEL.Mask(function() - PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) - end, function() - PIXEL.DrawSimpleLinearGradient(x, y, w, h, self:GetBarColor(), Color(200, 200, 200, 0), true) - end) - - local newX = self.LastX - - if newX < (h / 2) then - newX = (h / 2) - end - - if newX > w - (h / 2) then - newX = w - (h / 2) - end - - - PIXEL.DrawFullRoundedBox(8, newX - (h / 2), 0, h, h, color_white) - x, y, wh = newX + PIXEL.Scale(3), PIXEL.Scale(3), h - PIXEL.Scale(6) - local barColor = self:GetBarColor() - local r, g, b, a = barColor.r, barColor.g, barColor.b, self:GetAlpha() - PIXEL.DrawFullRoundedBox(4, x - (h / 2), y, wh, wh, Color(r, g, b, a)) -end - -vgui.Register("PIXEL.AlphaBar", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_color_cube.lua b/lua/pixelui/elements/cl_color_cube.lua deleted file mode 100644 index de57b4b..0000000 --- a/lua/pixelui/elements/cl_color_cube.lua +++ /dev/null @@ -1,124 +0,0 @@ -local PANEL = {} -local floor = math.floor -AccessorFunc(PANEL, "Hue", "Hue") -AccessorFunc(PANEL, "BaseRGB", "BaseRGB") -AccessorFunc(PANEL, "RGB", "RGB") -AccessorFunc(PANEL, "SlideX", "SlideX") -AccessorFunc(PANEL, "SlideY", "SlideY") - -function PANEL:Init() - self.BackgroundSat = vgui.Create("PIXEL.Image", self) - self.BackgroundSat:SetImage("vgui/gradient-r") - self.BackgroundSat:Dock(FILL) - - self.BackgroundValue = vgui.Create("PIXEL.Image", self) - self.BackgroundValue:Dock(FILL) - self.BackgroundValue:SetImage("vgui/gradient-d") - self.BackgroundValue:SetImageColor(color_black) - - self:SetBaseRGB(Color(255, 0, 0)) - self:SetRGB(Color(255, 0, 0)) - self:SetColor(Color(255, 0, 0)) - - self.LastX = 0 - self.LastY = 0 -end - -function PANEL:OnCursorMoved(x, y) - if not input.IsMouseDown(MOUSE_LEFT) then return end - local panelWide, panelTall = self:GetSize() - local wide = x / panelWide - local tall = y / panelTall - self.LastX = floor(wide * panelWide) - self.LastY = floor(tall * panelTall) - - self:TranslateValues(x, y) -end - -function PANEL:LayoutContent(w, h) - self.BackgroundSat:SetZPos(-9) - self.BackgroundValue:SetZPos(-8) -end - -function PANEL:Paint(w, h) - PIXEL.Mask( - function() - PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) - end, - function() - PIXEL.DrawRoundedBox(0, 0, 0, w, h, Color(self.BaseRGB.r, self.BaseRGB.g, self.BaseRGB.b, 255)) - PIXEL.DrawOutlinedBox(0, 0, w, h, 1, Color(0, 0, 0, 250)) - end - ) -end - -function PANEL:PaintOver(w, h) - local scale = PIXEL.Scale(20) - local newX = self.LastX - local newY = self.LastY - local x, y, wh - - if newX < (scale / 2) then - newX = (scale / 2) - end - - if newX > w - (scale / 2) then - newX = w - (scale / 2) - end - - if newY < (scale / 2) then - newY = (scale / 2) - end - - if newY > h - (scale / 2) then - newY = h - (scale / 2) - end - - newX = newX - (scale / 2) - newY = newY - (scale / 2) - - PIXEL.DrawFullRoundedBox(8, newX, newY, scale, scale, color_white) - x, y, wh = newX + PIXEL.Scale(3), newY + PIXEL.Scale(3), scale - PIXEL.Scale(6) - PIXEL.DrawFullRoundedBox(4, x, y, wh, wh, self:GetRGB()) -end - -function PANEL:TranslateValues(x, y) - self:UpdateColor(x, y) - self:OnUserChanged(self.RGB) - - return x, y -end - -function PANEL:UpdateColor(x, y) - x = x or self:GetSlideX() or 0 - y = y or self:GetSlideY() or 0 - - local value = 1 - math.Clamp(y / self:GetTall(), 0, 1) - local saturation = 1 - math.Clamp(x / self:GetWide(), 0, 1) - local h = ColorToHSV(self.BaseRGB) - - local color = HSVToColor(h, saturation, value) - - self:SetRGB(color) -end - -function PANEL:OnUserChanged() -end - -function PANEL:SetColor(color) - local h, s, v = ColorToHSV(color) - - self:SetBaseRGB(HSVToColor(h, 1, 1)) - - self:SetSlideY(1 - v) - self:SetSlideX(1 - s) - - self:UpdateColor() -end - -function PANEL:SetBaseRGB(color) - self.BaseRGB = color - self:UpdateColor() -end - -vgui.Register("PIXEL.ColorCube", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_color_picker_v2.lua b/lua/pixelui/elements/cl_color_picker_v2.lua deleted file mode 100644 index 022ae1f..0000000 --- a/lua/pixelui/elements/cl_color_picker_v2.lua +++ /dev/null @@ -1,352 +0,0 @@ - ---[[ -PIXEL UI -Copyright (C) 2021 Tom O'Sullivan (Tom.bat) - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -]] - -local PANEL = {} -AccessorFunc(PANEL, "ConVarRed", "ConVarR") -AccessorFunc(PANEL, "ConVarGreen", "ConVarG") -AccessorFunc(PANEL, "ConVarBlue", "ConVarBlue") -AccessorFunc(PANEL, "ConVarAlpha", "ConVarAlpha") -AccessorFunc(PANEL, "AlphaBarEnabled", "AlphaBar", FORCE_BOOL) -AccessorFunc(PANEL, "ShowTextEntries", "ShowTextEntries", FORCE_BOOL) -AccessorFunc(PANEL, "Color", "Color") -PIXEL.RegisterFont("UI.ColorPickerNumberEntry", "Rubik", 14) - -function PANEL:UpdateRGBEntryValues(panel, num, rgbType) - if panel.Forced then return end - local targetValue = tonumber(num) or 0 - - self:GetColor()[rgbType] = targetValue - - self.ColorCube:SetColor(self:GetColor()) - local pos = self.RGBPicker:GetColorPos(self.ColorCube:GetBaseRGB()) - self.RGBPicker:SetRGB(self.ColorCube:GetBaseRGB()) - self.RGBPicker.LastX = pos - - self:UpdateColor(self:GetColor()) -end - -function PANEL:UpdateNumberEntries(color) - self.RedEntry:SetValue(color.r) - self.GreenEntry:SetValue(color.g) - self.BlueEntry:SetValue(color.b) -end - -function PANEL:Init() - self:SetShowTextEntries(true) - self:SetSize(PIXEL.Scale(256), PIXEL.Scale(230)) - - self.RGBAPanel = vgui.Create("Panel", self) - self.RGBAPanel:Dock(BOTTOM) - self.RGBAPanel:DockMargin(0, PIXEL.Scale(10), 0, PIXEL.Scale(10)) - self.RGBAPanel:SetTall(PIXEL.Scale(35)) - - self.RedEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") - self.RedEntry:SetMin(0) - self.RedEntry:SetMax(255) - self.RedEntry:SetTall(PIXEL.Scale(25)) - self.RedEntry:SetWide(PIXEL.Scale(60)) - self.RedEntry:SetFont("UI.ColorPickerNumberEntry", true) - self.RedEntry.OutlineCol = Color(238, 75, 43) - - self.GreenEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") - self.GreenEntry:SetMin(0) - self.GreenEntry:SetMax(255) - self.GreenEntry:SetTall(PIXEL.Scale(25)) - self.GreenEntry:SetWide(PIXEL.Scale(60)) - self.GreenEntry.TextEntry:SetFont("UI.ColorPickerNumberEntry", true) - self.GreenEntry.OutlineCol = Color(170, 255, 0) - - self.BlueEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") - self.BlueEntry:SetMin(0) - self.BlueEntry:SetMax(255) - self.BlueEntry:SetTall(PIXEL.Scale(25)) - self.BlueEntry.TextEntry:SetFont("UI.ColorPickerNumberEntry", true) - self.BlueEntry.OutlineCol = Color(0, 100, 255) - - self.AlphaEntry = self.RGBAPanel:Add("PIXEL.NumberEntry") - self.AlphaEntry:SetMin(0) - self.AlphaEntry:SetMax(255) - self.AlphaEntry:SetTall(PIXEL.Scale(25)) - self.AlphaEntry:SetWide(PIXEL.Scale(60)) - self.AlphaEntry.TextEntry:SetFont("UI.ColorPickerNumberEntry", true) - - self.RGBAPanel.PerformLayout = function(s, w, h) - local boxH = PIXEL.Scale(30) - self.RedEntry:SetTall(boxH) - self.GreenEntry:SetTall(boxH) - self.BlueEntry:SetTall(boxH) - - if self.AlphaBarEnabled then - self.AlphaEntry:SetTall(boxH) - - local boxW = (w / 4) - (PIXEL.Scale(5) * 4) - - self.RedEntry:SetWide(boxW) - self.GreenEntry:SetWide(boxW) - self.BlueEntry:SetWide(boxW) - self.AlphaEntry:SetWide(boxW) - - for i = 1, 4 do - local x = (boxW + PIXEL.Scale(5)) * (i - 1) - - self.RGBAPanel:GetChildren()[i]:SetPos(x, 0) - end - else - local boxW = (w / 3) - (PIXEL.Scale(5) * 2) - - self.RedEntry:SetWide(boxW) - self.GreenEntry:SetWide(boxW) - self.BlueEntry:SetWide(boxW) - - for i = 1, 3 do - local x = (boxW + PIXEL.Scale(5)) * (i - 1) - - self.RGBAPanel:GetChildren()[i]:SetPos(x, 0) - end - end - end - - self.ColorCube = vgui.Create("PIXEL.ColorCube", self) - self.ColorCube:Dock(FILL) - - self.ColorCube.OnUserChanged = function(ctrl, color) - color.a = self:GetColor().a - self:UpdateColor(color) - end - - self.RGBPicker = vgui.Create("PIXEL.RGBPicker", self) - self.RGBPicker:Dock(BOTTOM) - self.RGBPicker:SetTall(PIXEL.Scale(20)) - self.RGBPicker:DockMargin(0, PIXEL.Scale(10), 0, 0) - self.RGBPicker:SetRGB(Color(255, 0, 0)) - - self.RGBPicker.OnChange = function(ctrl, color) - self:SetBaseColor(color) - self:UpdateNumberEntries(color) - end - - self.AlphaBar = vgui.Create("PIXEL.AlphaBar", self) - self.AlphaBar:Dock(BOTTOM) - self.AlphaBar:SetTall(PIXEL.Scale(20)) - self.AlphaBar:DockMargin(0, PIXEL.Scale(10), 0, 0) - - self.AlphaBar.OnChange = function(ctrl, alpha) - self:GetColor().a = math.floor(alpha * 255) - self:UpdateColor(self:GetColor()) - end - - self:SetColor(Color(255, 0, 0, 255)) - - - -- RGB Picker Changes - self.RedEntry.OnValueChanged = function(s, str) - self:UpdateRGBEntryValues(s, str, "r") - end - - self.GreenEntry.OnValueChanged = function(s, str) - self:UpdateRGBEntryValues(s, str, "g") - end - - self.BlueEntry.OnValueChanged = function(s, str) - self:UpdateRGBEntryValues(s, str, "b") - end - - self.AlphaEntry.OnValueChanged = function(s, str) - if s.Forced then return end - local targetValue = tonumber(num) or 0 - - local color = targetValue - self:GetColor()[type] = color - - self.AlphaBar:SetBarColor(ColorAlpha(color, 255)) - self.AlphaBar:SetValue(targetValue / 255) - - self:UpdateColor(color) - end - - self:SetAlphaBar(true) - self:InvalidateLayout() -end - -function PANEL:SetAlphaBar(enabled) - self.AlphaBarEnabled = enabled - - if IsValid(self.AlphaBar) then - self.AlphaBar:SetVisible(enabled) - end - - if IsValid(self.AlphaEntry) then - self.AlphaEntry:SetVisible(enabled) - end - self:InvalidateLayout() -end - -function PANEL:SetShowRGBA(enabled) - self:SetShowTextEntries(enabled) - self.RGBAPanel:SetVisible(enabled) - self:InvalidateLayout() -end - -function PANEL:SetConVarR(cvar) - self.ConVarRed = cvar -end - -function PANEL:SetConVarG(cvar) - self.ConVarGreen = cvar -end - -function PANEL:SetConVarB(cvar) - self.ConVarBlue = cvar -end - -function PANEL:SetConVarA(cvar) - self.ConVarAlpha = cvar - self:SetAlphaBar(cvar ~= nil) -end - -function PANEL:PerformLayout() - local h, s, v = ColorToHSV(self.ColorCube:GetBaseRGB()) - self.RGBPicker.LastY = (PIXEL.Scale(1) - h / PIXEL.Scale(360)) * self.RGBPicker:GetWide() -end - -function PANEL:TranslateValues(x, y) -end - -function PANEL:SetColor(color) - local h, s, v = ColorToHSV(color) - self.RGBPicker.LastY = (PIXEL.Scale(1) - h / PIXEL.Scale(360)) * self.RGBPicker:GetTall() - self.ColorCube:SetColor(color) - self:UpdateColor(color) -end - -function PANEL:SetVector(vec) - self:SetColor(Color(vec.x * 255, vec.y * 255, vec.z * 255, 255)) -end - -function PANEL:SetBaseColor(color) - self.ColorCube:SetBaseRGB(color) - self.ColorCube:TranslateValues() -end - -function PANEL:UpdateConVar(name, key, color) - if not name then return end - - local col = color[key] - RunConsoleCommand(name, tostring(col)) - self["ConVarOld" .. name] = col -end - -function PANEL:UpdateConVars(color) - self.NextConVarCheck = SysTime() + 0.2 - self:UpdateConVar(self.ConVarRed, 'r', color) - self:UpdateConVar(self.ConVarGreen, 'g', color) - self:UpdateConVar(self.ConVarBlue, 'b', color) - self:UpdateConVar(self.ConVarAlpha, 'a', color) -end - -function PANEL:UpdateColor(color) - self.AlphaBar:SetBarColor(ColorAlpha(color, 255)) - self.AlphaBar:SetValue(color.a / 255) - - if color.r ~= self.RedEntry:GetValue() then - self.RedEntry.Forced = true - self.RedEntry:SetValue(color.r) - self.RedEntry.Forced = nil - end - - if color.g ~= self.GreenEntry:GetValue() then - self.GreenEntry.Forced = true - self.GreenEntry:SetValue(color.r) - self.GreenEntry.Forced = nil - end - - if color.b ~= self.BlueEntry:GetValue() then - self.BlueEntry.Forced = true - self.BlueEntry:SetValue(color.r) - self.BlueEntry.Forced = nil - end - - if color.a ~= self.AlphaEntry:GetValue() then - self.AlphaEntry.Forced = true - self.AlphaEntry:SetValue(color.r) - self.AlphaEntry.Forced = nil - end - - self:UpdateConVars(color) - self:ValueChanged(color) - self.Color = color -end - -function PANEL:ValueChanged(color) -end - -function PANEL:GetColor() - self.Color.a = 255 - - if self.AlphaBar:IsVisible() then - self.Color.a = self.AlphaBar:GetAlpha() - end - - return self.Color -end - -function PANEL:GetVector() - local col = self:GetColor() - - return Vector(col.r / 255, col.g / 255, col.b / 255) -end - -function PANEL:Think() - self:ConVarThink() -end - -function PANEL:ConVarThink() - if input.IsMouseDown(MOUSE_LEFT) then return end - - if self.NextConVarCheck > SysTime() then return end - - local r, changed_r = self:DoConVarThink(self.ConVarRed) - local g, changed_g = self:DoConVarThink(self.ConVarGreen) - local b, changed_b = self:DoConVarThink(self.ConVarBlue) - local a, changed_a = 255, false - - if self.ConVarAlpha then - a, changed_a = self:DoConVarThink(self.ConVarAlpha, "a") - end - - if changed_r or changed_g or changed_b or changed_a then - self:SetColor(Color(r, g, b, a)) - end -end - -function PANEL:DoConVarThink(convar) - if not convar then return end - - local value = GetConVar(convar):GetInt() - local oldValue = self["ConVarOld" .. convar] - - if oldValue and value == oldValue then - return oldValue, false - end - - self["ConVarOld" .. convar] = value - - return value, true -end - -vgui.Register("PIXEL.ColorPickerV2", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/color_picker_v2/cl_alpha_bar.lua b/lua/pixelui/elements/color_picker_v2/cl_alpha_bar.lua new file mode 100644 index 0000000..44f4772 --- /dev/null +++ b/lua/pixelui/elements/color_picker_v2/cl_alpha_bar.lua @@ -0,0 +1,72 @@ +local PANEL = {} +local clamp = math.Clamp +local floor = math.floor + +AccessorFunc(PANEL, "BaseColor", "BaseColor") +AccessorFunc(PANEL, "Alpha", "Alpha") + +function PANEL:Init() + self:SetBaseColor(Color(255,0,0)) + self:SetSize(PIXEL.Scale(26), PIXEL.Scale(26)) + self:SetAlpha(255) + self.LastX = 0 +end + +function PANEL:OnCursorMoved(x, y) + if not input.IsMouseDown(MOUSE_LEFT) then return end + + local wide = x / self:GetWide() + local value = 1 - clamp(wide, 0, 1) + + self.LastX = floor(wide * self:GetWide()) + + self:OnChange(floor(value * 255)) + self:SetAlpha(floor(value * 255)) +end + +function PANEL:OnMousePressed() + self:MouseCapture(true) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:OnMouseReleased() + self:MouseCapture(false) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:OnChange(alpha) +end + +function PANEL:Paint(w, h) + local x, y = self:LocalToScreen() + local wh + + PIXEL.Mask(function() + PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) + end, function() + for i = 0, w / 2 do + local x2 = i * h + if x2 > w then break end + PIXEL.DrawImgur(x2, 0, h, h, "RPwfEvZ", color_white) + end + + PIXEL.DrawSimpleLinearGradient(x, y, w, h, self:GetBaseColor(), Color(200, 200, 200, 0), true) + end) + + local newX = self.LastX + + if newX < (h / 2) then + newX = (h / 2) + end + + if newX > w - (h / 2) then + newX = w - (h / 2) + end + + + PIXEL.DrawFullRoundedBox(8, newX - (h / 2), 0, h, h, color_white) + x, y, wh = newX + PIXEL.Scale(3), PIXEL.Scale(3), h - PIXEL.Scale(6) + PIXEL.DrawFullRoundedBox(4, x - (h / 2), y, wh, wh, ColorAlpha(self:GetBaseColor(), self:GetAlpha())) +end + +vgui.Register("PIXEL.AlphaBar", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/color_picker_v2/cl_color_picker_v2.lua b/lua/pixelui/elements/color_picker_v2/cl_color_picker_v2.lua new file mode 100644 index 0000000..29b2382 --- /dev/null +++ b/lua/pixelui/elements/color_picker_v2/cl_color_picker_v2.lua @@ -0,0 +1,240 @@ + +--[[ +PIXEL UI +Copyright (C) 2021 Tom O'Sullivan (Tom.bat) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +]] + +local PANEL = {} + +AccessorFunc(PANEL, "AlphaBarEnabled", "AlphaBar", FORCE_BOOL) +AccessorFunc(PANEL, "ShowTextEntries", "ShowTextEntries", FORCE_BOOL) +AccessorFunc(PANEL, "AutoHeight", "AutoHeight", FORCE_BOOL) + +AccessorFunc(PANEL, "Hue", "Hue") +AccessorFunc(PANEL, "Saturation", "Saturation") +AccessorFunc(PANEL, "Luminosity", "Luminosity") +AccessorFunc(PANEL, "Alpha", "Alpha") + +AccessorFunc(PANEL, "R", "R") +AccessorFunc(PANEL, "G", "G") +AccessorFunc(PANEL, "B", "B") + +PIXEL.RegisterFont("UI.ColorPickerNumberEntry", "Rubik", 12) + +function PANEL:Init() + self:SetShowTextEntries(true) + self:SetSize(PIXEL.Scale(256), PIXEL.Scale(50)) + + self.ColorBox = vgui.Create("EditablePanel", self) + self.ColorBox:Dock(LEFT) + self.ColorBox:SetWide(self:GetTall()) + self.ColorBox:DockMargin(0, 0, PIXEL.Scale(10), 0) + + self.ColorBox.Paint = function(s, w, h) + PIXEL.Mask(function() + PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) + end, function() + PIXEL.DrawImgur(0, 0, w, h, "RPwfEvZ", color_white) + + local color = PIXEL.SetColorTransparency(self:GetColor(), self:GetAlpha()) + PIXEL.DrawRoundedBox(0, 0, 0, w, h, color) + end) + end + + self.HueBar = vgui.Create("PIXEL.HueBar", self) + self.HueBar:Dock(TOP) + self.HueBar:SetTall(PIXEL.Scale(20)) + self.HueBar:DockMargin(0, 0, 0, 0) + + self.SaturationBar = vgui.Create("PIXEL.SaturationBar", self) + self.SaturationBar:Dock(TOP) + self.SaturationBar:SetTall(PIXEL.Scale(20)) + self.SaturationBar:DockMargin(0, PIXEL.Scale(10), 0, 0) + + self.LuminosityBar = vgui.Create("PIXEL.LuminosityBar", self) + self.LuminosityBar:Dock(TOP) + self.LuminosityBar:SetTall(PIXEL.Scale(20)) + self.LuminosityBar:DockMargin(0, PIXEL.Scale(10), 0, 0) + + self.AlphaBar = vgui.Create("PIXEL.AlphaBar", self) + self.AlphaBar:Dock(TOP) + self.AlphaBar:SetTall(PIXEL.Scale(20)) + self.AlphaBar:DockMargin(0, PIXEL.Scale(10), 0, 0) + + self.HueBar.OnChange = function(_, hue) + local s, l, a = self:GetSaturation(), self:GetLuminosity(), self:GetAlpha() + local color = HSLToColor(hue, s, l) + color.a = a + self:UpdateColor(hue, s, l, a, color) + end + + self.SaturationBar.OnChange = function(_, saturation) + local h, l, a = self:GetHue(), self:GetLuminosity(), self:GetAlpha() + local color = HSLToColor(h, saturation, l) + color.a = a + self:UpdateColor(h, saturation, l, a, color) + end + + self.LuminosityBar.OnChange = function(_, luminosity) + local h, s, a = self:GetHue(), self:GetSaturation(), self:GetAlpha() + local color = HSLToColor(h, s, luminosity) + color.a = a + self:UpdateColor(h, s, luminosity, a, color) + end + + self.AlphaBar.OnChange = function(_, alpha) + local h, s, l = self:GetHue(), self:GetSaturation(), self:GetLuminosity() + local color = HSLToColor(h, s, l) + color.a = alpha + self:UpdateColor(h, s, l, alpha, color) + end + + self:SetColor(Color(0, 0, 255)) + + self:SetAlphaBar(true) + self:SetAutoHeight(true) + self:InvalidateLayout() +end + +function PANEL:SetAlphaBar(enabled) + self.AlphaBarEnabled = enabled + + if IsValid(self.AlphaBar) then + self.AlphaBar:SetVisible(enabled) + end + + self:InvalidateLayout() +end + +function PANEL:CalculateHeight() + local height = self.HueBar:GetTall() + self.SaturationBar:GetTall() + self.LuminosityBar:GetTall() + PIXEL.Scale(20) + + if self.AlphaBar:IsVisible() then + height = height + self.AlphaBar:GetTall() + PIXEL.Scale(10) + end + + return height +end + +function PANEL:PerformLayout() + if self:GetAutoHeight() then + self:SetTall(self:CalculateHeight()) + end + + self.ColorBox:SetWide(self:GetTall() or 0) +end + +function PANEL:TranslateValues(x, y) +end + +function PANEL:SetColor(color) + local h, s, l = ColorToHSL(color) + + self:UpdateColor(h, s, l, color.a or 255, color) +end + +function PANEL:SetVector(vec) + self:SetColor(Color(vec.x * 255, vec.y * 255, vec.z * 255, 255)) +end + +function PANEL:UpdateColor(h, s, l, a, color) + self:SetHue(h) + self:SetSaturation(s) + self:SetLuminosity(l) + self:SetAlpha(a) + + if not color then + color = HSLToColor(h, s, l) + end + + local baseColor = PIXEL.CopyColor(color) + baseColor.a = 255 + + if IsValid(self.HueBar) then + self.HueBar:SetHue(h) + self.HueBar:SetSaturation(s) + self.HueBar:SetLuminosity(l) + end + + if IsValid(self.SaturationBar) then + self.SaturationBar:SetBaseColor(baseColor) + self.SaturationBar:SetHue(h) + self.SaturationBar:SetSaturation(s) + self.SaturationBar:SetLuminosity(l) + end + + if IsValid(self.LuminosityBar) then + self.LuminosityBar:SetBaseColor(baseColor) + self.LuminosityBar:SetHue(h) + self.LuminosityBar:SetSaturation(s) + self.LuminosityBar:SetLuminosity(l) + end + + if IsValid(self.AlphaBar) then + self.AlphaBar:SetBaseColor(baseColor) + self.AlphaBar:SetAlpha(a) + end + + self:ValueChanged(color) + self.Color = color + self.R = color.r + self.G = color.g + self.B = color.b +end + +function PANEL:ValueChanged(color) +end + +function PANEL:GetColor() + local h = self:GetHue() + local s = self:GetSaturation() + local l = self:GetLuminosity() + local color = HSLToColor(h, s, l) + + + return color +end + +function PANEL:GetVector() + local col = self:GetColor() + + return Vector(col.r / 255, col.g / 255, col.b / 255) +end + +function PANEL:Think() + self:ConVarThink() +end + +function PANEL:ConVarThink() + if input.IsMouseDown(MOUSE_LEFT) then return end + +end + +function PANEL:DoConVarThink(convar) + if not convar then return end + + local value = GetConVar(convar):GetInt() + local oldValue = self["ConVarOld" .. convar] + + if oldValue and value == oldValue then + return oldValue, false + end + + self["ConVarOld" .. convar] = value + + return value, true +end + +vgui.Register("PIXEL.ColorPickerV2", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_rgb_picker.lua b/lua/pixelui/elements/color_picker_v2/cl_hue_bar.lua similarity index 61% rename from lua/pixelui/elements/cl_rgb_picker.lua rename to lua/pixelui/elements/color_picker_v2/cl_hue_bar.lua index e0b8201..8b717c2 100644 --- a/lua/pixelui/elements/cl_rgb_picker.lua +++ b/lua/pixelui/elements/color_picker_v2/cl_hue_bar.lua @@ -1,12 +1,21 @@ local PANEL = {} local floor = math.floor local clamp = math.Clamp -local colToHSV, HSVToCol = ColorToHSV, HSVToColor local scale = PIXEL.Scale -AccessorFunc(PANEL, "RGBValue", "RGB") + +AccessorFunc(PANEL, "Hue", "Hue", FORCE_NUMBER) +AccessorFunc(PANEL, "Saturation", "Saturation", FORCE_NUMBER) +AccessorFunc(PANEL, "Luminosity", "Luminosity", FORCE_NUMBER) + +function PANEL:SetHue(value) + self.Hue = clamp(value, 0, 360) + self.LastX = (value / 360) * self:GetWide() +end function PANEL:Init() - self:SetRGB(color_white) + self:SetHue(0) + self:SetSaturation(1) + self:SetLuminosity(.5) self.LastX = 0 self.Steps = {} end @@ -17,44 +26,42 @@ function PANEL:PerformLayout(w, h) for i = 0, self.Times do local step = (1 / self.Times) * i - local color = HSVToCol(i, 1, 1) + local color = HSLToColor(i, self:GetSaturation(), self:GetLuminosity()) self.Steps[i] = { offset = step, color = color } end -end -function PANEL:GetPosColor(value) - local position = floor(value * self.Times) - local color = self.Steps[position].color - - return color + self.LastX = (self:GetHue() / 360) * self:GetWide() end -function PANEL:GetColorPos(color) - local h, _, _ = colToHSV(color) - local pos = floor((h * self:GetWide()) / self.Times) - return pos +function PANEL:GetColor() + local h = self:GetHue() or 0 + local s = self:GetSaturation() or 1 + local l = self:GetLuminosity() or 0.5 + + return HSLToColor(h, s, l) end function PANEL:OnCursorMoved(x, y) if not input.IsMouseDown(MOUSE_LEFT) then return end local wide = x / self:GetWide() - local value = clamp(wide, 0, 1) - local col = self:GetPosColor(value) + local hue = clamp(wide, 0, 1) + hue = floor(hue * self.Times) + self:SetHue(hue) + + local col = self:GetColor(hue) if col then - self.RGBValue = col - self.RGBValue.a = 255 - self:OnChange(self.RGBValue) + self:OnChange(self:GetHue()) end self.LastX = x end -function PANEL:OnChange(col) +function PANEL:OnChange(hue) end function PANEL:OnMousePressed() @@ -89,7 +96,7 @@ function PANEL:Paint(w, h) PIXEL.DrawFullRoundedBox(8, newX - (h / 2), 0, h, h, color_white) x, y, wh = newX + scale(3), scale(3), h - scale(6) - PIXEL.DrawFullRoundedBox(4, x - (h / 2), y, wh, wh, self:GetRGB()) + PIXEL.DrawFullRoundedBox(4, x - (h / 2), y, wh, wh, self:GetColor()) end -vgui.Register("PIXEL.RGBPicker", PANEL, "EditablePanel") \ No newline at end of file +vgui.Register("PIXEL.HueBar", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/color_picker_v2/cl_luminosity_bar.lua b/lua/pixelui/elements/color_picker_v2/cl_luminosity_bar.lua new file mode 100644 index 0000000..5aa64e1 --- /dev/null +++ b/lua/pixelui/elements/color_picker_v2/cl_luminosity_bar.lua @@ -0,0 +1,108 @@ +local PANEL = {} +local clamp = math.Clamp +local scale = PIXEL.Scale + +AccessorFunc(PANEL, "BaseColor", "BaseColor", FORCE_NUMBER) +AccessorFunc(PANEL, "Hue", "Hue", FORCE_NUMBER) +AccessorFunc(PANEL, "Saturation", "Saturation", FORCE_NUMBER) +AccessorFunc(PANEL, "Luminosity", "Luminosity", FORCE_NUMBER) + +function PANEL:Init() + self:SetHue(0) + self:SetSaturation(100) + self:SetLuminosity(50) + self.Steps = {} +end + +function PANEL:SetBaseColor(color) + self.BaseColor = color + self:GenerateGradient() +end + +function PANEL:PerformLayout(w, h) + self:GenerateGradient() + + if not self.LastX then + self.LastX = w / 2 + end +end + +function PANEL:GenerateGradient() + self.Steps = {} + self.Times = 100 -- The max number that the hue can be + + for i = 0, self.Times do + local step = (1 / self.Times) * i + local color = HSLToColor(self:GetHue(), self:GetSaturation(), i / 100) + + self.Steps[i] = { + offset = step, + color = color + } + end +end + +function PANEL:GetColor() + local h = self:GetHue() + local s = self:GetSaturation() + local l = self:GetLuminosity() + + return HSLToColor(h, s, l) +end + +function PANEL:OnCursorMoved(x, y) + if not input.IsMouseDown(MOUSE_LEFT) then return end + local wide = x / self:GetWide() + local luminosity = clamp(wide, 0, 1) + self:SetLuminosity(luminosity) + + local col = self:GetColor(hue) + + if col then + self:OnChange(self:GetLuminosity()) + end + + self.LastX = x +end + +function PANEL:OnChange(col) +end + +function PANEL:OnMousePressed() + self:MouseCapture(true) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:OnMouseReleased() + self:MouseCapture(false) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:Paint(w, h) + local x, y = self:LocalToScreen() + local wh + + PIXEL.Mask(function() + PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) + end, function() + PIXEL.DrawLinearGradient(x, y, w, h, self.Steps, true) + end) + + if not self.LastX then return end + + local newX = self.LastX + + if newX < (h / 2) then + newX = (h / 2) + end + + if newX > w - (h / 2) then + newX = w - (h / 2) + end + + PIXEL.DrawFullRoundedBox(8, newX - (h / 2), 0, h, h, color_white) + x, y, wh = newX + scale(3), scale(3), h - scale(6) + PIXEL.DrawFullRoundedBox(4, x - (h / 2), y, wh, wh, self:GetColor()) +end + +vgui.Register("PIXEL.LuminosityBar", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/color_picker_v2/cl_saturation_bar.lua b/lua/pixelui/elements/color_picker_v2/cl_saturation_bar.lua new file mode 100644 index 0000000..a28aebf --- /dev/null +++ b/lua/pixelui/elements/color_picker_v2/cl_saturation_bar.lua @@ -0,0 +1,88 @@ +local PANEL = {} +local floor = math.floor +local clamp = math.Clamp +local scale = PIXEL.Scale + +AccessorFunc(PANEL, "BaseColor", "BaseColor") +AccessorFunc(PANEL, "Hue", "Hue", FORCE_NUMBER) +AccessorFunc(PANEL, "Saturation", "Saturation", FORCE_NUMBER) +AccessorFunc(PANEL, "Luminosity", "Luminosity", FORCE_NUMBER) + +function PANEL:Init() + self:SetBaseColor(Color(255, 0, 0)) + self:SetHue(0) + self:SetSaturation(1) + self:SetLuminosity(.5) +end + + +function PANEL:PerformLayout(w, h) + if not self.LastX then + self.LastX = w + end +end + +function PANEL:GetColor() + local h = self:GetHue() or 0 + local s = self:GetSaturation() or 1 + local l = self:GetLuminosity() or .5 + + return HSLToColor(h, s, l) +end + +function PANEL:OnCursorMoved(x, y) + if not input.IsMouseDown(MOUSE_LEFT) then return end + local wide = x / self:GetWide() + local saturation = clamp(wide, 0, 1) + self:SetSaturation(saturation) + + local col = self:GetColor(hue) + + if col then + self:OnChange(self:GetSaturation()) + end + + self.LastX = x +end + +function PANEL:OnChange(col) +end + +function PANEL:OnMousePressed() + self:MouseCapture(true) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:OnMouseReleased() + self:MouseCapture(false) + self:OnCursorMoved(self:CursorPos()) +end + +function PANEL:Paint(w, h) + local x, y = self:LocalToScreen() + local wh + + PIXEL.Mask(function() + PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) + end, function() + PIXEL.DrawSimpleLinearGradient(x, y, w, h, Color(128, 128, 128), self:GetBaseColor(), true) + end) + + if not self.LastX then return end + + local newX = self.LastX + + if newX < (h / 2) then + newX = (h / 2) + end + + if newX > w - (h / 2) then + newX = w - (h / 2) + end + + PIXEL.DrawFullRoundedBox(8, newX - (h / 2), 0, h, h, color_white) + x, y, wh = newX + scale(3), scale(3), h - scale(6) + PIXEL.DrawFullRoundedBox(4, x - (h / 2), y, wh, wh, self:GetColor()) +end + +vgui.Register("PIXEL.SaturationBar", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/menus/test/pages/cl_other.lua b/lua/pixelui/menus/test/pages/cl_other.lua index 79f7813..8105341 100644 --- a/lua/pixelui/menus/test/pages/cl_other.lua +++ b/lua/pixelui/menus/test/pages/cl_other.lua @@ -46,9 +46,10 @@ function PANEL:Init() self.StepCounter:DockMargin(sc(50), sc(10), sc(50), sc(10)) self.ColorPicker = vgui.Create("PIXEL.ColorPickerV2", self.ScrollPanel) + self.ColorPicker:SetAlphaBar(true) self.ScrollPanel.LayoutContent = function(s, w, h) - self.ColorPicker:SetSize(w / 2 - PIXEL.Scale(50), w / 2) + // self.ColorPicker:SetSize(w / 2 - PIXEL.Scale(50), PIXEL.Scale(120)) self.ColorPicker:SetPos(PIXEL.Scale(50), self.StepCounter:GetY() + self.StepCounter:GetTall() + PIXEL.Scale(10)) end end From 8057af41f0dc7e3b931b9d20c3b52c03046543ed Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 12 Dec 2021 14:42:47 +0000 Subject: [PATCH 091/155] ayo cool sidebar --- lua/pixelui/elements/cl_sidebar.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 7cf2984..d8309b8 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -35,22 +35,28 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent + local backgroundThingCol = ARSENIC.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol + backgroundThingCol = ARSENIC.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol + backgroundThingCol = ARSENIC.Colors.Primary end local animTime = FrameTime() * 12 self.TextCol = PIXEL.LerpColor(animTime, self.TextCol, textCol) self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) - if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) end + if self:GetDrawOutline() then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundThingCol, ARSENIC.Scale(1)) + end local imgurID = self:GetImgurID() if imgurID then @@ -156,4 +162,4 @@ function PANEL:Paint(w, h) end end -vgui.Register("PIXEL.Sidebar", PANEL, "Panel") \ No newline at end of file +vgui.Register("PIXEL.Sidebar", PANEL, "Panel") From 1f49a5dd726487ee7e5b15c4ecda2c0d4c66fdbf Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 12 Dec 2021 14:49:21 +0000 Subject: [PATCH 092/155] Update cl_sidebar.lua --- lua/pixelui/elements/cl_sidebar.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index d8309b8..ad0d9fa 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -35,18 +35,18 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent - local backgroundThingCol = ARSENIC.Colors.Transparent + local backgroundStyleCol = ARSENIC.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundThingCol = ARSENIC.Colors.Primary + backgroundStyleCol = ARSENIC.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundThingCol = ARSENIC.Colors.Primary + backgroundStyleCol = ARSENIC.Colors.Primary end local animTime = FrameTime() * 12 @@ -55,7 +55,7 @@ function PANEL:Paint(w, h) if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) - PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundThingCol, ARSENIC.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundStyleCol, ARSENIC.Scale(1)) end local imgurID = self:GetImgurID() From 55ad010cdecb965aac8a7ff90092e2d8db4f32cc Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 12 Dec 2021 14:50:06 +0000 Subject: [PATCH 093/155] Update cl_sidebar.lua --- lua/pixelui/elements/cl_sidebar.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index ad0d9fa..0d983cf 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -35,18 +35,18 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent - local backgroundStyleCol = ARSENIC.Colors.Transparent + local backgroundStyleCol = PIXEL.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundStyleCol = ARSENIC.Colors.Primary + backgroundStyleCol = PIXEL.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundStyleCol = ARSENIC.Colors.Primary + backgroundStyleCol = PIXEL.Colors.Primary end local animTime = FrameTime() * 12 @@ -55,7 +55,7 @@ function PANEL:Paint(w, h) if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) - PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundStyleCol, ARSENIC.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundStyleCol, PIXEL.Scale(1)) end local imgurID = self:GetImgurID() From 9c2b0e91c47b09a7dfe42634d89eb078aa712ebf Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 12 Dec 2021 14:57:56 +0000 Subject: [PATCH 094/155] REFACTOR: BETTER STUPID VARAIBLE NAME --- lua/pixelui/elements/cl_sidebar.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 0d983cf..0f2259b 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -35,18 +35,18 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent - local backgroundStyleCol = PIXEL.Colors.Transparent + local hoverStyleCol = PIXEL.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundStyleCol = PIXEL.Colors.Primary + hoverStyleCol = PIXEL.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - backgroundStyleCol = PIXEL.Colors.Primary + hoverStyleCol = PIXEL.Colors.Primary end local animTime = FrameTime() * 12 @@ -55,7 +55,7 @@ function PANEL:Paint(w, h) if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) - PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, backgroundStyleCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverStyleCol, PIXEL.Scale(1)) end local imgurID = self:GetImgurID() From b4f57a3fd1a36d6b46290f0cb1f51f407e1f0c0d Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 14 Dec 2021 19:10:54 +0000 Subject: [PATCH 095/155] CHANGE NAME AGAIN --- lua/pixelui/elements/cl_sidebar.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 0f2259b..3aff8c6 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -35,18 +35,18 @@ end function PANEL:Paint(w, h) local textCol = PIXEL.Colors.SecondaryText local backgroundCol = PIXEL.Colors.Transparent - local hoverStyleCol = PIXEL.Colors.Transparent + local hoverLineCol = PIXEL.Colors.Transparent if self:IsHovered() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - hoverStyleCol = PIXEL.Colors.Primary + hoverLineCol = PIXEL.Colors.Primary end if self:IsDown() or self:GetToggle() then textCol = PIXEL.Colors.PrimaryText backgroundCol = self.BackgroundHoverCol - hoverStyleCol = PIXEL.Colors.Primary + hoverLineCol = PIXEL.Colors.Primary end local animTime = FrameTime() * 12 @@ -55,7 +55,7 @@ function PANEL:Paint(w, h) if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) - PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverStyleCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverLineCol, PIXEL.Scale(1)) end local imgurID = self:GetImgurID() From ac74d696712a67c1d253fcb1be85aa237423d8f7 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 2 Feb 2022 17:57:29 +0000 Subject: [PATCH 096/155] Update cl_frame.lua --- lua/pixelui/elements/cl_frame.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index ec4738d..13758ba 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -227,7 +227,7 @@ function PANEL:PaintHeader(x, y, w, h) return end - PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(6), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(8), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) end function PANEL:Paint(w, h) From 62341838958b6ed247795531badcb6f7fc350f0c Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 8 Mar 2022 20:57:38 +0000 Subject: [PATCH 097/155] stuff --- lua/pixelui/core/cl_player.lua | 3 +++ lua/pixelui/sh_config.lua | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 lua/pixelui/core/cl_player.lua diff --git a/lua/pixelui/core/cl_player.lua b/lua/pixelui/core/cl_player.lua new file mode 100644 index 0000000..cba5a57 --- /dev/null +++ b/lua/pixelui/core/cl_player.lua @@ -0,0 +1,3 @@ +function PIXEL.GetRank(ply) + return ply:GetUserGroup() or ply:GetSeccondaryUserGroup() +end \ No newline at end of file diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index a502923..95f70a6 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -19,7 +19,7 @@ Should we override the default derma popups for the PIXEL UI reskins? 0 = No - forced off. 1 = No - but users can opt in via convar (pixel_ui_override_popups). - 2 = Yes - but users can opt out via convar. + 2 = Yes - but users must opt in via convar. 3 = Yes - forced on. ]] PIXEL.OverrideDermaMenus = 0 @@ -51,4 +51,4 @@ PIXEL.Colors = { Bronze = Color(145, 94, 49), Transparent = Color(0, 0, 0, 0) -} +} \ No newline at end of file From 2c1f0871d56a4daaacc8134ab9c657773ef159aa Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 8 Mar 2022 20:56:58 +0000 Subject: [PATCH 098/155] refactor: Update version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e2cac26..e8ea05d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.3 \ No newline at end of file +1.2.4 From de071e25d6e191f6420465edd3bf615dd8b86d50 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 2 Apr 2022 18:46:13 +0100 Subject: [PATCH 099/155] refactor: Update version checker url --- lua/autorun/sh_pixelui_loader.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 1155841..d662c0f 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -60,7 +60,7 @@ resource.AddWorkshop("2468112758") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://raw.githubusercontent.com/TomDotBat/pixel-ui/master/VERSION", function(body) + http.Fetch("https://github.com/Pulsar-Dev/pixel-ui/blob/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) From 5b3616ea7c62d89bb5c680c9cdf08b156b0d54b1 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 29 May 2022 19:13:37 +0100 Subject: [PATCH 100/155] feat: Theming Support --- lua/autorun/sh_pixelui_loader.lua | 2 +- lua/pixelui/core/cl_imgur.lua | 23 +++-- .../core/{cl_player.lua => sh_player.lua} | 0 lua/pixelui/core/sh_theme.lua | 64 ++++++++++++++ lua/pixelui/elements/cl_avatar.lua | 45 ++++------ lua/pixelui/elements/cl_sidebar.lua | 4 +- lua/pixelui/sh_config.lua | 86 +++++++++++++++++-- 7 files changed, 179 insertions(+), 45 deletions(-) rename lua/pixelui/core/{cl_player.lua => sh_player.lua} (100%) create mode 100644 lua/pixelui/core/sh_theme.lua diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index d662c0f..1155841 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -60,7 +60,7 @@ resource.AddWorkshop("2468112758") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://github.com/Pulsar-Dev/pixel-ui/blob/master/VERSION", function(body) + http.Fetch("https://raw.githubusercontent.com/TomDotBat/pixel-ui/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) diff --git a/lua/pixelui/core/cl_imgur.lua b/lua/pixelui/core/cl_imgur.lua index e8319e3..3145ee3 100644 --- a/lua/pixelui/core/cl_imgur.lua +++ b/lua/pixelui/core/cl_imgur.lua @@ -21,19 +21,26 @@ local queue = {} local useProxy = false file.CreateDir("pixel") +file.CreateDir("pixel/icons") local function processQueue() if queue[1] then local id, matSettings, callback = unpack(queue[1]) - http.Fetch((useProxy and "https://proxy.duckduckgo.com/iu/?u=https://i.imgur.com/" or "https://i.imgur.com/") .. id .. ".png", - function(body, len, headers, code) - if len > 2097152 then - materials[id] = Material("nil") - else - file.Write("pixel/" .. id .. ".png", body) - materials[id] = Material("../data/pixel/" .. id .. ".png", matSettings or "noclamp smooth mips") - end + if file.Exists("pixel/icons/" .. id .. ".png", "DATA") then + materials[id] = Material("../data/pixel/icons/" .. id .. ".png", matSettings or "noclamp smooth mips") + return callback(materials[id]) + end + + http.Fetch(useproxy and "https://proxy.duckduckgo.com/iu/?u=https://i.imgur.com" or "https://i.imgur.com/" .. id .. ".png", + function(body, len, headers, code) + if len > 2097152 then + materials[id] = Material("nil") + return callback(materials[id]) + end + + file.Write("pixel/icons/" .. id .. ".png", body) + materials[id] = Material("../data/pixel/icons/" .. id .. ".png", matSettings or "noclamp smooth mips") callback(materials[id]) end, diff --git a/lua/pixelui/core/cl_player.lua b/lua/pixelui/core/sh_player.lua similarity index 100% rename from lua/pixelui/core/cl_player.lua rename to lua/pixelui/core/sh_player.lua diff --git a/lua/pixelui/core/sh_theme.lua b/lua/pixelui/core/sh_theme.lua new file mode 100644 index 0000000..9c12f07 --- /dev/null +++ b/lua/pixelui/core/sh_theme.lua @@ -0,0 +1,64 @@ +PIXEL.Colors = { + Background = Color(22, 22, 22), + Header = Color(28, 28, 28), + SecondaryHeader = Color(15, 15, 15), + Scroller = Color(61, 61, 61), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(220, 220, 220), + DisabledText = Color(40, 40, 40), + + Primary = Color(77, 79, 199), + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes = PIXEL.Themes or {} + +function PIXEL.SetTheme(theme) + file.Write("pixel/theme.txt", theme) + + if PIXEL.Themes[theme] then + PIXEL.Colors = PIXEL.Themes[theme] + else + print("PIXELUI: Invalid Theme") + return false + end +end + +local function printThemes() + print("PIXELUI: Valid Theme Options") + for k, v in pairs(PIXEL.Themes) do + print(" - " .. k) + end +end + +hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() + if !file.Exists("pixel/theme.txt", "DATA") then + PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] + return + end + local theme = file.Read("pixel/theme.txt", "DATA") + PIXEL.Colors = PIXEL.Themes[theme] +end) + +concommand.Add("pixel_set_theme", function(ply, cmd, args) + if !args[1] then + printThemes() + return + end + + PIXEL.SetTheme(args[1]) +end) + +concommand.Add("pixel_reset_theme", function(ply, cmd, args) + PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] +end) \ No newline at end of file diff --git a/lua/pixelui/elements/cl_avatar.lua b/lua/pixelui/elements/cl_avatar.lua index 7fb149b..b807829 100644 --- a/lua/pixelui/elements/cl_avatar.lua +++ b/lua/pixelui/elements/cl_avatar.lua @@ -1,43 +1,35 @@ + --[[ - PIXEL UI - Copyright Notice - © 2023 Thomas O'Sullivan - All rights reserved +PIXEL UI +Copyright (C) 2021 Tom O'Sullivan (Tom.bat) - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . ---]] +You should have received a copy of the GNU General Public License +along with this program. If not, see . +]] local PANEL = {} -AccessorFunc(PANEL, "MaskSize", "MaskSize", FORCE_NUMBER) +AccessorFunc(PANEL, "Rounding", "Rounding", FORCE_NUMBER) function PANEL:Init() self.Avatar = vgui.Create("AvatarImage", self) self.Avatar:SetPaintedManually(true) self.CirclePoly = {} - self:SetMaskSize(1) + self:SetRounding(10) end function PANEL:PerformLayout(w, h) self.Avatar:SetSize(w, h) - - self.CirclePoly = {} - local maskSize = self:GetMaskSize() - - local t = 0 - for i = 1, 360 do - t = math.rad(i * 720) / 720 - self.CirclePoly[i] = {x = w / 2 + math.cos(t) * maskSize, y = h / 2 + math.sin(t) * maskSize} - end end function PANEL:SetPlayer(ply, size) @@ -48,9 +40,6 @@ function PANEL:SetSteamID(id, size) self.Avatar:SetSteamID(id, size) end -local render = render -local surface = surface -local whiteTexture = surface.GetTextureID("vgui/white") function PANEL:Paint(w, h) render.ClearStencil() render.SetStencilEnable(true) @@ -64,9 +53,7 @@ function PANEL:Paint(w, h) render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NEVER) render.SetStencilReferenceValue(1) - surface.SetTexture(whiteTexture) - surface.SetDrawColor(255, 255, 255, 255) - surface.DrawPoly(self.CirclePoly) + PIXEL.DrawFullRoundedBox(self:GetRounding(), 0, 0, w, h, color_white) render.SetStencilFailOperation(STENCILOPERATION_ZERO) render.SetStencilPassOperation(STENCILOPERATION_REPLACE) diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index 3aff8c6..b326eba 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -53,7 +53,7 @@ function PANEL:Paint(w, h) self.TextCol = PIXEL.LerpColor(animTime, self.TextCol, textCol) self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) - if self:GetDrawOutline() then + if self:GetDrawOutline() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverLineCol, PIXEL.Scale(1)) end @@ -61,7 +61,7 @@ function PANEL:Paint(w, h) local imgurID = self:GetImgurID() if imgurID then local iconSize = h * .65 - PIXEL.DrawImgur(PIXEL.Scale(10), (h - iconSize) / 2, iconSize, iconSize, imgurID, self.TextCol) + PIXEL.DrawImgur(PIXEL.Scale(10), (h - iconSize) / 2, iconSize, iconSize, imgurID, Color(255,255,255)) PIXEL.DrawSimpleText(self:GetName(), "SidebarItem", PIXEL.Scale(20) + iconSize, h / 2, self.TextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) return end diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index 95f70a6..cf2eab3 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -1,3 +1,4 @@ + --[[ PIXEL UI - Copyright Notice © 2023 Thomas O'Sullivan - All rights reserved @@ -32,21 +33,96 @@ PIXEL.ProgressImageID = "635PPvg" --[[ Colour definitions. ]] -PIXEL.Colors = { + +PIXEL.DefaultTheme = "Dark" + +PIXEL.Themes = PIXEL.Themes or {} -- do not touch +PIXEL.Themes["Dark"] = { Background = Color(22, 22, 22), Header = Color(28, 28, 28), + SecondaryHeader = Color(43, 43, 43), Scroller = Color(61, 61, 61), PrimaryText = Color(255, 255, 255), SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - Primary = Color(47, 128, 200), + Primary = Color(77, 79, 199), Disabled = Color(180, 180, 180), - Positive = Color(66, 134, 50), - Negative = Color(164, 50, 50), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["Light"] = { + Background = HexColor("#F7F8FA"), + Header = HexColor("#edf1f5"), + SecondaryHeader = HexColor("#DFE1E4"), + Scroller = HexColor("#edf1f5"), + + PrimaryText = HexColor("#292D31"), + SecondaryText = HexColor("#808080"), + DisabledText = HexColor("#9ba0a3"), + + Primary = HexColor("#6f42c1"), + Disabled = HexColor("#9ba0a3"), + Positive = HexColor("#79CB60"), + Negative = HexColor("#d73a49"), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["GitHubDark"] = { + Background = HexColor("#24292e"), + Header = HexColor("#2f363d"), + SecondaryHeader = HexColor("#2b3036"), + Scroller = HexColor("#2f363d"), + + PrimaryText = HexColor("#b7d1d9"), + SecondaryText = HexColor("#c9d1d9"), + DisabledText = HexColor("#39414a"), + + Primary = HexColor("#b392f0"), + Disabled = HexColor("#6a737d"), + Positive = HexColor("#85e89d"), + Negative = HexColor("#f97583"), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["NightOwl"] = { + Background = HexColor("#011627"), -- Background + Header = HexColor("#0b2942"), -- Seccond Background + SecondaryHeader = HexColor("#13344f"), -- Active + Scroller = HexColor("#0b2942"), -- Seccond Background + + PrimaryText = HexColor("#FBFBFB"), -- Text + SecondaryText = HexColor("#d9d9d9"), -- Buttons + DisabledText = HexColor("#697098"), -- Disabled + + Primary = HexColor("#c792ea"), -- Purple + Disabled = HexColor("#697098"), -- Disabled + Positive = HexColor("#addb67"), -- Green + Negative = HexColor("#ff6363"), -- Red - Gold = Color(214, 174, 34), + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), From 8542abd7f259ab5c774d6bd09d350ea66ff4a86f Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 29 May 2022 20:49:38 +0100 Subject: [PATCH 101/155] feat: Theme changer ui --- lua/pixelui/core/sh_theme.lua | 21 ++--------- lua/pixelui/panels/cl_themeeditor.lua | 54 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 lua/pixelui/panels/cl_themeeditor.lua diff --git a/lua/pixelui/core/sh_theme.lua b/lua/pixelui/core/sh_theme.lua index 9c12f07..2107f90 100644 --- a/lua/pixelui/core/sh_theme.lua +++ b/lua/pixelui/core/sh_theme.lua @@ -28,19 +28,15 @@ function PIXEL.SetTheme(theme) if PIXEL.Themes[theme] then PIXEL.Colors = PIXEL.Themes[theme] + if CLIENT then + local ply = LocalPlayer() + ply.PIXELTheme = theme + end else - print("PIXELUI: Invalid Theme") return false end end -local function printThemes() - print("PIXELUI: Valid Theme Options") - for k, v in pairs(PIXEL.Themes) do - print(" - " .. k) - end -end - hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() if !file.Exists("pixel/theme.txt", "DATA") then PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] @@ -50,15 +46,6 @@ hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() PIXEL.Colors = PIXEL.Themes[theme] end) -concommand.Add("pixel_set_theme", function(ply, cmd, args) - if !args[1] then - printThemes() - return - end - - PIXEL.SetTheme(args[1]) -end) - concommand.Add("pixel_reset_theme", function(ply, cmd, args) PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] end) \ No newline at end of file diff --git a/lua/pixelui/panels/cl_themeeditor.lua b/lua/pixelui/panels/cl_themeeditor.lua new file mode 100644 index 0000000..b846a2e --- /dev/null +++ b/lua/pixelui/panels/cl_themeeditor.lua @@ -0,0 +1,54 @@ +local PANEL = {} +local sc = PIXEL.Scale + +function PANEL:Init() + self:SetSize(sc(200), sc(175)) + self:MakePopup() + self:Center() + + self:SetTitle("Theme Changer") + + local panW, panH = self:GetSize() + + self.DropDown = self:Add("PIXEL.ComboBox") + self.DropDown:SetPos((panW / 2) - (self.DropDown:GetWide() / 2), panH / 2 - sc(15)) + self.DropDown:SetSizeToText(false) + + for k, v in pairs(PIXEL.Themes) do + self.DropDown:AddChoice(k, k, k) + end + self.DropDown:SetValue(LocalPlayer().PIXELTheme) + + local themeSelected + function self.DropDown:OnSelect(index, text, data) + themeSelected = data + end + + self.Submit = self:Add("PIXEL.TextButton") + self.Submit:Dock(BOTTOM) + local dockMargin = sc(10) + self.Submit:DockMargin(dockMargin, dockMargin, dockMargin, dockMargin) + self.Submit:SetText("Submit") + + self.Submit.DoClick = function() + PIXEL.SetTheme(themeSelected) + self:Close() + notification.AddLegacy("PIXELUI: Theme changed to " .. themeSelected, 0, 3) + end +end + +function PANEL:PaintOver(w, h) + PIXEL.DrawSimpleText("Select new theme:", "Lyth_Pulsar.Font.Size20", w / 2, self.DropDown:GetY() - sc(15), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) +end + +vgui.Register("PIXELUI.ThemeChanger", PANEL, "PIXEL.Frame") + +concommand.Add("pixel_change_theme", function() + local ThemeChanger + if not ThemeChanger then + ThemeChanger = vgui.Create("PIXELUI.ThemeChanger") + else + ThemeChanger:Close() + ThemeChanger = vgui.Create("PIXELUI.ThemeChanger") + end +end) \ No newline at end of file From b0b104f8373883de0e01aa7610c1acc65c06830b Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 30 May 2022 00:12:06 +0100 Subject: [PATCH 102/155] feat: Notification overwrite --- lua/pixelui/elements/cl_notification.lua | 105 +++++++++++++++++++++++ lua/pixelui/sh_config.lua | 5 ++ 2 files changed, 110 insertions(+) create mode 100644 lua/pixelui/elements/cl_notification.lua diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua new file mode 100644 index 0000000..401261c --- /dev/null +++ b/lua/pixelui/elements/cl_notification.lua @@ -0,0 +1,105 @@ + +local sc = PIXEL.Scale +local Notices = {} +local notifAmount = 0 +surface.CreateFont("PIXEL.NotifyFont", { + font = "Open Sans Bold", + size = 25, + weight = 500, + antialias = true, +}) + + +function PIXEL.Notify(text, type, length) + local parent = nil + if ( GetOverlayPanel ) then parent = GetOverlayPanel() end + + local notif = vgui.Create("PIXEL.Notification", parent) + notif:SetLength(math.max(length, 0)) + notif:SetText(text) + + if notifAmount > 0 then + notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200) - (sc(50) * notifAmount)) + else + notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200)) + end + table.insert(Notices, notif) +end + +hook.Add("Initialize", "NotificationOverride", function() + local oldNotification = notification.AddLegacy + + function notification.AddLegacy(text, type, length) + if PIXEL.DisableNotification then + oldNotification(text, type, length) + else + PIXEL.Notify(text, type, length) + end + end +end) + +local PANEL = {} + +function PANEL:SetText(txt) + self.NotifyText = txt + surface.SetFont("PIXEL.NotifyFont") + self:SetWide(surface.GetTextSize(txt) + sc(25)) +end + +function PANEL:SetLength(sec) + sec = sec + .2 + self.Length = sec + + timer.Simple(sec, function() + self:Close() + end) +end + +function PANEL:Init() + notifAmount = notifAmount + 1 + self:SetTall(sc(40)) + self:SetWide(sc(40)) + self.NotifyText = "" + self:SetVisible(false) + self:Open() +end + +function PANEL:SizeToContents() +end + +function PANEL:SetLegacyType() +end + +function PANEL:Paint(w, h) + local shouldDraw = not (LocalPlayer and IsValid(LocalPlayer()) and IsValid(LocalPlayer():GetActiveWeapon()) and LocalPlayer():GetActiveWeapon():GetClass() == "gmod_camera") + if not shouldDraw then return end + + PIXEL.DrawRoundedBoxEx(sc(6), sc(5), 0, w, h, Color(0, 0, 0, 200), false, true, false, true) + PIXEL.DrawRoundedBoxEx(sc(6), 0, 0, sc(5), h, PIXEL.Colors.Primary, true, false, true, false) + PIXEL.DrawSimpleText(self.NotifyText, "PIXEL.NotifyFont", w / 2, h / 2 - sc(1), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) +end + +function PANEL:SetProgress(frac) +end + +function PANEL:KillSelf() +end + +function PANEL:Open() + self:SetAlpha(0) + self:SetVisible(true) + self:AlphaTo(255, .1, 0) +end + +function PANEL:Close() + self:AlphaTo(0, .1, 0, function(anim, pnl) + if not IsValid(pnl) then return end + pnl:SetVisible(false) + pnl:Remove() + end) + + notifAmount = notifAmount - 1 +end + + +vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index cf2eab3..c71768e 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -25,6 +25,11 @@ ]] PIXEL.OverrideDermaMenus = 0 +--[[ + Should we disable the PIXEL UI Reskin of the notification? +]] +PIXEL.DisableNotification = false + --[[ The Imgur ID of the progress image you want to appear when Imgur content is loading. ]] From 698d8acc5e531c79181cc8dd5716089ae0e5c92a Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 31 May 2022 00:17:30 +0100 Subject: [PATCH 103/155] new themes pog --- lua/pixelui/core/cl_fonts.lua | 19 ++++++++++++ lua/pixelui/core/sh_theme.lua | 1 + lua/pixelui/sh_config.lua | 54 ++++++++++++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/core/cl_fonts.lua b/lua/pixelui/core/cl_fonts.lua index 62c4937..db6fea3 100644 --- a/lua/pixelui/core/cl_fonts.lua +++ b/lua/pixelui/core/cl_fonts.lua @@ -57,6 +57,25 @@ do PIXEL.RegisterFontUnscaled(name, font, PIXEL.Scale(size), weight) end + function PIXEL.GenerateFont(size, weight, font, name) + weight = weight or 700 + PIXEL.Fonts = PIXEL.Fonts or {} + fontName = name or "PIXEL.Font.Size" .. size + font = font or "Open Sans Bold" + + if !PIXEL.Fonts[fontName] or PIXEL.Fonts[fontName].size != size or PIXEL.Fonts[fontName].weight != weight then + PIXEL.Fonts[fontName] = { + name = fontName, + size = size, + weight = weight + } + PIXEL.RegisterFont(fontName, font, size, weight) + return fontName + end + + return fontName + end + hook.Add("OnScreenSizeChanged", "PIXEL.UI.ReRegisterFonts", function() for k,v in pairs(scaledFonts) do PIXEL.RegisterFont(k, v.font, v.size, v.weight) diff --git a/lua/pixelui/core/sh_theme.lua b/lua/pixelui/core/sh_theme.lua index 2107f90..5bb9ca5 100644 --- a/lua/pixelui/core/sh_theme.lua +++ b/lua/pixelui/core/sh_theme.lua @@ -33,6 +33,7 @@ function PIXEL.SetTheme(theme) ply.PIXELTheme = theme end else + PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] return false end end diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index c71768e..e92d865 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -52,7 +52,7 @@ PIXEL.Themes["Dark"] = { SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - Primary = Color(77, 79, 199), + Primary = Color(74, 61, 255), Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), Negative = Color(235, 68, 68), @@ -75,7 +75,7 @@ PIXEL.Themes["Light"] = { SecondaryText = HexColor("#808080"), DisabledText = HexColor("#9ba0a3"), - Primary = HexColor("#6f42c1"), + Primary = Color(74, 61, 255), Disabled = HexColor("#9ba0a3"), Positive = HexColor("#79CB60"), Negative = HexColor("#d73a49"), @@ -94,7 +94,7 @@ PIXEL.Themes["GitHubDark"] = { SecondaryHeader = HexColor("#2b3036"), Scroller = HexColor("#2f363d"), - PrimaryText = HexColor("#b7d1d9"), + PrimaryText = Color(74, 61, 255), SecondaryText = HexColor("#c9d1d9"), DisabledText = HexColor("#39414a"), @@ -121,7 +121,7 @@ PIXEL.Themes["NightOwl"] = { SecondaryText = HexColor("#d9d9d9"), -- Buttons DisabledText = HexColor("#697098"), -- Disabled - Primary = HexColor("#c792ea"), -- Purple + Primary = Color(74, 61, 255), Disabled = HexColor("#697098"), -- Disabled Positive = HexColor("#addb67"), -- Green Negative = HexColor("#ff6363"), -- Red @@ -131,5 +131,51 @@ PIXEL.Themes["NightOwl"] = { Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["DiscordDark"] = { + Background = Color(54, 57, 63), + Header = Color(47, 49, 54), + SecondaryHeader = Color(51, 54, 59), + Scroller = Color(32, 34, 37), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(185, 187, 190), + DisabledText = Color(40, 40, 40), + + Primary = Color(88, 101, 242), + Disabled = Color(114, 118, 125), + Positive = Color(87, 242, 135), + Negative = Color(237, 66, 69), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["DiscordLight"] = { + Background = Color(255, 255, 255), + Header = Color(242, 243, 245), + SecondaryHeader = Color(220, 223, 227), + Scroller = Color(204, 204, 204), + + PrimaryText = Color(6, 6, 7), + SecondaryText = Color(79, 86, 96), + DisabledText = Color(79, 86, 96), + + Primary = Color(88, 101, 242), + Disabled = Color(79, 86, 96), + Positive = Color(87, 242, 135), + Negative = Color(237, 66, 69), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + Transparent = Color(0, 0, 0, 0) } \ No newline at end of file From 5a76a5bec4d950423b01845ff8b59ca082076d06 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 20:26:58 +0100 Subject: [PATCH 104/155] feat: add sounds --- lua/effects/pixel_confetti/init.lua | 51 +++++ lua/pixelui/core/cl_sounds.lua | 28 +++ lua/pixelui/core/sh_confetti.lua | 21 ++ lua/pixelui/elements/cl_button.lua | 210 ++++++++++++------ lua/pixelui/elements/cl_category.lua | 2 +- lua/pixelui/elements/cl_combo_box.lua | 9 +- lua/pixelui/elements/cl_frame.lua | 3 + lua/pixelui/elements/cl_imgur_button.lua | 1 + lua/pixelui/elements/cl_menu.lua | 26 ++- lua/pixelui/elements/cl_menu_option.lua | 9 + lua/pixelui/elements/cl_navbar.lua | 1 + lua/pixelui/elements/cl_property_sheet.lua | 1 + lua/pixelui/elements/cl_sidebar.lua | 1 + lua/pixelui/elements/cl_slider.lua | 1 + lua/pixelui/elements/cl_text_button.lua | 9 +- .../buttons-navigation/Button_1.mp3 | Bin 0 -> 2552 bytes .../buttons-navigation/Button_2.mp3 | Bin 0 -> 4851 bytes .../buttons-navigation/Button_3.mp3 | Bin 0 -> 3597 bytes .../buttons-navigation/Button_4.mp3 | Bin 0 -> 1089 bytes .../buttons-navigation/Button_5.mp3 | Bin 0 -> 1507 bytes .../buttons-navigation/Button_6.mp3 | Bin 0 -> 1298 bytes .../buttons-navigation/Button_7.mp3 | Bin 0 -> 1298 bytes .../buttons-navigation/Collapse.mp3 | Bin 0 -> 6732 bytes .../buttons-navigation/Expand.mp3 | Bin 0 -> 4013 bytes .../buttons-navigation/Tab_1.mp3 | Bin 0 -> 1504 bytes .../buttons-navigation/Tab_2.mp3 | Bin 0 -> 3594 bytes .../buttons-navigation/Tab_3.mp3 | Bin 0 -> 2967 bytes .../complete-success/Complete_1.mp3 | Bin 0 -> 13212 bytes .../complete-success/Complete_2.mp3 | Bin 0 -> 5271 bytes .../complete-success/Complete_3.mp3 | Bin 0 -> 2972 bytes .../complete-success/Success_1.mp3 | Bin 0 -> 12166 bytes .../complete-success/Success_2.mp3 | Bin 0 -> 20317 bytes .../complete-success/Success_3.mp3 | Bin 0 -> 12375 bytes .../pixelui-sounds/errors-cancel/Cancel_1.mp3 | Bin 0 -> 1507 bytes .../pixelui-sounds/errors-cancel/Cancel_2.mp3 | Bin 0 -> 1507 bytes .../pixelui-sounds/errors-cancel/Error_1.mp3 | Bin 0 -> 3805 bytes .../pixelui-sounds/errors-cancel/Error_2.mp3 | Bin 0 -> 2969 bytes .../pixelui-sounds/errors-cancel/Error_3.mp3 | Bin 0 -> 4014 bytes .../pixelui-sounds/errors-cancel/Error_4.mp3 | Bin 0 -> 4850 bytes .../pixelui-sounds/errors-cancel/Error_5.mp3 | Bin 0 -> 2969 bytes sound/pixelui-sounds/license.txt | 10 + .../notifications-alerts/Alert_1.mp3 | Bin 0 -> 15299 bytes .../notifications-alerts/Alert_2.mp3 | Bin 0 -> 11955 bytes .../notifications-alerts/Alert_3.mp3 | Bin 0 -> 24912 bytes .../notifications-alerts/Alert_4.mp3 | Bin 0 -> 12791 bytes .../notifications-alerts/Alert_5.mp3 | Bin 0 -> 7151 bytes .../notifications-alerts/Notification_1.mp3 | Bin 0 -> 12380 bytes .../notifications-alerts/Notification_2.mp3 | Bin 0 -> 7574 bytes .../notifications-alerts/Notification_3.mp3 | Bin 0 -> 19486 bytes .../notifications-alerts/Notification_4.mp3 | Bin 0 -> 13216 bytes .../notifications-alerts/Notification_5.mp3 | Bin 0 -> 17607 bytes .../notifications-alerts/Notification_6.mp3 | Bin 0 -> 36204 bytes .../notifications-alerts/Notification_7.mp3 | Bin 0 -> 27427 bytes .../notifications-alerts/Notification_8.mp3 | Bin 0 -> 30771 bytes .../notifications-alerts/Notification_9.mp3 | Bin 0 -> 22411 bytes 55 files changed, 302 insertions(+), 81 deletions(-) create mode 100644 lua/effects/pixel_confetti/init.lua create mode 100644 lua/pixelui/core/cl_sounds.lua create mode 100644 lua/pixelui/core/sh_confetti.lua create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_1.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_2.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_3.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_4.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_5.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_6.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Button_7.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Collapse.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Expand.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Tab_1.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Tab_2.mp3 create mode 100644 sound/pixelui-sounds/buttons-navigation/Tab_3.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Complete_1.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Complete_2.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Complete_3.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Success_1.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Success_2.mp3 create mode 100644 sound/pixelui-sounds/complete-success/Success_3.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Cancel_1.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Cancel_2.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_1.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_2.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_3.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_4.mp3 create mode 100644 sound/pixelui-sounds/errors-cancel/Error_5.mp3 create mode 100644 sound/pixelui-sounds/license.txt create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_1.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_2.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_3.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_4.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Alert_5.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_1.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_2.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_3.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_4.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_5.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_6.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_7.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_8.mp3 create mode 100644 sound/pixelui-sounds/notifications-alerts/Notification_9.mp3 diff --git a/lua/effects/pixel_confetti/init.lua b/lua/effects/pixel_confetti/init.lua new file mode 100644 index 0000000..5216b5a --- /dev/null +++ b/lua/effects/pixel_confetti/init.lua @@ -0,0 +1,51 @@ +-- Credit to GlorifiedPig#6666 For Making This + +AddCSLuaFile() +EFFECT.Mat = Material( "particles/balloon_bit" ) +local particleCount = 200 +local confettiSize = 2 +local confettiSpread = 650 +local confettiLife = 8 + +function EFFECT:Init( data ) + local vOrigin = data:GetOrigin() + local emitter = ParticleEmitter( vOrigin, true ) + + for i = 0, particleCount do + local randomPos = VectorRand() + local particle = emitter:Add( self.Mat, vOrigin + randomPos ) + + if particle then + local vel = math.Rand( 10, confettiSpread ) + particle:SetVelocity( randomPos * vel ) + + particle:SetLifeTime( 0 ) + particle:SetDieTime( confettiLife ) + + particle:SetStartAlpha( 255 ) + particle:SetEndAlpha( 255 ) + + local Size = math.Rand( confettiSize - 1, confettiSize + 2 ) + particle:SetStartSize( Size ) + particle:SetEndSize( 0 ) + particle:SetRoll( math.Rand( 0, 360 ) ) + particle:SetRollDelta( math.Rand( -2, 2 ) ) + + particle:SetAirResistance( 200 ) + particle:SetGravity( Vector( 0, 0, -300 ) ) + + particle:SetColor( math.Rand( 50, 255 ), math.Rand( 50, 255 ), math.Rand( 50, 255 ) ) + + particle:SetCollide( true ) + + particle:SetAngleVelocity( Angle( math.Rand( -160, 160 ), math.Rand( -160, 160 ), math.Rand( -160, 160 ) ) ) + + particle:SetBounce( 1 ) + particle:SetLighting( false ) + end + end + + emitter:Finish() +end + +function EFFECT:Render() end \ No newline at end of file diff --git a/lua/pixelui/core/cl_sounds.lua b/lua/pixelui/core/cl_sounds.lua new file mode 100644 index 0000000..97e37b5 --- /dev/null +++ b/lua/pixelui/core/cl_sounds.lua @@ -0,0 +1,28 @@ +do + function PIXEL.PlaySound(type, sound) + local soundPath = "pixelui-sounds/" .. type .. "/" .. sound .. ".mp3" + + if not file.Exists("sound/" .. soundPath, "GAME") then print(soundPath, "bad") return end + + surface.PlaySound(soundPath) + end + + local buttonSounds = { + [1] = "Button_4", + [2] = "Button_5", + } + + function PIXEL.PlayButtonSound() + local randSound = math.random(1, 2) + PIXEL.PlaySound("buttons-navigation", buttonSounds[randSound]) + end + + + function PIXEL.PlayExpand(type) + if type == "open" then + PIXEL.PlaySound("buttons-navigation", "Expand") + else + PIXEL.PlaySound("buttons-navigation", "Collapse") + end + end +end \ No newline at end of file diff --git a/lua/pixelui/core/sh_confetti.lua b/lua/pixelui/core/sh_confetti.lua new file mode 100644 index 0000000..30398fb --- /dev/null +++ b/lua/pixelui/core/sh_confetti.lua @@ -0,0 +1,21 @@ +if SERVER then + util.AddNetworkString("PIXEL.SpawnConfetti") + util.PrecacheSound("pixel_confetti.mp3") + function PIXEL.SpawnConfetti(ply) + local effectData = EffectData() + effectData:SetOrigin(ply:GetPos()) + util.Effect("pixel_confetti", effectData) + sound.Play("pixelui-sounds/pixel_confetti.mp3", ply:GetPos()) + end + + net.Receive("PIXEL.SpawnConfetti", function(_, ply) + PIXEL.SpawnConfetti(ply) + end) +end + +if CLIENT then + function PIXEL.SpawnConfetti() + net.Start("PIXEL.SpawnConfetti") + net.SendToServer() + end +end \ No newline at end of file diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index 1e56b26..0ae64f9 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -19,110 +19,152 @@ local PANEL = {} AccessorFunc(PANEL, "IsToggle", "IsToggle", FORCE_BOOL) AccessorFunc(PANEL, "Toggle", "Toggle", FORCE_BOOL) +AccessorFunc(PANEL, "Clicky", "Clicky", FORCE_BOOL) +AccessorFunc(PANEL, "Sounds", "Sounds", FORCE_BOOL) + function PANEL:Init() - self:SetIsToggle(false) - self:SetToggle(false) - self:SetMouseInputEnabled(true) + self:SetIsToggle(false) + self:SetToggle(false) + self:SetMouseInputEnabled(true) + + self:SetCursor("hand") + self:SetClicky(false) + self:SetSounds(true) - self:SetCursor("hand") + local btnSize = PIXEL.Scale(30) + self:SetSize(btnSize, btnSize) - local btnSize = PIXEL.Scale(30) - self:SetSize(btnSize, btnSize) + self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) + self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) + self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) + self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) + self.ClickyCol = PIXEL.OffsetColor(self.NormalCol, -35) - self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) - self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) - self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) - self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) + self.BackgroundCol = self.NormalCol + self.BackgroundClickyCol = self.ClickyCol - self.BackgroundCol = self.NormalCol + self.ClickyScale = PIXEL.Scale(3) + self.Clicky = self:GetClicky() + self.ClickyMove = false +end + +function PANEL:PerformLayout() + local tall = self:GetTall() + + if tall > 75 then + self.ClickyScale = self:GetTall() / 25 + elseif tall > 50 then + self.ClickyScale = self:GetTall() / 17 + elseif tall > 25 then + self.ClickyScale = self:GetTall() / 10 + elseif tall > 15 then + self.ClickyScale = self:GetTall() / 5 + end end function PANEL:DoToggle(...) - if not self:GetIsToggle() then return end + if not self:GetIsToggle() then return end - self:SetToggle(not self:GetToggle()) - self:OnToggled(self:GetToggle(), ...) + self:SetToggle(not self:GetToggle()) + self:OnToggled(self:GetToggle(), ...) end local localPly function PANEL:OnMousePressed(mouseCode) - if not self:IsEnabled() then return end + if not self:IsEnabled() then return end + self.ClickyMove = true + if self:GetSounds() then + PIXEL.PlayButtonSound() + end - if not localPly then - localPly = LocalPlayer() - end + if not localPly then + localPly = LocalPlayer() + end - if self:IsSelectable() and mouseCode == MOUSE_LEFT and (input.IsShiftDown() or input.IsControlDown()) and not (localPly:KeyDown(IN_FORWARD) or localPly:KeyDown(IN_BACK) or localPly:KeyDown(IN_MOVELEFT) or localPly:KeyDown(IN_MOVERIGHT)) then - return self:StartBoxSelection() - end + if self:IsSelectable() and mouseCode == MOUSE_LEFT and (input.IsShiftDown() or input.IsControlDown()) and not (localPly:KeyDown(IN_FORWARD) or localPly:KeyDown(IN_BACK) or localPly:KeyDown(IN_MOVELEFT) or localPly:KeyDown(IN_MOVERIGHT)) then + return self:StartBoxSelection() + end - self:MouseCapture(true) - self.Depressed = true - self:OnPressed(mouseCode) + self:MouseCapture(true) + self.Depressed = true + self:OnPressed(mouseCode) - self:DragMousePress(mouseCode) + self:DragMousePress(mouseCode) end function PANEL:OnMouseReleased(mouseCode) - self:MouseCapture(false) + self:MouseCapture(false) + + if not self:IsEnabled() then return end + if not self.Depressed and dragndrop.m_DraggingMain ~= self then return end - if not self:IsEnabled() then return end - if not self.Depressed and dragndrop.m_DraggingMain ~= self then return end + self.ClickyMove = false - if self.Depressed then - self.Depressed = nil - self:OnReleased(mouseCode) - end + if self.Depressed then + self.Depressed = nil + self:OnReleased(mouseCode) + end - if self:DragMouseRelease(mouseCode) then - return - end + if self:DragMouseRelease(mouseCode) then + return + end - if self:IsSelectable() and mouseCode == MOUSE_LEFT then - local canvas = self:GetSelectionCanvas() - if canvas then - canvas:UnselectAll() - end - end + if self:IsSelectable() and mouseCode == MOUSE_LEFT then + local canvas = self:GetSelectionCanvas() + if canvas then + canvas:UnselectAll() + end + end - if not self.Hovered then return end + if not self.Hovered then return end - self.Depressed = true + self.Depressed = true - if mouseCode == MOUSE_RIGHT then - self:DoRightClick() - elseif mouseCode == MOUSE_LEFT then - self:DoClick() - elseif mouseCode == MOUSE_MIDDLE then - self:DoMiddleClick() - end + if mouseCode == MOUSE_RIGHT then + self:DoRightClick() + elseif mouseCode == MOUSE_LEFT then + self:DoClick() + elseif mouseCode == MOUSE_MIDDLE then + self:DoMiddleClick() + end - self.Depressed = nil + self.Depressed = nil end function PANEL:PaintExtra(w, h) end function PANEL:Paint(w, h) - if not self:IsEnabled() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.DisabledCol) - self:PaintExtra(w, h) - return - end - - local bgCol = self.NormalCol - - if self:IsDown() or self:GetToggle() then - bgCol = self.ClickedCol - elseif self:IsHovered() then - bgCol = self.HoverCol - end - - self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) - - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) - - self:PaintExtra(w, h) + if not self:IsEnabled() then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.DisabledCol) + self:PaintExtra(w, h) + return + end + + local bgCol = self.NormalCol + + if self:IsDown() or self:GetToggle() then + bgCol = self.ClickedCol + elseif self:IsHovered() and not self.Clicky then + bgCol = self.HoverCol + end + + if not self.Clicky then + self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) + end + + if not self:GetClicky() then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) + else + if self.ClickyMove then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) + else + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.ClickyCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h - self.ClickyScale, self.BackgroundCol) + end + end + + self:PaintExtra(w, h) end function PANEL:IsDown() return self.Depressed end @@ -133,4 +175,30 @@ function PANEL:DoClick(...) self:DoToggle(...) end function PANEL:DoRightClick() end function PANEL:DoMiddleClick() end -vgui.Register("PIXEL.Button", PANEL, "Panel") \ No newline at end of file +vgui.Register("PIXEL.Button", PANEL, "Panel") + +concommand.Add("test", function() + local pnl = vgui.Create("PIXEL.Frame") + pnl:SetTitle("Test") + pnl:SetSize(650, 350) + pnl:Center() + local btn1 = pnl:Add("PIXEL.Button") + btn1:SetClicky(true) + btn1:SetSize(480, 200) + btn1:SetPos(10, 50) + + local btn2 = pnl:Add("PIXEL.Button") + btn2:SetClicky(true) + btn2:SetSize(100, 25) + btn2:SetPos(10, 275) + + local btn3 = pnl:Add("PIXEL.Button") + btn3:SetClicky(true) + btn3:SetSize(50, 200) + btn3:SetPos(525, 50) + + local btn4 = pnl:Add("PIXEL.Button") + btn4:SetClicky(true) + btn4:SetSize(300, 30) + btn4:SetPos(125, 275) +end) \ No newline at end of file diff --git a/lua/pixelui/elements/cl_category.lua b/lua/pixelui/elements/cl_category.lua index 1a819ac..89fcea4 100644 --- a/lua/pixelui/elements/cl_category.lua +++ b/lua/pixelui/elements/cl_category.lua @@ -23,7 +23,7 @@ PIXEL.RegisterFont("UI.CategoryHeader", "Open Sans Bold", 19) function PANEL:Init() self.ArrowRotation = 0 - + self:SetClicky(false) self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 6) end diff --git a/lua/pixelui/elements/cl_combo_box.lua b/lua/pixelui/elements/cl_combo_box.lua index 0ff09f5..5e6aa04 100644 --- a/lua/pixelui/elements/cl_combo_box.lua +++ b/lua/pixelui/elements/cl_combo_box.lua @@ -24,11 +24,12 @@ AccessorFunc(PANEL, "m_bDoSort", "SortItems", FORCE_BOOL) function PANEL:Init() self:SetSizeToText(true) - + self:SetClicky(false) self:Clear() self:SetTextAlign(TEXT_ALIGN_LEFT) self:SetSortItems(true) + self:SetSounds(false) end function PANEL:PerformLayout(w, h) @@ -129,7 +130,7 @@ end function PANEL:OpenMenu(pControlOpener) if pControlOpener and pControlOpener == self.TextEntry then return end - + PIXEL.PlayExpand("open") if #self.Choices == 0 then return end if IsValid(self.Menu) then @@ -171,6 +172,7 @@ function PANEL:OpenMenu(pControlOpener) self.Menu.OnRemove = function(s) if not IsValid(self) then return end + PIXEL.PlayExpand("close") self:SetToggle(false) end end @@ -199,8 +201,7 @@ function PANEL:SetValue(strValue) end function PANEL:DoClick() - if self:IsMenuOpen() then return self:CloseMenu() end - self:OpenMenu() + if not self:IsMenuOpen() then self:OpenMenu() end end function PANEL:PaintOver(w, h) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 13758ba..e371929 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -230,9 +230,12 @@ function PANEL:PaintHeader(x, y, w, h) PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(8), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) end +function PANEL:PaintMore(w,h) end + function PANEL:Paint(w, h) PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Background) self:PaintHeader(0, 0, w, PIXEL.Scale(30)) + self:PaintMore(w, h) end vgui.Register("PIXEL.Frame", PANEL, "EditablePanel") diff --git a/lua/pixelui/elements/cl_imgur_button.lua b/lua/pixelui/elements/cl_imgur_button.lua index a193d56..f639292 100644 --- a/lua/pixelui/elements/cl_imgur_button.lua +++ b/lua/pixelui/elements/cl_imgur_button.lua @@ -32,6 +32,7 @@ function PANEL:Init() self:SetHoverColor(color_white) self:SetClickColor(color_white) self:SetDisabledColor(color_white) + self:SetClicky(false) self:SetImageSize(1) end diff --git a/lua/pixelui/elements/cl_menu.lua b/lua/pixelui/elements/cl_menu.lua index 2f2e4d6..c577bf5 100644 --- a/lua/pixelui/elements/cl_menu.lua +++ b/lua/pixelui/elements/cl_menu.lua @@ -130,10 +130,6 @@ function PANEL:CloseSubMenu(menu) self:SetOpenSubMenu(nil) end -function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) -end - function PANEL:ChildCount() return #self:GetCanvas():GetChildren() end @@ -198,6 +194,28 @@ function PANEL:Open(x, y, skipanimation, ownerpanel) self:MakePopup() self:SetVisible(true) self:SetKeyboardInputEnabled(false) + + self.DrawTall = PIXEL.Scale(0) + local children = self:GetCanvas():GetChildren() + local childTall = children[1]:GetTall() + local childCount = 1 + for k, v in pairs(children) do + v:Hide(false) + end + timer.Create("PIXEL.Menu.Open", 0.025, self:ChildCount(), function() + if not IsValid(self) then return end + self.DrawTall = self.DrawTall + childTall + children[childCount]:Show(true) + childCount = childCount + 1 + + if self:ChildCount() == childCount then + self.DrawTall = self:GetTall() + end + end) +end + +function PANEL:Paint(w, h) + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, self.DrawTall, self.BackgroundCol) end function PANEL:OptionSelectedInternal(option) diff --git a/lua/pixelui/elements/cl_menu_option.lua b/lua/pixelui/elements/cl_menu_option.lua index 5daa00d..f7e896b 100644 --- a/lua/pixelui/elements/cl_menu_option.lua +++ b/lua/pixelui/elements/cl_menu_option.lua @@ -26,10 +26,18 @@ AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) PIXEL.RegisterFont("UI.MenuOption", "Open Sans SemiBold", 18) +function PANEL:Hide() + self.Hidden = true +end +function PANEL:Show() + self.Hidden = false +end + function PANEL:Init() self:SetTextAlign(TEXT_ALIGN_LEFT) self:SetFont("UI.MenuOption") self:SetChecked(false) + self:SetClicky(false) self.NormalCol = PIXEL.Colors.Transparent self.HoverCol = PIXEL.Colors.Scroller @@ -65,6 +73,7 @@ end function PANEL:OnCursorExited() end function PANEL:Paint(w, h) + if self.Hidden then return end self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, self:IsHovered() and self.HoverCol or self.NormalCol) surface.SetDrawColor(self.BackgroundCol) diff --git a/lua/pixelui/elements/cl_navbar.lua b/lua/pixelui/elements/cl_navbar.lua index 894e7e9..2d03e77 100644 --- a/lua/pixelui/elements/cl_navbar.lua +++ b/lua/pixelui/elements/cl_navbar.lua @@ -25,6 +25,7 @@ PIXEL.RegisterFont("UI.NavbarItem", "Open Sans SemiBold", 22) function PANEL:Init() self:SetName("N/A") self:SetColor(PIXEL.Colors.Primary) + self:SetClicky(false) self.NormalCol = PIXEL.Colors.PrimaryText self.HoverCol = PIXEL.Colors.SecondaryText diff --git a/lua/pixelui/elements/cl_property_sheet.lua b/lua/pixelui/elements/cl_property_sheet.lua index ecbea65..d3cb2b3 100644 --- a/lua/pixelui/elements/cl_property_sheet.lua +++ b/lua/pixelui/elements/cl_property_sheet.lua @@ -24,6 +24,7 @@ AccessorFunc(PANEL, "m_pPanel", "Panel") PIXEL.RegisterFont("UI.Tab", "Open Sans Bold", 16) function PANEL:Init() + self:SetClicky(false) self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, -4) self.SelectedCol = PIXEL.Colors.Primary self.UnselectedTextCol = PIXEL.Colors.SecondaryText diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index b326eba..a0760f0 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -26,6 +26,7 @@ PIXEL.RegisterFont("SidebarItem", "Open Sans Bold", 19) function PANEL:Init() self:SetName("N/A") self:SetDrawOutline(true) + self:SetClicky(false) self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) diff --git a/lua/pixelui/elements/cl_slider.lua b/lua/pixelui/elements/cl_slider.lua index 360cab6..73be22c 100644 --- a/lua/pixelui/elements/cl_slider.lua +++ b/lua/pixelui/elements/cl_slider.lua @@ -18,6 +18,7 @@ local PANEL = {} function PANEL:Init() + self:SetClicky(false) self.Fraction = 0 self.Grip = vgui.Create("PIXEL.ImgurButton", self) diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index 894a931..e4ee059 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -31,6 +31,9 @@ function PANEL:Init() self:SetFont("UI.TextButton") self:SetSize(PIXEL.Scale(100), PIXEL.Scale(30)) + self:SetClicky(true) + self:SetSounds(true) + end function PANEL:SizeToText() @@ -47,7 +50,11 @@ function PANEL:PaintExtra(w, h) return end - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + if self:GetClicky() then + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(2), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + else + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + end end vgui.Register("PIXEL.TextButton", PANEL, "PIXEL.Button") \ No newline at end of file diff --git a/sound/pixelui-sounds/buttons-navigation/Button_1.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2f63c46bcd992e0cf1774f8191daa567e3ef196b GIT binary patch literal 2552 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 GZ22AOTuxp9 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Button_2.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0de73c749b4addf68c19f665423d69fca787e1a0 GIT binary patch literal 4851 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 GgZ}`Om+?IS literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Button_3.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..f731b71b2e88a233b6716e07f5444fb4822aa416 GIT binary patch literal 3597 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 P`Z)T!8iSHgC}98qQvQc$ literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Button_5.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_5.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..7d362b4e362ab2998cc9763bd22273927b8b9000 GIT binary patch literal 1507 zcmeZtF=k-^0_KE}h=>RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&mm@FibE+ z3{XW(oD5x2MLoYEX3J20O5QQph$XRK~8FM zaeP5eVr5cdayCL%3@GcGmzbNM;e=gI540BPKiJs^Urr(mz==D|9=M@ zVPN10F^-)g%)q!)YfZVb0Aq^+149sp(2V0#k|pjrY%>sOl96ZObN=Z(;dtlar_6#3 zihmti7AU-tXFtWn#lpxutC6|M!NE|E!|}t99{D!=|C-T@9!fB{=rS-dFf=$U;904$ z{HR3dqS(W1jGrdFJh8O-sV||4W&< zT2?`R^^YAcVp7XIXU)+T5Uu}zE!I?HqTo51MK{;~|Nm1fCpIPZVz100k#4h}G7^Pc zE)P!}V*LL*=m;zG>6O6@GR6#y$y)ITm=!d7cn$_m$=S2%`-0-l%TiWeQabnHu8P`< zWr1JLpDGdl`Fp>%wSAcV`+BcU4X5_*%xX#K`9J@bYMFiLTaD@Vb?Y~Yh4+@<>ihAl zqAMO4=zk*b?_`eQ4~n|cx>+igk6T3T(-Mb_r7I-`N>n0)bk~NQbWPhjE$48$M#qZa z$$#z{{&^X6`BdE8b(YsvzG#O&+o!VX-TX%q7w>qQvR%F0leu+I*PN*)_5c4rVk~{! z_we}Bq?HZNrgE~(@>MMDI|K3%2NTy*mk-Pvl24|0T%CFL#f{_FH!fp6F*9UkX~h|d zLsRmvEDjAcxa!o&vvKDB;KN*2tF~6D8MY?>PiM59IpfN%s42;>)<&?@Ej_mS|5i1v zH3!`P|9`l!E|@KlN%A9yOv#+OJB$-U)NTdNU1^tQ`EbT6Da*#r6|)UHryEMlQ9QG8 zc3EXVTDJH2i z7u?Hux^wHyv3P0Tb?0Dl%dGUy{9f8YF@Q88L zUzl_@MqSG4&)uFIQ{$Izj=I*>C2bP3i^0^Q6zfZF*tT&=WMuDd#tFYq&c9RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&mB^S{OkX zKsGKBxDiIqu-$=L{5F`%q#UUGg)W?s5NKw?p1ZZQKW1YqXX1LZ+p3ib_ff_e$= z6bloWmrN0!1Ub;a%nYCV@puhWiXkL8*cIqmexO5q63fy|E%b~G^bCQafB^r0I~+jp zpe)b4w0s~FsE>geh%^|g34y(Yz<)vjWHr!{$v{UMn}Rqnpu*e$VKQq>_GqsJv;Y4N zIKsfd*^wO>lExr7Nm1v&ya3|_kdzjGdHLQ2GmTO%?@n;kGd#e-$ara4%14ERC;ZNw ze{8|_$kP5COQXO?3lp}MqjO7NA3WUf!|ua>jYkiDAN=tD#~gdT|CawRvcGD)AvuSE zqk}=3v$qxK0LhilrRyvwP5a+)M(k8eBY^A-Ezys!V6X=FEft#Ziz|Gz@jGCY^P-5+zX z(=<||{r~TvBdpBaEsI5D{xC3l@GatzF;o!Z$mcl06LeX%sneu0LU``2()U^63T?jy zJCmiR+O6f--T7*{?&IkqJ-(O1*BTcEXI+hZcV*Mw_5c5${xA1^{<(h@;jEL4t6qvR zN?zR>|Nnb+sXzlOm!@E@)|E>u)Gig9uT=WQCX;wDaK+;5=5@bfP19PIhwB9gOsQZ{ z{gLyO@0>^Y`b*zmwy5y@zPdo;TUMyq**&qHM;9&+Im#@^eLB+LIM`&Bnb6nhh7-V7_$0nsdL4>Sl)Y<+iN~Q`)d* z+j-@XHA`=JEPJ=EQnH~XoK^9aS@5Yz*|zM?|8M=BCUv#KicdxMJlh^Gsff(PMMs=n zmncPap0Zhd$7Jy#^@Cv>Pfn}WNJtP|aOTjBXDidf<{W$J5-Ij+!$#prH97M;wwwsK zId^TZN01W#1mSrmts&Ffey`rCrOY$)A1haP(xFHDySnNFcH4`J{1@?Y^mR1`<&0Ih F005u=;a30v literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Button_7.mp3 b/sound/pixelui-sounds/buttons-navigation/Button_7.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..3192f4f6b15961d1e7b0ae8351be4a91af3c417e GIT binary patch literal 1298 zcmeZtF=k-^0_KE}h=>RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&myfn?o4} z1~^6FQc#A8g@H4=E+jP!A)X;dK>u(7t#c|ZDap@MFo!vT11J{a>>Ge^z6ekxJ+UAs zwYWIGASbahDKR-4Au9%yb00EGa|yn3KK$VbNM;e=gI542X+yG%RYbc4FOaZh1{|-39 zz`*&U)TiWo17rKlH`;~*ObiV9kMBu;|M=}d2Ir2Q)6I`8P;OWu-(JDj;K0N5;34my z3eGRK{OJ>(nDBM1NW9RdA=>UV3G&s_M^znKlzQX~jp^FKXObu~PqU%DgRFMM{0a z-wuc`>ihpY=m<;m>5^I&*&YVYWd69uHHIsiye=IQTjuP+{^Z){$iUDD@fEsiD|(Iy z2&O1JmUH~>t9Z3{j!H{p^mU;s%|##l+Skh5ciU<8_}JpVPhWl2R4V>(XP2gE`>V(! z@l884?^rMU`%hTOL;KaLWh>5HIn?4~U{DyKDD-VcQS&^XtY=JHc+(^u-=5*QDsZIZ z1XED)OtHxhO>LsK-8%aZHoHt%DX^6Dz(dVje7m`3u_rEjIW`Iu?J%jW^Av z`ii`qlj$|HUEJd66ywy1A3z@BVCMc(_k=f5pHrkSoWp!$0FNc-B14yT{%IR}*Su+9 zGLgDsHR0ThfR+tKE=i8X5}ZtvStt2@Y19p>UgVh`V(2u1>yX5!w>9zxCZ(M#ZfbP6 z*+^RC1Vz3%u~uvKt=jmP8jNgg{Wo|-g1gQvwCrB#k}mxs$>z$Iq%gfH=lHK^*&1n0 t?>=~ALbO9jRmn67ecw}Cc?@ENMMZ_ApouX(e)C!%M_*TCP^JjQ3joEf()s`Z literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Collapse.mp3 b/sound/pixelui-sounds/buttons-navigation/Collapse.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..1c6e780de657e523acfc3a4c437870b40c11743a GIT binary patch literal 6732 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/buttons-navigation/Tab_3.mp3 b/sound/pixelui-sounds/buttons-navigation/Tab_3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..443e1c42d6f43b4a1968e92b55f819098c9b7833 GIT binary patch literal 2967 zcmd6pX;_l^8pdC714RYb(lj?zDh)x+rA6ET4JAb-om5;XHNZqE&C(LLaZ6JVntI%G z$)a6b+-LilO9J+ zhz>s-^<|g!`!YSw1|7{}(xsD8;>l=oBE#Fqmk1c5B(g?Xe<{TEA03DP?4Yc7{QHaz zTAb|n^*^`%wE)NjGFr@|D87zN4L8I{?*~g7u0+yb*)_$TgVeagQ7l$y++k``I5i^n zFIQXax-%k}kACctp2hX25>}{kx=)ZU*nbBAWkN*<> zf3g6wpP##!R81UYFO^NRwYNf}tgKNeaZf7Insbk|{_{y-(3s+bcn?qp00ZDX9Qng6cE!Bur^HPbVl3Xqh86ggdv6UR8GL=pHQbKrrugPP-*P=Dj03Zth zG7aLR(Qf6<1v~)&z|{8*Fkbgt>iH^xM_y5N-oU`nWIz3zA@aQK>3sl9Mb0L8fNyY8 zM^OU{K7CIFg_Z`O12(0C41p&rNO9?MVFyji{8DkYdle1Y}qktZzfey`Yh8CNd;1 zGt1ince}c+2(IM$Vi%x$|0lkLSn4mSk~(iNyaQ>8nO_?tS{4B)`PwQ1PLpAzvwuGUA#℘u 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/complete-success/Complete_2.mp3 b/sound/pixelui-sounds/complete-success/Complete_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0af95a2d24511e1fee0539472e762b85a19a0386 GIT binary patch literal 5271 zcmc(iXH-+$wt#nv5FqpxKp<2p(gO&}A)!f?0D(h?&}%@72p%Q$A|OZ?P3BnWH0234j3H+5~rRKZ|l-wovpkVI+0wDh@g`}ih1N;N=A>J;2?*CdF z{ByB?AWG3YIKcl`r8}k48y8BrU}|mxAmyo`v~>OzP~x9~f}$$wpEK05f6ky(byfa3 z^N$(;XMj_r_`oT*)21}$=N{sYRQ%Nhj53SUHo^W|fP*sQiKmnW2RjA&;lo|**lf#5qNY+Oe2$Q-cRUOiAoh;t*sYDYQiJmEwgB!EGxaN`9rX8 zO^MRP4|AA-C~JIwG;)O{5h@JOZY^B4;T`Ntgs@B~2t13qVOrru-#9H_8xz({C=4Pt z#e}oUpW@$20~Nv(k)Y2QZ_Vf>E+Vq`C4=shO+}AH@sUNRDRGzxdtw#&$5;p#!N(+% zL?%zmRi0x4>yq?_{ZF{x{NzL?nfF794CR@=U0(oJPnN2ts{EB3<}WqG-ez#Eiu3h_ z*l8W8GZx`F3N9kF7#Nfol$98iloWS@b@&U*)1ER}mn;tKDQCl{q-sx}2<-OxnuQl@ zLfz45=rD1_ebe=VY*OBHS*6Qx#@~5ql}% zQJqzD+0ZsW)e0%+E^VKi7Pr0Nx94%MTSwO!{8%y!-wl1){5%Sd9u2dra`~XX3R&3u z=xb(XJ9lEP8-N&sKqlntGI_pKAzBc_T#`b4R{+K>do5~_ZWD_Ntyiu{X{;<@WAW)r zuB{|E+oMaJ%$puN4)=~h-|02!v6%<$zNfDk73pjDGpq>e$bS&pWvct(nNF@N2!z&# zG|u#yaTxCG?Qrf-dDU_(Hf; zOdK{-9vm3dTTXNV<8A*BMvm4p5EfSsI)xuvXp^QbE#@CRvXGKo zQu&@wTjW^oU);uBzlmUR{v`Grk8BSD+O6d}aRgsMa6%A{K0#kaP;BRRWhZRCmVC5_`$zLT|Cg97qy--OZVFHe|_(#5nQ z)%pN*$h)|OT=fgX)o`j13^Fcp2hOxEi}4UHi5kj5Xd(05(Rs#Pc}#GG^Tk3PVcv?9 z{nbh&-iooLtGe>Bd>y`mu5MpNbi**7@44EJd9$m`rEHC!-ny7}`nY=z8$u(Md-yOu z6H1G~ylp#?@rLyk{0}6{pv*hToK9nCcZqhCX)2h>FcU7pjIH2efW+=#$l=U9Z3j;Z zy%=q3G`Bc&8n3CJNu2MYJwExWb6DGBF4oPsKtuB&AZ$?O*ood`8m(UgC2IW?Wa)8IFANB6Uw~DEmbHgP1#Jx6FKcUPQR_Lj*)|TIEbkfAS61Nd*aYejC=IZg{mY$0UDyM?4 z$WFLlnW=`hGYubw4_dNK!nj3CC5}7Xp@$j;;`ch%45E8-K&;vP+TXF~u$CEuMqKP} z4jJ0KudmL}9tMQ1)+jH2ae4ktrc3kDMGYy{hEIYS>)Y3_rVZ|SR0=%#YQVP~6;#6h za?pZ43|&lXFwA=T=Q9*Ds^bl3jQR}HNEIUfP{!J#O?YzER6)Wy{+#!($ObHU621=k zhGMS!I<{QfoGSdD-0`Nb!WLm`V|cUrku&n)t1C2TIomP6mt}(#m>FR6pQCWS4Hp?# zD{ZxZuZ(6*)WZYe(@`!xZb^|%iVl$u_|>}6NeSh={imX7Lx#eF^&-5MJ_0;Vr;M_> zB^JKeXPY;V^3GVY+26K*pYsqn4LR8tVX(QFb}d+*6~~3whZUd5j#D@}DjP2U;4X>q z@P}*Q*~0wH-1tmBBaLeW9Xw@ z%lI&H?UzYXbQ((7xPp6!R@_69S5hCQtA*dpQ=9%XuEZdu4As|itscwThQkAS@0moA zH93N2gNnNPCGjuVB+71u`e%aa6>1%F%1fQKIb3E@&s-4u9B*T!eM!jdCP;W79Gekm zK5>;NuuMlYrh|ClTa7z_e=ijLX3*^D-hq=}R1fGm&ckf_Zh129{mfHoN3?@p`e~lq z*wWtdj~n;rl}S5PAxZFvL_VC6_z5GFDwN&Qz%tiHF9pi8O0K@kq9FPvnLCK4Z?1~( z_&z$Q?dt;vnGjtaR(3f?$bjG&*o@8Eza*Yoj6e^)s#~!DhesO}KaUqQdW5|&o%evHL zDWQQiQN-Ug_VoFEz-FRa{p9)-t)%7S=YoxWRT2tiM*PG;Tu)7rOsn^@A&y@ory@&0 z;B!L+W5(KS+s`fc8+hckH+_9vAcmb0PkhRcwS=HO_vuXX=?#th>-aPx$0ik$W5c~F z05p(V5GZVQi)5P1_D8q4m7TnSQa;!eaUfg8S10ZYva083NgA`Sdn)bQbY)>God^|0 z$-fb=&GBZdgWOLguDQV?o6DDj(&C^rw~Cp${a$Qawfa?ah$O(QQ%b|Rb`Em)EnhGv zZ2nOv0Erth@6%ST*_Xa3MiV>1gL+o~)N*_Ep(O@&=QjkGkdszE8aN{hcocWmVOu*% z^Ccu}m7Q4XKV%N3qdY^Ee%l$R;P|Y1encWlaXVwzztFy^V6M+833emY%kB9V3YKQz0)E6_MXoD*IHH+-G;5ba*|$U_R)#x+NGHpVYaieW@J$Jfy; zuo-+?d#6R}4ry(#Rhz)B3NC6186e1ULz*fxS0!^ zJHvKvJI(;S+*z-lD|{qSUCk1aDU|@;75hGO;Hy-{8Sq1d`Q_XnJPBlnM>%~B-yL6p zNl(arYg8c*fXL||203dTU7M7pyqNWyP*Ues(?sY5 zM#x8p(2(pW@n>e=`p0p%au z>)_F4dhIpIS7q41#xopKGCz1SFFCQ*yLa~z1_jw4AmW#^0}Y0}v`m}dU%uchs(-4) z&+wE+?b+W54|E!%AvBuZBR&g9QY4-MD5k91SdF-9e*B;^aa&ItS?6$f04m&NGwo2s z7)GE9MG{9O?C7Ch)gy=$A?G3){qI|wwl$#_G=8sYVJbC_HTm*-P&+TJ%PNdK`)Ik0 z@vQGN768P!6j#C5THd*N^)r{|yJS97%k>uT5A%kjD>@7D#T%tBHzTL6e-=R%OkKBM zzpYt9rtA6ubz{F*IsZ-b?Bi!--fJzv=&hOskl1d#L2GkiRk`aKk7#D*WOlne$B6|# z7rEoka_dg6q1+^=4~I$>WFdc}ctbOg!)8$xRM)suoZv&`HFWy z2!L5qg|dk-oI5krtu{*K)G9|2r`aYZmESXPyjOKp+T{JgbXihKQw|j|H&Vl%wZVBKUm(p!4$mjACE2^XXua(^oJ*XY>U>Dz0d5xaX>DO+)Qb|B%*%xO-d5nao(O6Q~zGpiH%dJb6;# zN==FS)ICgayd@h8XmiB{QAh732+#>}7Ua2B$pv%pA(8-Nu~0QnBpbs51{4d6jUKAJ zoS{N*%gm;;)|;%Vx!GPVxzLOe4=CAe<&o7v_zg@~vNSU5o<-y|>A5IqlF9MC2_Qh8 zD)bnD!6aFQQ&&NXNFiiODt2li3=CE3q+Qn+q9I%SNxLs+&VHE1{n<+n5j^&9vwiO*j#~0( zqaM```y`>Z;?4vHzl_}it=DT_;o8I#xl7OD*s+p=*7aFdf-N_Vd+pRXO)R)*JZ0f$ z%8CnlpROJ*HQrJhGv{;A7opA3^UdviFLm^!+2}C5u;bDCnOTQxx%4Iodp&OQkF!*v zXHg^AMH6c$L`OmTNUK*#QW)=I{?LN^c#-$ELu<8 zAn$RFQ%;T`cRuWq?%NMCURB5vlr^I+y!=pkCRpD*RK{@#M9vqp`Zl~hd0xicz2(aS z-M1Q~=QC;GN+w%^NU)0p_(h5>U;9;lGn=K)o4dU3QJF5mQI!# zY`o*^qOtO3LAWX6l*tdfq&5o;T0u&HerVzQ6zf{(bN3zV7R`v&KOI zA(FmsBoav|;6lxy1hP)}_@1CJsQ?jgi30xZZ4r5NrqBzgonX^hOaLvmP(sU(#R#Er z=)S?UuY1{FHZwx-SUQ`<5O>mqopiS_rqdx8B7i~*!JsWMUxaA!Mc^@5+<#WSS>FWS z1dabMJ%F2?8&;SHCcGU%I9M=^Lqp-jL&yrNZUmz9KLJ#QmE#m)8=LJD5=@EorT7K? z<8BqY2bq2>DxG;8XV%qcP1Vk*Qmi5UmUaLu_* zI2hUE2lumFNUEw~1oo{2@O|%~I^{E6su^FP8sP!u0$VAn>It{#X>XqAk` za%PWO>UsT~*>=C4qibt9GA-|BWm;!p$I*nzx3TLgs|DsVFV|I`a{<`~ogmg;ejflp zXW(YuH<-+#B(2`Cbi@F#BDM6>u|x&gUrK1VEwH1P+tM`Bo_Yn_Avd6rS+7f~M)-Vq z`SBW$XwHrRm$bu5kM(*&UlBKJn~d9JwRa$5A#ejXI7WDIMxFq&`bRGOF1Y5>Ce4NE zwpiX9;%@O(FOw@gOtK3hrN-eMC7|6%X-A|+cgB!oA)@Uxe6*#c@uZ5N|B^-?;^31x zw-i-gicTqfyb|^3@kz53BmVOX7z@ z*KIJh472eh%!39W@OFut$M9 z(3u)K+%6hKC#3Ng+$wMwEuvceC?q-(Wd zei2TKQbm3-yD_I3}ZSj9V@Eh0Z3kB`Bg(Q63~+^s-{v| zXR?ZhOi3hFdHdWO>QIx8@}z>?#EO+z*VUnBelU#nMo}T&$|W96 zA>8I^oR%M~F-+w#GDfk+dxY@UfdVTPymxqr4H>!vLeKcgzySI?ARj+kR#RwnKYF0k zS&lq&Bh6yO5OO`x@W#@%0pHEvXzMQ{u0JFMoez)=>CE6F&8W=}Yi**OY%XI^LAg6^ zUV2}u*-qW{D#z)eW1*>_cqHAU&ugbG0f90n!V_yMr`)?nIm)?0l z=-Ql`Lxwd?gPS$Z4FP0@Mh^rm0gICmc%l6^P=2j0oAdya5d zIx?-6*f2vvD#RyBerHj4(cE>+mVL|&W7VpajMFjtF-R0hS+Z007Zs(2E06>H;+7Z4 zaW*kMWt4u9c=fWGgC^(W-A+E&_r6B)ZtH0VVX%s`*9fLLXb*1q9PXa`Jh_L?=5lW* z=!E7JU>5vB{4yt`gCaAOyypE}>>?%}q-*#Gt7!)!=?%6;k|&++y}*y$eYfUge;q8& z8Z5kid}aQkCs^|)JTz)+VfLkj?MARIae5FrY0nSRr!y^Pcm+z?Q!IYYRK&=6k~x+_ z14D|J?&aROLu1(w;~2cP;B&pylYgu{BjR?Y@ukw#uR=Je zh^f7vF%yMS(l)N%xv>=^x8sM)*rDZrY&d65sGfm_jADmtayXvP$GUO?P4}*hCH6EH zmbI;@Ox`k}4QE}Id=qMJYisu?F-}TOa3TJ81ka|Ka$2v-uCkRRnD;}q;WOQwdGDM~ z9W&ne#BnPxb6BQu1|J)PtN9?P_TZ+xZ5cs@W-w^k7XX#hAkW6v?3HMW)O&UTm72UW z>xC~a;!icTG$|Wfxo*=ZDV>fTvRk)7ySedJI8h*LZt^JivrI0t6Puhpu&(=?xwD`m eXSWZyPV%;)Lg8w#%}Pg0;z69~*QoOUoPPnks}$@2 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/complete-success/Success_1.mp3 b/sound/pixelui-sounds/complete-success/Success_1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..fedfb994318338b9518c4f7fe64a0e82b7a60d3b GIT binary patch literal 12166 zcmc(lbySqy_vk0c0fwQ6knVDTp>w25x~03jRfcY)rMpW|kd{VLkq|{n2>}6-P?4Am z@B4kfzx%uQpS#xguJt=>&6@q3ePVxR?|q(go_SOigs=cN1#GQvY;1fZklx7d)-Ikt zmNq`t9(DjtB#II6FCEFP&e`Ke7hvz>>+IVX(yiwVDx_epsIor6||J~R3ug>mX zNI_>`PxpUX+TXNv*7x_gucfOAU_{&&0i?*^!j1g5fJ6xXA2kSJ`Tt%cs30W%-)j*6 zdmDhhs=nY255diJdj7Vy_P)N10{_^6cT=e^uc`fC_LJY#I9hwT-88fGaPbR?)-O)6Ut$kx|>)$J*T&aQhSdGhWz@{+3BkQ~Tb(nEs6-hWr;30;%|KdvB=~ zl|=t9$bb0%-TVJh0O;%KDc;Z$-x#7{9pE4=#xIEA7eF9x>i#L13%UM(h+pG><57TNSiZ*Z^RPNq5rW7PKN(q%UC z{#?e3kZygfKuki|2@#zYAt;rS5T}_f3EAwO1i@VB4&z1=ilJzvF99UxxL=ar9;tX0 zOz~UWPSZ3CYRGEm5mL5&~0=lPFUSG$=|uHOLvcryw)9-1wkPR#3AXC_0x= zt~O!*oynJ4+2pl#o82|)TKb%b57?Vu;@e(npWrX~savw1> zu#D)H!>1I^H<$?XLB(0H^U~!sz^xd?+fs3)sGc$f+)XWM3+U&eNR)aPLY*Lf+HSPG z)?#_Zi}Ac#y9)aT;8(x{Fb&fYDnYF)tkR_cOSeGy0D?<%y6;{isAOu+w)WhxHRKLL zo(VXm?Ss%M7{EVyLY|()$ZBO3w5}30JNzR^y!7~Q;v|mI8Mx$vs0k)+ zU{TC{22>Yjujc~%1r&`r`3j{nVnhR&3%d=+fQz2+x?s3o{4w@ja%R;{#K~|maNtn5yLI9gxIOyP9z{4BnY4c5NI5`(0)2{-4LFLgBM zm`hTXQcSGFNekbFAG8OnH}5MMNV40xibr!{FEuUHHn9!MG*J&jw;Cd~pV}=Wo;zxj zyD5XjQcVq6DGexe5p|&RdG^}A-M*)hyN@e-In2srcPm>g9AKLt z6<)f$ux$Rrm*ZvYV&nTO|LWZM4*=|bfHwQRoc@0NggxA3zNe~w9pf@~M|$g6NPPT? z_<9GKtszZ=(ML=+0GLVhSgwz@`c}(0pS2AcQ-xgr41G0MySq~YGf_%K@m`w99uL`L zy?fOOi66X-YZXVLmLBITPC2MX8av`D{^g;_NwhydVQ2*KVaitc%27=azEpG~D@;~M z`!^g*U}i>gXu@|x6n5g?th|nM`f>His_9~iAQnKmj=J(+G@Z05|^%xk&ZYVt$W9o&i6y%8^yBplBPxIb|{cmM<(yok>F; z8!KNy6-zUGnCodz?+^?`FFS)bpg{>o%S^X9k;%))T-%yDNWD}*;Jk|HtntiJ z%H?0fY%_|Cv@z+2En1_kf@9TxtVG2}%ay>X3;}X52Y?_91g~g@rMiDi!e(`z9@&mq zv{j+T%Q?BNO50q z?`LQmHhFvM0=>BIs{s{`kD#-*4(H**urqWPj77&N2M>@Fz(-JHRhuw897*zlxoRWg zkudf?2K9`^Wx=5L>C0OnGVp|gKZ5_O-GCZ&YhY!kIgt)m7irNtfj+B58mp~SKh%BU z7_;+5`?QK7?L^%6mDP~)!~4mw%O-eWkQJXlR#LpgPP{mJ)0ZDq=8hu*JK%d83ADIiYf&toXs^*>ALvM0O6uPZA<(3e-{jASxX)`QuL*2El;%BX`rd@x< zP;|Vm3rgTlzyU;$NURLO6jkkbkDY)mSaF~R99jm)@k4CQ+U(nM5!Z$>{V`e{5&yCD;Ie*gmHc~&{=;aI#4lZyu7!!n-xKl@#~VzZAJ=#|B*-dadhL_X-~Xng zCWDXz&4VALnPOn*`WGzxWkqOSjFPyWhM} zbQ6QX$))b2VBAI)?XuT4G>;kL!!Xx}Msasrfa~wD3=m-(-pYAl5i!LE6_nr{PwfDG z>V@cDwNmQv@mnCFNHvW>Zs_-@0r8Zr=qa~|Cu`VzB-&g*r@ddB`(`%N_7XuN3x4j1 z@x^9)paR(5{%Ot$#5;I~Srs?PLZ(8P=98-D560|Yr+FvKa__WOF&4zSL^JUafm%^L zc^Y0!;5buuIG|OT-@j?t%;?9tiozBf4t(1w|H=B%JqlRtv&TX9;^3*b7!1ZueK``8 zs2KxOYX73c6XRx?!0j^y&x6T#@L8LgVfBq9(1YViVH8kcbhpzDMnEPb|{GA%_*?S_s@d$PS!A(A#wQ_fP@5a zz9aS)NHcPRHISR%)=ozTx`n#&(3Z!LMe$ak>G23DPLiRPRuD1nj+`lgFi7*5Qs2QG zm@H}#FKpA|OjdCrbEFZ}_7!Rn8NIhkg)>T{?=VH880ho!*9GSHhN%PO{!Ewgbj6uq zX&;5><^y6DS3D+whMG9^6~$Bz^%^}9LeW=24u+i-au2;HHD|r+7QdJ|jldozhls!G z_bMmE1}J`v7x5~w)D+l{%n>d7nrN#)2!UbCS@px$+3|I*?qV)|#)Sd>c+Tb3R^-%w zZGFtZYF2@)w;r+~s~B0C?~;fUwVFh5G9!4gmC@Q_&f1hnoLp~G7cU4im(RQl*Xe9Q zHe=SC{(ier(;sk(_$LI*uWP>rl(v6~!H!+V%c8>kGT6R@v_q)becWdL@gnxfJAODQ z40D3WBCNd$tZ$ez3`RR|j)^1!CD%IC4PQN>W28Z~l*EA);P+%xB1RP&sOOQd`mC;+Kcf4I=7#`=1r1M5E)Qgn4b}pH=$*bF6M5PC>(wn0PdTtSZariR z);uj_ynoCy(2-F-vML;e1G3)Jp~2}dsKi`v^jijEZVdR-hiMEfG#Iu*Guw2{KQeZ( zj)N#b^Cd)O!;$lq>S;7m&lriL+b4Rg-Wq%aIK?w123F%0X!TV_fk zk&7Y+<6r>sVYU110+M zZae0ZCqWkT=W$zRyFxVrPKfZ37n>>&=rIF@i#|LAvH*d@K`^UFCW&glrR~4Cjd|v? zTkoZA9kUPu$!^ZWyR>`#EUy&H&k) z)#6-0$tqo}=54n?3SbRHARTlg z3grZ?z@B!?NxDbxQ?$oGMTi?&wAcKpO@O!8`XY?wx23awSeMGuCc+?Nf&1>KPI%bT ze)!E~7|eBan9WoaDK;G4U69HF-irmD(OQAYa`ee`D>_)La(s-I6X-`9 z+v0FbA!_L+do+hA1_ev7tNw_;Ny<)}3H(T4p{!^AOu>YiSjC>?Zy>drK>AxCS?H$X zid*^xi7~&AjqcTObr|M&>klV<5Ulc*bnq@uBm<0)#xl zagppXReaA!iqsB=(|SDoG_9LDUaJ%sicAg53D#t8Ii={R{toWXI)P4H^ctlgTfo2` zsygNC0u{jL&@jwEuou6<9gp!YgIajOO9aT$xk2uR;y_%Enw61nY4V(Cy0>|YS7xhi zC`;@fE>M)`^-8YdpFg9^%hh-+@UI&U4uvomU`KMZ>n)I0q}og&Bh>BNfEHPW>U3L> zII#{7lPKoTz#XcEo88}2E}Ijb)MOGP2XNvLw-=|I~Dm zU$Ym?Sp|{Xo!})HAc@6b;s!_HG8LM43F+I!RAGPJhm1jLutH{jw{Pz>$SO>x3xjYH z2#4WhLa8L2g!?6j#0AVTI+oPkIzdc)nw~!i5h)b4d)BqgLm3;|u`FO=T+SQO2An;1eb>7|uyvvee&?wbfSaaNmm&s#G7=Eofa5`Ys>ohDodZ$Q;I z9}65_*U*A4wH1lfULM5P)-D`N8zK?UGY<3_%Lm+g$PT1hQpn2h^zEJWEf80bP_0-W zaao;Ng^T%7U>^Bu%^O{XF_&;7IVX)2??qWs;)v7V@~doiO5>Sf;%WG4E-r59qfFua7SwL?8|$ z9cp_yI|gP;%qcMx00Q6xg#9mdyx6>dQAeYxP1hkL`7oaf5-nhK`S+hNIG(p zN!6pA{@A=_if2w!@CURuOM$UM+~O(euo5wt2FHmykQ~H0XKoMJAw6@(ttz}v!7MBg zKxxCzl!7=p;Vv&8xq2aL@Do{C>6%_cB+N)d=wUiRj-^7#a2S+5TI5A>FuFRwF8SN`I8T zcJhYZT}XbX8m{@HL>^tX;F$K(o{EW|v6E@f#L6{N1>l^Lf_k`IBbgY6Ip++!UGK_Z zGTNBZ@W?mSk}xWFV|bjgsoiIxYqtopI#0Iw2U$}A6k2dQ$F4o_vM^5zV9NB|+!ZNw zwjLj#BlDftxiqz_{Lh^*9VaH>m+hMbp{2pYCXP6F*t6?jH>Oj-^9VD^88wRj7Z5~i}o2L^MQ z;y8xE>|!uK?F|{LZMe(5L=8s{l*)lcyy$T&=;hv&j&afG{#56AV9Zh)kB6&6>%6aI zTT8toVbgd^y6vBOU3>~Z&+#GSQ+>LdvxCQ#{0b`1ekY_AGm<(q>C z5ojX*IoKBQc1~Yul6Ac)e@@x+)O`__*L?S!b*J0 zsje_{KMD_+Lpk?N@D`{KJYknl33Z7bxR+5j&`S}-Pjkv6jd4bu&K94BVJNB(jXc6b zIrKMJrUzhPGQ@L@QSAhu$upt$C`ayj!HmZTAU%R^YJJvPzmBPnmS|>|7a)Gn007GQ zl5E=n`|HgvEtc-}s_z^IQ~OCux3Z1hN(tY?Lq0moZI@LafgBS2N__?+7&o^05ywwm z9Y4x$zRm8fFh=Y*`+oSbc(-4saMf0TRi})1cSd@`&ExE}k{XNI%7E9PnQwL^7hx-d zK|fCmvn+y5&42dZ0!@O))?MH$X3R&E`(OyQg8Hj_p?V4Uxtaq4#>uok`O4M@k)KgfdB#X zxd4J_BLa*I_0uh)XJ`$faFvm}Gh2>QlAqo;FaM;JEZncWt6helO&~7Zp<--?>E#@w zw14=1Q9eYdp8te?yxr5IHca5os$uH_JDsV_!qu@=c5|l+NSOf6=z}v*H7BMNNE%|( z#+O&HX$lnRps?;JHgtCVTvY#{kLj(^ue+Vx+i;b{2!6G8wzFZ7I%YOR0=?0cP{Ccl z>K1GLnA5d(;}+-}_)WM0gs8?8Wsp$@yz!8myDm?)wsp+4eku1oB)~qMy?|TneXMdh z30eXvNs~EcR?r=z`%7g}N$nJa4Q)xpjXC>?L7i&vt*Oioxq8SyH&)EFawVK%`P zldZB@V>&oX^=hNm#HhB#Ia=j8+`ght1_fZmJ#1C*pAqjV;t4kBH!WhJH5RMzBnaex zGp7|`PDtys7Xi02>yv!A6k?6vBC4Av$RDnUCfawV*Jc0y26JT}BNl;|F7jowU^vFx zRx3zLYliO@XcIh9PzWOuOb<^e`yAd_81&HIpe70MUUXN%K4!ds)^XEIJRLBpVe(_A z#pOZEfiSZqXx;2ONf2{?|%K}IV4JmLG9(<;He#h+6Y>RZh%&aHnOOf_asCUak3LR>COek13E#Wq9-Ub@sVBR9kkSSAvlNU~pjXk_CaelGDeKxyS` zTcepe8#m!C&^9>HZ3IH())@XMqcr*^G0vk5DJ-H+7N__0aUPg>O{D4-$lXsDAo)Zeo71Jy z4Q~_v+$)SFa-sKX2&pwdI#Xw~RT|MIya7~E^>f@`>3kAw*wFEbUQ6tPYvEGh(8zbY zd2vHIdBxGEBTnEI7-}{R>D=-TvQIGyaVG55O4B>mD|yesM|Iyo@`B+9jmIzP%re`C zMHYYBi;=&8(38k~!bX}*lsj2zR_SblH{6%6C?sSG_~RJ1K&D9tHNk}q&yaG-s#@sT zJQFp&IP#RgtHLz_tFG;g@TZG7O#}#%itpu!E@2o zr?32NzGz`ES{!M#9`b_D4P_Hy+A(emm~GGX^VZDwHs$a8OUP6Ti@t_V)t=Okb2TR~ z+XgxH9-xHS^VtkE7@8%#ArawO_~p$m0#oq@F*N5Z^kWt5${ulJV|{;+v5gHm)y;U) zZ%yW2-2&}_2!8NEh^%x61=?CPQ0~R7$ zh(kZV3(25~E7m5SApWoplG*xIUnEVU!Wmq@zn(&8YxbZyW>hifkfm1hbEoAZ8LwYW zkuFq#!(Rh#>UHIKNuBt^afXb!_M}h-H|s? zLURrWa9_VWzY88ZDHcZXu|1A8`3a{xgv3%3Smf1rx$W@!tE!RBgfP* ze>~#j-#IifK!8U$qaPkuXBD27XoVfHrX)h(I@6YHau()&ox( z_l%D?5;e6XJ-Qf(-W2;%+e_S?3Gw+n7HaUidn|UYsWpF|Cibym=&7qvboF)ET8}HM z{hWJAmurbDPlrk8}+{N$^x1J;9&tUR`n?9hYV4(hkr0N;DVnZH&W3mpSa_UJ1| zcC!%^#bV4@c-;5&GEw)8VdGlX?iP^(na0n5SQ(Voh<8%51Rh`sFsRmaPUoIUc09~5zF_u1iHxk?YBTZQPS>7Fe-4QP&cqV>Jj*ICIf z4@+K@i^K8kt^Z4WavK=!37U<8V5b_DJ)0MVG0OniQO+yx|`GSU0v4ZfIBHOJ-dtfL4Z`Dy4^6} zG3&O$sPO5mT!qEbRIeK=X;j<}#g~udDB#^sCH$JJ69>~gTp!h!Dm3iJy;aEQa`NRM zhrDHPZ0=#Pj2PenaJ%TY3&Ndw#b=Zb@q7=g-p5c$^y*F(#A@9fI4O;%r0V%pvL1~S z?hX+00mYSP+=o2fj?fM%hhETxp5Zi6T1|(mq`M4ie9*19j-N8wc@4wrFPaQW6<_oI z^$*@&_~eg5+`3L!_w{5;pwVAP(geO1;#a%gd-B z2Rqwr?BC`Ok#9NJIY3?j3-F^2k zCQq>jjG@CRKEw3wr$(R5=bm=+&uOzs=ECj;KDj zV5m8(>Cp)c#jwXeN|X$tZJAGY`@X}r`!cWKqxe%qba*MJ?qgcEiZ7krs+WpCvX`tk z*@?48fR~R==hr%S2-%RR2PHU{Y8a4qeXdm!X*OtiFx+; zXa4fgH{cY$;AJ`CDln+Z5^a?yXLj0!0wNT2Dr}TCxbj8PG{rN;XPh;!-jq0h!kK-f z5lTg|)z*r^E4fVjaQxC|_Q=)4al2&qJHOQ0+Y`*E$^a4^g=+c@zw*2>>0KT@+rs+8 zC`yjgfJvdjj9{HgcK{kE6`e!VD#T%U-#W>Hp?&coeDv`Yux*jY+t zPyWgwG(o4-btz&0fEPyzxh=Hg*n4S08T8vkr6`bL`()R+v2~O3U~Ho3sYzo(-Y}WZ z&f;16COk76-q((w(a_G9t0;|0Ckmy#NXH8`wY)5qCO2vcz1OXMcGI6R6s*cM-_C2PHFp2qj z@9&VCB9Xy>2|uWM-Q*BS4y;^O{@T>Oh1H$Hx%fUBdC(k~ygYjzOXG-a+|A+w5pgBG z&tl32x7sB7ywS+?UW;VL5_vHc&k0xJGaaBB=YPevTonTxM=b;{3`9?&~^n zkY}#(BNL*HLfY)Oi@@5vIO#0(G$2a-Ko%pENoO#J#KRvqm zG3ZxSZVsB0FuR|1^0S8*&*~RZj*fD<1=;gwK_D`*smk%G$n?+)6+0NuK_j(BvL{)vt)oMn z$BDDhlX%tcrK_jedb>K}l1pg?Z<|Kkn!4Wz(>* z-zmJNxWvZ7!-YL8xA{!{=C}!9(>+HAea~CFg2MQOAi8^xId%XMG2n zOVTezKmel^5#YN;MN;x-y5s56WxOm@OeA=PLO4!^1X<(d96n`{`>p!pRZN^Vx9|V$ zq9?axF2Qhv0f*}1bz1_?-5iE|_BiqkQ$CULGIWJoIU%!*TT|{Z;KT4B{DqcI6ceyS zH}~3GVEw29U7>>>*JEUSf@TR4c=T{L<5?jMi^bNrdRWW6+b?}nv-*N1c8EnVf2`5I zDAtVFg-Whey$15<+?MLp=e^4@;Jpq92w|Q|1H?cyrd)*AAz2^Bjx${G;+sgK9%?^A z9_|i_tUi^+d9g+LfeO<7WKn{xHBG*W4k@jK{^UYSxXV zPto#%rQ9w59;9huImDqVby>?=)N^W7gmdm~OeBF3v*Fz$YX*5E3F6Xy{mrsEMYD6l zlrqs7&PP}2*3KUdwNpDTD5DwYWjPadEh}sE=W&kBqhot}>BZ}CP+;zTo9`N=TyBUl)f%C=_ydKqgIJwYJ^0Oq_3N3$1~ z*is%vadUG~lcN2*!gDXTt8 zhtiP$U&j7tsCEBZH`(jC$u-Hmhzf~1s)2ukjCHa_q3e&;)X z&-~f5=3X(^zGLoLGfPR97Y+n1uogN71_say4z%uK;ppaRX6b3+Y7J83lcECsj|}@o z=HLpI`Pz7TIk>rkxc)1mf{Lu%T-+_Z9W0$~{&TI@zl&Ym`FI?>++6;9rVaE=2OS?* z_19WzAS$kZMVR}4DqLLusqk?N{(oAy1o{5&7CvEa{{Op$>;HWYNJmMB2g-vAeVn$B zm6eT`7ZuNc`+x*()R9rs_&@!}gSOaNxI05nGjn&g@VB(Ea{50~0;p8Z)ymDoqM&2q z;1iONQ_;{fv9Pmq@$d_Yic8AKDXOSxXzLmn7{4*MvbA?|b@%f1fA>B#JUl8kJ}EUL zE4QGiq`b1GzP_ost+Ts#U}$t=diL|u%KG}3?cM#O?`J=LUf=$Gcm`e`4(+5Bw3EF2 zF9-iEbnyREQ}e`{3T^y%06c1pfY{TAaD#9+g}QI7_DMtNvM8gM=T8K3I)f?#EI4E;0*gut$!jVE1cHIXiV1Vre8PeQBL@EhQMq%OP)Y!g z-I5d3E?X)cO9;hOnINS>_L>dO&NqeHasyG<6|oC4R$+UK%S^0vsA`21GN3zou_s4d zCpp33LobY*;OwIC;+umHz+=q>KCN1_utcC1vTeSOu#X@B{92XTx&5nk)&vw7;-qcG zyWk*Ma#_=0KUnIH0*_jwh#{yyG-Y~kLD*5uc95K6(3e6TvlzY6(B?`77b*s7N^$!D znzA%-%EEqSL0fl~efeyh>{OX>l_(GB?(XP07ywezb^BClK$3SdDKSzyvV;^n4f6m1 zWO{gz6et_2q2mqlqTq%l4L#6&o|m$856STAVu&d^(>k~=A2KOnMxPZIupAP@z~R=$ zI`U$~Qa4|nDQc8<_05)n)#Q5)0v;(L$5^omMNtahw8>Bg4JhK(4-R(fw=_lr0N?>* z{ZVlK1{LZck^wJ3@F3JNK_#J85ZHs^tO^Nq5sdUE@x8jzBZ8VMAz2_j0w|Gl~7_x>A%(}(6ms>MlI$6Ch-xwnCCnh=!q(+6Z z@?12&HUn-}b#*n620?IKOf|4Bk$=t+L%;dL;tA7?G7OcI(Zakv^>d9KzSdiN;AiUD zc|etuJMe@tJ!X44SJipLkf5n>3rt1M##fhRr!^f;^AE`7+F04T9kT;Wl&f-%Z*vj^ z;T_XrC}r0F0fnFjsi-}Thk)H`>;rEFghuog`%Tat-p7N(PvxQE#mHZek84g>Q>eSsO`aR3y$JYdwa-jrg#REo9yG9utdm zSd+1OvcApBpv8c`;5ywTNYfggZ0U!4K>z|6MDttj)d3K5fu~NOwkLQ6rDG{!rNYHr zgkZb+KPHFfp`zCICj{HMoJ|m?7{-+=f%=MrOssot6<<9BC0G0rZOoGqkPOH zg!DMKw=H*cnY1Y5s+NNsH`Zl1FB?&-@ie<&2AwgeFu}u0$E#6E<@e#=w^kq{6X;{1 z&ZM%xPq?igj^o+Zd4MyIp# z3yT9cmG{S5lpIF4n9wE-7_9v>$S=yNB!!%xw1RZ%u_A?(jp6e7%+DaU%6rU-+ zu5^dB61ISMr;(!G`Q_zT$9K97gizOn)X}{I&JD8iE6kt=F%POf9jI;w%8MR&J(U0B zLrOAcRgpT2zSU0r5d^h1PcCd&v{o{aB96G#Lweq6ME1HjssYV~OswajTuu9!zj+Ph zhp5nGz3!V|)ecH4_Rmigb@Hv+w$P@q)U5CsZ~{>08EaJr04b`Uz+pp`aRx3QEnUAu z%yYA1sUKQu5|@B$ee#V9l7$P6s}-eI{fSNT!?65E)WBL z2TYLAlz<R}GYe%Eavb#Pn$|jD63XSoY>Fve;CX+D$!q#;x`Dl~;m2vsi#rkZVy5$#WW?F8*_M z4a-XFgtBD-Yk$k|jnF|t(BDD@N4l6m;4jb#NHHCt0+3?sVBje%M*b>fMOqSNz8JTX z);hXAQ=~}GhbSR(2Hzk(MgQUQzPb$*eh?yJWbA~S_^A2&{onLb$2D2w1~n=$W$}5g z&=HMSqbJ*;zz>;Zg52OO=s05e0oap#2i)rB#!{e(O}dwk_q!2h4gUuS1zASBYV;ag zvYPoer6~VBYC4$-9?Yx4#kh{woBQvh9(%2*!Z|=T=t#;BcZjpbSjnlkb2eF4G?LEeYCe- zj=U&EpZfwX&-o80gzVQ7f`1`DEwhQ?n#TcP3s|Bp0stDYlrsAooi|sH#ppP`*#=GR zBsK43#pRd7Ok;hnj?@nlJFefA&}(Ecc`4H02e+9$sgn~~SDU3m%IA^+x9@dMOdG0m z(Ek~DxCoK}ib>^>R`X)%**Hm7sa>;Pty6eYMQ6hRLCY=l?!JVi13ZBCZsgnj#~}Hy z3iDN`l^+1@P8KJ(KU!F9ZbIxa!=(Um*3(i3wG`Xp3lMDxikg&WJ-m*gT6HadbUVwk zG4xSSCIB$}sY$c0GP0FZQ7{7Tve6o=yeE(EI1S$F3sO^8`j6nrfo$3k<7p59#a8)F zdhoNa_~zE?EslhdqTq9XD~;7_Huq2=u~g{Y&d(AoM{y1>S>Gz{ zB)2CSo{LlSSUdmXX{I*i8v->y=gVChIlT6dK2$u`Xe*R?(=Fr%HE zf=9sPLa&nqB>a6enEhGpkxarmfc3zF`g&j3HW$G>q%8HD^pM!5cmhSV!2+uP!z7|!5l=tGKjf$>Hqq*)|Z zB6n<(*4it}*i7Q~j0{V36sdOp$aW+*a+panP;l9w>RCo(n(LjOnKlaf1zt}>v_OrCU!XDYioZn091;+ej&9Epr3#33EOXviQ0`BX-{0l!^ShR&Y9xG2pm1y(%2*7Pm@ZRyNq2-dx= zW@ZwTyJtL%B*#r#&T{wc2T1zNZ*|~=2J)5#9|MpHzPyE}6a<=pr%-638WlkshG@+K z8VFnIXOv5XKYRQ2uHn%!Oa7Pi(SW&0yrucGF2+EO&PP7GDJPo=7$-YqR^M7XY)6FpTAfX2^@<}Jl>J!|oVr`IL+$$!{j-fEH&$NUw<*#Q0`4B|>Ag zV5C3UDfspU$Oj5UEnI(brTL19{B_Oa7&?J?6y0mZ`AOe=y;ZREPHr|ngIEj<@MK*RQ;SULS|BMVZQ;7X-_5SN+2cg~SZVwiT`@~E}YRB4Zawzy98 zhhSjxE(ExL{gDfvC76;~@GF0{!}F`%g2%eE^CdBvhgwir1PCQ8A@m*Enewva&^~wy zmHbg}Mq8$IDJoSdn={ve?kktRx*aa{ZjP zaNYI=C^ZD7`5#cT1RXszDCDS?i&s>2(wpwnanBb>(x8M2m2H$-Z#4jb;iaW(FrbOP zn;upmOSe0L{`rw_4Xsl?fF06dE7!;D%FOwvB7pD6uZJB30|KYetT*b0WatbzEi;1- z4L&lHy`jC_o&hrsJg8RbWugz*AY z5P~{K&D`)yLn?`m&St!*I7OC}J>krh&q7#L+GPVFBIhkk;I+mgv8xd^$M*8}xc(jfG6J*)R0njjjN>p;0FC;|qLPz>%zk)7<^>@W`h z`Qo637f(72dvOPw=xh>`5@}p-_SRc-D~}!gaU7V&YVUW1T6Prxq}*Su*zh@U)8_;> z!-^Epnv!2B>}+1P&&xBMf8;tKv@<}Xq5_#1Nyc(CPnBoq3=xIrcla)3Lee9Gwx`&lFdI;PKkf8jc7=`#f_OHM4RI*H>}bc87k@}R1LChyqqdPjmA z%f@<`xbWr1faCl0_YQ7lz*MlE8z2p`0wEPMxm}hA<-ltVn!^#2I%Rm4VjaPncl%L9 zP@SC8xPpUbW#L7bC+%Nd&(#0@08yG!iUoGfQemvXoquE=m-{VP4O!m-!0kP%GXR{x zEn`XInj@P6!-Xrnu9S>roW|-Y+83al5LBH_ z`b3Y9QU;`Sw;yX$)CGlhf!ia_XaAj0cMLq-XB+vi>+giW2ogC!#?&7NRjIT@Q{x5+Jb zu-M?k-`pRU3FY}qz~k++@q`2bXn>JGa3LpNy5Ay6u~{{K%e{A(9XK5k>k+$N6H*1-XU#%+gwLil8 zL`PyImz+@Pb|l0n3b*D;0EJ^L3OA--yT27<;=>x>%WTfctp!-?&T&3V#z+$7!Qanp z8rsP-f4pOy4*j^=0fVx-U2vP>y}?pAukl=FkpUw~>s$nBJj?9NwG zl7!augDjJpSp_p}GUq8IB$kqfM@uln4B@EMI*#4(Zh%B=9Ov0UKOrd!{0;~9z%Fo~ zwG05yl4!DIF?5J*mlZC9quXd*KgZX?fACl+v>K`vbPCv$yM9&7o5Uu-_~rRoT#`t(*}poTa@(z4%>6s?>0)!KYXsGH zo9OuXFLnz;m#)UDabYK=zm4KMeZHt|>|D}LlzR=hawa`*x;VW6b%RjQ))}GWkQ7a} zwM|1U(k~4pWx{L9G=T7t-#7U2+0w`rq9cgM$I%MLu+cB5`wXfSPlF0Js6!|$oTlu4An>Deqcq+9C4eSooZ^y62NPq)|afD1{M?v<76 zF>P*T4cv82Jo8t*GbE>*+Fnx^tvVBIHP)Zut23YHObv)t7j#CAIL{p+I zKn9F|bKRI5uk2*5RX%R-h_mO}1ZMDfcBFF~?X6;GRTenIzW_~#AYar_t6g1#+3?Eg z8!3=bvWyGT^Gaj`v#g~gjyN{UrNzj5zbf0-ny+}f20eMqg5Y>i+D8AnD^gP!y0ha% zs~ZOc>!D-eonihzbXWhr`gDg$l;%L;QPT7IhnnTdm?t%f4My9Xqs}E4 z>mcrpexfbIVw7G!?LfBUL_&)IE0O2o$04~{Wkd`mkxY+dWoBe91T9Jt{vmE zRYO@Y(21s)JpXC^q6P<4%Y*mK_bSNIwI;2M^~O=u$Zz0NpJ`?s{nW;3ZRsE$Jqi}# za(=|&CoFpz+)0mf+?b}@y;j6BDeCQi$n{&X=$??-d1>tFH;GdNz+UwhytIf3A$6QtO7oZE+nUop=^xGD27VUm$ ze=U|u=66H?N>9dy*RptTcz}Eanz0Q;pN;#f*;FR}N&US+Sh|m@yFFYdvB)3s**+Po z_2&b?d-`Offj5(JtuQ#$D$ltTtKRzg&Cc%yzLX6tBWC#H6n;OyKjm!lv-5ejr*ykV=w?@ zIU}W``SF@cU?Ek&T3Z>(KD10@73&#I{Vh>&B1NwGLgtG70(1&Ot?waV_t3(Am2vR3 zkwVfs6SBsZCu$&72O=!ufc@!;%@L&PU2hLx=5)3|CamBUmS+S5E(;xpHBY&2%~qnO zODF684BWhDB1P2!)I_~Pg&cF{f@HNc!?&aRYfHmdubtc%{&Z+QIC|{q|1>s5aCQGQ z@x~=WiM&;{Eyh^9YD5HA8Sy*&44tGTc7pbI!p;!sutB{HaH+H2P^?bfYO<@CeaLw(Sb0oZ&+9j)Yblq}6J*|Gc=psVoNO?Vvio2%Gdl6|R0 z=921HA#|~D@hI(u>4YACtZ(12QG_+7o-%ZP(q<2(y0;dXN7b{kSe!Hp<3j!Atu(iL zZ~P!AR4lp+yywG_SiGS+BaxYQnT%L8?DQJR%IFpponA!%fxs>7j~O2=6H_!w62M9d zno~SDn%}bY--$iZjgw~&#O=TlagExFOp{ZyrVTCnhtM8RgQqlg|4FFO} z(>fvVa+=9vE-b{>@k~!qJ2tanRi_hLkc6(2MYM zbQV|3h1pO@O6JMSf>rCSi}^#HCV0p3Oh&U8rmqLc&3}9@FPn76(0mwED z8+%X3jLF)9x&S%m&5m3b!Lyd}OfVHj=kFr3JfkG5yF^ab&+pPLy1-qWgBoF{+U<3>T-Z(ha-AI06(v*T5$xBSt zzijt$zE_Rq{?#P5B|nx3%fnlvTl?2I^?U+TCh5yC5%#eL4>>~t8ROdu+VRq-k^$fy zlg`^)?RB4u?CNjU-Zr)U73aZjf0i)6^z62(J)H6H9-r!+U9CUXd*B}Dhcb5>rbIqP zFn4D-I(+4?QjD5#vzcOESfolGh@$|ZSqKGsrSNFH%080@&k7XuAp}G0NYG0<((4&Lfrr#H-i1jL)#2jxrQ-T6isb9ERy+47* zFht_@K2p0ydD+9P@j9{L*;jnJDgo~{Ql-!1nBlQOs-bGAoPD987W%bjf>mxy#xz*? zspiUwNywUeBVI7x?muU9x#4-SJXfjUC~ROtx6kB};aaCm9X|oTJtP_YUK{J0QlN!Q zFcSSv@|ru*sqy1;E(U9ggqQ0LG0UsXWWx4o`~!kTEvUj#bH54=%!X=+LaMo10N@!r zLm+^S(r*cJ8K|VjN{2CVwUgdRF!J{lg12)SvCK>aZgD zmx02Cbk#G}LNb=qEe{zjlZ5gQo(|jFkB|QWnmMV#LifG~zst6S0wHlN=)KotIzYfg zz@#Sk?}%N)-pU{(1N<;3e(QIm zCzJI#87;KQTUkIs#vyg(_ovkXyTZV3&)d0Ku9ytIyh&QW&`iDW^ZhMhgDiW~ZCfFA z!VKyHvb0{9J+Q=Rw0*ur%FQ6^sQsa-@Qsh3vOH22ar5`hKLZyjLYhTR;>mM5g4JE< ze%w6uC$S3r^V-o2CHZr*-WCUcq}R1xfKI|^G^#K#KzdTP8T;Ttipdoh0zsjv8$P%( zHQZnl6$ENapU+2NFde+5ej^wU1H$IWq9NLGkf>ftdJ7! zmGi8xcFK&KTE^S+eLhpJRPTgx9yviTKo_vHWL0Pwpg&5Hr52$hN!46w1;utwpQ(@T z)xe>Hn=86Sr0%C*y15$x$QSBljHbg^C#-L=sI0hRfy{%^C~zUHfMzuLG@?ZLONm~bP)*@1QuZv7um&C0(1CKv304*_9|+WpOZ3yQMh z$^0Hr7G+CRvDMt?=zO@Ay5y?Sa2Vq?TcIiqqtg(;DxNg(&xn$G{Dp*eh9G<0Z`GpK`_90Ahy&TH)qOZ^fzyCQY! zPInlU5e{%R;Xv&$o>n^DR=~C;c9^SH5dOe~ zz)>>V>Zs3?>CE$2x6j;<1Qo`4oZqlPWQI(aF6#)ju9 zhB8K-R0Ndc%UNPP|II+DikMIYPRzo40Teu;>miT%&(Jj?3m%lqq)20H?-h4h?bC_L z{$WMln57_N=C?Wqhb3ca6dI>5K;L0!d~h+;+&^jt5tM`$k>`HW@ucW3NIjs(Usy{U ztChbrPYDRUB7a3_iNJ^Ashlb}Bshz}IM2yC%Lt0UUM|`6DHu2lq-PXPLrKzp zgRlx5Y$h4DBb-~piA_IL#gN#`pGjN|e@6hJc~XcEKiONLq!1VObNM}(-WE&lubE~N zCxy#qx|+A>>1xw8w&rR)$6wCY`IOyoJA3GFuv#oLO2eVeciKrnlv6j4y*WRQSj*Sl zbc@*1pqPHbKYdSv_$O6Ovrk!%hP3dapH5zZ*j-pCVdV%l=uJjRdoo7DL!s?T^5~)9 ztq63Qa`YqV?_%Pw6Q5?XyMz~@BiL#C9t<@1`k_cD&;rd=4<|<)#D2~c0C@c(J$+q; z(CyiHih9cktgY&py~Ib(1hHOCw~Jg-i;W`DO3Nf*q3V2Q+VD;fECB{&`U#;xB_c!=2rB2KlQA2gYwc3gLQR| z^qUQjE*%f8FPq*va}9BBac!hqLtx7u zM3~nI_6-cSEf(j8LtimD_`+SxI5Zd%5%9Y?Fg>M?N^yb2+~X$K7sE z1BFIrg~9|!H3lU!hCQSfRt|!J$DA5mqGO#;)HrSY9LwrOWcAUSYwt?c{R}nHl0x;m zQ*hg-?c{C!cq*jh%U*yEVP|xz(9qqll!9ugrJ&=`3h$dS(FdvEGogBf9}F{jjj8m6 z?ROgUH`4bL#OAJpEz2U~{22B7O5I3Lh(p zM@sIC5~iw-!H)owp;4u{<`s-;UQWLeemf1i9g<9>0t!}gjg_~vpS6FSeMY~TJn%ou z{0jfaoVNRXbZ^uq007Iy0l?wXEpj4dt+6f-tG9WK1)-gD#!4PRrb3XP?xrY7+d!s`rQk=*f9pd>uv5*rP?J*~ilejuH_}MaeYWX;S~#VREjrV69fykh*r(Y@cUpGX3>=)_|V}T<2o1nC0(s~eMjkJf)zJ{a2eY61? zL7K;J{aZ2egPhkc@c8Dp#~APLo5jZa(6!zm#%%7j>32PXMd|~#RZX~sACze8qiO$6 zG4HDlH4MG6S3nE+xB74nt9q-Cgh8e&rB6_jn1r7bi zO)QKP!|%NaFa8Sgi^-kAs#qAJpk37u`H+_=HPaOT&aY{}p@n+^t0c!N(%LKTglL!cg#O_09G5 zm&sVEi%=cYza9JxFF@yEsD|Pw=mkEZiP_Y;jRaB-M%!~=#);UF$lP|9I%r|AanIDU z?#Vz|jRzSAPv*mmLpg&MD9th@3pF#qBmn&BH|=sC_wq8)%UfQVNT%Zd>&-3Vt6m+E z7Sq7$c(jN=Rh(yAq4Oa*ik4{#;|UP8Ube7Q2PrZov0-LzP z&K^_V!f`GBR*kg8KMmX1l>*ipFHfaExz^~{jeiM=@?0@!tDp+01s78hIp}n7>4+B6 z(Xe07n^0yf(aXH-|2u=7SyVz%%kYUUV>TZe#i-H$>3GbFp#dKFvXYnp5;wX!zO6nD zQCi`{+5&M3Au0PT{=$mAPtV+hBtN4#r6SV8jg%%NGn~Io|C$;W%~JTMe7?!R@i_fk zfz>=$g9Eegj(1ErZ>pS^ve>cz`=LMF@Nr(+F~++*jmpMO#{O1dqBS0e{_kB>V<|_3 z@3TIJa@|wF!0GF>p+R?D^lw+|Sby4%@G|09vr51VqL<+Radc%Q+x2b!Me|eKP!k5nY#g1d}ZM z8ulajBC*%s!yyGxJa3$F&xo;$bX*6%a&BhC7!m2crgYiArX7~P-mO^o>Hqxe`-n+M zbIxU7==-s5)5onlO5?X`z@v=@C!K-WJDkrLUk~=pX;3-yKXc5WrSQh-We&trSb+Se z6=jF2Wv}XXPl9EAB@|ZZsQd!A#d^^M8DX$x&X!d7-kYU$>(Y6eL>hE=Ds@Zc)`wPh zGj{DVZVBcUj{RFrISxk&tic$)kQ*vsE`c9Tst!V{4#Cd%DyTgrk{a$$u(2c7EK5;r z9o7e-kyC1OeLTNaCbj{-0U3&E-04cHi7i$|W_YeLcsQxVI2n#5cny6;F=y$?Ok0KC zZ4=tN9(0$7H>XunFf5=!8f!-iHouuq#+vF!^E(W9t2MxYH{AH`gW^^fm_esyyP_L! z4Dx*VRaxc}OH6fN)4+n>pGbS$vWC3Z+%@9OWTs!Bx>oghs)Dh;!3{VpXvVkXRP6dGp?9(ovGvVeFW$J% ziFD;wgMH-`rpT=x*GDTZJoK=NyuMp4)9O7tHgj5(qaWmzK$kz}?3uz&Xc~ANMOvDm zkeGlu|7xdJG^JCX8ICOG)Ry^6PB%SG1ma)ravk0z9p98oc~8%uxDpy5s7n%OBnEtH z4C|WVoFS|GHv@;hXUs%K!oc&Ma%Cz3H)j>!($h;CzJL2uc<{g)S)sl6GEWHcyW(R_ zXkvZN*g26?ONGM#L>55%{L5$O8P&2ym^Quq&`czkI2`t%tNQZYC4btoAMxi}BO%x# z6XvZlpITULb?bnmNFx?$dB19&OX3!M39Tb`g?c1$r{DZnI}z!9HMlW!{*hotYA$q` zQ~NVk;4pYh*UWn|_S)#pkM~il^?lp3LaK|pM<@N|oo&g;uT`U%7g%fLiIPmG97dUw zA7#EHXWxm%y=dr12r980Hanh=R3R-@RVb|6FTwE5(AIL4_f1{$jz~ zaG)T8=Hld5yO3CJdcKS#)ln-fQHx3A6ED%ZC#sn?O)lellywV#aZR(o<5{F`mBkV2 zb0C&wSM09Jzo;EP6Ziw^B`5?}77w*yREuSAbrsD?_mk9rokgaP?I+&*b)bNoy{G;_ zyP1GSiMo%!vjxrKfcGw6#L3NAJrertCyPkWFtncjib&yd?}-IP$N68#dpp|GC#u=Z z*&f%hzZyIoweRp1;0H_`kuCeaw;lDcrVBBi{hX>oN8a$z^s4`c)hio-Y(P= zb_Y*3JI`BFbyr4bhJUolh6bzAW3J@V8Mm&+6w%?2*l48_-(qaZyJ>j^&nTzN$Fz}j zpOjeB9^d}}p{|M}U{Lu;SyJu6xg>O#e76JgD)|Huo$|ye z%lmMn{8iZbC63i#94F6>FP7%*)hD`BpJTe+e~4g?z#(n|u&H*1Wg~Z4_{Cz7lft^m z#Zo@`4q>19xQVgGdR9uKvcG||(nfQD zU%bW&Vg!qEQhTvpxg{Ei9lY}Y`nmq{O<=8xA1kHc!Tcqk^$dCpTN`UH{wW{8`8!{< zrzzv#nlW_3Dz1$Lf1v_?$7nuOl2x1$ekjn~t{JJwGjb0O$L+aoflMTbk_OCkbh!oMPXXF%rj~(QMvP8h8L0f!1aFvu!oHZHwN=cbxLO{q?s#Bg? z$r*C-8Z|65*+3@%4g?!M{cerzvo!bo-_a1*_=jxK-h31SKOg2Vl6ZDPoEn+5mWt7DpSSaU8vBtJ7$zBZoReq6bdZInkkCHYoYX0>tnzV5=L zIxTDVMMKb+KH}5}=rP_?rubAtElIJWU{H!IhaJ@=W>M6H9ax1`4uG8a6uLbMQ3nFg zPAZ-T6~HbH*6ktnx8;Pk!x~!8--JgF7={Fglo}gkotxdS=IS@^gG#@} zM6(rJ5x1Wyffaroc5ev_nw%f?q%O*G_lh?9YaCxSDJ~5TVr*A3W*;C1S#wRI9gBU( zAvESD=#$qXYPn-w8-ndroF^84m=&9^`PH=)gp(oF5?-_DWcb zSQYM{$%UYW3Zt{5t%6;lL7_A$q?Q9^LT|$OvU-MKAL$Uz;QP0(OQpZsQcrhJbQL(GN)GfC}YIu{_;tmbG6R-cG6rr zjvDmI5(5bdu47Eu*--?Ct>H~48#h^7I>~I+CEoQBby;g!ju)p(qI!PwJ+x%2^(Cp9lN3`XUE=}e&rf0Fky>h$8 zJ7#tvEvOE0+bqnmpQ-MGHH;dqGpIH_;R$)u+3HB$$7XN|HQ$WeOuk*;BkM`h8a7uU zTVd`IjW9!p3xUx?KuZrFgGHDMw@pA&3VyRDQfpyJ{9UU@QPN`>wRY-4p$gdBG#En< zgs!VF%toa+DOF3v-f$>R!#q#8SK0;< z(<%}O%wSQbicy4@cCtIx4{K=c~#x*YBUV~HA1#8YX&aKOo zT)kt>yQ=qZ^Y?SLEEl&XqI=xi+a;&Oi=r;7|Sm zg`x?g!!;zVBD+@>PxhgkU%>=~$!uBSc;5W!F+gIjQGVCxj8-{*)%d{Be8RKB?zJsA z$>n(%jfTZ1Gutx5ty{y3)Rfn=9^)w7tlNIYNti+0T;>D5%Nyy|36H&KEb zL*!!?UE}zl)F8IpNme86%bFpPzpX)kykKO9uTikoX{W7WpAY+OO1!SvcFbv8I;HwXP;)H5 z2O_I`;>@CR%>uXnY|$LRU^-zV35pgO2YTVjO`4QQoxp>3e3lcOC%{9%hYOwbazevs z>(-6@E2py5<`~q-O-!+_UsAa=w}z8NJpvJxl_PU=saE)!)7ZJzJE6#t5#I`>Uw|&b zXsO(ARVOpZPK+f~bLi$f-z*YA8QNSTWadh529a0C7(#V2IvK0_Mq_K)*Eg)4$ zJWWdR*rEqV!bgO~1W1A+Fp?w4$3!WItnDm5ECQ3b+x0f5#x)&C``MUu*LCGHW|FNvYU53z| zdEMFr@|!-v=;KnwO^4AS8q6;`rRx`Ial9t=tm6?W4wa>|5cZz^ySTpt-%EG?l9%O{KI88IbHvS3r z>Y9_IySCP5PT%5lyKxU0?3xi-JmG7Kw;$Ovx0JavzefepZbr@tZL?MS?R(Zp=I%v`E4;lNQ1Xao}&Ke~&_$7~B zy?aG>05MqG{Pl<20&XPE;RA+lzxB_zcLSFirNdgM{aPHkZ8nq!RM)(En_HUaXw^wN zq>|9@GqImU7o~XxeVbiK&t609ClHN)ytUx^>}V&LJUFR(c7Pp)=77E~7o@mMOH)IZ zusqX6Pn6KH5OaC2Y_CJyIENmZ=Eg#PKrz1_iGLVE!^36J+M zgo8VA0$W!WkCi6H(Zg#Dvrvzs;VI=Q|M>32i-FR)@l*Fm58+$;i4{_C}gyVX$yu#hC)Y>71qH(09`RR7oN+ZkF*_d zM&$+Lqu>lu`K?M~rB-66hMbTtsu+d*HM&_JM8;W8ie=@gV`2P_L-oktdaP~=zl?R? zn{U(hD1`VvRSk$9^O*0gx9dgIM@E|%R||cn0>S*Q%Gex956tg2YO`OV|BuNfco-sB zLxC(AO31_#&BvG@MJl+II|S%m%m))iHMSx;Uti6*@N^@{Z(ImcIPg}M@KeUxRVaM# zvNp9*kY}>av7`OS`^H5zaLLu8Myx7V-h^6nA?losnw|G`rGV21j^Ovd{I>$vj;Y>R z&BftrGo_VgH1%mkI8v)`9>O_PR(1YC6VzvqdV!v{&|7G>Tgu zPM!R6lVUrUA()ASxUe}+LmGW{zTP*`n^;Xu0%vZIh8$IZQo{t7{{`p_glsN~8`6m~ z)z4&(pGbm~NF*=Vkpl{IB);w^PD1+Jvw~1i?zPeOQ$=gG+I0=CL{%!M)sCNyTByr> zsv;u>D|k^F=~Wt$$_$Bg!uw@J3_o)iRU`JZ=*o-k=F7JpS5BOUCns}n5m>MgKy0t+ zaqrR>FBp^z^BXdIJ?Sv@A%CpkDDgzv){O1eaH+9FLHQ^adui!KlN*{w#3dW!Y+;fO zMhS&`zZPrlYdlTjujErhd4{Wng(JDVn9(j7;yoz4D#DLoW^t&&|A0bKGbP|)p;6Ac z>e~u5^#QT|rpH?v^D&kycK#F0Rx>91)r9!~9^hxqFkHRzPfg*LaKL+w2WoPiHqToh zqA!)pB)DGVglD9I3*!?h&XMeRg=0QR6gh!+m8Ix*c$1K=YKl03RCygYJ50_+)KRv$ zNRFtG0V^3{w)#VLn6=B2(+*}NiGK7SeEm%)%>7;9Ggpu_- zj;JYpyy>*zJLB>)vgySGM2K~ZU{JX4gxXK?Y#+v!tY=F;fM37-UM~v}>4-wbsuMt`3k%bzym;43AkR^o)Rcx@pNu?pu>T#vQvg%hl zn?_z0B&G29>dk)9=QmGM%M0X&K2?#&(@UO-w$z*j?_M6;%1+(r9Az&SZPe#`hCTQ%`X8LFa482@5D0^|g7~ z1;j@OCFD$h2CW4Ru?vFJ$#u)Z`B~vB`i`q8JfErot)@}(-U5Asbz5C&bIAmfRI=dq zDjI!8WCCv#-%Ml~!SH7z^@T+}X72AWL>f*)k6{{E^D_V0E(b!j5k&@nb3%4tu&_=@ zv{-;Cf1{IaDwAzgmy)ewEFKIO^}{u26oOlF-(Z)Kt8NoMjY6ZUX(@7}2m|`zJ^btX-q!*+|biq)C%G;P0JNU;7t@z`#F|^KzV9NuEoGD4Sk#5iZi?eTHAugsfs9 zk_>m3ua6&!#Q^-R6hekCfcQV+m_rGEjcZ6sfrT1b`N*1gn>&G-A(VHT<$HF%!i5Ceh z@(!AQWy(ZZJ&i}XCo`BdS86iZc)l%LFwfaIj+2(gDgK|WKJoWbaL{oG>;w%8y@?LY zI8R7YQ6sff8LVdxj6XdumHg&@Uov(ldS3V&U9kC|Y`tTFJglFRP z*7mtPI+3z7+!L6=IR5Z`QKL{b9lBv8g5yM3f12qxD@s`WDCBWsDUUdt85zU1*sl$^ z#aO!ff10`WcP98Yz5}z(M3@L=j#Jc(<&bKVInx|FsM$1c?-YKFYvcX3+U1&{SD3(Ww#-V;F(3LO}#QAiQKA(LW$84=B*A&vyjDUgN|60U^Z zz;Ws8)WMWBd#Kz7L`tx`t>-_hCf;oyX!;6|;@td{{T&08P>J&Su2TE*aw)5Whf-y* zQJwj8jX+Z5Bq4)g=f%sgLaI3Z&PjPxy%U@3qBqRY?^CVTx%fdl;FMv0WKs@j)%T|o zxk5MIFT^XRH;`7?nKbX4$s9pDFqDF_-TE7sQJIrdQtThM%|1S6i-JX}59O7H{x0#t zE!$5@gv7q98Iat+4G1JYstw`_Lmyuam3O8R)WMjW`PTK7Z2@x6o|!gDa0&gQPbbgG z*`(GbV`_Iu6Gduu!J;8GpF{b%A>&Q&a%QKLu0QGtz5mh;X3u=@Bx3c*(y+z2ajaH-Syw#dgcB=;X|=J4gqe zh^I%Bl`E2vpB^F#%qu++KNJcE8;tXq%=T+G+Tyvs=+Uq8Z@?a;X6#8X?LacU{!60D zJ7(3}O)>HaW7`h_5cNb6Hl+)Afk)Y5IRHuArQ){S^Nz4{U-Nrn#rU^lkFG4`oPsUR z`g~Qf@V0vKQ#I*H9Nthp zTvbatWoxcq2vWI;ZypYHF4P67@7gUFSy~Bq^WL$09|%LjmIm}emP8ftL1Kr-I_BeD z5?~YLEkM%%c;TEls*w(RQ0md_mrEfH9?B#KXL|LLCK{UlXd}jd8=g?BIfl@R;PF$A z-pR&lOEg~M7Jk>c)1bt%IAcUmvo3x7G^4ld5N_aV<@kPl^^+Pm!y!xR#_*s+R2KHz zO0AmXt-qSirPtB|B9psaL7Hk7p(%|vWzy8Lk3XjQ%SK-Ld4AUjhX*e9^KoZ_d@6Z% zQCOdYQ~hFo_SF|`?mVKqkZY36`M$KC2jg~;9B)}Cg|M%mV*Zpn+P-IUl)-)GgR(4$ ze%qV51?Wo*eBv++C7{D-C2X2t2fjy_5C0Uc)WTUh+J})Sf;TRX={uZ{aG$Y!=w3&v z#8({HaDe~CY2TMp>UWYzL@NJk9`tE8QFHNEDv?cT`if7oGsj*>X5}|hPu#bijhqm9 z>-?U@&(em}6<+`XAOSDXsO!=LR-JsMgYZ6{0R-bHnB_IrepndtGtAlCcYHLT(@}7A zM35)qchdG1ipJCH9Lwd;Tz>pXJ2)4W?BcO36Em)UMAA%tY`{EzRAJRDO20oSwp?8G z$|B~+{Jm+G6e#9$yF5cOaL)`Ok-A35F}h7xij$=;yX~ozpTX5>;3?c@81OaACCUrTyQSbmsBotTo%+dsD%QGcvC{Z_Sf#F2AZu9?l--DOiiK{aNB zJJJPn)}&;bN_ck7ZAR0qWL;@upFh1`nke_FMmM*-O!a{5`h7jhGqVTn)fveH?nAEY(6ctHI# z)1`VLvyQ20gn2C@)cm5J#q&1d9uO!X+##k$D+2^sCR~bhvowtTh^fkpI~Fp2uNF?z z=kGn&Ac^i4EM|M&h6XDg@<}rXd7f~#E)&(mbnNSGQ|$z^1C`OT+YODvBFPF4ydBG- zg=M8wicKMx)F_jJg7_li^PB!N@G@g|sG57N#j&~x|H8fKZTYihXYF$1PS!yam-M&Q z*H*)dKGuAf7x?7R)@|w2lMh2$X|0o{$}6Q=zBemeGc&1Cmm77SJTXs#GS^WBKgAw! zv!PG`C`EA7ng6bn&&qDoEjdG4-A^~74IyHaATcggr(XT$}|FGEc>cR0`M zp(VT2jS^6nlUWP4NJ19t$PU&hHt(dvN7|#7bZu#5c*|7_qix!bMOYI7VxRkf7c^Bq z*YChDK(7L&904{ogm8 z>pdaoW-ZjZ9&M74eddElc_$nUJExhR0J*9-2q|S=)bHll-c!6Mu1hVSuG+Zr@>!zI z+|<(uX&%z%K$WZXS!$%_#CNlo8!mk(Ha9p-v$IqL2H+U94Jbz3{)iZ`l@2Tr=0m0m z)Q187j9j**DC)ilylST%zLkqf!Hc64>r#Ljf#-c<8NdXU>$ZUY;_CXuq`28DBT`>R zpyUG~g$i(Ld)|aBMtx_}D>zasQqdQaXROkuphI1HxpxQlJ2_H+%#L7B)Zf}!RsN4o zD8c}G3eFDMCFt3SfYye7yw}|Un78{FoLZRJ~Dsj6=@@R}9}VWu$ZhmqE0u-22yxYys*K&O?P(>Ud>X0RRTV O)m+oq!PmLlHuiPH2LNKxooCN|lcECPhF@=tYWv^ePy7QL2DSQ=}tJ z0YyNNDkx0^g#9Nz&+p#P^M85otGh2wrtF?`zH??KvoouqB0&NWE|{&csi`R;K}Se? z*t&Z8THE>BdO83)k{A^5@4EBEIu}nuU4WzST^BD;0R2xDicn?m<>77X=VIsX_^)U0 z{(acPTT87Y2^uY~`d=l0v4*iYfrpx4&dA^1-tq2Tl*B(iP!I}@m38$0+kbjO$sJp7cfxJf z-tM+RcDD9z|6R*Ss8#i}_i}LYyo1uW^|kf53lN*&AAMLtJ(0;sM_=jRO#h&uWhDQ_ zghq>9{V(r`)M^qK>HjMDUnT%!BO_G;?Ky%Y+O`2sQZgdqXb~|qno#!71)eB&{*(T% zUky(uFG7a!93TS#BJKbM9De>h0|PS~8yDB*%R)kEDXFVh<>i%b+|bg}*Ecpcv$C?Y zb8>QX^YZh%cP}(FEIK+qJ~=rpEh{hY$rC)jva+_Jp{3>J%g(oN`};>m#>YQ?{=BfT zyu7}?wY&T4*U1S;G){2Rp5UZ}6fyJ9#ZC6_l!*JshsrPhX228uHvp^?fIKB+Q2-!` z0{{}pHLq1DfVf1x0Kljbby)r?IGk0NBTQ_Lf--D3G>MYrElnIrU#^6L_5SVGdzyy1 zx~~?vDM=$26#4XL5C1H1kdMapfM@I={H7cW4UIjA?eC=C5)AJPdc?@pYz6cwk{TDj zRH}bd;(VSj@|8g8!i){{LXT>OH3F_@1NC+AV`0fWFAaBsXkUudHwt4`Q^}TYP(<3y zJnOP`B#Eo!#edL#@hRT&M$||8q5+lyoh#r4Tm$JN5%9$Dja9_|#{-?|_KrxWVVwW- z+S)(2Oh=+r(7#3$tar(zL1@4B3}@GHhyi2H!t1�l+)VkqY`YhK%-nmLipnjYc$V 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Cancel_1.mp3 b/sound/pixelui-sounds/errors-cancel/Cancel_1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b88d437754a583d8bd4e5a5af15f8803e6811455 GIT binary patch literal 1507 zcmeZtF=k-^0_KE}h=>RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&mzqSwI;E z1~^6FQc#A8g)xRMBsB~no*_m+|8N1Vb56`lPR&s;ggJo&C>G-E8-Q@W2v8(Fu^=b4 zxH!HbC$TaqF*zF{D+ZKx%}dTt$;?Yv2uLhS%q?aBg#gUFdZ0YWOToSYPB1UQoMK@D z^OCt6+>>BWJDC{51t?@Ngaik>0zJzQbcj!4S(>SZo{@o`p@9KV3bKpykY(D)Pgz{3B3 z2OMEw;4~<t)B*y)4E0S?B44Dly#t=;Ho z%(U_Gsk9${Qt2^oxQ-^Djhk}z{_%Y;{@ER5ozMPb!t;MClK=m!|Nl3!|9HX#hXN*P zAx_psjSPVz9<$Cmh^whss~rxXFEdAMqFBn0_cDw&GRqiVJ!_tD&Z4LL{1f4phIgvP zTJgFDzFo-^ZZEpOY)P=Ok*Rmo#s97>H}358Tv@mN7h4ur3s1BCpBrjI+;dnPwEiF5 z`P=<}?%6N@e+M05Y2X(48X!4~fiu5*DfiX}28a1VXaBVnHk&wvS1=1JIb?>hE-#&S zf+0SUvGct;d*xxrBhFn%-%oz!aQ95_q}AWd{buC{dFOxnS$l2vOr=F1yCv&i?pB*w z$Y$vBuyc(-Knz2t=Vg}z>;?zi7^K9H=NEo`Qz+FgVx++v^*CD!9zcyqQ~e_W$E0i%Z@f?hB0G{pGZ$`mJ1#rO8jZ_#GnS@Bdj^F6FY} zNLN7k6EB&+*~gmp*7irNqFN|@6fA>Yt*hr zT$$?qKj|9R(sS!2uKx|$#nh;vBlhT)fA`9e(C!7Br?3h(r3-FK@V{`xHsaHdwF^$_ zO!8J)@#5+Kn<<+nPQ0yUDYcoEh0n@n`qTMOvaUsIS<3%^cT6K8p^@2Zm5-yZt1&2x HuOb8h`=LTt literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Cancel_2.mp3 b/sound/pixelui-sounds/errors-cancel/Cancel_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b32e66ad0441a71cb31322437a70a053932c844d GIT binary patch literal 1507 zcmeZtF=k-^0_KE}h=>RvLkP&uP0Y$Kiccy^%u8YLHE~p6fXWGi8elAR9Do|x+NNJv*e~>SOf&mB^8M{Il zKsGKBxDt%n2Mou@Gn90EF{JfFkLM z1v#n3#qk9>iIqu-$=L{5F`%q#UUGg)W?s5NKw?p1ZZQKW1YqXX1LZ+p3ib_ff_e$= z6bloWmz|93j{%qrn13=P;Q-Tcfz!Cae_Q}$HPDgCKt~#zf;cds0#1oQ9`nyzd##+n z!vB8<905jR!A>=ipA4L-(=-p88Ze|!v{;ZU{cyGXO9uU>HHBNIALQU$!ua=lI@Pt%wl408?7pwxsonO z?RY7g6Tu-FDO8$z>HT!iFJ}cjU+LGTI5NBI343|$*;230G1Fm=W4@tj`XvVjWyfBo zVwI4NgRa5e|9=M^VQ1tqNY}f2jDaz>Q_*o>ri1jE)qIwc8%{oatSf!SMaNKM&Y4z0 zjuXcp9;vUK)Tv<>{+Brt$FvPB|0KH=*XvnKPVQ4$VHBwBc-?vPnCytgy+& zvxv7EMR^<^;v?uOxvIK z_3Sz9JPa#ldb>oO=UQ5wzgvAO*UV|lIA%Vb|NF3OrP9KsY@7CMFp>JdNbzT8xaR-1 z1sB*G5`?Bsp0uxWa$`~lvy}J5aFt2wD^F)F)17*^al!G3z23ax(TAh2f8KNL``@dn zH(vGYy->DZGh7#s+2%Y)niI438W9yM;5>HBMP7`tV5p=4C85 zb~j|{s{C~G%V+GdaGo0c=iC4P-{<7*Sfjl+ukRGdLsAVVpZqwvyzwii7^?&0y&ocX z|CQ#v{QBr%UZA()CngWWSaW097kBJ-EDV}`-BogH^vp_g>89Ir8a!ksmCGpno#Wgt znIva9zo~ELn{^N8G~3LK-QL(8JZDC{mE)x7DKjf96erKlpW$o#vsIc|B15;z$I;i- L7?fdGQ6B&RJOw{F literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Error_1.mp3 b/sound/pixelui-sounds/errors-cancel/Error_1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b8930c9d3515eb39007c87e7ef88371ed6cba0ed GIT binary patch literal 3805 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 TI*0&ZD%>eU{!e@TuiE+#OPMbt literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Error_2.mp3 b/sound/pixelui-sounds/errors-cancel/Error_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..6f7f79647a8edbfcc40415e22d1e2b5f3f4a9780 GIT binary patch literal 2969 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 h*-wtY44Du)BgfM7HyGxi2Lkt8VC1oPt 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 AO#lD@ literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/errors-cancel/Error_4.mp3 b/sound/pixelui-sounds/errors-cancel/Error_4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..623bad17bbe89cd67ca51be77a56efe27474cd7e GIT binary patch literal 4850 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 z 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Alert_2.mp3 b/sound/pixelui-sounds/notifications-alerts/Alert_2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..7d40e78af0c1798ffd32569f07ea2e248d310e5a GIT binary patch literal 11955 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Alert_3.mp3 b/sound/pixelui-sounds/notifications-alerts/Alert_3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0ab6c8daea5fd4dbafb9525229498542d379b955 GIT binary patch literal 24912 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Alert_4.mp3 b/sound/pixelui-sounds/notifications-alerts/Alert_4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c5c70c5a9007e192fc4cb50183c6858bb7d417ad GIT binary patch literal 12791 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 au3(l}bAlR;CY;*nVzd7L*#G}}SN{i$@y~Ps literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Alert_5.mp3 b/sound/pixelui-sounds/notifications-alerts/Alert_5.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..25520e70610618d9e9bfcf4ea35d57abbd819e84 GIT binary patch literal 7151 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 O??=x6>nQ$O8p04E z%*%b>xu3P(ukU)^>&yA?{oi|E*YE7J&N^!!6?q{{;3hEa^o@;;Zv@$mc0oA0d0JR` zB3x|%4Y&*#_{Sr?^&DJpyvMelUJh=q0PK$izOk&`T-*`f4pz>#f6w*$YqEj!rj@{%ge&u8R2Jzuy*>7 zOLgNaxLUi}IJiCnYa=`nE?&UxefYCp;EjI^rl+AT`w!T^m5IXt0TYD%2ld8gwv6n3y0C2zz^bcXxMRU*EvMz{tqR z7cX9DPq^{S+#q`JDgsi~>6v$L& z()y-IA>rG`pI}E1`diYMrYGa%{H0Ns+Wi0klFon%M+VXQrPcT{9igMMkw*15Cbxa+ z-Viw)_<~7BgKGm8B_5&%dN?t^gb+(3sc}>WRaf09V+NHD4^h85-zTs>aa(;qkDAIJ z<30>noxHq!14LoGJt1bkM!O;=NE_+_Xr0s5Tw0c;0nA_E0u=Ph>5kUe@EEP>-75ct5b>4*!*X6hE z>=`&VUfC#)e1+h}u%SDTCoxj`s|Do8>>6ZEI#p2UKP15zbo43o(CA3|-Y0gUbrLa5 zUprLf&6stOCd2kYu6ri_ihn+LD3UiHy)fxLjV5-44J#}S2q|D;Pcx{&3f5GfG@Lf? zK)B&;G(8`$z*V#!m>@%?H^{`d4C3-azCnP#~R*QK{S8v zVZlZhul0SyrukLB%qm*^kMAYJBXUq%7=Ja zh-@;Gt-n)%e-OI;QWAK9`Z!D6X#XFe{dJjY_kDybi$imA3#WicE2h-cq69}BZRKMi zNYwFHj~iYzMGYprbNm6rli4OcWwo5?5B{3D5y3F)5$}%KjQY5T$fJU}xnW6)pUgH& zqvWLqRq@@)O*#oO`&X)C#=sc83mN_EtrWQwB7J-ng67O=k9JZh_{qg+sq?wW`wt+= zVy%5|qR{*TC5jz^IIEg6xpsw_(hpg@DnC<30|x~mclO-;jf%6C^WB#pSiH56pIv#H z9+Rl_#Et~R+@(c?9@9_#^U&{GAY6bzfY5v&s?*@Z;v|^@VQMc>AI&>`fqbN6n%q#7I6BPemgj{Dk6aMCpVs`-|Jd~pAP9YfS zb$Vr3N?ma}r=V}#OlKmjXfFV;b?jKnECno4Mp|$c(UR7q8#4P`PdnZxxFb0e?W0oE zyo|h~@s8M&n6oy+&vrYc+$_Y=pRM3#A6Zw3G&KFo#dn2sB02bL!-V2keTwH=FDjGC zcLL8ijTKpV5l5vBq$+)2%UdAqQ2hE$WkOnyVDp@c@Fo%aPhBGH@^TnKneJ9(k%W~# z_maQGmnceGevxcqOdNWDmAn44^{1|S#gsErc0?XK{`w$&xNkr3pmdiU3x+RLHa7jW z?&-1=YDeg7{toJhFUqo`JFOl(+^&4sru(h`H+E9?rLXMx#6=o?HcvSw z5$DHC&X%DC=rU!R%^n{@2m2NX1mGjrb<_)VWRe-|D_TTo4T92IPQhw*91G*n*O@!y zagZoVN}i|QPC*~%%^)Lt`^Mk&Xz$M>ODtria&nYzTbkBs-G45^_KPCV15 zpy;qE|F)C6y{BRh7pb{T-%AxT>Ru-`IvOnHM`I!=Zr)82QWS=jH63XO^y{^cor-C z<2WAqX5po1rFwUBpC5|AaonMFrcWt!OYD1OCrWcAkS6*q3bkQHd+}BR`88wD;)GSz zZfpMq0xQw>xMoVXSEGWW6W&k(rec=>HE0ej+6wD~w=;EIfex~=20 znM*< znk2$zRTD`_?UK2{5;R1A1A#uRnUvKZ3ZyeUIvwM-r}9u{Mru?Bvjbb4cAV06c@rV` zqdRQAui-*rG`ix}aF+bD!*BH8*oK$CflrCV0w7jFo)f4|^}w&xbKcP`Cx(!D$zZ+B z@TZ=07+^p!u8BRU%T11}<$J5`ItC69$H^yVZxh8(%|{A8!D8txK4|2uB#vD(dRZ6F zb5AS!f)AC80BBijSIk2F8;aM_haOduHk%)KnHQ|1u3O6n+1?W7KSd+NPArIff;T?( z$}yvd<-U`XOFaVm7Z3nSoIsQn7<-sdZdbH0(UFGZ5!1)~Ac=8~rJN;L)23_;EWDgT zmRt*@Mja~-{2IGfP5ZDsv6{__(K4;}E+jcp>cT=%b!9E3qZOrlXqQ{^;B$X&Y2M}! zM2}n{H+!b3Z#u8|B7)95qCLaPRC-d~ViFhzV6I>QC4}*&R;Cz>}%yOttU7Ai<@b%XR>24S1G`rQ`1x z^Tpo*Tyn5BNPvVFQJ%gYOT_BAmJ^xg~Iabj& zNW!yDQ@w@@_@4*`{|uU>iTb@eD09S0Sa;s~6Q`WB<$}rX`zaS*iSXI-jQR`%zxuJ; z?gNVBaI54W^KFS2FMD97&eh3)OzO8$7V*2p$BkdcZi~KaDKID z9`5FB@%Th=b&;|h)5u>WS^6%mTBA;_imk@J0TH-fb6VekL`UF?51m<%>A5H@(3ukt zJmIYScBb(ieHBcoO%$e%6*axnGW?7mUop38E47x~i+Y z!jK6(dvSzgI1uOzgv_iCvrd9?HGZ|q4szfzY2a z093oeG}&%}U_l`F37zWu_#8Ol+#dP~WC1H5-O)W)8@5)JRoCxtG zyy=_iC#jg#$r+XH(l#WV-S&6TLC3nofEEk75@$O8UcLxS2Uaw)@Oz9104QW=*#QY^ zu87x8V`)g2FC-o;zsO@TI}YCkXa7Q-S+K>1HsGqLq(9_d-DOlL9r(x&;!Hr5?pC6s(-)6-8LGItvCmmhW_oc83pCY8cl;D-U#e zYm4s?-M2d7*$s|qz`|34xJZjr3an2wS{m%KUtu zvh2r24$4$+vDtOOPW~J`Ls_b7pD8|LhFksd0^XkT)3^MoT|<6f|6)GJ9BTyvjDf=i zZ2?%yUf+H7+eM(?gH#Njl#|Anily+9oTw{WzUz@K|ET9K6-r4op4d1_TVb@Y%fNn7NBUYBEX=wwge#}A)(!{k_HM+ zYV{vrxVp)G`jKBSg_Z!c9*0d*<@*JsgUIhAS~U!XIjcZ?aAy6Wf$V{cqu`0jE6I|z#O2m@G4%mo zh#=-&>JH>0vZ2wOT^@Od2@Eu2UuFOm|?^Pu%O!?e6)cM>Sk9L za(@B;J;+wWB><#H~nfLwfnIogE&$u$gp~Xy>_qr^WwK5YR6IZaC z;|d=7F4_v}Y;8{#>5ty^y<(j~jgAW!X&B7pyXFeE3Lkz&jWV3|D_~pc$K_O?NZ0qF zeo{a@A^bHZbyd5r2P@2|o%XkCZ%=0d0FM?RIb?Hto$GC2%!MXEqTe?{eh4CPCbS-t z*C#UO5bV&>)FS}snoj-fj5br#=^QlFcV|T?D=!K>b~PsGF?XFNJC<@rXGvNTH1ckN z9%JC`KV#7FsX*f=E{Y%H)mBov{Qdqc3EdvKr;v+VX+};E)5~FiHcVe&8Itxcw%)#= zLtXp_M=`=m*(A#A>Xo`;p1PrCN0*leR{i%%(Xi%LRj&2Kuu84+X^n1y zBG6U)>*)F5NE!Wf)`7tnQBt1l7~NygM27x2j@GYcn3SDygRRFiPqHs-#oEn2Hn|9e zJ$fRX9iK|Y05g4?9T9l-wsr%hsn9)ZNq+KO&RxRu*AsOZIl!t3dkC{+WKN~f25ix? z6BGJ$-)SRD*k}sn>q3Z*58{p#x%M5-#G1z#+^pVh)kI%y5@0eltr;8mR_3N!#tnrF+C{g$GO zJ+)N#AALGkP7}#!S)>&BIdqW`TnHAde(z2vs-=U_vQ@Dcvgn9!Ze3?**EkA1!AGkd30T(dss`))>I`tqiGFF(f2Cb_G_Kf;Ki(Y{ zxDR5tk94=n&o7m*&}f2beH!qsW7`>sJS#@lEV!lB_fkmVPdV__y}%NEpR=^@z(sVW zTQ67Um8}O1?pBSOQc2wxa(m=bp?J3$X>^@ItqGA6UCKg2(xD%f%vzl zjw<%|xd|rvJTh<@MBj@LF`?`4wUxJ7Qn%uHs{}G(RWtOtU$KeMdQ-vZTz zDx1|%Xk=;2aK#h?zw^I*7)V>mqM5bTbr#%F+819}c=(Q~nKDK)U5u(l!u@%N?dC^n zdg21P8fr8;RlnF$0zzohhKnX{((*Ub&&Im+m$uNB&ITOhH9HGb zDg0i@(Fl;?dp%rdWFT^16vIK=eV-&9KP2VSK6BdScJwDZGxBv_$~V8vie8Jz{c${~$gp!XOf z;1VK2sC%zsT0w9T6^%FekUSWyjRbMA6W)CW7KzJJ0;xYNp^1}{dN)Q3dW9%qXdD)0 zVAS-Q#uJaNS&mn!ee0QLRF#<^@X0WNXC>cEhPhc1R7ym9Q%oEE)uig>ydOFPt|G|UzGL3mDQlk z%eNx6u?o$o{5oYS?VkwMj-}m*cm2t7zw3RN0^|lS@UZS?CI2X(VZ(oiR^f3AG#v_( zs3Ra`ua_Z@`HK09;>!#J>KDO$*F_#@?qfAR^_|8&c{l60ewSfr_rBSf!gPx2{qcs1 z4&i6B<#2*hYB2KCH#P2uzi_RwNa_QqyImZGxbDFdHuWwOg?)vXim=5ZmDF;hwrdwP zT2E1^UO~IbDoVSrCep!{s~#^|N?pJf(mG$YYLaDSI87T3OU0foPi1S^GDOQWN@U>t zB8z`$$p5uuYhzJz+^Ephr29F&)NYpQ)@(enNd?1`H?c})YqZW5+7_sDPC3Xe&=!FE zyN0U&ixNu@+ZVK^Y@NbRA-v48<6p_UALu%lF=z`_ZAcA~9*=`X9n>6pY3l<%^?CC- zeWv!#aosY!UPN_|;pBdwHe7ixR+sl%Z+h>6^id4f2}1xSEs3^~KzFImQ@U7?#`E}% zw;PTTwTdp!avUrbBKXMKvJ!_C*NIHKuW4;YykeGehf`G)bf={2-DGMJ!xE+|j>Ive z_JfhGdaW5xd~(N>f1(-{?H)GTxwt$J9qn!P^L6#6drG78LGzAG=)ORd;i)U%EzmZ` zXc9FhLB40NbLE%dq?mdV^g>u)R3)Acje|Vlq!)W?{kzbKE1Uf!AkMK0^_E>c5 zl_6vA=s4_Sh^PcT&5T~9#0)`V0V&P>7Z4}?UMhk&N|g5V(2RbLDE`Lqll%9$JQ+rF z<--U-J^-GF39Qm`t!4@5N+9Zy$X(p)XAE5n6dhBsDsd_4B-(xMk=QSMLp1Fkch}~u zQI+1DCGN*1W!!@(7|jcEudy0VFy!O~$DZLRcpXd#7BCV3G{IqPEo4cQqLDPWK)V>D z0tT1_aR$AzJL zDtpB-%>Ial-CNu?`XFPQNlx7T4TkV`bW22>_q}tIJpPH}G2_3^w)fHS zukHc_G>yGprC*Aj3BJ(Er`e@sB?2Y~z_(n0-*|=chnjdm>x|N2Z(S;fPRT>57!pEj$K5suj+#5(1ID)c$i)0CJi z*!|g|l^w~oL>%@fVSOr*SOW~pqXzFxYF^JJR5r!1r;D>k3w2aorTcNieeqPv*T9xr zW6+prpcYRpKc$GXu)p6?mmBogToN>L~p}ioG z?OlA9H;>RNIag;MWv&J4D%~Svi*w3OpOw~rX=n>3P{i%5=FxYvwDQ@Z#m3R@9~AE{ z=`&W!?%S!P(RW2=rx^6efIu3C)smL^wVZ-Q231hu1(*laiO}&#Tjynck1PnJUXUED zp)RALAawiN#^Apce?4+Rpi?${>0;~XST1Ji6Q;KRQm+4(W&heCv=0dBV*s-U&8T!~ P1|FaC|C0H?l;nQ^lPXyk literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Notification_3.mp3 b/sound/pixelui-sounds/notifications-alerts/Notification_3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..6460cb2d321b4190a05e03430fe5c7a9d98c75f8 GIT binary patch literal 19486 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Notification_4.mp3 b/sound/pixelui-sounds/notifications-alerts/Notification_4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..fe4c619a1b0293f08fcc824c1b5f55f5804b85eb GIT binary patch literal 13216 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Notification_6.mp3 b/sound/pixelui-sounds/notifications-alerts/Notification_6.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..3ea05ed530818d907b6a49bfb5f5e4c77b0a841d GIT binary patch literal 36204 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 literal 0 HcmV?d00001 diff --git a/sound/pixelui-sounds/notifications-alerts/Notification_7.mp3 b/sound/pixelui-sounds/notifications-alerts/Notification_7.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c26d22329618ff476e5839704a03353fde19dcbd GIT binary patch literal 27427 zcmbrlWn5c9)9@XF2Py7u#hqepaV_rN;_g;`asO9D^C&WRc62fIur+hA{GWT>|K059!q02#?(F#AcUnHa z(^kvVNkvsd8AQYV)OdI$|EKfV|JUJp!NdE1N4R+eDQpA;Y8{~h7xlN9>j5s;RG z7Vjeu&g0jqID6Py*_uDj&Dn`Y@V^s5dz5HNDXaZI2!h8EYf~2oOLzCTE)J$XW~S!$ z|4&NvD3x(Cceb!~vZhfpbu)Ez2R;1`|NT7Zqx=a>Q&~;&KVbjm;TGcmA24n{S>gYk z;-i$8k55YQe+T}5c0gL1nlg{b&mJeDWa?!lAjHYb&B?>f{W$jD2Hc8w{HUE2MZDVKe z;P~|X^5*X0>B}D{Y5q7#K7pr;|277c|MYD6I%RCp|6KsLYCRwjx<|A&zXc2-ftG!n zsv5NND54R_pW8U^B*8>MM1cL+pNG^HUQkgK`=yV7$}iB05`20-m}ZlqLxmMtuNdRJyfL0 zK>Mi^IU3hrdmd|I0nb}XD>w=YL`OoWNgLhKj6calvMvvRQ_yX{pZL&GUnsClcv}SA z76&h0od5vv^NhD9n&6?HJ<2BTQdpk`qb7hos|L8$=s^Zyw9^_IUBF1KbIZ9e5-;Nt z!ca)*M54h2>Cw4fZgv`IBVvvU-Ui-Wsg5nJ{C`s)q&1Gd33*V_%-9!RHnmj&S1&5_ z{s0d+%GR|%Kedu8wRn^N)?jikTr$}PPKfhDG%rN+dMq|ScS}wkkCtF@b$@3$$7O6G z#U=JQ<&Ip)^4}{jEqWosVLnXC=oS63W|wj5O4pom<~*=#rxs#;HqPl25Gn}s6`ykXt2g7Gv@91v4SAdb zp}wuG8Q~Sk-DU9fG*hzAeOb_#qB__YhO?qm%kxRM56#S2&iBXGP*tc0Bk$C=Yd^yQ+e5O|#=Y6q92r+>tWK2gymK`}*6q=X?l#=&%co2R37Ozjt zamiid(KF4lld^Hb35d8)U|@l#wP{E|I7shluD|_9Lt0nD6~m`pzEoSbJ%czk@4tIk zx**|kueq$TRABd22<+}kam($Cbm*jss!Uv8B#*UP*Dt3O)^bC3WWyaIi1T3b=NPE9 zf;vDB2Xwms*M`r54_Ed<)t}-&`TI&;IUppMlDJ0iqTHNmBA=Ih9SY9C$hrh`*#%}J z(I;FAbSw-;;lX61-51DjWA%%NzJB{y`vty(pa%JIIj~kcV@y*>e-dg__yM?x{dup_ znysC0m^$Q9Mw*OqWdjfR*`xM1I@cv}_lMlRT zN1t@>Uv*~RB(RHz-B?cp!qk7i#sf2B%(OJjzo>4y8MU>&DR}i@YAP6?kULIFK6DQ* zL6diIB|P-{D`m~#UsU;bBTXT3%rr4)hA#s(`6Z9)RHvc_&|+sV3d3x(UKS}$V|^a7 zi@z#Pdt3JnTZjOEn�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 b1Hb{8YB-$8MFs#6{(X!j`X8|SUrqc!WQ9XP literal 0 HcmV?d00001 From d6bfc9c17c7dc79cbd92dfc265a03ca190b3f73e Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:06:17 +0100 Subject: [PATCH 105/155] feat: More sounds --- lua/pixelui/core/cl_sounds.lua | 24 +++++++++++++++++ lua/pixelui/elements/cl_frame.lua | 2 ++ lua/pixelui/elements/cl_navbar.lua | 2 ++ lua/pixelui/elements/cl_notification.lua | 34 ++++++++++++------------ lua/pixelui/elements/cl_sidebar.lua | 3 +++ 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/lua/pixelui/core/cl_sounds.lua b/lua/pixelui/core/cl_sounds.lua index 97e37b5..b2f234c 100644 --- a/lua/pixelui/core/cl_sounds.lua +++ b/lua/pixelui/core/cl_sounds.lua @@ -25,4 +25,28 @@ do PIXEL.PlaySound("buttons-navigation", "Collapse") end end + + function PIXEL.PlayNotify() + PIXEL.PlaySound("notifications-alerts", "Alert_2") + end + + local tabSounds = { + [1] = "Tab_1", + [2] = "Tab_2", + [3] = "Tab_3" + } + + function PIXEL.PlayChangeTab() + local randSound = math.random(1, 3) + PIXEL.PlaySound("buttons-navigation", tabSounds[randSound]) + end + + function PIXEL.PlayCancel() + PIXEL.PlaySound("errors-cancel", "Cancel_2") + end + + function PIXEL.PlayError(num) + if not num then num = 1 end + PIXEL.PlaySound("errors-cancel", "Cancel_" .. num) + end end \ No newline at end of file diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index e371929..ea93212 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -200,6 +200,8 @@ function PANEL:PerformLayout(w, h) end function PANEL:Open() + PIXEL.PlayButtonSound() + self:SetVisible(false) self:SetAlpha(0) self:SetVisible(true) self:AlphaTo(255, .1, 0) diff --git a/lua/pixelui/elements/cl_navbar.lua b/lua/pixelui/elements/cl_navbar.lua index 2d03e77..c45421f 100644 --- a/lua/pixelui/elements/cl_navbar.lua +++ b/lua/pixelui/elements/cl_navbar.lua @@ -26,6 +26,7 @@ function PANEL:Init() self:SetName("N/A") self:SetColor(PIXEL.Colors.Primary) self:SetClicky(false) + self:SetSounds(false) self.NormalCol = PIXEL.Colors.PrimaryText self.HoverCol = PIXEL.Colors.SecondaryText @@ -94,6 +95,7 @@ end function PANEL:SelectItem(id) local item = self.Items[id] if not item then return end + PIXEL.PlayChangeTab() if self.SelectedItem and self.SelectedItem == id then return end self.SelectedItem = id diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua index 401261c..7b4e7e3 100644 --- a/lua/pixelui/elements/cl_notification.lua +++ b/lua/pixelui/elements/cl_notification.lua @@ -1,7 +1,8 @@ local sc = PIXEL.Scale local Notices = {} -local notifAmount = 0 +local notifyAmount = 0 + surface.CreateFont("PIXEL.NotifyFont", { font = "Open Sans Bold", size = 25, @@ -11,22 +12,24 @@ surface.CreateFont("PIXEL.NotifyFont", { function PIXEL.Notify(text, type, length) + local ply = LocalPlayer() + if not ply.NotifyAmount then ply.NotifyAmount = 0 end + ply.NotifyAmount = ply.NotifyAmount + 1 local parent = nil if ( GetOverlayPanel ) then parent = GetOverlayPanel() end - local notif = vgui.Create("PIXEL.Notification", parent) notif:SetLength(math.max(length, 0)) notif:SetText(text) + table.insert(Notices, notif) - if notifAmount > 0 then - notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200) - (sc(50) * notifAmount)) + if ply.NotifyAmount > 0 then + notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200) - (sc(50) * ply.NotifyAmount)) else notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200)) end - table.insert(Notices, notif) end -hook.Add("Initialize", "NotificationOverride", function() +hook.Add("Initialize", "PIXEL.NotificationOverride", function() local oldNotification = notification.AddLegacy function notification.AddLegacy(text, type, length) @@ -42,8 +45,7 @@ local PANEL = {} function PANEL:SetText(txt) self.NotifyText = txt - surface.SetFont("PIXEL.NotifyFont") - self:SetWide(surface.GetTextSize(txt) + sc(25)) + self:SetWide(PIXEL.GetTextSize(txt, "PIXEL.NotifyFont") + sc(25)) end function PANEL:SetLength(sec) @@ -56,7 +58,6 @@ function PANEL:SetLength(sec) end function PANEL:Init() - notifAmount = notifAmount + 1 self:SetTall(sc(40)) self:SetWide(sc(40)) self.NotifyText = "" @@ -79,27 +80,26 @@ function PANEL:Paint(w, h) PIXEL.DrawSimpleText(self.NotifyText, "PIXEL.NotifyFont", w / 2, h / 2 - sc(1), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end -function PANEL:SetProgress(frac) -end - -function PANEL:KillSelf() -end - function PANEL:Open() self:SetAlpha(0) self:SetVisible(true) self:AlphaTo(255, .1, 0) + PIXEL.PlayNotify() end function PANEL:Close() + local ply = LocalPlayer() self:AlphaTo(0, .1, 0, function(anim, pnl) if not IsValid(pnl) then return end pnl:SetVisible(false) pnl:Remove() end) - notifAmount = notifAmount - 1 + ply.NotifyAmount = ply.NotifyAmount - 1 end +function PANEL:SetProgress(frac) end + +function PANEL:KillSelf() end -vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") \ No newline at end of file +vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index a0760f0..d0ab703 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -27,6 +27,7 @@ function PANEL:Init() self:SetName("N/A") self:SetDrawOutline(true) self:SetClicky(false) + self:SetSounds(false) self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) @@ -133,6 +134,8 @@ function PANEL:SelectItem(id) local item = self.Items[id] if not item then return end + PIXEL.PlayChangeTab() + if self.SelectedItem and self.SelectedItem == id then return end self.SelectedItem = id From 833765429dc3d690c9d1e3dc0f759cab56b17b3f Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:18:42 +0100 Subject: [PATCH 106/155] feat: even more ui sounds --- lua/pixelui/core/cl_sounds.lua | 15 ++++++++++++++- lua/pixelui/elements/cl_notification.lua | 17 ++++++++++++++++- lua/pixelui/elements/cl_text_entry_internal.lua | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/core/cl_sounds.lua b/lua/pixelui/core/cl_sounds.lua index b2f234c..b5e2967 100644 --- a/lua/pixelui/core/cl_sounds.lua +++ b/lua/pixelui/core/cl_sounds.lua @@ -17,6 +17,9 @@ do PIXEL.PlaySound("buttons-navigation", buttonSounds[randSound]) end + function PIXEL.PlayKeyType() + PIXEL.PlayButtonSound() + end function PIXEL.PlayExpand(type) if type == "open" then @@ -47,6 +50,16 @@ do function PIXEL.PlayError(num) if not num then num = 1 end - PIXEL.PlaySound("errors-cancel", "Cancel_" .. num) + PIXEL.PlaySound("errors-cancel", "Error_" .. num) + end + + function PIXEL.PlayComplete(num) + if not num then num = 1 end + PIXEL.PlaySound("complete-success", "Complete_" .. num) + end + + function PIXEL.PlaySuccess(num) + if not num then num = 1 end + PIXEL.PlaySound("complete-success", "Success_" .. num) end end \ No newline at end of file diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua index 7b4e7e3..2c15b54 100644 --- a/lua/pixelui/elements/cl_notification.lua +++ b/lua/pixelui/elements/cl_notification.lua @@ -20,6 +20,7 @@ function PIXEL.Notify(text, type, length) local notif = vgui.Create("PIXEL.Notification", parent) notif:SetLength(math.max(length, 0)) notif:SetText(text) + notif:SetType(type) table.insert(Notices, notif) if ply.NotifyAmount > 0 then @@ -48,6 +49,21 @@ function PANEL:SetText(txt) self:SetWide(PIXEL.GetTextSize(txt, "PIXEL.NotifyFont") + sc(25)) end +function PANEL:SetType(type) + self.NotifyType = type + if type == NOTIFY_GENERIC then + PIXEL.PlayNotify() + elseif type == NOTIFY_ERROR then + PIXEL.PlayError(1) + elseif type == NOTIFY_UNDO then + PIXEL.PlayError(2) + elseif type == NOTIFY_HINT then + PIXEL.PlaySuccess(1) + elseif type == NOTIFY_CLEANUP then + PIXEL.PlayError(5) + end +end + function PANEL:SetLength(sec) sec = sec + .2 self.Length = sec @@ -84,7 +100,6 @@ function PANEL:Open() self:SetAlpha(0) self:SetVisible(true) self:AlphaTo(255, .1, 0) - PIXEL.PlayNotify() end function PANEL:Close() diff --git a/lua/pixelui/elements/cl_text_entry_internal.lua b/lua/pixelui/elements/cl_text_entry_internal.lua index a73130f..5267c73 100644 --- a/lua/pixelui/elements/cl_text_entry_internal.lua +++ b/lua/pixelui/elements/cl_text_entry_internal.lua @@ -137,6 +137,7 @@ function PANEL:UpdateFromMenu() end function PANEL:OnTextChanged(noMenuRemoval) + PIXEL.PlayKeyType() self.HistoryPos = 0 if self:GetUpdateOnType() then From c60922071c130f8e3ef2328383c8bbdff23ead13 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:20:56 +0100 Subject: [PATCH 107/155] refactor: disabling sounds --- lua/pixelui/core/cl_sounds.lua | 2 ++ lua/pixelui/core/{sh_confetti.lua => sv_confetti.lua} | 9 +-------- lua/pixelui/sh_config.lua | 5 +++++ 3 files changed, 8 insertions(+), 8 deletions(-) rename lua/pixelui/core/{sh_confetti.lua => sv_confetti.lua} (75%) diff --git a/lua/pixelui/core/cl_sounds.lua b/lua/pixelui/core/cl_sounds.lua index b5e2967..c9ea43c 100644 --- a/lua/pixelui/core/cl_sounds.lua +++ b/lua/pixelui/core/cl_sounds.lua @@ -1,5 +1,7 @@ +PIXEL = PIXEL or {} do function PIXEL.PlaySound(type, sound) + if PIXEL.DisableUISounds then return end local soundPath = "pixelui-sounds/" .. type .. "/" .. sound .. ".mp3" if not file.Exists("sound/" .. soundPath, "GAME") then print(soundPath, "bad") return end diff --git a/lua/pixelui/core/sh_confetti.lua b/lua/pixelui/core/sv_confetti.lua similarity index 75% rename from lua/pixelui/core/sh_confetti.lua rename to lua/pixelui/core/sv_confetti.lua index 30398fb..91b00b7 100644 --- a/lua/pixelui/core/sh_confetti.lua +++ b/lua/pixelui/core/sv_confetti.lua @@ -1,4 +1,4 @@ -if SERVER then +do util.AddNetworkString("PIXEL.SpawnConfetti") util.PrecacheSound("pixel_confetti.mp3") function PIXEL.SpawnConfetti(ply) @@ -11,11 +11,4 @@ if SERVER then net.Receive("PIXEL.SpawnConfetti", function(_, ply) PIXEL.SpawnConfetti(ply) end) -end - -if CLIENT then - function PIXEL.SpawnConfetti() - net.Start("PIXEL.SpawnConfetti") - net.SendToServer() - end end \ No newline at end of file diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index e92d865..96ec6c0 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -30,6 +30,11 @@ PIXEL.OverrideDermaMenus = 0 ]] PIXEL.DisableNotification = false +--[[ + Should we disable The UI Sounds? +]] +PIXEL.DisableUISounds = false + --[[ The Imgur ID of the progress image you want to appear when Imgur content is loading. ]] From 20c928c595d652a2f0836a617badbcfea5c8e9b5 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:25:05 +0100 Subject: [PATCH 108/155] refactor: remove useless code --- lua/pixelui/core/sv_confetti.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lua/pixelui/core/sv_confetti.lua b/lua/pixelui/core/sv_confetti.lua index 91b00b7..bfcfba5 100644 --- a/lua/pixelui/core/sv_confetti.lua +++ b/lua/pixelui/core/sv_confetti.lua @@ -7,8 +7,4 @@ do util.Effect("pixel_confetti", effectData) sound.Play("pixelui-sounds/pixel_confetti.mp3", ply:GetPos()) end - - net.Receive("PIXEL.SpawnConfetti", function(_, ply) - PIXEL.SpawnConfetti(ply) - end) end \ No newline at end of file From 95eb3e1a2986f502435a7c18ee64ddc03c322111 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:33:53 +0100 Subject: [PATCH 109/155] refactor: update autorun info --- lua/autorun/sh_pixelui_loader.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 1155841..7c873e2 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -55,16 +55,16 @@ hook.Run("PIXEL.UI.FullyLoaded") if CLIENT then return end -resource.AddWorkshop("2468112758") +resource.AddWorkshop("2825396224") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://raw.githubusercontent.com/TomDotBat/pixel-ui/master/VERSION", function(body) + http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) - MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/TomDotBat/pixel-ui/releases\n") + MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") MsgC(red, "New version: " .. body .. "\n") return From 5b7c64956500044bd7986d64b2be94adefb4e64b Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 25 Jun 2022 00:32:22 +0100 Subject: [PATCH 110/155] feat: Feature showcase menu --- lua/pixelui/elements/cl_text_button.lua | 4 +- lua/pixelui/test/cl_menu.lua | 84 +++++++++++++++++++++++ lua/pixelui/test/pages/cl_avatar.lua | 31 +++++++++ lua/pixelui/test/pages/cl_buttons.lua | 72 +++++++++++++++++++ lua/pixelui/test/pages/cl_navigation.lua | 21 ++++++ lua/pixelui/test/pages/cl_other.lua | 42 ++++++++++++ lua/pixelui/test/pages/cl_scrollpanel.lua | 23 +++++++ lua/pixelui/test/pages/cl_text.lua | 34 +++++++++ 8 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 lua/pixelui/test/cl_menu.lua create mode 100644 lua/pixelui/test/pages/cl_avatar.lua create mode 100644 lua/pixelui/test/pages/cl_buttons.lua create mode 100644 lua/pixelui/test/pages/cl_navigation.lua create mode 100644 lua/pixelui/test/pages/cl_other.lua create mode 100644 lua/pixelui/test/pages/cl_scrollpanel.lua create mode 100644 lua/pixelui/test/pages/cl_text.lua diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index e4ee059..5db7b63 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -50,7 +50,9 @@ function PANEL:PaintExtra(w, h) return end - if self:GetClicky() then + if self.ClickyMove and self:GetClicky() then + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2 - PIXEL.Scale(2)) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + elseif self:GetClicky() then PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(2), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) else PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) diff --git a/lua/pixelui/test/cl_menu.lua b/lua/pixelui/test/cl_menu.lua new file mode 100644 index 0000000..8c54147 --- /dev/null +++ b/lua/pixelui/test/cl_menu.lua @@ -0,0 +1,84 @@ +PIXEL = PIXEL or {} +local PANEL = {} + +function PANEL:Init() + self:SetSize(PIXEL.Scale(900), PIXEL.Scale(550)) + self:Center() + self:MakePopup() + self:SetTitle("PIXEL Test") + + self.Sidebar = self:CreateSidebar("PIXEL.Test.Avatar", "8bKjn4t") + + self.Sidebar:AddItem("PIXEL.Test.Avatar", "Avatar", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Avatar") + end) + self.Sidebar:AddItem("PIXEL.Test.Buttons", "Buttons", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Buttons") + end) + self.Sidebar:AddItem("PIXEL.Test.Navigation", "Navigation", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Navigation") + end) + self.Sidebar:AddItem("PIXEL.Test.ScrollPanel", "ScrollPanel", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.ScrollPanel") + end) + self.Sidebar:AddItem("PIXEL.Test.Text", "Text", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Text") + end) + self.Sidebar:AddItem("PIXEL.Test.Other", "Other", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Other") + end) +end + +function PANEL:ChangeTab(panel) + if not self.SideBar:IsMouseInputEnabled() then return end + + if not IsValid(self.ContentPanel) then + self.ContentPanel = vgui.Create(panel, self) + self.ContentPanel:Dock(FILL) + self.ContentPanel:InvalidateLayout(true) + + function self.ContentPanel.Think(s) + if not self.DragThink then return end + if self:DragThink(self) then return end + if self:SizeThink(self, s) then return end + self:SetCursor("arrow") + + if self.y < 0 then + self:SetPos(self.x, 0) + end + end + + function self.ContentPanel.OnMousePressed() + self:OnMousePressed() + end + + function self.ContentPanel.OnMouseReleased() + self:OnMouseReleased() + end + + return + end + + self.SideBar:SetMouseInputEnabled(false) + + self.ContentPanel:AlphaTo(0, .15, 0, function(anim, pnl) + self.ContentPanel:Remove() + self.ContentPanel = vgui.Create(panel, self) + self.ContentPanel:Dock(FILL) + self.ContentPanel:InvalidateLayout(true) + + self.ContentPanel:AlphaTo(255, .15, 0, function(anim2, pnl2) + self.SideBar:SetMouseInputEnabled(true) + end) + end) +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.Main", PANEL, "PIXEL.Frame") + +concommand.Add("pixel_test", function() + vgui.Create("PIXEL.Test.Main") +end) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_avatar.lua b/lua/pixelui/test/pages/cl_avatar.lua new file mode 100644 index 0000000..41ced19 --- /dev/null +++ b/lua/pixelui/test/pages/cl_avatar.lua @@ -0,0 +1,31 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} +PIXEL.GenerateFont(50) + +function PANEL:Init() + self.Avatar = vgui.Create("PIXEL.Avatar", self) + self.Avatar:SetPlayer(LocalPlayer(), sc(200)) + self.Avatar:SetRounding(sc(8)) + self.Avatar:SetDrawOnTop(true) + self.Avatar:SetSize(sc(200), sc(200)) + self.Avatar:SetPos(sc(250), sc(100)) + + self.Label = vgui.Create("PIXEL.Label", self) + self.Label:SetText("Hey " .. LocalPlayer():Nick() .. "!") + self.Label:SetWide(sc(500)) + self.Label:SetTall(sc(100)) + self.Label:SetFont("PIXEL.Font.Size50") + self.Label:SetPos(sc(230), sc(300)) + + +end + +function PANEL:PaintMore(w,h) + +end + +function PANEL:LayoutContent(w,h) +end + +vgui.Register("PIXEL.Test.Avatar", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_buttons.lua b/lua/pixelui/test/pages/cl_buttons.lua new file mode 100644 index 0000000..9f2ec89 --- /dev/null +++ b/lua/pixelui/test/pages/cl_buttons.lua @@ -0,0 +1,72 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + + +function PANEL:Init() + self.Button = vgui.Create("PIXEL.Button", self) + self.Button:Dock(TOP) + self.Button:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.Button:SetTall(sc(50)) + self.Button.DoClick = function() + notification.AddLegacy("Normal Button!", NOTIFY_GENERIC, 5) + end + + self.ClickyButton = vgui.Create("PIXEL.Button", self) + self.ClickyButton:Dock(TOP) + self.ClickyButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.ClickyButton:SetTall(sc(50)) + self.ClickyButton:SetClicky(true) + self.ClickyButton.DoClick = function() + notification.AddLegacy("Normal Clicky Button!", NOTIFY_GENERIC, 5) + end + + self.ClickyTextButton = vgui.Create("PIXEL.TextButton", self) + self.ClickyTextButton:Dock(TOP) + self.ClickyTextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.ClickyTextButton:SetTall(sc(50)) + self.ClickyTextButton:SetText("Clicky Button!") + self.ClickyTextButton.DoClick = function() + notification.AddLegacy("Clicky Text Button!", NOTIFY_GENERIC, 5) + end + + self.TextButton = vgui.Create("PIXEL.TextButton", self) + self.TextButton:Dock(TOP) + self.TextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.TextButton:SetTall(sc(50)) + self.TextButton:SetText("Non Clicky Button!") + self.TextButton:SetClicky(false) + self.TextButton.DoClick = function() + notification.AddLegacy("Non Clicky Text button!", NOTIFY_GENERIC, 5) + end + + self.NoSoundButton = vgui.Create("PIXEL.TextButton", self) + self.NoSoundButton:Dock(TOP) + self.NoSoundButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.NoSoundButton:SetTall(sc(50)) + self.NoSoundButton:SetText("No Sound Clicky Button!") + self.NoSoundButton:SetSounds(false) + self.NoSoundButton.DoClick = function() + notification.AddLegacy("No Sound Button!", NOTIFY_GENERIC, 5) + end + + + self.ImgurButton = vgui.Create("PIXEL.ImgurButton", self) + self.ImgurButton:Dock(TOP) + self.ImgurButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.ImgurButton:SetSize(sc(50), sc(50)) + self.ImgurButton:SetImgurID("8bKjn4t") + self.ImgurButton:SetNormalColor(PIXEL.Colors.PrimaryText) + self.ImgurButton:SetHoverColor(PIXEL.Colors.Negative) + self.ImgurButton:SetClickColor(PIXEL.Colors.Positive) + self.ImgurButton:SetDisabledColor(PIXEL.Colors.DisabledText) + self.ImgurButton.DoClick = function() + notification.AddLegacy("Imgur Button!", NOTIFY_GENERIC, 5) + end +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.Buttons", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_navigation.lua b/lua/pixelui/test/pages/cl_navigation.lua new file mode 100644 index 0000000..c3b1aa9 --- /dev/null +++ b/lua/pixelui/test/pages/cl_navigation.lua @@ -0,0 +1,21 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + +function PANEL:Init() + self.Navbar = vgui.Create("PIXEL.Navbar", self) + self.Navbar:Dock(TOP) + self.Navbar:SetTall(sc(50)) + self.Navbar:AddItem("test1", "Test 1", function() notification.AddLegacy("Clicked 1!", NOTIFY_GENERIC, 5) end, 1, PIXEL.Colors.Gold) + self.Navbar:AddItem("test2", "Test 2", function() notification.AddLegacy("Clicked 2!", NOTIFY_GENERIC, 5) end, 2, PIXEL.Colors.Diamond) + self.Navbar:AddItem("test3", "Test 3", function() notification.AddLegacy("Clicked 3!", NOTIFY_GENERIC, 5) end, 3, PIXEL.Colors.Silver) + self.Navbar:AddItem("test4", "Test 4", function() notification.AddLegacy("Clicked 4!", NOTIFY_GENERIC, 5) end, 4, PIXEL.Colors.Bronze) + self.Navbar:AddItem("test5", "Test 5", function() notification.AddLegacy("Clicked 5!", NOTIFY_GENERIC, 5) end, 5, PIXEL.Colors.Primary) + + +end + +function PANEL:PaintMore(w,h) +end + +vgui.Register("PIXEL.Test.Navigation", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_other.lua b/lua/pixelui/test/pages/cl_other.lua new file mode 100644 index 0000000..1553641 --- /dev/null +++ b/lua/pixelui/test/pages/cl_other.lua @@ -0,0 +1,42 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + +PIXEL.GenerateFont(25) + +function PANEL:Init() + self.Category = vgui.Create("PIXEL.Category", self) + self.Category:Dock(TOP) + self.Category:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.Category:SetTitle("Categorys!") + + self.Slider = vgui.Create("PIXEL.Slider", self) + self.Slider:Dock(TOP) + self.Slider:DockMargin(sc(50), sc(10), sc(50), sc(10)) + + self.LabelledCheckbox = vgui.Create("PIXEL.LabelledCheckbox", self) + self.LabelledCheckbox:Dock(TOP) + self.LabelledCheckbox:DockMargin(sc(50), sc(10), sc(50), sc(10)) + self.LabelledCheckbox:SetText("Labelled Checkbox!") + self.LabelledCheckbox:SetFont("PIXEL.Font.Size25") + + self.ComboBox = vgui.Create("PIXEL.ComboBox", self) + self.ComboBox:Dock(TOP) + self.ComboBox:DockMargin(sc(50), sc(10), sc(50), sc(10)) + self.ComboBox:SetSizeToText(false) + self.ComboBox:AddChoice("Choice 1", "Choice 1", "Choice 1") + self.ComboBox:AddChoice("Choice 2", "Choice 2", "Choice 2") + self.ComboBox:AddChoice("Choice 3", "Choice 3", "Choice 3") + self.ComboBox:AddChoice("Choice 4", "Choice 4", "Choice 4") + self.ComboBox:AddChoice("Choice 5", "Choice 5", "Choice 5") + + self.ColorPicker = vgui.Create("PIXEL.ColorPicker", self) + self.ColorPicker:Dock(FILL) + self.ColorPicker:DockMargin(sc(50), sc(10), sc(50), sc(10)) +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.Other", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_scrollpanel.lua b/lua/pixelui/test/pages/cl_scrollpanel.lua new file mode 100644 index 0000000..35c7c59 --- /dev/null +++ b/lua/pixelui/test/pages/cl_scrollpanel.lua @@ -0,0 +1,23 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + +function PANEL:Init() + self.ScrollPanel = vgui.Create("PIXEL.ScrollPanel", self) + self.ScrollPanel:Dock(FILL) + self.ScrollPanel:DockMargin(0, 0, 0, 0) + + for i = 0, 250 do + self.ClickyTextButton = vgui.Create("PIXEL.TextButton", self.ScrollPanel) + self.ClickyTextButton:Dock(TOP) + self.ClickyTextButton:DockMargin(sc(5), sc(5), sc(5), sc(5)) + self.ClickyTextButton:SetTall(sc(50)) + self.ClickyTextButton:SetText("Clicky Button!") + end +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.ScrollPanel", PANEL) \ No newline at end of file diff --git a/lua/pixelui/test/pages/cl_text.lua b/lua/pixelui/test/pages/cl_text.lua new file mode 100644 index 0000000..5eae5a7 --- /dev/null +++ b/lua/pixelui/test/pages/cl_text.lua @@ -0,0 +1,34 @@ +PIXEL = PIXEL or {} +local sc = PIXEL.Scale +local PANEL = {} + +function PANEL:Init() + self.TextEntry = vgui.Create("PIXEL.TextEntry", self) + self.TextEntry:Dock(TOP) + self.TextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) + self.TextEntry:SetTall(sc(35)) + self.TextEntry:SetPlaceholderText("Placeholder Text!") + + self.BadValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) + self.BadValidatedTextEntry:Dock(TOP) + self.BadValidatedTextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) + self.BadValidatedTextEntry:SetPlaceholderText("Bad Text!") + + function self.BadValidatedTextEntry:IsTextValid(text) + return false, "Bad Text!" + end + + self.GoodValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) + self.GoodValidatedTextEntry:Dock(TOP) + self.GoodValidatedTextEntry:DockMargin(sc(20), sc(0), sc(20), sc(20)) + self.GoodValidatedTextEntry:SetPlaceholderText("Good Text!") + function self.GoodValidatedTextEntry:IsTextValid(text) + return true, "Good Text!" + end +end + +function PANEL:PaintMore(w,h) + +end + +vgui.Register("PIXEL.Test.Text", PANEL) \ No newline at end of file From 6e616e32360580993a5ed376fecb5879da2fa39e Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 25 Jun 2022 12:52:27 +0100 Subject: [PATCH 111/155] stuff --- .github/workflows/retype-action.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/retype-action.yml diff --git a/.github/workflows/retype-action.yml b/.github/workflows/retype-action.yml new file mode 100644 index 0000000..5d4c449 --- /dev/null +++ b/.github/workflows/retype-action.yml @@ -0,0 +1,21 @@ +name: Publish Retype powered website to GitHub Pages +on: + workflow_dispatch: + push: + branches: + - wiki + +jobs: + publish: + name: Publish to retype branch + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: retypeapp/action-build@latest + + - uses: retypeapp/action-github-pages@latest + with: + update-branch: true \ No newline at end of file From ca6d309fd3d4d1f0b102dea4c13170e1676ea451 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 25 Jun 2022 12:54:31 +0100 Subject: [PATCH 112/155] Revert "stuff" This reverts commit f324e311e3b79c42f007230892760b30b95b118e. --- .github/workflows/retype-action.yml | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 .github/workflows/retype-action.yml diff --git a/.github/workflows/retype-action.yml b/.github/workflows/retype-action.yml deleted file mode 100644 index 5d4c449..0000000 --- a/.github/workflows/retype-action.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Publish Retype powered website to GitHub Pages -on: - workflow_dispatch: - push: - branches: - - wiki - -jobs: - publish: - name: Publish to retype branch - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - uses: retypeapp/action-build@latest - - - uses: retypeapp/action-github-pages@latest - with: - update-branch: true \ No newline at end of file From ae1f59dbbac8243d5e124e7401f45d1448715045 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 25 Jun 2022 17:31:59 +0100 Subject: [PATCH 113/155] refactor: change text position --- lua/pixelui/elements/cl_text_button.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index 5db7b63..4838d5f 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -51,9 +51,9 @@ function PANEL:PaintExtra(w, h) end if self.ClickyMove and self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2 - PIXEL.Scale(2)) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2 - PIXEL.Scale(4)) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) elseif self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(2), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(4), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) else PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) end From b768aaf92cbf6d6f812d80a50c62a723b1c30450 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 26 Jun 2022 15:05:58 +0100 Subject: [PATCH 114/155] feat: Allow servers to have custom themes without breaking shit --- lua/autorun/sh_pixelui_loader.lua | 23 ++++ lua/pixelui/cl_themes.lua | 30 +++++ lua/pixelui/core/cl_color.lua | 4 + lua/pixelui/core/cl_theme.lua | 52 ++++++++ lua/pixelui/core/cl_themes.lua | 149 +++++++++++++++++++++++ lua/pixelui/core/sh_theme.lua | 52 -------- lua/pixelui/elements/cl_button.lua | 26 ---- lua/pixelui/elements/cl_notification.lua | 2 +- lua/pixelui/panels/cl_themeeditor.lua | 30 ++++- lua/pixelui/sh_config.lua | 147 +--------------------- 10 files changed, 285 insertions(+), 230 deletions(-) create mode 100644 lua/pixelui/cl_themes.lua create mode 100644 lua/pixelui/core/cl_theme.lua create mode 100644 lua/pixelui/core/cl_themes.lua delete mode 100644 lua/pixelui/core/sh_theme.lua diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 7c873e2..8ca131b 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -19,6 +19,29 @@ PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} PIXEL.UI.Version = "1.2.3" +PIXEL.Colors = { + Background = Color(22, 22, 22), + Header = Color(28, 28, 28), + SecondaryHeader = Color(15, 15, 15), + Scroller = Color(61, 61, 61), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(220, 220, 220), + DisabledText = Color(40, 40, 40), + + Primary = Color(77, 79, 199), + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + function PIXEL.LoadDirectory(path) local files, folders = file.Find(path .. "/*", "LUA") diff --git a/lua/pixelui/cl_themes.lua b/lua/pixelui/cl_themes.lua new file mode 100644 index 0000000..690f18b --- /dev/null +++ b/lua/pixelui/cl_themes.lua @@ -0,0 +1,30 @@ +PIXEL.Themes = PIXEL.Themes or {} + +--[[ + Want to make custom themes for your server? + Here is a basic example of how to do it: +]] +--[[ +PIXEL.Themes["Your Theme Name"] = { + Background = Color(22, 22, 22), -- UI Background Color + Header = Color(28, 28, 28), -- UI Header Color + SecondaryHeader = Color(43, 43, 43), -- UI Secondary Header Color + Scroller = Color(61, 61, 61), -- UI Scroller Color + + PrimaryText = Color(255, 255, 255), -- UI Primary Text Color + SecondaryText = Color(220, 220, 220), -- UI Secondary Text Color + DisabledText = Color(40, 40, 40), -- UI Disabled Text Color + + Primary = Color(74, 61, 255), -- Primary Server Color + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} +]] diff --git a/lua/pixelui/core/cl_color.lua b/lua/pixelui/core/cl_color.lua index 4fdb710..456c0e4 100644 --- a/lua/pixelui/core/cl_color.lua +++ b/lua/pixelui/core/cl_color.lua @@ -149,6 +149,10 @@ function PIXEL.IsColorEqualTo(from, to) return from.r == to.r and from.g == to.g and from.b == to.b and from.a == to.a end +function PIXEL.SetColorTransparency(color, transparency) + return Color(color.r, color.g, color.b, transparency) +end + local colorMeta = FindMetaTable("Color") colorMeta.Copy = PIXEL.CopyColor colorMeta.IsLight = PIXEL.IsColorLight diff --git a/lua/pixelui/core/cl_theme.lua b/lua/pixelui/core/cl_theme.lua new file mode 100644 index 0000000..6a76494 --- /dev/null +++ b/lua/pixelui/core/cl_theme.lua @@ -0,0 +1,52 @@ +if not file.Exists("pixel/themes/", "DATA") then + file.CreateDir("pixel/themes/") +end + +function PIXEL.SetTheme(theme, cross) + print(theme, cross) + if not cross then + local ip = game.GetIPAddress() + ip = ip:gsub(":", "-") + ip = string.Replace(ip, ".", "_") + + file.CreateDir("pixel/themes/" .. ip .. "/") + file.Write("pixel/themes/" .. ip .. "/theme.txt", theme) + else + file.Write("pixel/themes/theme.txt", theme) + end + + if PIXEL.Themes[theme] then + PIXEL.Colors = PIXEL.Themes[theme] + local ply = LocalPlayer() + ply.PIXELTheme = theme + else + PIXEL.Colors = PIXEL.Themes["Dark"] + return false + end +end + +hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() + local ply = LocalPlayer() + local ip = game.GetIPAddress() + ip = ip:gsub(":", "-") + ip = string.Replace(ip, ".", "_") + if file.Exists("pixel/themes/" .. ip .. "/theme.txt", "DATA") then + local theme = file.Read("pixel/" .. ip .. "/theme.txt", "DATA") + PIXEL.Colors = PIXEL.Themes[theme] + ply.PIXELTheme = theme + return + end + + if not file.Exists("pixel/themes/theme.txt", "DATA") then + PIXEL.Colors = PIXEL.Themes["Dark"] + return + end + + local theme = file.Read("pixel/theme.txt", "DATA") + PIXEL.Colors = PIXEL.Themes[theme] + ply.PIXELTheme = theme +end) + +concommand.Add("pixel_reset_theme", function(ply, cmd, args) + PIXEL.Colors = PIXEL.Themes["Dark"] +end) \ No newline at end of file diff --git a/lua/pixelui/core/cl_themes.lua b/lua/pixelui/core/cl_themes.lua new file mode 100644 index 0000000..874e28a --- /dev/null +++ b/lua/pixelui/core/cl_themes.lua @@ -0,0 +1,149 @@ +PIXEL = PIXEL or {} +PIXEL.Themes = PIXEL.Themes or {} +PIXEL.DefaultThemes = PIXEL.DefaultThemes or { + "Dark", "Light", "GitHubDark", "NightOwl", "DiscordDark", "DiscordLight" +} + +PIXEL.Themes["Dark"] = { + included = true, + Background = Color(22, 22, 22), + Header = Color(28, 28, 28), + SecondaryHeader = Color(43, 43, 43), + Scroller = Color(61, 61, 61), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(220, 220, 220), + DisabledText = Color(40, 40, 40), + + Primary = Color(74, 61, 255), + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["Light"] = { + included = true, + Background = PIXEL.HexToColor("#F7F8FA"), + Header = PIXEL.HexToColor("#edf1f5"), + SecondaryHeader = PIXEL.HexToColor("#DFE1E4"), + Scroller = PIXEL.HexToColor("#edf1f5"), + + PrimaryText = PIXEL.HexToColor("#292D31"), + SecondaryText = PIXEL.HexToColor("#808080"), + DisabledText = PIXEL.HexToColor("#9ba0a3"), + + Primary = Color(74, 61, 255), + Disabled = PIXEL.HexToColor("#9ba0a3"), + Positive = PIXEL.HexToColor("#79CB60"), + Negative = PIXEL.HexToColor("#d73a49"), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["GitHubDark"] = { + included = true, + Background = PIXEL.HexToColor("#24292e"), + Header = PIXEL.HexToColor("#2f363d"), + SecondaryHeader = PIXEL.HexToColor("#2b3036"), + Scroller = PIXEL.HexToColor("#2f363d"), + + PrimaryText = Color(74, 61, 255), + SecondaryText = PIXEL.HexToColor("#c9d1d9"), + DisabledText = PIXEL.HexToColor("#39414a"), + + Primary = PIXEL.HexToColor("#b392f0"), + Disabled = PIXEL.HexToColor("#6a737d"), + Positive = PIXEL.HexToColor("#85e89d"), + Negative = PIXEL.HexToColor("#f97583"), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["NightOwl"] = { + included = true, + Background = PIXEL.HexToColor("#011627"), -- Background + Header = PIXEL.HexToColor("#0b2942"), -- Seccond Background + SecondaryHeader = PIXEL.HexToColor("#13344f"), -- Active + Scroller = PIXEL.HexToColor("#0b2942"), -- Seccond Background + + PrimaryText = PIXEL.HexToColor("#FBFBFB"), -- Text + SecondaryText = PIXEL.HexToColor("#d9d9d9"), -- Buttons + DisabledText = PIXEL.HexToColor("#697098"), -- Disabled + + Primary = Color(74, 61, 255), + Disabled = PIXEL.HexToColor("#697098"), -- Disabled + Positive = PIXEL.HexToColor("#addb67"), -- Green + Negative = PIXEL.HexToColor("#ff6363"), -- Red + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["DiscordDark"] = { + included = true, + Background = Color(54, 57, 63), + Header = Color(47, 49, 54), + SecondaryHeader = Color(51, 54, 59), + Scroller = Color(32, 34, 37), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(185, 187, 190), + DisabledText = Color(40, 40, 40), + + Primary = Color(88, 101, 242), + Disabled = Color(114, 118, 125), + Positive = Color(87, 242, 135), + Negative = Color(237, 66, 69), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} + +PIXEL.Themes["DiscordLight"] = { + included = true, + Background = Color(255, 255, 255), + Header = Color(242, 243, 245), + SecondaryHeader = Color(220, 223, 227), + Scroller = Color(204, 204, 204), + + PrimaryText = Color(6, 6, 7), + SecondaryText = Color(79, 86, 96), + DisabledText = Color(79, 86, 96), + + Primary = Color(88, 101, 242), + Disabled = Color(79, 86, 96), + Positive = Color(87, 242, 135), + Negative = Color(237, 66, 69), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} \ No newline at end of file diff --git a/lua/pixelui/core/sh_theme.lua b/lua/pixelui/core/sh_theme.lua deleted file mode 100644 index 5bb9ca5..0000000 --- a/lua/pixelui/core/sh_theme.lua +++ /dev/null @@ -1,52 +0,0 @@ -PIXEL.Colors = { - Background = Color(22, 22, 22), - Header = Color(28, 28, 28), - SecondaryHeader = Color(15, 15, 15), - Scroller = Color(61, 61, 61), - - PrimaryText = Color(255, 255, 255), - SecondaryText = Color(220, 220, 220), - DisabledText = Color(40, 40, 40), - - Primary = Color(77, 79, 199), - Disabled = Color(180, 180, 180), - Positive = Color(68, 235, 124), - Negative = Color(235, 68, 68), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes = PIXEL.Themes or {} - -function PIXEL.SetTheme(theme) - file.Write("pixel/theme.txt", theme) - - if PIXEL.Themes[theme] then - PIXEL.Colors = PIXEL.Themes[theme] - if CLIENT then - local ply = LocalPlayer() - ply.PIXELTheme = theme - end - else - PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] - return false - end -end - -hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() - if !file.Exists("pixel/theme.txt", "DATA") then - PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] - return - end - local theme = file.Read("pixel/theme.txt", "DATA") - PIXEL.Colors = PIXEL.Themes[theme] -end) - -concommand.Add("pixel_reset_theme", function(ply, cmd, args) - PIXEL.Colors = PIXEL.Themes[PIXEL.DefaultTheme] -end) \ No newline at end of file diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index 0ae64f9..bfc75b0 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -176,29 +176,3 @@ function PANEL:DoRightClick() end function PANEL:DoMiddleClick() end vgui.Register("PIXEL.Button", PANEL, "Panel") - -concommand.Add("test", function() - local pnl = vgui.Create("PIXEL.Frame") - pnl:SetTitle("Test") - pnl:SetSize(650, 350) - pnl:Center() - local btn1 = pnl:Add("PIXEL.Button") - btn1:SetClicky(true) - btn1:SetSize(480, 200) - btn1:SetPos(10, 50) - - local btn2 = pnl:Add("PIXEL.Button") - btn2:SetClicky(true) - btn2:SetSize(100, 25) - btn2:SetPos(10, 275) - - local btn3 = pnl:Add("PIXEL.Button") - btn3:SetClicky(true) - btn3:SetSize(50, 200) - btn3:SetPos(525, 50) - - local btn4 = pnl:Add("PIXEL.Button") - btn4:SetClicky(true) - btn4:SetSize(300, 30) - btn4:SetPos(125, 275) -end) \ No newline at end of file diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua index 2c15b54..857f00d 100644 --- a/lua/pixelui/elements/cl_notification.lua +++ b/lua/pixelui/elements/cl_notification.lua @@ -91,7 +91,7 @@ function PANEL:Paint(w, h) local shouldDraw = not (LocalPlayer and IsValid(LocalPlayer()) and IsValid(LocalPlayer():GetActiveWeapon()) and LocalPlayer():GetActiveWeapon():GetClass() == "gmod_camera") if not shouldDraw then return end - PIXEL.DrawRoundedBoxEx(sc(6), sc(5), 0, w, h, Color(0, 0, 0, 200), false, true, false, true) + PIXEL.DrawRoundedBoxEx(sc(6), sc(5), 0, w, h, PIXEL.SetColorTransparency(PIXEL.Colors.Background, 200), false, true, false, true) PIXEL.DrawRoundedBoxEx(sc(6), 0, 0, sc(5), h, PIXEL.Colors.Primary, true, false, true, false) PIXEL.DrawSimpleText(self.NotifyText, "PIXEL.NotifyFont", w / 2, h / 2 - sc(1), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end diff --git a/lua/pixelui/panels/cl_themeeditor.lua b/lua/pixelui/panels/cl_themeeditor.lua index b846a2e..46a2396 100644 --- a/lua/pixelui/panels/cl_themeeditor.lua +++ b/lua/pixelui/panels/cl_themeeditor.lua @@ -1,8 +1,8 @@ local PANEL = {} local sc = PIXEL.Scale - +PIXEL.GenerateFont(18) function PANEL:Init() - self:SetSize(sc(200), sc(175)) + self:SetSize(sc(200), sc(200)) self:MakePopup() self:Center() @@ -11,7 +11,7 @@ function PANEL:Init() local panW, panH = self:GetSize() self.DropDown = self:Add("PIXEL.ComboBox") - self.DropDown:SetPos((panW / 2) - (self.DropDown:GetWide() / 2), panH / 2 - sc(15)) + self.DropDown:SetPos((panW / 2) - (self.DropDown:GetWide() / 2), panH / 2 - sc(35)) self.DropDown:SetSizeToText(false) for k, v in pairs(PIXEL.Themes) do @@ -19,9 +19,29 @@ function PANEL:Init() end self.DropDown:SetValue(LocalPlayer().PIXELTheme) - local themeSelected + + self.SaveCross = self:Add("PIXEL.LabelledCheckbox") + self.SaveCross:SetPos((panW / 2) - (self.SaveCross:GetWide() / 2) - sc(50), panH / 2 + sc(10)) + self.SaveCross:SetText("Save Across Servers?") + self.SaveCross:SetFont("PIXEL.Font.Size18") + local crossServer = false + if not table.HasValue(PIXEL.DefaultThemes, LocalPlayer().PIXELTheme) then + self.SaveCross.Checkbox:SetEnabled(false) + crossServer = false + end + + + local themeSelected = LocalPlayer().PIXELTheme + function self.DropDown:OnSelect(index, text, data) themeSelected = data + if PIXEL.Themes[themeSelected].included then + self:GetParent().SaveCross.Checkbox:SetEnabled(true) + crossServer = true + else + self:GetParent().SaveCross.Checkbox:SetEnabled(false) + crossServer = false + end end self.Submit = self:Add("PIXEL.TextButton") @@ -31,7 +51,7 @@ function PANEL:Init() self.Submit:SetText("Submit") self.Submit.DoClick = function() - PIXEL.SetTheme(themeSelected) + PIXEL.SetTheme(themeSelected, crossServer) self:Close() notification.AddLegacy("PIXELUI: Theme changed to " .. themeSelected, 0, 3) end diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index 96ec6c0..cf7137e 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -38,149 +38,4 @@ PIXEL.DisableUISounds = false --[[ The Imgur ID of the progress image you want to appear when Imgur content is loading. ]] -PIXEL.ProgressImageID = "635PPvg" - ---[[ - Colour definitions. -]] - -PIXEL.DefaultTheme = "Dark" - -PIXEL.Themes = PIXEL.Themes or {} -- do not touch -PIXEL.Themes["Dark"] = { - Background = Color(22, 22, 22), - Header = Color(28, 28, 28), - SecondaryHeader = Color(43, 43, 43), - Scroller = Color(61, 61, 61), - - PrimaryText = Color(255, 255, 255), - SecondaryText = Color(220, 220, 220), - DisabledText = Color(40, 40, 40), - - Primary = Color(74, 61, 255), - Disabled = Color(180, 180, 180), - Positive = Color(68, 235, 124), - Negative = Color(235, 68, 68), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["Light"] = { - Background = HexColor("#F7F8FA"), - Header = HexColor("#edf1f5"), - SecondaryHeader = HexColor("#DFE1E4"), - Scroller = HexColor("#edf1f5"), - - PrimaryText = HexColor("#292D31"), - SecondaryText = HexColor("#808080"), - DisabledText = HexColor("#9ba0a3"), - - Primary = Color(74, 61, 255), - Disabled = HexColor("#9ba0a3"), - Positive = HexColor("#79CB60"), - Negative = HexColor("#d73a49"), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["GitHubDark"] = { - Background = HexColor("#24292e"), - Header = HexColor("#2f363d"), - SecondaryHeader = HexColor("#2b3036"), - Scroller = HexColor("#2f363d"), - - PrimaryText = Color(74, 61, 255), - SecondaryText = HexColor("#c9d1d9"), - DisabledText = HexColor("#39414a"), - - Primary = HexColor("#b392f0"), - Disabled = HexColor("#6a737d"), - Positive = HexColor("#85e89d"), - Negative = HexColor("#f97583"), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["NightOwl"] = { - Background = HexColor("#011627"), -- Background - Header = HexColor("#0b2942"), -- Seccond Background - SecondaryHeader = HexColor("#13344f"), -- Active - Scroller = HexColor("#0b2942"), -- Seccond Background - - PrimaryText = HexColor("#FBFBFB"), -- Text - SecondaryText = HexColor("#d9d9d9"), -- Buttons - DisabledText = HexColor("#697098"), -- Disabled - - Primary = Color(74, 61, 255), - Disabled = HexColor("#697098"), -- Disabled - Positive = HexColor("#addb67"), -- Green - Negative = HexColor("#ff6363"), -- Red - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["DiscordDark"] = { - Background = Color(54, 57, 63), - Header = Color(47, 49, 54), - SecondaryHeader = Color(51, 54, 59), - Scroller = Color(32, 34, 37), - - PrimaryText = Color(255, 255, 255), - SecondaryText = Color(185, 187, 190), - DisabledText = Color(40, 40, 40), - - Primary = Color(88, 101, 242), - Disabled = Color(114, 118, 125), - Positive = Color(87, 242, 135), - Negative = Color(237, 66, 69), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} - -PIXEL.Themes["DiscordLight"] = { - Background = Color(255, 255, 255), - Header = Color(242, 243, 245), - SecondaryHeader = Color(220, 223, 227), - Scroller = Color(204, 204, 204), - - PrimaryText = Color(6, 6, 7), - SecondaryText = Color(79, 86, 96), - DisabledText = Color(79, 86, 96), - - Primary = Color(88, 101, 242), - Disabled = Color(79, 86, 96), - Positive = Color(87, 242, 135), - Negative = Color(237, 66, 69), - - Diamond = Color(185, 242, 255), - Gold = Color(255, 215, 0), - Silver = Color(192, 192, 192), - Bronze = Color(145, 94, 49), - - Transparent = Color(0, 0, 0, 0) -} \ No newline at end of file +PIXEL.ProgressImageID = "635PPvg" \ No newline at end of file From 5b763a085989f9852103d277bade67271060bf5d Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Jun 2022 17:56:58 +0100 Subject: [PATCH 115/155] better theming styff --- lua/pixelui/core/{ => themes}/cl_theme.lua | 24 ++++++++++++++++----- lua/pixelui/core/{ => themes}/cl_themes.lua | 0 lua/pixelui/core/themes/sh_themes.lua | 22 +++++++++++++++++++ lua/pixelui/elements/cl_sidebar.lua | 3 ++- lua/pixelui/elements/cl_text_entry.lua | 5 ++++- 5 files changed, 47 insertions(+), 7 deletions(-) rename lua/pixelui/core/{ => themes}/cl_theme.lua (71%) rename lua/pixelui/core/{ => themes}/cl_themes.lua (100%) create mode 100644 lua/pixelui/core/themes/sh_themes.lua diff --git a/lua/pixelui/core/cl_theme.lua b/lua/pixelui/core/themes/cl_theme.lua similarity index 71% rename from lua/pixelui/core/cl_theme.lua rename to lua/pixelui/core/themes/cl_theme.lua index 6a76494..0eabf2e 100644 --- a/lua/pixelui/core/cl_theme.lua +++ b/lua/pixelui/core/themes/cl_theme.lua @@ -3,7 +3,6 @@ if not file.Exists("pixel/themes/", "DATA") then end function PIXEL.SetTheme(theme, cross) - print(theme, cross) if not cross then local ip = game.GetIPAddress() ip = ip:gsub(":", "-") @@ -25,26 +24,41 @@ function PIXEL.SetTheme(theme, cross) end end -hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() +local function setJoinTheme() local ply = LocalPlayer() local ip = game.GetIPAddress() ip = ip:gsub(":", "-") ip = string.Replace(ip, ".", "_") if file.Exists("pixel/themes/" .. ip .. "/theme.txt", "DATA") then - local theme = file.Read("pixel/" .. ip .. "/theme.txt", "DATA") + local theme = file.Read("pixel/themes/" .. ip .. "/theme.txt", "DATA") + if theme == "" then theme = "Dark" end + if not PIXEL.Themes[theme] then + ply.PIXELTheme = "Dark" + PIXEL.Colors = PIXEL.Themes["Dark"] + return + end + PIXEL.Colors = PIXEL.Themes[theme] ply.PIXELTheme = theme return end - if not file.Exists("pixel/themes/theme.txt", "DATA") then + if not file.Exists("pixel/themes/theme.txt", "DATA") then return end + + local theme = file.Read("pixel/theme.txt", "DATA") + if theme == "" then theme = "Dark" end + if not PIXEL.Themes[theme] then + ply.PIXELTheme = "Dark" PIXEL.Colors = PIXEL.Themes["Dark"] return end - local theme = file.Read("pixel/theme.txt", "DATA") PIXEL.Colors = PIXEL.Themes[theme] ply.PIXELTheme = theme +end + +hook.Add("InitPostEntity", "PIXELUI.LoadTheme", function() + setJoinTheme() end) concommand.Add("pixel_reset_theme", function(ply, cmd, args) diff --git a/lua/pixelui/core/cl_themes.lua b/lua/pixelui/core/themes/cl_themes.lua similarity index 100% rename from lua/pixelui/core/cl_themes.lua rename to lua/pixelui/core/themes/cl_themes.lua diff --git a/lua/pixelui/core/themes/sh_themes.lua b/lua/pixelui/core/themes/sh_themes.lua new file mode 100644 index 0000000..0e0aa17 --- /dev/null +++ b/lua/pixelui/core/themes/sh_themes.lua @@ -0,0 +1,22 @@ +PIXEL.Colors = { + Background = Color(22, 22, 22), + Header = Color(28, 28, 28), + SecondaryHeader = Color(15, 15, 15), + Scroller = Color(61, 61, 61), + + PrimaryText = Color(255, 255, 255), + SecondaryText = Color(220, 220, 220), + DisabledText = Color(40, 40, 40), + + Primary = Color(77, 79, 199), + Disabled = Color(180, 180, 180), + Positive = Color(68, 235, 124), + Negative = Color(235, 68, 68), + + Diamond = Color(185, 242, 255), + Gold = Color(255, 215, 0), + Silver = Color(192, 192, 192), + Bronze = Color(145, 94, 49), + + Transparent = Color(0, 0, 0, 0) +} \ No newline at end of file diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index d0ab703..be206bc 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -79,6 +79,7 @@ AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "ImgurScale", "ImgurScale", FORCE_NUMBER) AccessorFunc(PANEL, "ImgurOffset", "ImgurOffset", FORCE_NUMBER) AccessorFunc(PANEL, "ButtonOffset", "ButtonOffset", FORCE_NUMBER) +AccessorFunc(PANEL, "ButtonBtmOffset", "ButtonBtmOffset", FORCE_NUMBER) function PANEL:Init() self.Items = {} @@ -150,7 +151,7 @@ end function PANEL:PerformLayout(w, h) local sideSpacing = PIXEL.Scale(7) local topSpacing = PIXEL.Scale(7) - self:DockPadding(sideSpacing, self:GetImgurID() and w * self:GetImgurScale() + self:GetImgurOffset() + self:GetButtonOffset() + topSpacing * 2 or topSpacing, sideSpacing, topSpacing) + self:DockPadding(sideSpacing, self:GetImgurID() and w * self:GetImgurScale() + self:GetImgurOffset() + self:GetButtonOffset() + topSpacing * 2 or topSpacing, sideSpacing, self:GetButtonBtmOffset() or topSpacing) self.Scroller:Dock(FILL) self.Scroller:GetCanvas():DockPadding(0, 0, self.Scroller.VBar.Enabled and sideSpacing or 0, 0) diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 006c622..1d9033e 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -39,7 +39,10 @@ end function PANEL:Paint(w, h) if not self:IsEnabled() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.DisabledCol) - PIXEL.DrawSimpleText("Disabled", "UI.TextEntry", PIXEL.Scale(4), h / 2, PIXEL.Colors.SecondaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + end + + if not self:IsEnabled() and self:GetValue() == "" then + PIXEL.DrawSimpleText(self:GetPlaceholderText() or "", "UI.TextEntry", PIXEL.Scale(10), h / 2, self.PlaceholderTextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) return end From b1a16580a8b6c968b45835ebd0a807d0150303f1 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 27 Jun 2022 15:37:44 +0100 Subject: [PATCH 116/155] update version --- VERSION | 2 +- lua/autorun/sh_pixelui_loader.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index e8ea05d..589268e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.4 +1.3.0 \ No newline at end of file diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 8ca131b..e628904 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -17,7 +17,7 @@ PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} -PIXEL.UI.Version = "1.2.3" +PIXEL.UI.Version = "1.3.0" PIXEL.Colors = { Background = Color(22, 22, 22), From bc019eac3d49bf41311468780c3ba2deda640916 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 15 Aug 2022 10:55:19 +0100 Subject: [PATCH 117/155] refactor: Add back function to support old addons --- lua/pixelui/elements/cl_avatar.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_avatar.lua b/lua/pixelui/elements/cl_avatar.lua index b807829..967c6b4 100644 --- a/lua/pixelui/elements/cl_avatar.lua +++ b/lua/pixelui/elements/cl_avatar.lua @@ -19,6 +19,7 @@ along with this program. If not, see . local PANEL = {} AccessorFunc(PANEL, "Rounding", "Rounding", FORCE_NUMBER) +AccessorFunc(PANEL, "MaskSize", "MaskSize", FORCE_NUMBER) function PANEL:Init() self.Avatar = vgui.Create("AvatarImage", self) @@ -53,7 +54,7 @@ function PANEL:Paint(w, h) render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NEVER) render.SetStencilReferenceValue(1) - PIXEL.DrawFullRoundedBox(self:GetRounding(), 0, 0, w, h, color_white) + PIXEL.DrawFullRoundedBox(self:GetRounding() or self:GetMaskSize(), 0, 0, w, h, color_white) render.SetStencilFailOperation(STENCILOPERATION_ZERO) render.SetStencilPassOperation(STENCILOPERATION_REPLACE) From b93ddcb6e2da5f2f87217514f93111792606fef9 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 2 Jul 2022 19:49:15 +0100 Subject: [PATCH 118/155] remove notifications because broken --- VERSION | 2 +- lua/autorun/sh_pixelui_loader.lua | 2 +- lua/pixelui/elements/cl_notification.lua | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 589268e..6261a05 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.0 \ No newline at end of file +1.3.1 \ No newline at end of file diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index e628904..12fa7c8 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -17,7 +17,7 @@ PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} -PIXEL.UI.Version = "1.3.0" +PIXEL.UI.Version = "1.3.1" PIXEL.Colors = { Background = Color(22, 22, 22), diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua index 857f00d..18737d1 100644 --- a/lua/pixelui/elements/cl_notification.lua +++ b/lua/pixelui/elements/cl_notification.lua @@ -2,7 +2,7 @@ local sc = PIXEL.Scale local Notices = {} local notifyAmount = 0 - +--[[ surface.CreateFont("PIXEL.NotifyFont", { font = "Open Sans Bold", size = 25, @@ -118,3 +118,4 @@ function PANEL:SetProgress(frac) end function PANEL:KillSelf() end vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") +--]] \ No newline at end of file From e0259dde3664745e416fb9ba9ad67b4a47b73e4b Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 13:57:41 +0100 Subject: [PATCH 119/155] refactor: move some files around --- lua/pixelui/{panels => menus}/cl_themeeditor.lua | 0 lua/pixelui/{ => menus}/test/cl_menu.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_avatar.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_buttons.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_navigation.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_other.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_scrollpanel.lua | 0 lua/pixelui/{ => menus}/test/pages/cl_text.lua | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename lua/pixelui/{panels => menus}/cl_themeeditor.lua (100%) rename lua/pixelui/{ => menus}/test/cl_menu.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_avatar.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_buttons.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_navigation.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_other.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_scrollpanel.lua (100%) rename lua/pixelui/{ => menus}/test/pages/cl_text.lua (100%) diff --git a/lua/pixelui/panels/cl_themeeditor.lua b/lua/pixelui/menus/cl_themeeditor.lua similarity index 100% rename from lua/pixelui/panels/cl_themeeditor.lua rename to lua/pixelui/menus/cl_themeeditor.lua diff --git a/lua/pixelui/test/cl_menu.lua b/lua/pixelui/menus/test/cl_menu.lua similarity index 100% rename from lua/pixelui/test/cl_menu.lua rename to lua/pixelui/menus/test/cl_menu.lua diff --git a/lua/pixelui/test/pages/cl_avatar.lua b/lua/pixelui/menus/test/pages/cl_avatar.lua similarity index 100% rename from lua/pixelui/test/pages/cl_avatar.lua rename to lua/pixelui/menus/test/pages/cl_avatar.lua diff --git a/lua/pixelui/test/pages/cl_buttons.lua b/lua/pixelui/menus/test/pages/cl_buttons.lua similarity index 100% rename from lua/pixelui/test/pages/cl_buttons.lua rename to lua/pixelui/menus/test/pages/cl_buttons.lua diff --git a/lua/pixelui/test/pages/cl_navigation.lua b/lua/pixelui/menus/test/pages/cl_navigation.lua similarity index 100% rename from lua/pixelui/test/pages/cl_navigation.lua rename to lua/pixelui/menus/test/pages/cl_navigation.lua diff --git a/lua/pixelui/test/pages/cl_other.lua b/lua/pixelui/menus/test/pages/cl_other.lua similarity index 100% rename from lua/pixelui/test/pages/cl_other.lua rename to lua/pixelui/menus/test/pages/cl_other.lua diff --git a/lua/pixelui/test/pages/cl_scrollpanel.lua b/lua/pixelui/menus/test/pages/cl_scrollpanel.lua similarity index 100% rename from lua/pixelui/test/pages/cl_scrollpanel.lua rename to lua/pixelui/menus/test/pages/cl_scrollpanel.lua diff --git a/lua/pixelui/test/pages/cl_text.lua b/lua/pixelui/menus/test/pages/cl_text.lua similarity index 100% rename from lua/pixelui/test/pages/cl_text.lua rename to lua/pixelui/menus/test/pages/cl_text.lua From f54ecdc946a4d6a6454ac9b8363d123fc2c41089 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 13:57:47 +0100 Subject: [PATCH 120/155] feat: slide out frames --- lua/pixelui/elements/cl_frame.lua | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index ea93212..db27770 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -23,6 +23,9 @@ AccessorFunc(PANEL, "MinWidth", "MinWidth", FORCE_NUMBER) AccessorFunc(PANEL, "MinHeight", "MinHeight", FORCE_NUMBER) AccessorFunc(PANEL, "ScreenLock", "ScreenLock", FORCE_BOOL) AccessorFunc(PANEL, "RemoveOnClose", "RemoveOnClose", FORCE_BOOL) +AccessorFunc(PANEL, "SlideOut", "SlideOut", FORCE_BOOL) +AccessorFunc(PANEL, "SlideDirection", "SlideDirection", FORCE_NUMBER) -- 1 = up, 2 = right, 3 = down, 4 = left + AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) @@ -41,6 +44,9 @@ function PANEL:Init() self:Close() end + self:SetSlideOut(true) + self:SetSlideDirection(4) + self.ExtraButtons = {} self:SetTitle("PIXEL Frame") @@ -207,8 +213,29 @@ function PANEL:Open() self:AlphaTo(255, .1, 0) end + function PANEL:Close() - self:AlphaTo(0, .1, 0, function(anim, pnl) + if not self:GetSlideOut() then + self:AlphaTo(0, .1, 0, function(anim, pnl) + if not IsValid(pnl) then return end + pnl:SetVisible(false) + pnl:OnClose() + if pnl:GetRemoveOnClose() then pnl:Remove() end + end) + return + end + + local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() + local slideDirections = { + [1] = {x = (scrw / 2) - (wide / 2), y = -tall, size = function() self:SizeTo(wide, 0, .3, 0, -1) end}, -- up + [2] = {x = scrw, y = posY, size = function() end}, -- right + [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end}, -- down + [4] = {x = -wide, y = posY, size = function() end}, -- left + } + + local direction = self:GetSlideDirection() or 1 + slideDirections[direction].size() + self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, .5, 0, -1, function(anim, pnl) if not IsValid(pnl) then return end pnl:SetVisible(false) pnl:OnClose() From 59aaa43646fdbb8f81159d56a5b13e4c7e6e6265 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 13:58:58 +0100 Subject: [PATCH 121/155] a --- lua/pixelui/elements/cl_frame.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index db27770..ab41f1d 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -227,10 +227,10 @@ function PANEL:Close() local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() local slideDirections = { - [1] = {x = (scrw / 2) - (wide / 2), y = -tall, size = function() self:SizeTo(wide, 0, .3, 0, -1) end}, -- up - [2] = {x = scrw, y = posY, size = function() end}, -- right - [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end}, -- down - [4] = {x = -wide, y = posY, size = function() end}, -- left + [1] = {x = (scrw / 2) - (wide / 2), y = -tall,size = function() self:SizeTo(wide, 0, .3, 0, -1) end},-- up + [2] = {x = scrw,y = posY,size = function() end},-- right + [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end},-- down + [4] = {x = -wide,y = posY,size = function() end},-- left } local direction = self:GetSlideDirection() or 1 From 07af29d73aee6461c5872da714e9fb2821502932 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 17:34:08 +0100 Subject: [PATCH 122/155] refactor: stop slide out by default --- lua/pixelui/elements/cl_frame.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index ab41f1d..49672df 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -44,8 +44,7 @@ function PANEL:Init() self:Close() end - self:SetSlideOut(true) - self:SetSlideDirection(4) + self:SetSlideOut(false) self.ExtraButtons = {} From 53169481ab0d467ef951d351084fe328c5c1c221 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 19:39:55 +0100 Subject: [PATCH 123/155] feat: slideTime --- lua/pixelui/elements/cl_frame.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 49672df..a8a7165 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -25,6 +25,7 @@ AccessorFunc(PANEL, "ScreenLock", "ScreenLock", FORCE_BOOL) AccessorFunc(PANEL, "RemoveOnClose", "RemoveOnClose", FORCE_BOOL) AccessorFunc(PANEL, "SlideOut", "SlideOut", FORCE_BOOL) AccessorFunc(PANEL, "SlideDirection", "SlideDirection", FORCE_NUMBER) -- 1 = up, 2 = right, 3 = down, 4 = left +AccessorFunc(PANEL, "SlideTime", "SlideTime", FORCE_NUMBER) AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) @@ -44,7 +45,8 @@ function PANEL:Init() self:Close() end - self:SetSlideOut(false) + self:SetSlideOut(true) + self:SetSlideDirection(3) self.ExtraButtons = {} @@ -226,7 +228,7 @@ function PANEL:Close() local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() local slideDirections = { - [1] = {x = (scrw / 2) - (wide / 2), y = -tall,size = function() self:SizeTo(wide, 0, .3, 0, -1) end},-- up + [1] = {x = (scrw / 2) - (wide / 2), y = -tall,size = function() self:SizeTo(wide, 0, (self:GetSlideTime() - 0.2) or .3, 0, -1) end},-- up [2] = {x = scrw,y = posY,size = function() end},-- right [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end},-- down [4] = {x = -wide,y = posY,size = function() end},-- left @@ -234,7 +236,7 @@ function PANEL:Close() local direction = self:GetSlideDirection() or 1 slideDirections[direction].size() - self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, .5, 0, -1, function(anim, pnl) + self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, self:GetSlideTime() or .5, 0, -1, function(anim, pnl) if not IsValid(pnl) then return end pnl:SetVisible(false) pnl:OnClose() From bd42a3e79331bc8a874e2011ec6077fbe46cae98 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 24 Sep 2022 19:40:09 +0100 Subject: [PATCH 124/155] a --- lua/pixelui/elements/cl_frame.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index a8a7165..a9a24e6 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -45,8 +45,7 @@ function PANEL:Init() self:Close() end - self:SetSlideOut(true) - self:SetSlideDirection(3) + self:SetSlideOut(false) self.ExtraButtons = {} From 3a26d2ee918d5adb5ee107c785f2713da37fe526 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 20 Nov 2022 12:33:35 +0000 Subject: [PATCH 125/155] feat: Ability to add icons on PIXEL.Navbar --- lua/pixelui/elements/cl_navbar.lua | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/elements/cl_navbar.lua b/lua/pixelui/elements/cl_navbar.lua index c45421f..57e0007 100644 --- a/lua/pixelui/elements/cl_navbar.lua +++ b/lua/pixelui/elements/cl_navbar.lua @@ -19,6 +19,8 @@ local PANEL = {} AccessorFunc(PANEL, "Name", "Name", FORCE_STRING) AccessorFunc(PANEL, "Color", "Color") +AccessorFunc(PANEL, "ImgurID", "ImgurID") +AccessorFunc(PANEL, "ImgurScale", "ImgurScale") PIXEL.RegisterFont("UI.NavbarItem", "Open Sans SemiBold", 22) @@ -27,6 +29,7 @@ function PANEL:Init() self:SetColor(PIXEL.Colors.Primary) self:SetClicky(false) self:SetSounds(false) + self:SetImgurScale(0.2) self.NormalCol = PIXEL.Colors.PrimaryText self.HoverCol = PIXEL.Colors.SecondaryText @@ -49,6 +52,14 @@ function PANEL:Paint(w, h) local animTime = FrameTime() * 12 self.TextCol = PIXEL.LerpColor(animTime, self.TextCol, textCol) + local imgurID = self:GetImgurID() + if imgurID then + local imageSize = w * self:GetImgurScale() + PIXEL.DrawImgur(0, (self:GetTall() / 2) - (imageSize / 2), imageSize, imageSize, imgurID, color_white) + PIXEL.DrawSimpleText(self:GetName(), "UI.NavbarItem", imageSize + PIXEL.Scale(3), h / 2, self.TextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + return + end + PIXEL.DrawSimpleText(self:GetName(), "UI.NavbarItem", w / 2, h / 2, self.TextCol, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end @@ -66,9 +77,10 @@ function PANEL:Init() self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 10) end -function PANEL:AddItem(id, name, doClick, order, color) +function PANEL:AddItem(id, name, doClick, order, color, imgurID) local btn = vgui.Create("PIXEL.NavbarItem", self) + btn:SetImgurID(imgurID) btn:SetName(name:upper()) btn:SetZPos(order or table.Count(self.Items) + 1) btn:SetColor((IsColor(color) and color) or PIXEL.Colors.Primary) @@ -111,7 +123,7 @@ end function PANEL:PerformLayout(w, h) for k,v in pairs(self.Items) do v:Dock(LEFT) - v:SetWide(v:GetItemSize() + PIXEL.Scale(30)) + v:SetWide(v:GetItemSize() + PIXEL.Scale(50)) end end @@ -136,4 +148,4 @@ function PANEL:Paint(w, h) surface.DrawRect(self.SelectionX + 2, h - selectorH, self.SelectionW - 4, selectorH / 2) end -vgui.Register("PIXEL.Navbar", PANEL, "Panel") \ No newline at end of file +vgui.Register("PIXEL.Navbar", PANEL, "Panel") From 6ee4be58dbf176afcdcecb756fef97d662525d4d Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 20 Nov 2022 12:43:40 +0000 Subject: [PATCH 126/155] a --- lua/autorun/sh_pixelui_loader.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 12fa7c8..7be0ff4 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -65,11 +65,15 @@ function PIXEL.LoadDirectory(path) return files, folders end -function PIXEL.LoadDirectoryRecursive(basePath) +function PIXEL.LoadDirectoryRecursive(basePath, onLoad) local _, folders = PIXEL.LoadDirectory(basePath) for _, folderName in ipairs(folders) do PIXEL.LoadDirectoryRecursive(basePath .. "/" .. folderName) end + + if onLoad and isfunction(onLoad) then + onLoad() + end end PIXEL.LoadDirectoryRecursive("pixelui") @@ -83,11 +87,11 @@ resource.AddWorkshop("2825396224") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) + http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pulsar-lib/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) - MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") + MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pulsar-lib/releases/latest\n") MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") MsgC(red, "New version: " .. body .. "\n") return From cb4462d150968d8d96fafe1db3552db091ffe23e Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 21 Nov 2022 18:50:44 +0000 Subject: [PATCH 127/155] feat: add PIXEL.OldAvatar to fix addons having wrong corner sizes --- lua/autorun/sh_pixelui_loader.lua | 5 ++ lua/pixelui/elements/cl_avatar.lua | 75 +++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 7be0ff4..55ccf15 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -42,6 +42,11 @@ PIXEL.Colors = { Transparent = Color(0, 0, 0, 0) } + +function PIXEL.Warn(...) + MsgC(PIXEL.Colors.Gold, "[PIXEL UI - Warning] ", PIXEL.Colors.Negative, ..., "\n") +end + function PIXEL.LoadDirectory(path) local files, folders = file.Find(path .. "/*", "LUA") diff --git a/lua/pixelui/elements/cl_avatar.lua b/lua/pixelui/elements/cl_avatar.lua index 967c6b4..80e7106 100644 --- a/lua/pixelui/elements/cl_avatar.lua +++ b/lua/pixelui/elements/cl_avatar.lua @@ -70,4 +70,77 @@ function PANEL:Paint(w, h) render.ClearStencil() end -vgui.Register("PIXEL.Avatar", PANEL, "Panel") \ No newline at end of file +vgui.Register("PIXEL.Avatar", PANEL, "Panel") + + +-- old avatar + +PANEL = {} + +AccessorFunc(PANEL, "MaskSize", "MaskSize", FORCE_NUMBER) + +function PANEL:Init() + PIXEL.Warn("Please update to using PIXEL.Avatar instead of using PIXEL.OldAvatar! This panel is deprecated and may be removed in a future release.") + self.Avatar = vgui.Create("AvatarImage", self) + self.Avatar:SetPaintedManually(true) + + self.CirclePoly = {} + self:SetMaskSize(1) +end + +function PANEL:PerformLayout(w, h) + self.Avatar:SetSize(w, h) + + self.CirclePoly = {} + local maskSize = self:GetMaskSize() + + local t = 0 + for i = 1, 360 do + t = math.rad(i * 720) / 720 + self.CirclePoly[i] = {x = w / 2 + math.cos(t) * maskSize, y = h / 2 + math.sin(t) * maskSize} + end +end + +function PANEL:SetPlayer(ply, size) + self.Avatar:SetPlayer(ply, size) +end + +function PANEL:SetSteamID(id, size) + self.Avatar:SetSteamID(id, size) +end + +local render = render +local surface = surface +local whiteTexture = surface.GetTextureID("vgui/white") +function PANEL:Paint(w, h) + render.ClearStencil() + render.SetStencilEnable(true) + + render.SetStencilWriteMask(1) + render.SetStencilTestMask(1) + + render.SetStencilFailOperation(STENCILOPERATION_REPLACE) + render.SetStencilPassOperation(STENCILOPERATION_ZERO) + render.SetStencilZFailOperation(STENCILOPERATION_ZERO) + render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NEVER) + render.SetStencilReferenceValue(1) + + surface.SetTexture(whiteTexture) + surface.SetDrawColor(255, 255, 255, 255) + surface.DrawPoly(self.CirclePoly) + + render.SetStencilFailOperation(STENCILOPERATION_ZERO) + render.SetStencilPassOperation(STENCILOPERATION_REPLACE) + render.SetStencilZFailOperation(STENCILOPERATION_ZERO) + render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL) + render.SetStencilReferenceValue(1) + + self.Avatar:SetPaintedManually(false) + self.Avatar:PaintManual() + self.Avatar:SetPaintedManually(true) + + render.SetStencilEnable(false) + render.ClearStencil() +end + +vgui.Register("PIXEL.OldAvatar", PANEL, "Panel") From f4951a51860a06ebcde3740a3bd3a2c1a1da548a Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:52:45 +0100 Subject: [PATCH 128/155] feat: OnOpen and OnClose functions for combo boxes --- lua/pixelui/elements/cl_combo_box.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_combo_box.lua b/lua/pixelui/elements/cl_combo_box.lua index 5e6aa04..5758351 100644 --- a/lua/pixelui/elements/cl_combo_box.lua +++ b/lua/pixelui/elements/cl_combo_box.lua @@ -47,6 +47,7 @@ function PANEL:Clear() if not self.Menu then return end self.Menu:Remove() + self:OnClose() self.Menu = nil end @@ -130,8 +131,9 @@ end function PANEL:OpenMenu(pControlOpener) if pControlOpener and pControlOpener == self.TextEntry then return end - PIXEL.PlayExpand("open") if #self.Choices == 0 then return end + PIXEL.PlayExpand("open") + self:OnOpen() if IsValid(self.Menu) then self.Menu:Remove() @@ -173,6 +175,7 @@ function PANEL:OpenMenu(pControlOpener) self.Menu.OnRemove = function(s) if not IsValid(self) then return end PIXEL.PlayExpand("close") + self:OnClose() self:SetToggle(false) end end @@ -180,6 +183,7 @@ end function PANEL:CloseMenu() if not IsValid(self.Menu) then return end self.Menu:Remove() + self:OnClose() end function PANEL:CheckConVarChanges() @@ -204,6 +208,12 @@ function PANEL:DoClick() if not self:IsMenuOpen() then self:OpenMenu() end end +function PANEL:OnOpen() +end + +function PANEL:OnClose() +end + function PANEL:PaintOver(w, h) local dropBtnSize = PIXEL.Scale(8) PIXEL.DrawImgur(w - dropBtnSize - PIXEL.Scale(8), h / 2 - dropBtnSize / 2, dropBtnSize, dropBtnSize, "30Bvuwi", PIXEL.Colors.PrimaryText) From 60738359de86f6d54d29d2723e197cc288a2d71a Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:53:06 +0100 Subject: [PATCH 129/155] feat: function to stop scrolling in scrollpanel? --- lua/pixelui/elements/cl_scrollpanel.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lua/pixelui/elements/cl_scrollpanel.lua b/lua/pixelui/elements/cl_scrollpanel.lua index ef06c87..c171980 100644 --- a/lua/pixelui/elements/cl_scrollpanel.lua +++ b/lua/pixelui/elements/cl_scrollpanel.lua @@ -21,8 +21,11 @@ AccessorFunc(PANEL, "Padding", "Padding") AccessorFunc(PANEL, "Canvas", "Canvas") AccessorFunc(PANEL, "ScrollbarLeft", "ScrollbarLeftSide") AccessorFunc(PANEL, "BarDockShouldOffset", "BarDockShouldOffset", FORCE_BOOL) +AccessorFunc(PANEL, "CanScroll", "CanScroll", FORCE_BOOL) function PANEL:Init() + self:SetCanScroll(true) + self.Canvas = vgui.Create("Panel", self) self.Canvas.OnMousePressed = function(s, code) s:GetParent():OnMousePressed(code) end self.Canvas:SetMouseInputEnabled(true) @@ -121,6 +124,8 @@ function PANEL:Think() end function PANEL:OnMouseWheeled(delta) + if not self:GetCanScroll() then return end + if (delta > 0 and self.VBar.Scroll <= self.VBar.CanvasSize * 0.005) or (delta < 0 and self.VBar.Scroll >= self.VBar.CanvasSize * 0.995) then self.ScrollDelta = self.ScrollDelta + delta / 10 From c6140de6fe87ff52dbb5e5113affa369d1665877 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:53:31 +0100 Subject: [PATCH 130/155] Update updater url --- lua/autorun/sh_pixelui_loader.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 55ccf15..7837e63 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -92,11 +92,11 @@ resource.AddWorkshop("2825396224") hook.Add("Think", "PIXEL.UI.VersionChecker", function() hook.Remove("Think", "PIXEL.UI.VersionChecker") - http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pulsar-lib/master/VERSION", function(body) + http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) if PIXEL.UI.Version ~= string.Trim(body) then local red = Color(192, 27, 27) - MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pulsar-lib/releases/latest\n") + MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") MsgC(red, "New version: " .. body .. "\n") return From 22f7eb862eb061255d1befe74eb04dc56aa2bb22 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 7 Dec 2022 23:07:01 +0000 Subject: [PATCH 131/155] fix: Theme changer font errors --- lua/pixelui/menus/cl_themeeditor.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/menus/cl_themeeditor.lua b/lua/pixelui/menus/cl_themeeditor.lua index 46a2396..9f5d4da 100644 --- a/lua/pixelui/menus/cl_themeeditor.lua +++ b/lua/pixelui/menus/cl_themeeditor.lua @@ -1,6 +1,8 @@ local PANEL = {} local sc = PIXEL.Scale PIXEL.GenerateFont(18) +PIXEL.GenerateFont(20) + function PANEL:Init() self:SetSize(sc(200), sc(200)) self:MakePopup() @@ -58,7 +60,7 @@ function PANEL:Init() end function PANEL:PaintOver(w, h) - PIXEL.DrawSimpleText("Select new theme:", "Lyth_Pulsar.Font.Size20", w / 2, self.DropDown:GetY() - sc(15), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText("Select new theme:", "PIXEL.Font.Size20", w / 2, self.DropDown:GetY() - sc(15), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end vgui.Register("PIXELUI.ThemeChanger", PANEL, "PIXEL.Frame") @@ -71,4 +73,4 @@ concommand.Add("pixel_change_theme", function() ThemeChanger:Close() ThemeChanger = vgui.Create("PIXELUI.ThemeChanger") end -end) \ No newline at end of file +end) From 772be022f346c5976fa6b80c4a497d981487986f Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 19 Dec 2022 19:50:00 +0000 Subject: [PATCH 132/155] pro scaling optimisations --- lua/pixelui/core/cl_scaling.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/core/cl_scaling.lua b/lua/pixelui/core/cl_scaling.lua index 5a878e8..657115a 100644 --- a/lua/pixelui/core/cl_scaling.lua +++ b/lua/pixelui/core/cl_scaling.lua @@ -15,10 +15,9 @@ along with this program. If not, see . --]] -local scrH = ScrH -local max = math.max +local scrH = scrH or ScrH() function PIXEL.Scale(value) - return max(value * (scrH() / 1080), 1) + return value * (scrH / 1080) end local constants = {} @@ -36,4 +35,5 @@ hook.Add("OnScreenSizeChanged", "PIXEL.UI.UpdateScaledConstants", function() for varName, size in pairs(constants) do scaledConstants[varName] = PIXEL.Scale(size) end + scrH = ScrH() end) From 8cf6e977075dac5f8a48169bfa86a8b39a49c9aa Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:17:39 +0000 Subject: [PATCH 133/155] feat: Color Override for overheads --- lua/pixelui/drawing/cl_overheads.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lua/pixelui/drawing/cl_overheads.lua b/lua/pixelui/drawing/cl_overheads.lua index a0c83f8..53c5e0e 100644 --- a/lua/pixelui/drawing/cl_overheads.lua +++ b/lua/pixelui/drawing/cl_overheads.lua @@ -27,7 +27,7 @@ local disableClipping = DisableClipping local start3d2d, end3d2d = cam.Start3D2D, cam.End3D2D local Icon = icon -local function drawOverhead(ent, pos, text, ang, scale) +local function drawOverhead(ent, pos, text, ang, scale, col) if ang then ang = ent:LocalToWorldAngles(ang) else @@ -46,12 +46,12 @@ local function drawOverhead(ent, pos, text, ang, scale) start3d2d(pos, ang, scale or 0.05) if not Icon then - PIXEL.DrawRoundedBox(12, x, y, w, h, PIXEL.Colors.Primary) + PIXEL.DrawRoundedBox(12, x, y, w, h, col or PIXEL.Colors.Primary) PIXEL.DrawText(text, "UI.Overhead", 0, y + 1, PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER) else x = x - 40 PIXEL.DrawRoundedBox(12, x, y, h, h, PIXEL.Colors.Primary) - PIXEL.DrawRoundedBoxEx(12, x + (h - 12), y + h - 20, w + 15, 20, PIXEL.Colors.Primary, false, false, false, true) + PIXEL.DrawRoundedBoxEx(12, x + (h - 12), y + h - 20, w + 15, 20, col or PIXEL.Colors.Primary, false, false, false, true) PIXEL.DrawText(text, "UI.Overhead", x + h + 15, y + 8, PIXEL.Colors.PrimaryText) PIXEL.DrawImgur(x + 10, y + 10, h - 20, h - 20, Icon, color_white) end @@ -61,7 +61,7 @@ local function drawOverhead(ent, pos, text, ang, scale) end local entOffset = 2 -function PIXEL.DrawEntOverhead(ent, text, angleOverride, posOverride, scaleOverride) +function PIXEL.DrawEntOverhead(ent, text, angleOverride, posOverride, scaleOverride, colOverride) if checkDistance(ent) then return end if posOverride then @@ -72,12 +72,12 @@ function PIXEL.DrawEntOverhead(ent, text, angleOverride, posOverride, scaleOverr local pos = ent:OBBMaxs() pos:SetUnpacked(0, 0, pos[3] + entOffset) - drawOverhead(ent, ent:LocalToWorld(pos), text, angleOverride, scaleOverride) + drawOverhead(ent, ent:LocalToWorld(pos), text, angleOverride, scaleOverride, colOverride) end local eyeOffset = Vector(0, 0, 7) local fallbackOffset = Vector(0, 0, 73) -function PIXEL.DrawNPCOverhead(ent, text, angleOverride, offsetOverride, scaleOverride) +function PIXEL.DrawNPCOverhead(ent, text, angleOverride, offsetOverride, scaleOverride, colOverride) if checkDistance(ent) then return end local eyeId = ent:LookupAttachment("eyes") @@ -90,7 +90,7 @@ function PIXEL.DrawNPCOverhead(ent, text, angleOverride, offsetOverride, scaleOv end end - drawOverhead(ent, ent:GetPos() + fallbackOffset, text, angleOverride, scaleOverride) + drawOverhead(ent, ent:GetPos() + fallbackOffset, text, angleOverride, scaleOverride, colOverride) end function PIXEL.EnableIconOverheads(new) From dd7d94b28de8dbfa7ee336f21a6f8221ae8e3acd Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:11:46 +0100 Subject: [PATCH 134/155] fix: TextButton text being offset when ClickyButton --- lua/pixelui/elements/cl_text_button.lua | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lua/pixelui/elements/cl_text_button.lua b/lua/pixelui/elements/cl_text_button.lua index 4838d5f..b720c15 100644 --- a/lua/pixelui/elements/cl_text_button.lua +++ b/lua/pixelui/elements/cl_text_button.lua @@ -16,12 +16,10 @@ --]] local PANEL = {} - AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) AccessorFunc(PANEL, "TextSpacing", "TextSpacing", FORCE_NUMBER) AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) - PIXEL.RegisterFont("UI.TextButton", "Open Sans SemiBold", 20) function PANEL:Init() @@ -29,11 +27,9 @@ function PANEL:Init() self:SetTextAlign(TEXT_ALIGN_CENTER) self:SetTextSpacing(PIXEL.Scale(6)) self:SetFont("UI.TextButton") - self:SetSize(PIXEL.Scale(100), PIXEL.Scale(30)) self:SetClicky(true) self:SetSounds(true) - end function PANEL:SizeToText() @@ -47,13 +43,14 @@ function PANEL:PaintExtra(w, h) if not self:IsEnabled() then PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.DisabledText, textAlign, TEXT_ALIGN_CENTER) + return end if self.ClickyMove and self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2 - PIXEL.Scale(4)) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, (h / 2) + self.ClickyScale, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) elseif self:GetClicky() then - PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2 - PIXEL.Scale(4), PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) else PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) end From 07e8651d1815372b9d0183a23f38b8f02e2dbe3d Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:12:04 +0100 Subject: [PATCH 135/155] =?UTF-8?q?=E2=9C=A8=20feat:=20Mini=20Sidebar=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/pixelui/elements/cl_mini_sidebar.lua | 166 +++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 lua/pixelui/elements/cl_mini_sidebar.lua diff --git a/lua/pixelui/elements/cl_mini_sidebar.lua b/lua/pixelui/elements/cl_mini_sidebar.lua new file mode 100644 index 0000000..39010b8 --- /dev/null +++ b/lua/pixelui/elements/cl_mini_sidebar.lua @@ -0,0 +1,166 @@ + +--[[ +PIXEL UI +Copyright (C) 2021 Tom O'Sullivan (Tom.bat) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +]] + +local PANEL = {} + +AccessorFunc(PANEL, "Name", "Name", FORCE_STRING) +AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) +AccessorFunc(PANEL, "DrawOutline", "DrawOutline", FORCE_BOOL) + +PIXEL.RegisterFont("SidebarItem", "Rubik", 19) + +function PANEL:Init() + self:SetName("N/A") + self:SetDrawOutline(true) + self:SetClicky(false) + self:SetSounds(false) + self:SetTooltip(self:GetName() or "N/A") + + self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) + self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) + self.BackgroundHoverCol = ColorAlpha(PIXEL.Colors.Scroller, 80) +end + +function PANEL:Paint(w, h) + local textCol = PIXEL.Colors.SecondaryText + local backgroundCol = PIXEL.Colors.Transparent + local hoverLineCol = PIXEL.Colors.Transparent + + if self:IsHovered() then + textCol = PIXEL.Colors.PrimaryText + backgroundCol = self.BackgroundHoverCol + hoverLineCol = PIXEL.Colors.Primary + end + + if self:IsDown() or self:GetToggle() then + textCol = PIXEL.Colors.PrimaryText + backgroundCol = self.BackgroundHoverCol + hoverLineCol = PIXEL.Colors.Primary + end + + local animTime = FrameTime() * 12 + self.TextCol = PIXEL.LerpColor(animTime, self.TextCol, textCol) + self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, backgroundCol) + + if self:GetDrawOutline() then + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol, PIXEL.Scale(1)) + PIXEL.DrawRoundedBox(0, 0, 0, PIXEL.Scale(3), h, hoverLineCol, PIXEL.Scale(1)) + end + + local imgurID = self:GetImgurID() + local iconSize = h * .65 + PIXEL.DrawImgur(PIXEL.Scale(9), (h - iconSize) / 2 + PIXEL.Scale(1), iconSize, iconSize, imgurID, Color(255,255,255)) +end + +vgui.Register("PIXEL.SidebarItem", PANEL, "PIXEL.Button") + +PANEL = {} + +AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) +AccessorFunc(PANEL, "ImgurScale", "ImgurScale", FORCE_NUMBER) +AccessorFunc(PANEL, "ImgurOffset", "ImgurOffset", FORCE_NUMBER) +AccessorFunc(PANEL, "ButtonOffset", "ButtonOffset", FORCE_NUMBER) +AccessorFunc(PANEL, "ButtonBtmOffset", "ButtonBtmOffset", FORCE_NUMBER) + +function PANEL:Init() + self.Items = {} + + self.Scroller = vgui.Create("PIXEL.ScrollPanel", self) + self.Scroller:SetBarDockShouldOffset(true) + self.Scroller.LayoutContent = function(s, w, h) + local spacing = PIXEL.Scale(8) + local height = PIXEL.Scale(36) + for k,v in pairs(self.Items) do + v:SetTall(height) + v:Dock(TOP) + v:DockMargin(0, 0, 0, spacing) + end + end + + self:SetImgurScale(.6) + self:SetImgurOffset(0) + self:SetButtonOffset(0) + + self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Header) +end + +function PANEL:AddItem(id, name, imgurID, doClick, order) + local btn = vgui.Create("PIXEL.SidebarItem", self.Scroller) + + btn:SetZPos(order or table.Count(self.Items) + 1) + btn:SetName(name) + if imgurID then btn:SetImgurID(imgurID) end + btn.Function = doClick + + btn.DoClick = function(s) + self:SelectItem(id) + end + + self.Items[id] = btn + + return btn +end + +function PANEL:RemoveItem(id) + local item = self.Items[id] + if not item then return end + + item:Remove() + self.Items[id] = nil + + if self.SelectedItem != id then return end + self:SelectItem(next(self.Items)) +end + +function PANEL:SelectItem(id) + local item = self.Items[id] + if not item then return end + + PIXEL.PlayChangeTab() + + if self.SelectedItem and self.SelectedItem == id then return end + self.SelectedItem = id + + for k,v in pairs(self.Items) do + v:SetToggle(false) + end + + item:SetToggle(true) + item.Function(item) +end + +function PANEL:PerformLayout(w, h) + local sideSpacing = PIXEL.Scale(7) + local topSpacing = PIXEL.Scale(7) + self:DockPadding(sideSpacing, self:GetImgurID() and w * self:GetImgurScale() + self:GetImgurOffset() + self:GetButtonOffset() + topSpacing * 2 or topSpacing, sideSpacing, self:GetButtonBtmOffset() or topSpacing) + + self.Scroller:Dock(FILL) + self.Scroller:GetCanvas():DockPadding(0, 0, self.Scroller.VBar.Enabled and sideSpacing or 0, 0) +end + +function PANEL:Paint(w, h) + PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), 0, 0, w, h, self.BackgroundCol, false, false, true) + + local imgurID = self:GetImgurID() + if imgurID then + local imageSize = w * self:GetImgurScale() + PIXEL.DrawImgur((w - imageSize) / 2, imageSize / 2 - (imageSize / 3), imageSize, imageSize, imgurID, color_white) + end +end + +vgui.Register("PIXEL.MiniSidebar", PANEL, "Panel") From cdd345b3bbd1599389fa7e4ea86333fd97158a77 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:57:23 +0100 Subject: [PATCH 136/155] Update VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6261a05..1892b92 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.1 \ No newline at end of file +1.3.2 From 80818b5f71db368f5bf1eb6d88d4e03eca6283a3 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 23 Apr 2023 01:31:17 +0100 Subject: [PATCH 137/155] feat: better readme --- pixelui.png | Bin 0 -> 8314 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pixelui.png diff --git a/pixelui.png b/pixelui.png new file mode 100644 index 0000000000000000000000000000000000000000..190b741c5bdfa3e2ca337a9004518f552d5363c5 GIT binary patch literal 8314 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 literal 0 HcmV?d00001 From 5eb1562b8481d67b991a2ff620dd3109321f4194 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 25 Apr 2023 17:18:06 +0100 Subject: [PATCH 138/155] stuff --- lua/autorun/sh_pixelui_loader.lua | 97 +++--- lua/pixelui/core/themes/cl_themes.lua | 43 +-- lua/pixelui/core/themes/sh_themes.lua | 19 +- lua/pixelui/elements/cl_button.lua | 261 +++++++-------- lua/pixelui/elements/cl_category.lua | 44 +-- lua/pixelui/elements/cl_check_box.lua | 7 +- lua/pixelui/elements/cl_frame.lua | 430 ++++++++++++++----------- lua/pixelui/elements/cl_sidebar.lua | 36 +-- lua/pixelui/elements/cl_text_entry.lua | 138 +++++--- lua/pixelui/menus/test/cl_menu.lua | 148 +++++---- 10 files changed, 657 insertions(+), 566 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 7837e63..9fe676f 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -24,82 +24,79 @@ PIXEL.Colors = { Header = Color(28, 28, 28), SecondaryHeader = Color(15, 15, 15), Scroller = Color(61, 61, 61), - + -- PrimaryText = Color(255, 255, 255), SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - - Primary = Color(77, 79, 199), + -- + Primary = Color(2, 153, 204), Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), Negative = Color(235, 68, 68), - + -- Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - + -- Transparent = Color(0, 0, 0, 0) } - function PIXEL.Warn(...) MsgC(PIXEL.Colors.Gold, "[PIXEL UI - Warning] ", PIXEL.Colors.Negative, ..., "\n") end function PIXEL.LoadDirectory(path) - local files, folders = file.Find(path .. "/*", "LUA") - - for _, fileName in ipairs(files) do - local filePath = path .. "/" .. fileName - - if CLIENT then - include(filePath) - else - if fileName:StartWith("cl_") then - AddCSLuaFile(filePath) - elseif fileName:StartWith("sh_") then - AddCSLuaFile(filePath) - include(filePath) - else - include(filePath) - end - end - end - - return files, folders + local files, folders = file.Find(path .. "/*", "LUA") + + for _, fileName in ipairs(files) do + local filePath = path .. "/" .. fileName + + if CLIENT then + include(filePath) + else + if fileName:StartWith("cl_") then + AddCSLuaFile(filePath) + elseif fileName:StartWith("sh_") then + AddCSLuaFile(filePath) + include(filePath) + else + include(filePath) + end + end + end + + return files, folders end function PIXEL.LoadDirectoryRecursive(basePath, onLoad) - local _, folders = PIXEL.LoadDirectory(basePath) - for _, folderName in ipairs(folders) do - PIXEL.LoadDirectoryRecursive(basePath .. "/" .. folderName) - end - - if onLoad and isfunction(onLoad) then - onLoad() - end + local _, folders = PIXEL.LoadDirectory(basePath) + + for _, folderName in ipairs(folders) do + PIXEL.LoadDirectoryRecursive(basePath .. "/" .. folderName) + end + + if onLoad and isfunction(onLoad) then + onLoad() + end end PIXEL.LoadDirectoryRecursive("pixelui") - hook.Run("PIXEL.UI.FullyLoaded") - if CLIENT then return end - resource.AddWorkshop("2825396224") hook.Add("Think", "PIXEL.UI.VersionChecker", function() - hook.Remove("Think", "PIXEL.UI.VersionChecker") - - http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) - if PIXEL.UI.Version ~= string.Trim(body) then - local red = Color(192, 27, 27) - - MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") - MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") - MsgC(red, "New version: " .. body .. "\n") - return - end - end) -end) + hook.Remove("Think", "PIXEL.UI.VersionChecker") + + http.Fetch("https://raw.githubusercontent.com/Pulsar-Dev/pixel-ui/master/VERSION", function(body) + if PIXEL.UI.Version ~= string.Trim(body) then + local red = Color(192, 27, 27) + MsgC(red, "[PIXEL UI] There is an update available, please download it at: https://github.com/Pulsar-Dev/pixel-ui/releases/latest\n") + MsgC(red, "\nYour version: " .. PIXEL.UI.Version .. "\n") + MsgC(red, "New version: " .. body .. "\n") + + return + end + end) +end) \ No newline at end of file diff --git a/lua/pixelui/core/themes/cl_themes.lua b/lua/pixelui/core/themes/cl_themes.lua index 874e28a..a279f23 100644 --- a/lua/pixelui/core/themes/cl_themes.lua +++ b/lua/pixelui/core/themes/cl_themes.lua @@ -1,8 +1,7 @@ PIXEL = PIXEL or {} PIXEL.Themes = PIXEL.Themes or {} -PIXEL.DefaultThemes = PIXEL.DefaultThemes or { - "Dark", "Light", "GitHubDark", "NightOwl", "DiscordDark", "DiscordLight" -} + +PIXEL.DefaultThemes = PIXEL.DefaultThemes or {"Dark", "Light", "GitHubDark", "NightOwl", "DiscordDark", "DiscordLight"} PIXEL.Themes["Dark"] = { included = true, @@ -10,21 +9,17 @@ PIXEL.Themes["Dark"] = { Header = Color(28, 28, 28), SecondaryHeader = Color(43, 43, 43), Scroller = Color(61, 61, 61), - PrimaryText = Color(255, 255, 255), SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - - Primary = Color(74, 61, 255), + Primary = Color(2, 153, 204), Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), Negative = Color(235, 68, 68), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -34,21 +29,17 @@ PIXEL.Themes["Light"] = { Header = PIXEL.HexToColor("#edf1f5"), SecondaryHeader = PIXEL.HexToColor("#DFE1E4"), Scroller = PIXEL.HexToColor("#edf1f5"), - PrimaryText = PIXEL.HexToColor("#292D31"), SecondaryText = PIXEL.HexToColor("#808080"), DisabledText = PIXEL.HexToColor("#9ba0a3"), - - Primary = Color(74, 61, 255), + Primary = Color(2, 153, 204), Disabled = PIXEL.HexToColor("#9ba0a3"), Positive = PIXEL.HexToColor("#79CB60"), Negative = PIXEL.HexToColor("#d73a49"), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -58,21 +49,17 @@ PIXEL.Themes["GitHubDark"] = { Header = PIXEL.HexToColor("#2f363d"), SecondaryHeader = PIXEL.HexToColor("#2b3036"), Scroller = PIXEL.HexToColor("#2f363d"), - - PrimaryText = Color(74, 61, 255), + PrimaryText = Color(255, 255, 255), SecondaryText = PIXEL.HexToColor("#c9d1d9"), DisabledText = PIXEL.HexToColor("#39414a"), - - Primary = PIXEL.HexToColor("#b392f0"), + Primary = Color(2, 153, 204), Disabled = PIXEL.HexToColor("#6a737d"), Positive = PIXEL.HexToColor("#85e89d"), Negative = PIXEL.HexToColor("#f97583"), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -82,21 +69,17 @@ PIXEL.Themes["NightOwl"] = { Header = PIXEL.HexToColor("#0b2942"), -- Seccond Background SecondaryHeader = PIXEL.HexToColor("#13344f"), -- Active Scroller = PIXEL.HexToColor("#0b2942"), -- Seccond Background - PrimaryText = PIXEL.HexToColor("#FBFBFB"), -- Text SecondaryText = PIXEL.HexToColor("#d9d9d9"), -- Buttons DisabledText = PIXEL.HexToColor("#697098"), -- Disabled - - Primary = Color(74, 61, 255), + Primary = Color(2, 153, 204), Disabled = PIXEL.HexToColor("#697098"), -- Disabled Positive = PIXEL.HexToColor("#addb67"), -- Green Negative = PIXEL.HexToColor("#ff6363"), -- Red - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -106,21 +89,17 @@ PIXEL.Themes["DiscordDark"] = { Header = Color(47, 49, 54), SecondaryHeader = Color(51, 54, 59), Scroller = Color(32, 34, 37), - PrimaryText = Color(255, 255, 255), SecondaryText = Color(185, 187, 190), DisabledText = Color(40, 40, 40), - - Primary = Color(88, 101, 242), + Primary = Color(2, 153, 204), Disabled = Color(114, 118, 125), Positive = Color(87, 242, 135), Negative = Color(237, 66, 69), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } @@ -130,20 +109,16 @@ PIXEL.Themes["DiscordLight"] = { Header = Color(242, 243, 245), SecondaryHeader = Color(220, 223, 227), Scroller = Color(204, 204, 204), - PrimaryText = Color(6, 6, 7), SecondaryText = Color(79, 86, 96), DisabledText = Color(79, 86, 96), - - Primary = Color(88, 101, 242), + Primary = Color(2, 153, 204), Disabled = Color(79, 86, 96), Positive = Color(87, 242, 135), Negative = Color(237, 66, 69), - Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } \ No newline at end of file diff --git a/lua/pixelui/core/themes/sh_themes.lua b/lua/pixelui/core/themes/sh_themes.lua index 0e0aa17..fe28098 100644 --- a/lua/pixelui/core/themes/sh_themes.lua +++ b/lua/pixelui/core/themes/sh_themes.lua @@ -1,22 +1,23 @@ PIXEL.Colors = { - Background = Color(22, 22, 22), - Header = Color(28, 28, 28), - SecondaryHeader = Color(15, 15, 15), + Background = Color(31, 31, 31), + Header = Color(40, 41, 42), + SecondaryHeader = Color(45, 47, 49), Scroller = Color(61, 61, 61), - + Outline = Color(55, 56, 57), + -- PrimaryText = Color(255, 255, 255), SecondaryText = Color(220, 220, 220), DisabledText = Color(40, 40, 40), - - Primary = Color(77, 79, 199), + -- + Primary = Color(66, 133, 244), + -- Disabled = Color(180, 180, 180), Positive = Color(68, 235, 124), - Negative = Color(235, 68, 68), - + Negative = Color(179, 38, 30), + -- Diamond = Color(185, 242, 255), Gold = Color(255, 215, 0), Silver = Color(192, 192, 192), Bronze = Color(145, 94, 49), - Transparent = Color(0, 0, 0, 0) } \ No newline at end of file diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index bfc75b0..d0f2104 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -16,163 +16,166 @@ --]] local PANEL = {} - AccessorFunc(PANEL, "IsToggle", "IsToggle", FORCE_BOOL) AccessorFunc(PANEL, "Toggle", "Toggle", FORCE_BOOL) AccessorFunc(PANEL, "Clicky", "Clicky", FORCE_BOOL) AccessorFunc(PANEL, "Sounds", "Sounds", FORCE_BOOL) - function PANEL:Init() - self:SetIsToggle(false) - self:SetToggle(false) - self:SetMouseInputEnabled(true) - - self:SetCursor("hand") - self:SetClicky(false) - self:SetSounds(true) - - local btnSize = PIXEL.Scale(30) - self:SetSize(btnSize, btnSize) - - self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) - self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) - self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) - self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) - self.ClickyCol = PIXEL.OffsetColor(self.NormalCol, -35) - - self.BackgroundCol = self.NormalCol - self.BackgroundClickyCol = self.ClickyCol - - self.ClickyScale = PIXEL.Scale(3) - self.Clicky = self:GetClicky() - self.ClickyMove = false + self:SetIsToggle(false) + self:SetToggle(false) + self:SetMouseInputEnabled(true) + self:SetCursor("hand") + self:SetClicky(false) + self:SetSounds(true) + local btnSize = PIXEL.Scale(30) + self:SetSize(btnSize, btnSize) + self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) + self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) + self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) + self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) + self.ClickyCol = PIXEL.OffsetColor(self.NormalCol, -35) + self.BackgroundCol = self.NormalCol + self.BackgroundClickyCol = self.ClickyCol + self.ClickyScale = PIXEL.Scale(3) + self.Clicky = self:GetClicky() + self.ClickyMove = false end function PANEL:PerformLayout() - local tall = self:GetTall() - - if tall > 75 then - self.ClickyScale = self:GetTall() / 25 - elseif tall > 50 then - self.ClickyScale = self:GetTall() / 17 - elseif tall > 25 then - self.ClickyScale = self:GetTall() / 10 - elseif tall > 15 then - self.ClickyScale = self:GetTall() / 5 - end + local tall = self:GetTall() + + if tall > 75 then + self.ClickyScale = self:GetTall() / 25 + elseif tall > 50 then + self.ClickyScale = self:GetTall() / 17 + elseif tall > 25 then + self.ClickyScale = self:GetTall() / 10 + elseif tall > 15 then + self.ClickyScale = self:GetTall() / 5 + end end function PANEL:DoToggle(...) - if not self:GetIsToggle() then return end - - self:SetToggle(not self:GetToggle()) - self:OnToggled(self:GetToggle(), ...) + if not self:GetIsToggle() then return end + self:SetToggle(not self:GetToggle()) + self:OnToggled(self:GetToggle(), ...) end local localPly -function PANEL:OnMousePressed(mouseCode) - if not self:IsEnabled() then return end - self.ClickyMove = true - if self:GetSounds() then - PIXEL.PlayButtonSound() - end - - if not localPly then - localPly = LocalPlayer() - end - if self:IsSelectable() and mouseCode == MOUSE_LEFT and (input.IsShiftDown() or input.IsControlDown()) and not (localPly:KeyDown(IN_FORWARD) or localPly:KeyDown(IN_BACK) or localPly:KeyDown(IN_MOVELEFT) or localPly:KeyDown(IN_MOVERIGHT)) then - return self:StartBoxSelection() - end - - self:MouseCapture(true) - self.Depressed = true - self:OnPressed(mouseCode) - - self:DragMousePress(mouseCode) +function PANEL:OnMousePressed(mouseCode) + if not self:IsEnabled() then return end + self.ClickyMove = true + + if self:GetSounds() then + PIXEL.PlayButtonSound() + end + + if not localPly then + localPly = LocalPlayer() + end + + if self:IsSelectable() and mouseCode == MOUSE_LEFT and (input.IsShiftDown() or input.IsControlDown()) and not (localPly:KeyDown(IN_FORWARD) or localPly:KeyDown(IN_BACK) or localPly:KeyDown(IN_MOVELEFT) or localPly:KeyDown(IN_MOVERIGHT)) then return self:StartBoxSelection() end + self:MouseCapture(true) + self.Depressed = true + self:OnPressed(mouseCode) + self:DragMousePress(mouseCode) end function PANEL:OnMouseReleased(mouseCode) - self:MouseCapture(false) - - if not self:IsEnabled() then return end - if not self.Depressed and dragndrop.m_DraggingMain ~= self then return end - - self.ClickyMove = false - - if self.Depressed then - self.Depressed = nil - self:OnReleased(mouseCode) - end + self:MouseCapture(false) + if not self:IsEnabled() then return end + if not self.Depressed and dragndrop.m_DraggingMain ~= self then return end + self.ClickyMove = false + + if self.Depressed then + self.Depressed = nil + self:OnReleased(mouseCode) + end + + if self:DragMouseRelease(mouseCode) then return end + + if self:IsSelectable() and mouseCode == MOUSE_LEFT then + local canvas = self:GetSelectionCanvas() + + if canvas then + canvas:UnselectAll() + end + end + + if not self.Hovered then return end + self.Depressed = true + + if mouseCode == MOUSE_RIGHT then + self:DoRightClick() + elseif mouseCode == MOUSE_LEFT then + self:DoClick() + elseif mouseCode == MOUSE_MIDDLE then + self:DoMiddleClick() + end + + self.Depressed = nil +end - if self:DragMouseRelease(mouseCode) then - return - end +function PANEL:PaintExtra(w, h) +end - if self:IsSelectable() and mouseCode == MOUSE_LEFT then - local canvas = self:GetSelectionCanvas() - if canvas then - canvas:UnselectAll() - end - end +function PANEL:Paint(w, h) + if not self:IsEnabled() then + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h, self.DisabledCol) + self:PaintExtra(w, h) + + return + end + + local bgCol = self.NormalCol + + if self:IsDown() or self:GetToggle() then + bgCol = self.ClickedCol + elseif self:IsHovered() and not self.Clicky then + bgCol = self.HoverCol + end + + if not self.Clicky then + self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) + end + + if not self:GetClicky() then + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h, self.BackgroundCol) + else + if self.ClickyMove then + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) + else + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h, self.ClickyCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(6), 0, 0, w, h - self.ClickyScale, self.BackgroundCol) + end + end + + self:PaintExtra(w, h) +end - if not self.Hovered then return end +function PANEL:IsDown() + return self.Depressed +end - self.Depressed = true +function PANEL:OnPressed(mouseCode) +end - if mouseCode == MOUSE_RIGHT then - self:DoRightClick() - elseif mouseCode == MOUSE_LEFT then - self:DoClick() - elseif mouseCode == MOUSE_MIDDLE then - self:DoMiddleClick() - end +function PANEL:OnReleased(mouseCode) +end - self.Depressed = nil +function PANEL:OnToggled(enabled) end -function PANEL:PaintExtra(w, h) end +function PANEL:DoClick(...) + self:DoToggle(...) +end -function PANEL:Paint(w, h) - if not self:IsEnabled() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.DisabledCol) - self:PaintExtra(w, h) - return - end - - local bgCol = self.NormalCol - - if self:IsDown() or self:GetToggle() then - bgCol = self.ClickedCol - elseif self:IsHovered() and not self.Clicky then - bgCol = self.HoverCol - end - - if not self.Clicky then - self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) - end - - if not self:GetClicky() then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) - else - if self.ClickyMove then - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, self.ClickyScale, w, h - self.ClickyScale, self.BackgroundCol) - else - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.ClickyCol) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h - self.ClickyScale, self.BackgroundCol) - end - end - - self:PaintExtra(w, h) +function PANEL:DoRightClick() end -function PANEL:IsDown() return self.Depressed end -function PANEL:OnPressed(mouseCode) end -function PANEL:OnReleased(mouseCode) end -function PANEL:OnToggled(enabled) end -function PANEL:DoClick(...) self:DoToggle(...) end -function PANEL:DoRightClick() end -function PANEL:DoMiddleClick() end +function PANEL:DoMiddleClick() +end -vgui.Register("PIXEL.Button", PANEL, "Panel") +vgui.Register("PIXEL.Button", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_category.lua b/lua/pixelui/elements/cl_category.lua index 89fcea4..bc33bd1 100644 --- a/lua/pixelui/elements/cl_category.lua +++ b/lua/pixelui/elements/cl_category.lua @@ -16,9 +16,7 @@ --]] local PANEL = {} - AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) - PIXEL.RegisterFont("UI.CategoryHeader", "Open Sans Bold", 19) function PANEL:Init() @@ -32,20 +30,17 @@ function PANEL:DoClick() end local lerp = Lerp + function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(PIXEL.Scale(8), 0, 0, w, h, self.BackgroundCol) PIXEL.DrawSimpleText(self.Title, "UI.CategoryHeader", PIXEL.Scale(10), h / 2, PIXEL.Colors.PrimaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) - self.ArrowRotation = lerp(FrameTime() * 10, self.ArrowRotation, self:GetParent():GetExpanded() and 0 or 90) - local arrowSize = h * .45 PIXEL.DrawImgurRotated(w - h * .3 - PIXEL.Scale(4), h / 2, arrowSize, arrowSize, self.ArrowRotation, "30Bvuwi", PIXEL.Colors.PrimaryText) end vgui.Register("PIXEL.CategoryHeader", PANEL, "PIXEL.Button") - PANEL = {} - AccessorFunc(PANEL, "m_bSizeExpanded", "Expanded", FORCE_BOOL) AccessorFunc(PANEL, "m_iContentHeight", "StartHeight") AccessorFunc(PANEL, "m_fAnimTime", "AnimTime") @@ -55,20 +50,17 @@ AccessorFunc(PANEL, "m_pList", "List") function PANEL:Init() self.Header = vgui.Create("PIXEL.CategoryHeader", self) - self:SetTitle("PIXEL Category") - self:SetExpanded(true) self:SetMouseInputEnabled(true) - self:SetAnimTime(0.2) self.SlideAnimation = Derma_Anim("Anim", self, self.AnimSlide) - self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 2) end function PANEL:UnselectAll() local children = self:GetChildren() + for k, v in pairs(children) do if v.SetSelected then v:SetSelected(false) @@ -92,7 +84,6 @@ function PANEL:SetContents(contents) self.Contents = contents self.Contents:SetParent(self) self.Contents:Dock(FILL) - local margin = PIXEL.Scale(8) self.Contents:DockMargin(margin, margin, margin, margin) @@ -119,21 +110,24 @@ end function PANEL:Toggle() self:SetExpanded(not self:GetExpanded()) - self.SlideAnimation:Start(self:GetAnimTime(), {From = self:GetTall()}) + self.SlideAnimation:Start(self:GetAnimTime(), { + From = self:GetTall() + }) self:InvalidateLayout(true) - self:OnToggle(self:GetExpanded()) end -function PANEL:OnToggle(expanded) end +function PANEL:OnToggle(expanded) +end function PANEL:DoExpansion(b) if self:GetExpanded() == b then return end self:Toggle() end -function PANEL:LayoutContent(w, h) end +function PANEL:LayoutContent(w, h) +end function PANEL:PerformLayout(w, h) self.Header:Dock(TOP) @@ -149,20 +143,26 @@ function PANEL:PerformLayout(w, h) end if self:GetExpanded() then - if IsValid(self.Contents) and #self.Contents:GetChildren() > 0 then self.Contents:SizeToChildren(false, true) end + if IsValid(self.Contents) and #self.Contents:GetChildren() > 0 then + self.Contents:SizeToChildren(false, true) + end + self:SizeToChildren(false, true) else - if IsValid(self.Contents) and not self.OldHeight then self.OldHeight = self.Contents:GetTall() end + if IsValid(self.Contents) and not self.OldHeight then + self.OldHeight = self.Contents:GetTall() + end + self:SetTall(self.Header:GetTall()) end self.SlideAnimation:Run() - self:LayoutContent(w, h) end function PANEL:OnMousePressed(mcode) if not self:GetParent().OnMousePressed then return end + return self:GetParent():OnMousePressed(mcode) end @@ -173,6 +173,7 @@ function PANEL:AnimSlide(anim, delta, data) if anim.Started then if not IsValid(self.Contents) and (self.OldHeight or 0) < self.Header:GetTall() then self.OldHeight = 0 + for id, pnl in pairs(self:GetChildren()) do self.OldHeight = self.OldHeight + pnl:GetTall() end @@ -185,11 +186,12 @@ function PANEL:AnimSlide(anim, delta, data) end end - if IsValid(self.Contents) then self.Contents:SetVisible(true) end + if IsValid(self.Contents) then + self.Contents:SetVisible(true) + end self:GetParent():InvalidateLayout() self:GetParent():GetParent():InvalidateLayout() - self:SetTall(Lerp(delta, data.From, data.To)) end diff --git a/lua/pixelui/elements/cl_check_box.lua b/lua/pixelui/elements/cl_check_box.lua index 2c87f37..72fda42 100644 --- a/lua/pixelui/elements/cl_check_box.lua +++ b/lua/pixelui/elements/cl_check_box.lua @@ -19,19 +19,14 @@ local PANEL = {} function PANEL:Init() self:SetIsToggle(true) - local boxSize = PIXEL.Scale(20) self:SetSize(boxSize, boxSize) - self:SetImgurID("YvG7VI6") - self:SetNormalColor(PIXEL.Colors.Transparent) self:SetHoverColor(PIXEL.Colors.PrimaryText) self:SetClickColor(PIXEL.Colors.PrimaryText) self:SetDisabledColor(PIXEL.Colors.Transparent) - self:SetImageSize(.8) - self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Primary) end @@ -39,6 +34,7 @@ function PANEL:PaintBackground(w, h) if not self:IsEnabled() then PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Disabled) self:PaintExtra(w, h) + return end @@ -50,7 +46,6 @@ function PANEL:PaintBackground(w, h) local animTime = FrameTime() * 12 self.BackgroundCol = PIXEL.LerpColor(animTime, self.BackgroundCol, bgCol) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, self.BackgroundCol) end diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index a9a24e6..1369ea4 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -16,7 +16,6 @@ --]] local PANEL = {} - AccessorFunc(PANEL, "Draggable", "Draggable", FORCE_BOOL) AccessorFunc(PANEL, "Sizable", "Sizable", FORCE_BOOL) AccessorFunc(PANEL, "MinWidth", "MinWidth", FORCE_NUMBER) @@ -26,245 +25,296 @@ AccessorFunc(PANEL, "RemoveOnClose", "RemoveOnClose", FORCE_BOOL) AccessorFunc(PANEL, "SlideOut", "SlideOut", FORCE_BOOL) AccessorFunc(PANEL, "SlideDirection", "SlideDirection", FORCE_NUMBER) -- 1 = up, 2 = right, 3 = down, 4 = left AccessorFunc(PANEL, "SlideTime", "SlideTime", FORCE_NUMBER) - - AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) - PIXEL.RegisterFont("UI.FrameTitle", "Open Sans Bold", 22) function PANEL:Init() - self.CloseButton = vgui.Create("PIXEL.ImgurButton", self) - self.CloseButton:SetImgurID("z1uAU0b") - self.CloseButton:SetNormalColor(PIXEL.Colors.PrimaryText) - self.CloseButton:SetHoverColor(PIXEL.Colors.Negative) - self.CloseButton:SetClickColor(PIXEL.Colors.Negative) - self.CloseButton:SetDisabledColor(PIXEL.Colors.DisabledText) - - self.CloseButton.DoClick = function(s) - self:Close() - end + self.CloseButton = vgui.Create("PIXEL.ImgurButton", self) + self.CloseButton:SetImgurID("z1uAU0b") + self.CloseButton:SetNormalColor(PIXEL.Colors.PrimaryText) + self.CloseButton:SetHoverColor(PIXEL.Colors.Negative) + self.CloseButton:SetClickColor(PIXEL.Colors.Negative) + self.CloseButton:SetDisabledColor(PIXEL.Colors.DisabledText) + + self.CloseButton.DoClick = function(s) + self:Close() + end + + self:SetSlideOut(false) + self.ExtraButtons = {} + self:SetTitle("PIXEL Frame") + self:SetDraggable(true) + self:SetScreenLock(true) + self:SetRemoveOnClose(true) + local size = PIXEL.Scale(200) + self:SetMinWidth(size) + self:SetMinHeight(size) + local oldMakePopup = self.MakePopup + + function self:MakePopup() + oldMakePopup(self) + self:Open() + end +end - self:SetSlideOut(false) +function PANEL:DragThink(targetPanel, hoverPanel) + local scrw, scrh = ScrW(), ScrH() + local mousex, mousey = math.Clamp(gui.MouseX(), 1, scrw - 1), math.Clamp(gui.MouseY(), 1, scrh - 1) - self.ExtraButtons = {} + if targetPanel.Dragging then + local x = mousex - targetPanel.Dragging[1] + local y = mousey - targetPanel.Dragging[2] - self:SetTitle("PIXEL Frame") + if targetPanel:GetScreenLock() then + x = math.Clamp(x, 0, scrw - targetPanel:GetWide()) + y = math.Clamp(y, 0, scrh - targetPanel:GetTall()) + end - self:SetDraggable(true) - self:SetScreenLock(true) - self:SetRemoveOnClose(true) + targetPanel:SetPos(x, y) + end - local size = PIXEL.Scale(200) - self:SetMinWidth(size) - self:SetMinHeight(size) + local _, screenY = targetPanel:LocalToScreen(0, 0) - local oldMakePopup = self.MakePopup - function self:MakePopup() - oldMakePopup(self) - self:Open() - end -end + if (hoverPanel or targetPanel).Hovered and targetPanel:GetDraggable() and mousey < (screenY + PIXEL.Scale(30)) then + targetPanel:SetCursor("sizeall") -function PANEL:DragThink(targetPanel, hoverPanel) - local scrw, scrh = ScrW(), ScrH() - local mousex, mousey = math.Clamp(gui.MouseX(), 1, scrw - 1), math.Clamp(gui.MouseY(), 1, scrh - 1) - - if targetPanel.Dragging then - local x = mousex - targetPanel.Dragging[1] - local y = mousey - targetPanel.Dragging[2] - - if targetPanel:GetScreenLock() then - x = math.Clamp(x, 0, scrw - targetPanel:GetWide()) - y = math.Clamp(y, 0, scrh - targetPanel:GetTall()) - end - - targetPanel:SetPos(x, y) - end - - local _, screenY = targetPanel:LocalToScreen(0, 0) - if (hoverPanel or targetPanel).Hovered and targetPanel:GetDraggable() and mousey < (screenY + PIXEL.Scale(30)) then - targetPanel:SetCursor("sizeall") - return true - end + return true + end end function PANEL:SizeThink(targetPanel, hoverPanel) - local scrw, scrh = ScrW(), ScrH() - local mousex, mousey = math.Clamp(gui.MouseX(), 1, scrw - 1), math.Clamp(gui.MouseY(), 1, scrh - 1) - - if targetPanel.Sizing then - local x = mousex - targetPanel.Sizing[1] - local y = mousey - targetPanel.Sizing[2] - local px, py = targetPanel:GetPos() - - local screenLock = self:GetScreenLock() - if x < targetPanel.MinWidth then x = targetPanel.MinWidth elseif x > scrw - px and screenLock then x = scrw - px end - if y < targetPanel.MinHeight then y = targetPanel.MinHeight elseif y > scrh - py and screenLock then y = scrh - py end - - targetPanel:SetSize(x, y) - targetPanel:SetCursor("sizenwse") - return true - end - - local screenX, screenY = targetPanel:LocalToScreen(0, 0) - if (hoverPanel or targetPanel).Hovered and targetPanel.Sizable and mousex > (screenX + targetPanel:GetWide() - PIXEL.Scale(20)) and mousey > (screenY + targetPanel:GetTall() - PIXEL.Scale(20)) then - (hoverPanel or targetPanel):SetCursor("sizenwse") - return true - end + local scrw, scrh = ScrW(), ScrH() + local mousex, mousey = math.Clamp(gui.MouseX(), 1, scrw - 1), math.Clamp(gui.MouseY(), 1, scrh - 1) + + if targetPanel.Sizing then + local x = mousex - targetPanel.Sizing[1] + local y = mousey - targetPanel.Sizing[2] + local px, py = targetPanel:GetPos() + local screenLock = self:GetScreenLock() + + if x < targetPanel.MinWidth then + x = targetPanel.MinWidth + elseif x > scrw - px and screenLock then + x = scrw - px + end + + if y < targetPanel.MinHeight then + y = targetPanel.MinHeight + elseif y > scrh - py and screenLock then + y = scrh - py + end + + targetPanel:SetSize(x, y) + targetPanel:SetCursor("sizenwse") + + return true + end + + local screenX, screenY = targetPanel:LocalToScreen(0, 0) + + if (hoverPanel or targetPanel).Hovered and targetPanel.Sizable and mousex > (screenX + targetPanel:GetWide() - PIXEL.Scale(20)) and mousey > (screenY + targetPanel:GetTall() - PIXEL.Scale(20)) then + (hoverPanel or targetPanel):SetCursor("sizenwse") + + return true + end end function PANEL:Think() - if self:DragThink(self) then return end - if self:SizeThink(self) then return end - - self:SetCursor("arrow") + if self:DragThink(self) then return end + if self:SizeThink(self) then return end + self:SetCursor("arrow") - if self.y < 0 then - self:SetPos(self.x, 0) - end + if self.y < 0 then + self:SetPos(self.x, 0) + end end function PANEL:OnMousePressed() - local screenX, screenY = self:LocalToScreen(0, 0) - local mouseX, mouseY = gui.MouseX(), gui.MouseY() - - if self.Sizable and mouseX > (screenX + self:GetWide() - PIXEL.Scale(30)) and mouseY > (screenY + self:GetTall() - PIXEL.Scale(30)) then - self.Sizing = {mouseX - self:GetWide(), mouseY - self:GetTall()} - self:MouseCapture(true) - return - end - - if self:GetDraggable() and mouseY < (screenY + PIXEL.Scale(30)) then - self.Dragging = {mouseX - self.x, mouseY - self.y} - self:MouseCapture(true) - return - end + local screenX, screenY = self:LocalToScreen(0, 0) + local mouseX, mouseY = gui.MouseX(), gui.MouseY() + + if self.Sizable and mouseX > (screenX + self:GetWide() - PIXEL.Scale(30)) and mouseY > (screenY + self:GetTall() - PIXEL.Scale(30)) then + self.Sizing = {mouseX - self:GetWide(), mouseY - self:GetTall()} + + self:MouseCapture(true) + + return + end + + if self:GetDraggable() and mouseY < (screenY + PIXEL.Scale(30)) then + self.Dragging = {mouseX - self.x, mouseY - self.y} + + self:MouseCapture(true) + + return + end end function PANEL:OnMouseReleased() - self.Dragging = nil - self.Sizing = nil - self:MouseCapture(false) + self.Dragging = nil + self.Sizing = nil + self:MouseCapture(false) end function PANEL:CreateSidebar(defaultItem, imgurID, imgurScale, imgurYOffset, buttonYOffset) - if IsValid(self.SideBar) then return end - self.SideBar = vgui.Create("PIXEL.Sidebar", self) - - if defaultItem then - timer.Simple(0, function() - if not IsValid(self.SideBar) then return end - self.SideBar:SelectItem(defaultItem) - end) - end - - if imgurID then self.SideBar:SetImgurID(imgurID) end - if imgurScale then self.SideBar:SetImgurScale(imgurScale) end - if imgurYOffset then self.SideBar:SetImgurOffset(imgurYOffset) end - if buttonYOffset then self.SideBar:SetButtonOffset(buttonYOffset) end - - return self.SideBar + if IsValid(self.SideBar) then return end + self.SideBar = vgui.Create("PIXEL.Sidebar", self) + + if defaultItem then + timer.Simple(0, function() + if not IsValid(self.SideBar) then return end + self.SideBar:SelectItem(defaultItem) + end) + end + + if imgurID then + self.SideBar:SetImgurID(imgurID) + end + + if imgurScale then + self.SideBar:SetImgurScale(imgurScale) + end + + if imgurYOffset then + self.SideBar:SetImgurOffset(imgurYOffset) + end + + if buttonYOffset then + self.SideBar:SetButtonOffset(buttonYOffset) + end + + return self.SideBar end function PANEL:AddHeaderButton(elem, size) - elem.HeaderIconSize = size or .45 - return table.insert(self.ExtraButtons, elem) + elem.HeaderIconSize = size or .45 + + return table.insert(self.ExtraButtons, elem) end -function PANEL:LayoutContent(w, h) end +function PANEL:LayoutContent(w, h) +end function PANEL:PerformLayout(w, h) - local headerH = PIXEL.Scale(30) - local btnPad = PIXEL.Scale(6) - local btnSpacing = PIXEL.Scale(6) - - if IsValid(self.CloseButton) then - local btnSize = headerH * .45 - self.CloseButton:SetSize(btnSize, btnSize) - self.CloseButton:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) - - btnPad = btnPad + btnSize + btnSpacing - end - - for _, btn in ipairs(self.ExtraButtons) do - local btnSize = headerH * btn.HeaderIconSize - btn:SetSize(btnSize, btnSize) - btn:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) - btnPad = btnPad + btnSize + btnSpacing - end - - if IsValid(self.SideBar) then - self.SideBar:SetPos(0, headerH) - self.SideBar:SetSize(PIXEL.Scale(200), h - headerH) - end - - local padding = PIXEL.Scale(6) - self:DockPadding(self.SideBar and PIXEL.Scale(200) + padding or padding, headerH + padding, padding, padding) - - self:LayoutContent(w, h) + local headerH = PIXEL.Scale(30) + local btnPad = PIXEL.Scale(6) + local btnSpacing = PIXEL.Scale(6) + + if IsValid(self.CloseButton) then + local btnSize = headerH * .45 + self.CloseButton:SetSize(btnSize, btnSize) + self.CloseButton:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) + btnPad = btnPad + btnSize + btnSpacing + end + + for _, btn in ipairs(self.ExtraButtons) do + local btnSize = headerH * btn.HeaderIconSize + btn:SetSize(btnSize, btnSize) + btn:SetPos(w - btnSize - btnPad, (headerH - btnSize) / 2) + btnPad = btnPad + btnSize + btnSpacing + end + + if IsValid(self.SideBar) then + self.SideBar:SetPos(0, headerH) + self.SideBar:SetSize(PIXEL.Scale(200), h - headerH) + end + + local padding = PIXEL.Scale(6) + self:DockPadding(self.SideBar and PIXEL.Scale(200) + padding or padding, headerH + padding, padding, padding) + self:LayoutContent(w, h) end function PANEL:Open() - PIXEL.PlayButtonSound() - self:SetVisible(false) - self:SetAlpha(0) - self:SetVisible(true) - self:AlphaTo(255, .1, 0) + PIXEL.PlayButtonSound() + self:SetVisible(false) + self:SetAlpha(0) + self:SetVisible(true) + self:AlphaTo(255, .1, 0) end - function PANEL:Close() - if not self:GetSlideOut() then - self:AlphaTo(0, .1, 0, function(anim, pnl) - if not IsValid(pnl) then return end - pnl:SetVisible(false) - pnl:OnClose() - if pnl:GetRemoveOnClose() then pnl:Remove() end - end) - return - end - - local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() - local slideDirections = { - [1] = {x = (scrw / 2) - (wide / 2), y = -tall,size = function() self:SizeTo(wide, 0, (self:GetSlideTime() - 0.2) or .3, 0, -1) end},-- up - [2] = {x = scrw,y = posY,size = function() end},-- right - [3] = {x = (scrw / 2) - (wide / 2), y = scrh + tall, size = function() end},-- down - [4] = {x = -wide,y = posY,size = function() end},-- left - } - - local direction = self:GetSlideDirection() or 1 - slideDirections[direction].size() - self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, self:GetSlideTime() or .5, 0, -1, function(anim, pnl) - if not IsValid(pnl) then return end - pnl:SetVisible(false) - pnl:OnClose() - if pnl:GetRemoveOnClose() then pnl:Remove() end - end) + if not self:GetSlideOut() then + self:AlphaTo(0, .1, 0, function(anim, pnl) + if not IsValid(pnl) then return end + pnl:SetVisible(false) + pnl:OnClose() + + if pnl:GetRemoveOnClose() then + pnl:Remove() + end + end) + + return + end + + local scrw, scrh, wide, tall, posY = ScrW(), ScrH(), self:GetWide(), self:GetTall(), self:GetY() + + local slideDirections = { + [1] = { + x = (scrw / 2) - (wide / 2), + y = -tall, + size = function() + self:SizeTo(wide, 0, (self:GetSlideTime() - 0.2) or .3, 0, -1) + end + }, -- up + [2] = { + x = scrw, + y = posY, + size = function() end + }, -- right + [3] = { + x = (scrw / 2) - (wide / 2), + y = scrh + tall, + size = function() end + }, -- down + [4] = { + x = -wide, + y = posY, + size = function() end + }, -- left + + } + + local direction = self:GetSlideDirection() or 1 + slideDirections[direction].size() + + self:MoveTo(slideDirections[direction].x, slideDirections[direction].y, self:GetSlideTime() or .5, 0, -1, function(anim, pnl) + if not IsValid(pnl) then return end + pnl:SetVisible(false) + pnl:OnClose() + + if pnl:GetRemoveOnClose() then + pnl:Remove() + end + end) end -function PANEL:OnClose() end +function PANEL:OnClose() +end function PANEL:PaintHeader(x, y, w, h) - PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), x, y, w, h, PIXEL.Colors.Header, true, true) + PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), x, y, w, h, PIXEL.Colors.Header, true, true) + local imgurID = self:GetImgurID() - local imgurID = self:GetImgurID() - if imgurID then - local iconSize = h * .6 - PIXEL.DrawImgur(PIXEL.Scale(6), x + (h - iconSize) / 2, y + iconSize, iconSize, imgurID, color_white) - PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(12) + iconSize, y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) - return - end + if imgurID then + local iconSize = h * .6 + PIXEL.DrawImgur(PIXEL.Scale(6), x + (h - iconSize) / 2, y + iconSize, iconSize, imgurID, color_white) + PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(12) + iconSize, y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) - PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(8), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) + return + end + + PIXEL.DrawSimpleText(self:GetTitle(), "UI.FrameTitle", x + PIXEL.Scale(8), y + h / 2, PIXEL.Colors.PrimaryText, nil, TEXT_ALIGN_CENTER) end -function PANEL:PaintMore(w,h) end +function PANEL:PaintMore(w, h) +end function PANEL:Paint(w, h) - PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Background) - self:PaintHeader(0, 0, w, PIXEL.Scale(30)) - self:PaintMore(w, h) + PIXEL.DrawRoundedBox(PIXEL.Scale(4), 0, 0, w, h, PIXEL.Colors.Background) + self:PaintHeader(0, 0, w, PIXEL.Scale(30)) + self:PaintMore(w, h) end -vgui.Register("PIXEL.Frame", PANEL, "EditablePanel") +vgui.Register("PIXEL.Frame", PANEL, "EditablePanel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_sidebar.lua b/lua/pixelui/elements/cl_sidebar.lua index be206bc..5091b48 100644 --- a/lua/pixelui/elements/cl_sidebar.lua +++ b/lua/pixelui/elements/cl_sidebar.lua @@ -16,11 +16,9 @@ --]] local PANEL = {} - AccessorFunc(PANEL, "Name", "Name", FORCE_STRING) AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "DrawOutline", "DrawOutline", FORCE_BOOL) - PIXEL.RegisterFont("SidebarItem", "Open Sans Bold", 19) function PANEL:Init() @@ -28,7 +26,6 @@ function PANEL:Init() self:SetDrawOutline(true) self:SetClicky(false) self:SetSounds(false) - self.TextCol = PIXEL.CopyColor(PIXEL.Colors.SecondaryText) self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) self.BackgroundHoverCol = ColorAlpha(PIXEL.Colors.Scroller, 80) @@ -61,10 +58,12 @@ function PANEL:Paint(w, h) end local imgurID = self:GetImgurID() + if imgurID then local iconSize = h * .65 - PIXEL.DrawImgur(PIXEL.Scale(10), (h - iconSize) / 2, iconSize, iconSize, imgurID, Color(255,255,255)) + PIXEL.DrawImgur(PIXEL.Scale(10), (h - iconSize) / 2, iconSize, iconSize, imgurID, Color(255, 255, 255)) PIXEL.DrawSimpleText(self:GetName(), "SidebarItem", PIXEL.Scale(20) + iconSize, h / 2, self.TextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + return end @@ -72,9 +71,7 @@ function PANEL:Paint(w, h) end vgui.Register("PIXEL.SidebarItem", PANEL, "PIXEL.Button") - PANEL = {} - AccessorFunc(PANEL, "ImgurID", "ImgurID", FORCE_STRING) AccessorFunc(PANEL, "ImgurScale", "ImgurScale", FORCE_NUMBER) AccessorFunc(PANEL, "ImgurOffset", "ImgurOffset", FORCE_NUMBER) @@ -83,13 +80,14 @@ AccessorFunc(PANEL, "ButtonBtmOffset", "ButtonBtmOffset", FORCE_NUMBER) function PANEL:Init() self.Items = {} - self.Scroller = vgui.Create("PIXEL.ScrollPanel", self) self.Scroller:SetBarDockShouldOffset(true) + self.Scroller.LayoutContent = function(s, w, h) local spacing = PIXEL.Scale(8) local height = PIXEL.Scale(35) - for k,v in pairs(self.Items) do + + for k, v in pairs(self.Items) do v:SetTall(height) v:Dock(TOP) v:DockMargin(0, 0, 0, spacing) @@ -99,16 +97,18 @@ function PANEL:Init() self:SetImgurScale(.6) self:SetImgurOffset(0) self:SetButtonOffset(0) - self.BackgroundCol = PIXEL.CopyColor(PIXEL.Colors.Header) end function PANEL:AddItem(id, name, imgurID, doClick, order) local btn = vgui.Create("PIXEL.SidebarItem", self.Scroller) - btn:SetZPos(order or table.Count(self.Items) + 1) btn:SetName(name) - if imgurID then btn:SetImgurID(imgurID) end + + if imgurID then + btn:SetImgurID(imgurID) + end + btn.Function = doClick btn.DoClick = function(s) @@ -123,24 +123,20 @@ end function PANEL:RemoveItem(id) local item = self.Items[id] if not item then return end - item:Remove() self.Items[id] = nil - - if self.SelectedItem != id then return end + if self.SelectedItem ~= id then return end self:SelectItem(next(self.Items)) end function PANEL:SelectItem(id) local item = self.Items[id] if not item then return end - PIXEL.PlayChangeTab() - if self.SelectedItem and self.SelectedItem == id then return end self.SelectedItem = id - for k,v in pairs(self.Items) do + for k, v in pairs(self.Items) do v:SetToggle(false) end @@ -152,19 +148,19 @@ function PANEL:PerformLayout(w, h) local sideSpacing = PIXEL.Scale(7) local topSpacing = PIXEL.Scale(7) self:DockPadding(sideSpacing, self:GetImgurID() and w * self:GetImgurScale() + self:GetImgurOffset() + self:GetButtonOffset() + topSpacing * 2 or topSpacing, sideSpacing, self:GetButtonBtmOffset() or topSpacing) - self.Scroller:Dock(FILL) self.Scroller:GetCanvas():DockPadding(0, 0, self.Scroller.VBar.Enabled and sideSpacing or 0, 0) end function PANEL:Paint(w, h) PIXEL.DrawRoundedBoxEx(PIXEL.Scale(6), 0, 0, w, h, self.BackgroundCol, false, false, true) - + PIXEL.DrawRoundedBox(0, 0, 0, w, PIXEL.Scale(1), PIXEL.Colors.Outline) local imgurID = self:GetImgurID() + if imgurID then local imageSize = w * self:GetImgurScale() PIXEL.DrawImgur((w - imageSize) / 2, self:GetImgurOffset() + PIXEL.Scale(15), imageSize, imageSize, imgurID, color_white) end end -vgui.Register("PIXEL.Sidebar", PANEL, "Panel") +vgui.Register("PIXEL.Sidebar", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 1d9033e..0ce9def 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -19,19 +19,15 @@ local PANEL = {} function PANEL:Init() self.TextEntry = vgui.Create("PIXEL.TextEntryInternal", self) - self.PlaceholderTextCol = PIXEL.OffsetColor(PIXEL.Colors.SecondaryText, -110) - self.DisabledCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 6) self.FocusedOutlineCol = PIXEL.Colors.PrimaryText - self.OutlineCol = PIXEL.OffsetColor(PIXEL.Colors.Scroller, 10) self.InnerOutlineCol = PIXEL.CopyColor(PIXEL.Colors.Transparent) end function PANEL:PerformLayout(w, h) self.TextEntry:Dock(FILL) - local xPad, yPad = PIXEL.Scale(4), PIXEL.Scale(8) self:DockPadding(xPad, yPad, xPad, yPad) end @@ -43,6 +39,7 @@ function PANEL:Paint(w, h) if not self:IsEnabled() and self:GetValue() == "" then PIXEL.DrawSimpleText(self:GetPlaceholderText() or "", "UI.TextEntry", PIXEL.Scale(10), h / 2, self.PlaceholderTextCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + return end @@ -52,7 +49,6 @@ function PANEL:Paint(w, h) local outlineThickness = PIXEL.Scale(1) PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(2), 0, 0, w, h, self.OutlineCol, outlineThickness) - local col = PIXEL.Colors.Transparent if self:IsEditing() then @@ -64,55 +60,123 @@ function PANEL:Paint(w, h) end self.InnerOutlineCol = PIXEL.LerpColor(FrameTime() * 8, self.InnerOutlineCol, col) - PIXEL.DrawOutlinedRoundedBox(PIXEL.Scale(2), outlineThickness, outlineThickness, w - outlineThickness * 2, h - outlineThickness * 2, self.InnerOutlineCol, PIXEL.Scale(1)) end -function PANEL:OnChange() end -function PANEL:OnValueChange(value) end +function PANEL:OnChange() +end -function PANEL:IsEnabled() return self.TextEntry:IsEnabled() end -function PANEL:SetEnabled(enabled) self.TextEntry:SetEnabled(enabled) end +function PANEL:OnValueChange(value) +end -function PANEL:GetValue() return self.TextEntry:GetValue() end -function PANEL:SetValue(value) self.TextEntry:SetValue(value) end +function PANEL:IsEnabled() + return self.TextEntry:IsEnabled() +end -function PANEL:IsMultiline() return self.TextEntry:IsMultiline() end -function PANEL:SetMultiline(isMultiline) self.TextEntry:SetMultiline(isMultiline) end +function PANEL:SetEnabled(enabled) + self.TextEntry:SetEnabled(enabled) +end -function PANEL:IsEditing() return self.TextEntry:IsEditing() end +function PANEL:GetValue() + return self.TextEntry:GetValue() +end -function PANEL:GetEnterAllowed() return self.TextEntry:GetEnterAllowed() end -function PANEL:SetEnterAllowed(allow) self.TextEntry:SetEnterAllowed(allow) end +function PANEL:SetValue(value) + self.TextEntry:SetValue(value) +end -function PANEL:GetUpdateOnType() return self.TextEntry:GetUpdateOnType() end -function PANEL:SetUpdateOnType(enabled) self.TextEntry:SetUpdateOnType(enabled) end +function PANEL:IsMultiline() + return self.TextEntry:IsMultiline() +end -function PANEL:GetNumeric() return self.TextEntry:GetNumeric() end -function PANEL:SetNumeric(enabled) self.TextEntry:SetNumeric(enabled) end +function PANEL:SetMultiline(isMultiline) + self.TextEntry:SetMultiline(isMultiline) +end -function PANEL:GetHistoryEnabled() return self.TextEntry:GetHistoryEnabled() end -function PANEL:SetHistoryEnabled(enabled) self.TextEntry:SetHistoryEnabled(enabled) end +function PANEL:IsEditing() + return self.TextEntry:IsEditing() +end -function PANEL:GetTabbingDisabled() return self.TextEntry:GetTabbingDisabled() end -function PANEL:SetTabbingDisabled(disabled) self.TextEntry:SetTabbingDisabled(disabled) end +function PANEL:GetEnterAllowed() + return self.TextEntry:GetEnterAllowed() +end -function PANEL:GetPlaceholderText() return self.TextEntry:GetPlaceholderText() end -function PANEL:SetPlaceholderText(text) self.TextEntry:SetPlaceholderText(text) end +function PANEL:SetEnterAllowed(allow) + self.TextEntry:SetEnterAllowed(allow) +end -function PANEL:GetInt() return self.TextEntry:GetInt() end -function PANEL:GetFloat() return self.TextEntry:GetFloat() end +function PANEL:GetUpdateOnType() + return self.TextEntry:GetUpdateOnType() +end -function PANEL:IsEditing() return self.TextEntry:IsEditing() end -function PANEL:SetEditable(enabled) self.TextEntry:SetEditable(enabled) end +function PANEL:SetUpdateOnType(enabled) + self.TextEntry:SetUpdateOnType(enabled) +end -function PANEL:AllowInput(value) end -function PANEL:GetAutoComplete(txt) end +function PANEL:GetNumeric() + return self.TextEntry:GetNumeric() +end -function PANEL:OnKeyCode(code) end -function PANEL:OnEnter() end +function PANEL:SetNumeric(enabled) + self.TextEntry:SetNumeric(enabled) +end + +function PANEL:GetHistoryEnabled() + return self.TextEntry:GetHistoryEnabled() +end -function PANEL:OnGetFocus() end -function PANEL:OnLoseFocus() end +function PANEL:SetHistoryEnabled(enabled) + self.TextEntry:SetHistoryEnabled(enabled) +end + +function PANEL:GetTabbingDisabled() + return self.TextEntry:GetTabbingDisabled() +end + +function PANEL:SetTabbingDisabled(disabled) + self.TextEntry:SetTabbingDisabled(disabled) +end + +function PANEL:GetPlaceholderText() + return self.TextEntry:GetPlaceholderText() +end + +function PANEL:SetPlaceholderText(text) + self.TextEntry:SetPlaceholderText(text) +end + +function PANEL:GetInt() + return self.TextEntry:GetInt() +end + +function PANEL:GetFloat() + return self.TextEntry:GetFloat() +end + +function PANEL:IsEditing() + return self.TextEntry:IsEditing() +end + +function PANEL:SetEditable(enabled) + self.TextEntry:SetEditable(enabled) +end + +function PANEL:AllowInput(value) +end + +function PANEL:GetAutoComplete(txt) +end + +function PANEL:OnKeyCode(code) +end + +function PANEL:OnEnter() +end + +function PANEL:OnGetFocus() +end + +function PANEL:OnLoseFocus() +end vgui.Register("PIXEL.TextEntry", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/menus/test/cl_menu.lua b/lua/pixelui/menus/test/cl_menu.lua index 8c54147..0c2e3f2 100644 --- a/lua/pixelui/menus/test/cl_menu.lua +++ b/lua/pixelui/menus/test/cl_menu.lua @@ -2,83 +2,91 @@ PIXEL = PIXEL or {} local PANEL = {} function PANEL:Init() - self:SetSize(PIXEL.Scale(900), PIXEL.Scale(550)) - self:Center() - self:MakePopup() - self:SetTitle("PIXEL Test") - - self.Sidebar = self:CreateSidebar("PIXEL.Test.Avatar", "8bKjn4t") - - self.Sidebar:AddItem("PIXEL.Test.Avatar", "Avatar", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Avatar") - end) - self.Sidebar:AddItem("PIXEL.Test.Buttons", "Buttons", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Buttons") - end) - self.Sidebar:AddItem("PIXEL.Test.Navigation", "Navigation", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Navigation") - end) - self.Sidebar:AddItem("PIXEL.Test.ScrollPanel", "ScrollPanel", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.ScrollPanel") - end) - self.Sidebar:AddItem("PIXEL.Test.Text", "Text", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Text") - end) - self.Sidebar:AddItem("PIXEL.Test.Other", "Other", "8bKjn4t", function() - self:ChangeTab("PIXEL.Test.Other") - end) + self:SetSize(PIXEL.Scale(900), PIXEL.Scale(550)) + self:Center() + self:MakePopup() + self:SetTitle("PIXEL Test") + self.Sidebar = self:CreateSidebar("PIXEL.Test.Avatar", "8bKjn4t") + + self.Sidebar:AddItem("PIXEL.Test.Avatar", "Avatar", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Avatar") + end) + + self.Sidebar:AddItem("PIXEL.Test.Buttons", "Buttons", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Buttons") + end) + + self.Sidebar:AddItem("PIXEL.Test.Navigation", "Navigation", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Navigation") + end) + + self.Sidebar:AddItem("PIXEL.Test.ScrollPanel", "ScrollPanel", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.ScrollPanel") + end) + + self.Sidebar:AddItem("PIXEL.Test.Text", "Text", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Text") + end) + + self.Sidebar:AddItem("PIXEL.Test.Other", "Other", "8bKjn4t", function() + self:ChangeTab("PIXEL.Test.Other") + end) end function PANEL:ChangeTab(panel) - if not self.SideBar:IsMouseInputEnabled() then return end - - if not IsValid(self.ContentPanel) then - self.ContentPanel = vgui.Create(panel, self) - self.ContentPanel:Dock(FILL) - self.ContentPanel:InvalidateLayout(true) - - function self.ContentPanel.Think(s) - if not self.DragThink then return end - if self:DragThink(self) then return end - if self:SizeThink(self, s) then return end - self:SetCursor("arrow") - - if self.y < 0 then - self:SetPos(self.x, 0) - end - end - - function self.ContentPanel.OnMousePressed() - self:OnMousePressed() - end - - function self.ContentPanel.OnMouseReleased() - self:OnMouseReleased() - end - - return - end - - self.SideBar:SetMouseInputEnabled(false) - - self.ContentPanel:AlphaTo(0, .15, 0, function(anim, pnl) - self.ContentPanel:Remove() - self.ContentPanel = vgui.Create(panel, self) - self.ContentPanel:Dock(FILL) - self.ContentPanel:InvalidateLayout(true) - - self.ContentPanel:AlphaTo(255, .15, 0, function(anim2, pnl2) - self.SideBar:SetMouseInputEnabled(true) - end) - end) + if not self.SideBar:IsMouseInputEnabled() then return end + + if not IsValid(self.ContentPanel) then + self.ContentPanel = vgui.Create(panel, self) + self.ContentPanel:Dock(FILL) + self.ContentPanel:InvalidateLayout(true) + + function self.ContentPanel.Think(s) + if not self.DragThink then return end + if self:DragThink(self) then return end + if self:SizeThink(self, s) then return end + self:SetCursor("arrow") + + if self.y < 0 then + self:SetPos(self.x, 0) + end + end + + function self.ContentPanel.OnMousePressed() + self:OnMousePressed() + end + + function self.ContentPanel.OnMouseReleased() + self:OnMouseReleased() + end + + return + end + + self.SideBar:SetMouseInputEnabled(false) + + self.ContentPanel:AlphaTo(0, .15, 0, function(anim, pnl) + self.ContentPanel:Remove() + self.ContentPanel = vgui.Create(panel, self) + self.ContentPanel:Dock(FILL) + self.ContentPanel:InvalidateLayout(true) + + self.ContentPanel:AlphaTo(255, .15, 0, function(anim2, pnl2) + self.SideBar:SetMouseInputEnabled(true) + end) + end) end -function PANEL:PaintMore(w,h) - +function PANEL:PaintMore(w, h) end vgui.Register("PIXEL.Test.Main", PANEL, "PIXEL.Frame") concommand.Add("pixel_test", function() - vgui.Create("PIXEL.Test.Main") -end) \ No newline at end of file + PIXEL.TestFrame = vgui.Create("PIXEL.Test.Main") +end) + +if IsValid(PIXEL.TestFrame) then + PIXEL.TestFrame:Remove() + PIXEL.TestFrame = vgui.Create("PIXEL.Test.Main") +end \ No newline at end of file From 790e9ccf215d3f29952e185b7141850039df1dbf Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 28 Apr 2023 16:01:50 +0100 Subject: [PATCH 139/155] feat: :GetTextValid function --- lua/pixelui/elements/cl_validated_text_entry.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lua/pixelui/elements/cl_validated_text_entry.lua b/lua/pixelui/elements/cl_validated_text_entry.lua index 14d0723..9866a0f 100644 --- a/lua/pixelui/elements/cl_validated_text_entry.lua +++ b/lua/pixelui/elements/cl_validated_text_entry.lua @@ -37,11 +37,13 @@ function PANEL:Init() if valid then self.Message:SetText(message or "") self.Message:SetTextColor(PIXEL.Colors.Positive) + self.TextValid = true s.OverrideCol = PIXEL.Colors.Positive else self.Message:SetText(message or "") self.Message:SetTextColor(PIXEL.Colors.Negative) + self.TextValid = false s.OverrideCol = PIXEL.Colors.Negative end @@ -56,6 +58,10 @@ function PANEL:IsTextValid(text) return false, "This is invalid text lol" end +function PANEL:GetTextValid() + return self.TextValid or true +end + function PANEL:OnValidate(valid, message) end function PANEL:PerformLayout(w, h) From 4f4ca21adadc4e782841cd9ef35830b75eb90c6d Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 13 Jun 2023 20:28:19 +0100 Subject: [PATCH 140/155] fix broken stuff --- lua/autorun/sh_pixelui_loader.lua | 5 +- lua/pixelui/elements/cl_avatar.lua | 83 ++------------ lua/pixelui/elements/cl_category.lua | 3 +- lua/pixelui/elements/cl_frame.lua | 1 - lua/pixelui/elements/cl_mini_sidebar.lua | 23 ++-- lua/pixelui/elements/cl_notification.lua | 121 -------------------- lua/pixelui/elements/cl_scrollpanel.lua | 2 +- lua/pixelui/menus/test/pages/cl_buttons.lua | 100 ++++++++-------- lua/pixelui/menus/test/pages/cl_text.lua | 30 ++--- 9 files changed, 93 insertions(+), 275 deletions(-) delete mode 100644 lua/pixelui/elements/cl_notification.lua diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index a252bb6..0b37839 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -11,9 +11,10 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + along with this program. If not, see . + You should have received a copy of the GNU General Public License ]] -along with this program. If not, see . -You should have received a copy of the GNU General Public License + PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} PIXEL.UI.Version = "1.3.1" diff --git a/lua/pixelui/elements/cl_avatar.lua b/lua/pixelui/elements/cl_avatar.lua index 3b9df22..baa037e 100644 --- a/lua/pixelui/elements/cl_avatar.lua +++ b/lua/pixelui/elements/cl_avatar.lua @@ -1,18 +1,18 @@ --[[ -PIXEL UI -Copyright (C) 2021 Tom O'Sullivan (Tom.bat) + PIXEL UI - Copyright Notice + © 2023 Thomas O'Sullivan - All rights reserved -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program. If not, see . + along with this program. If not, see . + You should have received a copy of the GNU General Public License ]] local PANEL = {} @@ -28,65 +28,6 @@ function PANEL:Init() self:SetRounding(10) end -end - self.Avatar:SetSize(w, h) -function PANEL:PerformLayout(w, h) - - -PANEL = {} - --- old avatar - - - -vgui.Register("PIXEL.Avatar", PANEL, "Panel") -end - render.ClearStencil() - render.SetStencilEnable(false) - - self.Avatar:SetPaintedManually(true) - self.Avatar:PaintManual() - self.Avatar:SetPaintedManually(false) - - render.SetStencilReferenceValue(1) - render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL) - render.SetStencilZFailOperation(STENCILOPERATION_ZERO) - render.SetStencilPassOperation(STENCILOPERATION_REPLACE) - render.SetStencilFailOperation(STENCILOPERATION_ZERO) - - PIXEL.DrawFullRoundedBox(self:GetRounding() or self:GetMaskSize(), 0, 0, w, h, color_white) - - render.SetStencilReferenceValue(1) - render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NEVER) - render.SetStencilZFailOperation(STENCILOPERATION_ZERO) - render.SetStencilPassOperation(STENCILOPERATION_ZERO) - render.SetStencilFailOperation(STENCILOPERATION_REPLACE) - - render.SetStencilTestMask(1) - render.SetStencilWriteMask(1) - - render.SetStencilEnable(true) - render.ClearStencil() -function PANEL:Paint(w, h) - -end -function PANEL:SetSteamID(id, size) - self.Avatar:SetSteamID(id, size) - -end - self.Avatar:SetPlayer(ply, size) -function PANEL:SetPlayer(ply, size) -AccessorFunc(PANEL, "MaskSize", "MaskSize", FORCE_NUMBER) - -function PANEL:Init() - PIXEL.Warn("Please update to using PIXEL.Avatar instead of using PIXEL.OldAvatar! This panel is deprecated and may be removed in a future release.") - self.Avatar = vgui.Create("AvatarImage", self) - self.Avatar:SetPaintedManually(true) - - self.CirclePoly = {} - self:SetRounding(10) -end - function PANEL:PerformLayout(w, h) self.Avatar:SetSize(w, h) end @@ -201,4 +142,4 @@ function PANEL:Paint(w, h) render.ClearStencil() end -vgui.Register("PIXEL.OldAvatar", PANEL, "Panel") +vgui.Register("PIXEL.OldAvatar", PANEL, "Panel") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_category.lua b/lua/pixelui/elements/cl_category.lua index 2b3a935..b8d222a 100644 --- a/lua/pixelui/elements/cl_category.lua +++ b/lua/pixelui/elements/cl_category.lua @@ -12,9 +12,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License ---]] - along with this program. If not, see . +]] local PANEL = {} AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) PIXEL.RegisterFont("UI.CategoryHeader", "Open Sans Bold", 19) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index f0d08a7..c10a8b6 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -272,7 +272,6 @@ function PANEL:Close() y = posY, size = function() end }, -- left - } local direction = self:GetSlideDirection() or 1 diff --git a/lua/pixelui/elements/cl_mini_sidebar.lua b/lua/pixelui/elements/cl_mini_sidebar.lua index 39010b8..e54f08f 100644 --- a/lua/pixelui/elements/cl_mini_sidebar.lua +++ b/lua/pixelui/elements/cl_mini_sidebar.lua @@ -1,19 +1,18 @@ - --[[ -PIXEL UI -Copyright (C) 2021 Tom O'Sullivan (Tom.bat) + PIXEL UI - Copyright Notice + © 2023 Thomas O'Sullivan - All rights reserved -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program. If not, see . + along with this program. If not, see . + You should have received a copy of the GNU General Public License ]] local PANEL = {} diff --git a/lua/pixelui/elements/cl_notification.lua b/lua/pixelui/elements/cl_notification.lua deleted file mode 100644 index 18737d1..0000000 --- a/lua/pixelui/elements/cl_notification.lua +++ /dev/null @@ -1,121 +0,0 @@ - -local sc = PIXEL.Scale -local Notices = {} -local notifyAmount = 0 ---[[ -surface.CreateFont("PIXEL.NotifyFont", { - font = "Open Sans Bold", - size = 25, - weight = 500, - antialias = true, -}) - - -function PIXEL.Notify(text, type, length) - local ply = LocalPlayer() - if not ply.NotifyAmount then ply.NotifyAmount = 0 end - ply.NotifyAmount = ply.NotifyAmount + 1 - local parent = nil - if ( GetOverlayPanel ) then parent = GetOverlayPanel() end - local notif = vgui.Create("PIXEL.Notification", parent) - notif:SetLength(math.max(length, 0)) - notif:SetText(text) - notif:SetType(type) - table.insert(Notices, notif) - - if ply.NotifyAmount > 0 then - notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200) - (sc(50) * ply.NotifyAmount)) - else - notif:SetPos(ScrW() - notif:GetWide() - sc(25), ScrH() - sc(200)) - end -end - -hook.Add("Initialize", "PIXEL.NotificationOverride", function() - local oldNotification = notification.AddLegacy - - function notification.AddLegacy(text, type, length) - if PIXEL.DisableNotification then - oldNotification(text, type, length) - else - PIXEL.Notify(text, type, length) - end - end -end) - -local PANEL = {} - -function PANEL:SetText(txt) - self.NotifyText = txt - self:SetWide(PIXEL.GetTextSize(txt, "PIXEL.NotifyFont") + sc(25)) -end - -function PANEL:SetType(type) - self.NotifyType = type - if type == NOTIFY_GENERIC then - PIXEL.PlayNotify() - elseif type == NOTIFY_ERROR then - PIXEL.PlayError(1) - elseif type == NOTIFY_UNDO then - PIXEL.PlayError(2) - elseif type == NOTIFY_HINT then - PIXEL.PlaySuccess(1) - elseif type == NOTIFY_CLEANUP then - PIXEL.PlayError(5) - end -end - -function PANEL:SetLength(sec) - sec = sec + .2 - self.Length = sec - - timer.Simple(sec, function() - self:Close() - end) -end - -function PANEL:Init() - self:SetTall(sc(40)) - self:SetWide(sc(40)) - self.NotifyText = "" - self:SetVisible(false) - self:Open() -end - -function PANEL:SizeToContents() -end - -function PANEL:SetLegacyType() -end - -function PANEL:Paint(w, h) - local shouldDraw = not (LocalPlayer and IsValid(LocalPlayer()) and IsValid(LocalPlayer():GetActiveWeapon()) and LocalPlayer():GetActiveWeapon():GetClass() == "gmod_camera") - if not shouldDraw then return end - - PIXEL.DrawRoundedBoxEx(sc(6), sc(5), 0, w, h, PIXEL.SetColorTransparency(PIXEL.Colors.Background, 200), false, true, false, true) - PIXEL.DrawRoundedBoxEx(sc(6), 0, 0, sc(5), h, PIXEL.Colors.Primary, true, false, true, false) - PIXEL.DrawSimpleText(self.NotifyText, "PIXEL.NotifyFont", w / 2, h / 2 - sc(1), PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) -end - -function PANEL:Open() - self:SetAlpha(0) - self:SetVisible(true) - self:AlphaTo(255, .1, 0) -end - -function PANEL:Close() - local ply = LocalPlayer() - self:AlphaTo(0, .1, 0, function(anim, pnl) - if not IsValid(pnl) then return end - pnl:SetVisible(false) - pnl:Remove() - end) - - ply.NotifyAmount = ply.NotifyAmount - 1 -end - -function PANEL:SetProgress(frac) end - -function PANEL:KillSelf() end - -vgui.Register("PIXEL.Notification", PANEL, "EditablePanel") ---]] \ No newline at end of file diff --git a/lua/pixelui/elements/cl_scrollpanel.lua b/lua/pixelui/elements/cl_scrollpanel.lua index c171980..0b0260c 100644 --- a/lua/pixelui/elements/cl_scrollpanel.lua +++ b/lua/pixelui/elements/cl_scrollpanel.lua @@ -25,7 +25,7 @@ AccessorFunc(PANEL, "CanScroll", "CanScroll", FORCE_BOOL) function PANEL:Init() self:SetCanScroll(true) - + self.Canvas = vgui.Create("Panel", self) self.Canvas.OnMousePressed = function(s, code) s:GetParent():OnMousePressed(code) end self.Canvas:SetMouseInputEnabled(true) diff --git a/lua/pixelui/menus/test/pages/cl_buttons.lua b/lua/pixelui/menus/test/pages/cl_buttons.lua index 9f2ec89..34921ab 100644 --- a/lua/pixelui/menus/test/pages/cl_buttons.lua +++ b/lua/pixelui/menus/test/pages/cl_buttons.lua @@ -4,65 +4,65 @@ local PANEL = {} function PANEL:Init() - self.Button = vgui.Create("PIXEL.Button", self) - self.Button:Dock(TOP) - self.Button:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.Button:SetTall(sc(50)) - self.Button.DoClick = function() - notification.AddLegacy("Normal Button!", NOTIFY_GENERIC, 5) - end + self.Button = vgui.Create("PIXEL.Button", self) + self.Button:Dock(TOP) + self.Button:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.Button:SetTall(sc(50)) + self.Button.DoClick = function() + notification.AddLegacy("Normal Button!", NOTIFY_GENERIC, 5) + end - self.ClickyButton = vgui.Create("PIXEL.Button", self) - self.ClickyButton:Dock(TOP) - self.ClickyButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.ClickyButton:SetTall(sc(50)) - self.ClickyButton:SetClicky(true) - self.ClickyButton.DoClick = function() - notification.AddLegacy("Normal Clicky Button!", NOTIFY_GENERIC, 5) - end + self.ClickyButton = vgui.Create("PIXEL.Button", self) + self.ClickyButton:Dock(TOP) + self.ClickyButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.ClickyButton:SetTall(sc(50)) + self.ClickyButton:SetClicky(true) + self.ClickyButton.DoClick = function() + notification.AddLegacy("Normal Clicky Button!", NOTIFY_GENERIC, 5) + end - self.ClickyTextButton = vgui.Create("PIXEL.TextButton", self) - self.ClickyTextButton:Dock(TOP) - self.ClickyTextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.ClickyTextButton:SetTall(sc(50)) - self.ClickyTextButton:SetText("Clicky Button!") - self.ClickyTextButton.DoClick = function() - notification.AddLegacy("Clicky Text Button!", NOTIFY_GENERIC, 5) - end + self.ClickyTextButton = vgui.Create("PIXEL.TextButton", self) + self.ClickyTextButton:Dock(TOP) + self.ClickyTextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.ClickyTextButton:SetTall(sc(50)) + self.ClickyTextButton:SetText("Clicky Button!") + self.ClickyTextButton.DoClick = function() + notification.AddLegacy("Clicky Text Button!", NOTIFY_GENERIC, 5) + end - self.TextButton = vgui.Create("PIXEL.TextButton", self) - self.TextButton:Dock(TOP) - self.TextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.TextButton:SetTall(sc(50)) - self.TextButton:SetText("Non Clicky Button!") - self.TextButton:SetClicky(false) - self.TextButton.DoClick = function() - notification.AddLegacy("Non Clicky Text button!", NOTIFY_GENERIC, 5) - end + self.TextButton = vgui.Create("PIXEL.TextButton", self) + self.TextButton:Dock(TOP) + self.TextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.TextButton:SetTall(sc(50)) + self.TextButton:SetText("Non Clicky Button!") + self.TextButton:SetClicky(false) + self.TextButton.DoClick = function() + notification.AddLegacy("Non Clicky Text button!", NOTIFY_GENERIC, 5) + end - self.NoSoundButton = vgui.Create("PIXEL.TextButton", self) - self.NoSoundButton:Dock(TOP) - self.NoSoundButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.NoSoundButton:SetTall(sc(50)) - self.NoSoundButton:SetText("No Sound Clicky Button!") - self.NoSoundButton:SetSounds(false) - self.NoSoundButton.DoClick = function() - notification.AddLegacy("No Sound Button!", NOTIFY_GENERIC, 5) - end + self.NoSoundButton = vgui.Create("PIXEL.TextButton", self) + self.NoSoundButton:Dock(TOP) + self.NoSoundButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.NoSoundButton:SetTall(sc(50)) + self.NoSoundButton:SetText("No Sound Clicky Button!") + self.NoSoundButton:SetSounds(false) + self.NoSoundButton.DoClick = function() + notification.AddLegacy("No Sound Button!", NOTIFY_GENERIC, 5) + end - self.ImgurButton = vgui.Create("PIXEL.ImgurButton", self) - self.ImgurButton:Dock(TOP) - self.ImgurButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.ImgurButton:SetSize(sc(50), sc(50)) - self.ImgurButton:SetImgurID("8bKjn4t") - self.ImgurButton:SetNormalColor(PIXEL.Colors.PrimaryText) + self.ImgurButton = vgui.Create("PIXEL.ImgurButton", self) + self.ImgurButton:Dock(TOP) + self.ImgurButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.ImgurButton:SetSize(sc(50), sc(50)) + self.ImgurButton:SetImgurID("8bKjn4t") + self.ImgurButton:SetNormalColor(PIXEL.Colors.PrimaryText) self.ImgurButton:SetHoverColor(PIXEL.Colors.Negative) self.ImgurButton:SetClickColor(PIXEL.Colors.Positive) self.ImgurButton:SetDisabledColor(PIXEL.Colors.DisabledText) - self.ImgurButton.DoClick = function() - notification.AddLegacy("Imgur Button!", NOTIFY_GENERIC, 5) - end + self.ImgurButton.DoClick = function() + notification.AddLegacy("Imgur Button!", NOTIFY_GENERIC, 5) + end end function PANEL:PaintMore(w,h) diff --git a/lua/pixelui/menus/test/pages/cl_text.lua b/lua/pixelui/menus/test/pages/cl_text.lua index 5eae5a7..607b0a6 100644 --- a/lua/pixelui/menus/test/pages/cl_text.lua +++ b/lua/pixelui/menus/test/pages/cl_text.lua @@ -3,26 +3,26 @@ local sc = PIXEL.Scale local PANEL = {} function PANEL:Init() - self.TextEntry = vgui.Create("PIXEL.TextEntry", self) - self.TextEntry:Dock(TOP) - self.TextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) - self.TextEntry:SetTall(sc(35)) - self.TextEntry:SetPlaceholderText("Placeholder Text!") + self.TextEntry = vgui.Create("PIXEL.TextEntry", self) + self.TextEntry:Dock(TOP) + self.TextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) + self.TextEntry:SetTall(sc(35)) + self.TextEntry:SetPlaceholderText("Placeholder Text!") - self.BadValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) - self.BadValidatedTextEntry:Dock(TOP) - self.BadValidatedTextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) - self.BadValidatedTextEntry:SetPlaceholderText("Bad Text!") + self.BadValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) + self.BadValidatedTextEntry:Dock(TOP) + self.BadValidatedTextEntry:DockMargin(sc(20), sc(20), sc(20), sc(20)) + self.BadValidatedTextEntry:SetPlaceholderText("Bad Text!") - function self.BadValidatedTextEntry:IsTextValid(text) + function self.BadValidatedTextEntry:IsTextValid(text) return false, "Bad Text!" end - self.GoodValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) - self.GoodValidatedTextEntry:Dock(TOP) - self.GoodValidatedTextEntry:DockMargin(sc(20), sc(0), sc(20), sc(20)) - self.GoodValidatedTextEntry:SetPlaceholderText("Good Text!") - function self.GoodValidatedTextEntry:IsTextValid(text) + self.GoodValidatedTextEntry = vgui.Create("PIXEL.ValidatedTextEntry", self) + self.GoodValidatedTextEntry:Dock(TOP) + self.GoodValidatedTextEntry:DockMargin(sc(20), sc(0), sc(20), sc(20)) + self.GoodValidatedTextEntry:SetPlaceholderText("Good Text!") + function self.GoodValidatedTextEntry:IsTextValid(text) return true, "Good Text!" end end From dedbc8e63373e51b89659c6096856bd11dc93f00 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 19 Jun 2023 20:10:27 +0100 Subject: [PATCH 141/155] feat: stuff --- .../{libraries => drawing}/cl_masks.lua | 0 lua/pixelui/elements/cl_button.lua | 18 ++++--- lua/pixelui/elements/cl_combo_box.lua | 5 ++ lua/pixelui/elements/cl_label.lua | 6 +++ lua/pixelui/elements/cl_step_counter.lua | 49 +++++++++++++++---- 5 files changed, 62 insertions(+), 16 deletions(-) rename lua/pixelui/{libraries => drawing}/cl_masks.lua (100%) diff --git a/lua/pixelui/libraries/cl_masks.lua b/lua/pixelui/drawing/cl_masks.lua similarity index 100% rename from lua/pixelui/libraries/cl_masks.lua rename to lua/pixelui/drawing/cl_masks.lua diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index 4a3cc97..e0d8c57 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -18,6 +18,17 @@ local PANEL = {} AccessorFunc(PANEL, "IsToggle", "IsToggle", FORCE_BOOL) AccessorFunc(PANEL, "Toggle", "Toggle", FORCE_BOOL) AccessorFunc(PANEL, "Sounds", "Sounds", FORCE_BOOL) +AccessorFunc(PANEL, "Color", "Color") + +function PANEL:SetColor(color) + self.Color = color + + self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) + self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) + self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) + self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) + self.BackgroundCol = self.NormalCol +end function PANEL:Init() self:SetIsToggle(false) @@ -28,12 +39,7 @@ function PANEL:Init() self:SetSounds(true) local btnSize = PIXEL.Scale(30) self:SetSize(btnSize, btnSize) - self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) - self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) - self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) - self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) - self.BackgroundCol = self.NormalCol - + self:SetColor(PIXEL.Colors.Primary) end function PANEL:DoToggle(...) diff --git a/lua/pixelui/elements/cl_combo_box.lua b/lua/pixelui/elements/cl_combo_box.lua index 7573398..ccc6d10 100644 --- a/lua/pixelui/elements/cl_combo_box.lua +++ b/lua/pixelui/elements/cl_combo_box.lua @@ -83,6 +83,10 @@ function PANEL:ChooseOption(value, index) self:SetText(value) + if not index then + index = table.KeyFromValue(self.Data, value) + end + self.selected = index local choicesKey = table.KeyFromValue(self.Choices, value) @@ -91,6 +95,7 @@ function PANEL:ChooseOption(value, index) else self:SetIcon(nil) end + self:OnSelect(index, value, self.Data[index]) if not self:GetSizeToText() then return end diff --git a/lua/pixelui/elements/cl_label.lua b/lua/pixelui/elements/cl_label.lua index af7e797..0a8ba83 100644 --- a/lua/pixelui/elements/cl_label.lua +++ b/lua/pixelui/elements/cl_label.lua @@ -22,9 +22,15 @@ AccessorFunc(PANEL, "TextColor", "TextColor") AccessorFunc(PANEL, "Ellipses", "Ellipses", FORCE_BOOL) AccessorFunc(PANEL, "AutoHeight", "AutoHeight", FORCE_BOOL) AccessorFunc(PANEL, "AutoWidth", "AutoWidth", FORCE_BOOL) +AccessorFunc(PANEL, "AutoSize", "AutoSize", FORCE_BOOL) AccessorFunc(PANEL, "AutoWrap", "AutoWrap", FORCE_BOOL) PIXEL.RegisterFont("UI.Label", "Rubik", 14) +function PANEL:SetAutoSize(autoSize) + self:SetAutoWidth(autoSize) + self:SetAutoHeight(autoSize) +end + function PANEL:Init() self:SetText("Label") self:SetFont("UI.Label") diff --git a/lua/pixelui/elements/cl_step_counter.lua b/lua/pixelui/elements/cl_step_counter.lua index 3dbd94f..57a6047 100644 --- a/lua/pixelui/elements/cl_step_counter.lua +++ b/lua/pixelui/elements/cl_step_counter.lua @@ -9,15 +9,18 @@ function PANEL:Init() self:SetTall(PIXEL.Scale(90)) self.BackgroundCol = PIXEL.Colors.Header - self.EnabledCol = PIXEL.Colors.Primary + self.EnabledCol = PIXEL.Colors.Positive + self.ActiveCol = PIXEL.Colors.Primary self.TextCol = PIXEL.Colors.SecondaryText end function PANEL:Paint(w, h) local backgroundCol = self.BackgroundCol + if self:GetEnabled() then backgroundCol = self.EnabledCol end + PIXEL.DrawRoundedBox(8, 0, 0, w, h, backgroundCol) PIXEL.DrawSimpleText(self:GetStep(), "StepCounterStep", w / 2, h / 2, self.TextCol, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end @@ -32,14 +35,32 @@ PIXEL.RegisterFont("StepCounterTitle", "Rubik", 24, 700) AccessorFunc(PANEL, "StepCount", "StepCount", FORCE_NUMBER) +AccessorFunc(PANEL, "CurrentStep", "CurrentStep", FORCE_NUMBER) AccessorFunc(PANEL, "Title", "Title", FORCE_STRING) +AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) + +function PANEL:ReloadSteps() + for k, v in ipairs(self.Steps) do + v:Remove() + end + + self.Steps = {} + + self:SetStepCount(self:GetStepCount()) +end + +function PANEL:SetCurrentStep(num) + self.CurrentStep = num + self:ReloadSteps() +end function PANEL:SetStepCount(count) self.StepCount = count - for i = 1, self:GetStepCount() do + for i = 1, count do self.Steps[i] = vgui.Create("PIXEL.StepCounterStep", self) self.Steps[i]:SetStep(i) - if i <= 3 then + + if self:GetCurrentStep() and i < self:GetCurrentStep() then self.Steps[i]:SetEnabled(true) end end @@ -49,11 +70,16 @@ end function PANEL:Init() self:SetTitle("PIXEL Step Counter") + self:SetFont("StepCounterTitle") self.Steps = {} end function PANEL:Paint(w, h) + if self:GetTitle() then + PIXEL.DrawSimpleText(self:GetTitle(), self:GetFont(), w / 2, 0, PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP) + end + for k, v in ipairs(self.Steps) do local nextStep = self.Steps[k + 1] if not nextStep then continue end @@ -63,14 +89,16 @@ function PANEL:Paint(w, h) local tall = PIXEL.Scale(4) local yPos = v:GetY() + (v:GetTall() / 2) - (tall / 2) local backgroundCol = PIXEL.Colors.Header - if nextStep:GetEnabled() then - backgroundCol = PIXEL.Colors.Primary + + if self.Steps[k]:GetEnabled() and not nextStep:GetEnabled() then + startX, yPos = self:LocalToScreen(startX, yPos) + PIXEL.DrawSimpleLinearGradient(startX, yPos, width, tall, PIXEL.Colors.Positive, backgroundCol, true) + continue + elseif nextStep:GetEnabled() then + backgroundCol = PIXEL.Colors.Positive end - PIXEL.DrawRoundedBox(0, startX, yPos, width, tall, backgroundCol) - end - if self:GetTitle() then - PIXEL.DrawSimpleText(self:GetTitle(), "StepCounterTitle", w / 2, 0, PIXEL.Colors.PrimaryText, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP) + PIXEL.DrawRoundedBox(0, startX, yPos, width, tall, backgroundCol) end end @@ -83,7 +111,8 @@ function PANEL:PerformLayout(w, h) v:SetSize(stepSize, stepSize) v:SetX((k - 1) * (stepSize + space)) if self:GetTitle() then - v:SetY(PIXEL.Scale(35)) + local _, textH = PIXEL.GetTextSize(self:GetTitle(), self:GetFont()) + v:SetY(PIXEL.Scale(35) + (textH / 3)) end end end From 9b72f929f26e0c4c533689cec696b912c10d49e4 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Tue, 20 Jun 2023 18:58:45 +0100 Subject: [PATCH 142/155] fix: PIXEL.Menu sizing being broken when setting an icon --- lua/pixelui/elements/cl_button.lua | 2 +- lua/pixelui/elements/cl_menu.lua | 12 +++++++++++- lua/pixelui/elements/cl_menu_option.lua | 12 ++++++++++-- lua/pixelui/menus/cl_message_popup.lua | 9 ++++++++- lua/pixelui/menus/cl_query_popup.lua | 13 +++++++++---- lua/pixelui/menus/cl_string_request_popup.lua | 12 +++++++++--- 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index e0d8c57..fa372da 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -23,7 +23,7 @@ AccessorFunc(PANEL, "Color", "Color") function PANEL:SetColor(color) self.Color = color - self.NormalCol = PIXEL.CopyColor(PIXEL.Colors.Primary) + self.NormalCol = PIXEL.CopyColor(self.Color) self.HoverCol = PIXEL.OffsetColor(self.NormalCol, -15) self.ClickedCol = PIXEL.OffsetColor(self.NormalCol, 15) self.DisabledCol = PIXEL.CopyColor(PIXEL.Colors.Disabled) diff --git a/lua/pixelui/elements/cl_menu.lua b/lua/pixelui/elements/cl_menu.lua index 3c22d75..436d2d0 100644 --- a/lua/pixelui/elements/cl_menu.lua +++ b/lua/pixelui/elements/cl_menu.lua @@ -34,6 +34,8 @@ function PANEL:Init() self:SetPadding(0) self.BackgroundCol = PIXEL.OffsetColor(PIXEL.Colors.Background, 10) RegisterDermaMenuForClose(self) + + self.OptionTexts = {} end function PANEL:AddPanel(pnl) @@ -52,6 +54,8 @@ function PANEL:AddOption(strText, funcFunction) self:AddPanel(pnl) + self.OptionTexts[strText] = pnl + return pnl end @@ -69,6 +73,8 @@ function PANEL:AddCVar(strText, convar, on, off, funcFunction) pnl:SetValueOff(off) self:AddPanel(pnl) + self.OptionTexts[strText] = pnl + return pnl end @@ -83,6 +89,8 @@ function PANEL:AddSpacer(text, func) pnl:SetTall(PIXEL.Scale(3)) self:AddPanel(pnl) + self.OptionTexts[text] = pnl + return pnl end @@ -97,6 +105,8 @@ function PANEL:AddSubMenu(strText, funcFunction) self:AddPanel(pnl) + self.OptionTexts[strText] = pnl + return subMenu, pnl end @@ -120,7 +130,7 @@ function PANEL:OpenSubMenu(item, menu) end if not IsValid(menu) then return end - local x, y = item:LocalToScreen(self:GetWide(), 0) + local x, y = item:LocalToScreen(self:GetWide() + PIXEL.Scale(2), 0) menu:Open(x, y, false, item) self:SetOpenSubMenu(menu) end diff --git a/lua/pixelui/elements/cl_menu_option.lua b/lua/pixelui/elements/cl_menu_option.lua index ba2dedf..b218d9e 100644 --- a/lua/pixelui/elements/cl_menu_option.lua +++ b/lua/pixelui/elements/cl_menu_option.lua @@ -22,12 +22,15 @@ AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) AccessorFunc(PANEL, "Icon", "Icon", FORCE_STRING) +AccessorFunc(PANEL, "IconColor", "IconColor", FORCE_COLOR) + PIXEL.RegisterFont("UI.MenuOption", "Rubik", 18, 600) function PANEL:Init() self:SetTextAlign(TEXT_ALIGN_LEFT) self:SetFont("UI.MenuOption") self:SetChecked(false) + self:SetIconColor(PIXEL.Colors.PrimaryText) self.NormalCol = PIXEL.Colors.Transparent self.HoverCol = PIXEL.Colors.Scroller self.BackgroundCol = PIXEL.CopyColor(self.NormalCol) @@ -68,7 +71,7 @@ function PANEL:Paint(w, h) local iconSize = 0 if self:GetIcon() then iconSize = self:GetTall() * .6 - PIXEL.DrawImgur(PIXEL.Scale(8), h / 2 - iconSize / 2, iconSize, iconSize, self:GetIcon(), PIXEL.Colors.PrimaryText) + PIXEL.DrawImgur(PIXEL.Scale(8), h / 2 - iconSize / 2, iconSize, iconSize, self:GetIcon(), self:GetIconColor()) end PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), PIXEL.Scale(14) + iconSize, h / 2, PIXEL.Colors.PrimaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) @@ -113,8 +116,13 @@ end function PANEL:CalculateWidth() PIXEL.SetFont(self:GetFont()) + local textWide = PIXEL.GetTextSize(self:GetText()) + + if self:GetIcon() then + textWide = textWide + self:GetTall() * .6 + PIXEL.Scale(8) + end - return PIXEL.GetTextSize(self:GetText()) + PIXEL.Scale(34) + return textWide + PIXEL.Scale(38) end function PANEL:PerformLayout(w, h) diff --git a/lua/pixelui/menus/cl_message_popup.lua b/lua/pixelui/menus/cl_message_popup.lua index d1d5148..0596522 100644 --- a/lua/pixelui/menus/cl_message_popup.lua +++ b/lua/pixelui/menus/cl_message_popup.lua @@ -45,11 +45,13 @@ end function PANEL:LayoutContent(w, h) self.Message:SetSize(self.Message:CalculateSize()) self.Message:Dock(TOP) - self.Message:DockMargin(0, 0, 0, PIXEL.Scale(8)) + self.Message:DockMargin(PIXEL.Scale(8), PIXEL.Scale(8), PIXEL.Scale(8), PIXEL.Scale(8)) self.Button:SizeToText() self.ButtonHolder:Dock(TOP) + self.ButtonHolder:DockMargin(0, 0, 0, PIXEL.Scale(8)) self.ButtonHolder:SetTall(self.Button:GetTall()) + self.Button:CenterHorizontal() if self.ButtonHolder:GetWide() < self.Button:GetWide() then @@ -61,6 +63,11 @@ function PANEL:LayoutContent(w, h) self:Center() end + if self:GetWide() - PIXEL.Scale(40) < self.Message:GetWide() then + self.Message:SetWide(self:GetWide() + self.Message:GetWide() - (self:GetWide() - PIXEL.Scale(40))) + end + + if self.HasSized and self.HasSized > 1 then return end self.HasSized = (self.HasSized or 0) + 1 diff --git a/lua/pixelui/menus/cl_query_popup.lua b/lua/pixelui/menus/cl_query_popup.lua index ed7538f..f3bba41 100644 --- a/lua/pixelui/menus/cl_query_popup.lua +++ b/lua/pixelui/menus/cl_query_popup.lua @@ -27,7 +27,7 @@ function PANEL:Init() self:SetDraggable(true) self:SetSizable(true) - self:SetMinWidth(PIXEL.Scale(240)) + self:SetMinWidth(PIXEL.Scale(260)) self:SetMinHeight(PIXEL.Scale(80)) self.Message = vgui.Create("PIXEL.Label", self) @@ -55,12 +55,13 @@ end function PANEL:LayoutContent(w, h) self.Message:SetSize(self.Message:CalculateSize()) self.Message:Dock(TOP) - self.Message:DockMargin(0, 0, 0, PIXEL.Scale(8)) + self.Message:DockMargin(PIXEL.Scale(8), PIXEL.Scale(8), PIXEL.Scale(8), PIXEL.Scale(8)) - for k,v in ipairs(self.Buttons) do + for k, v in ipairs(self.Buttons) do v:SizeToText() + v:SetTall(PIXEL.Scale(32)) v:Dock(LEFT) - v:DockMargin(PIXEL.Scale(4), 0, PIXEL.Scale(4), 0) + v:DockMargin(PIXEL.Scale(8), 0, PIXEL.Scale(8), PIXEL.Scale(8)) end self.ButtonHolder:SizeToChildren(true) @@ -86,6 +87,10 @@ function PANEL:LayoutContent(w, h) self:Center() end + if self:GetWide() - PIXEL.Scale(40) < self.Message:GetWide() then + self.Message:SetWide(self:GetWide() + self.Message:GetWide() - (self:GetWide() - PIXEL.Scale(40))) + end + if self.HasSized and self.HasSized > 1 then return end self.HasSized = (self.HasSized or 0) + 1 diff --git a/lua/pixelui/menus/cl_string_request_popup.lua b/lua/pixelui/menus/cl_string_request_popup.lua index 1b228ec..450d5ec 100644 --- a/lua/pixelui/menus/cl_string_request_popup.lua +++ b/lua/pixelui/menus/cl_string_request_popup.lua @@ -57,14 +57,20 @@ function PANEL:LayoutContent(w, h) self.Message:Dock(TOP) self.Message:DockMargin(0, 0, 0, PIXEL.Scale(8)) + if self:GetWide() - PIXEL.Scale(40) < self.Message:GetWide() then + self.Message:SetWide(self:GetWide() + self.Message:GetWide() - (self:GetWide() - PIXEL.Scale(40))) + end + + self.TextEntry:SetTall(PIXEL.Scale(32)) self.TextEntry:Dock(TOP) - self.TextEntry:DockMargin(0, 0, 0, PIXEL.Scale(10)) + self.TextEntry:DockMargin(0, 0, 0, PIXEL.Scale(8)) - for k,v in ipairs(self.Buttons) do + for k, v in ipairs(self.Buttons) do v:SizeToText() + v:SetTall(PIXEL.Scale(32)) v:Dock(LEFT) - v:DockMargin(PIXEL.Scale(4), 0, PIXEL.Scale(4), 0) + v:DockMargin(PIXEL.Scale(8), 0, PIXEL.Scale(8), PIXEL.Scale(8)) end self.ButtonHolder:SizeToChildren(true) From 68b483af59982354cd6ed53f0311e449575049b6 Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Fri, 30 Jun 2023 01:38:24 +0100 Subject: [PATCH 143/155] feat: Draw imgur overhead function --- lua/pixelui/drawing/cl_overheads.lua | 55 +++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/drawing/cl_overheads.lua b/lua/pixelui/drawing/cl_overheads.lua index cc9ab8c..6ef0f35 100644 --- a/lua/pixelui/drawing/cl_overheads.lua +++ b/lua/pixelui/drawing/cl_overheads.lua @@ -54,13 +54,35 @@ local function drawOverhead(ent, pos, text, ang, scale, col) PIXEL.DrawRoundedBox(12, x, y, h, h, PIXEL.Colors.Primary) PIXEL.DrawRoundedBoxEx(12, x + (h - 12), y + h - 20, w + 15, 20, col or PIXEL.Colors.Primary, false, false, false, true) PIXEL.DrawText(text, "UI.Overhead", x + h + 15, y + 8, PIXEL.Colors.PrimaryText) - PIXEL.DrawImgur(x + 10, y + 10, h - 20, h - 20, Icon, color_white) + PIXEL.DrawImgur(x + 10, y + 10, h - 20, h - 20, "j161cDa", color_white) end end3d2d() disableClipping(oldClipping) end +local function drawImgurOverhead(ent, pos, imgurId, size, ang, scale, col) + if ang then + ang = ent:LocalToWorldAngles(ang) + else + ang = (pos - localPly:GetPos()):Angle() + ang:SetUnpacked(0, ang[2] - 90, 90) + end + + + PIXEL.SetFont("UI.Overhead") + local w, h = PIXEL.GetTextSize("FUCKFUCKFUCKFUCK") + w = w + 40 + h = h + 6 + + local x, y = -(w * .5), -h + + + start3d2d(pos, ang, scale or 0.05) + PIXEL.DrawImgur(x + 10, y + 10, h - 20, h - 20, imgurId, color_white) + end3d2d() +end + local entOffset = 2 function PIXEL.DrawEntOverhead(ent, text, angleOverride, posOverride, scaleOverride, colOverride) if checkDistance(ent) then return end @@ -98,4 +120,35 @@ function PIXEL.EnableIconOverheads(new) local oldIcon = Icon Icon = new return oldIcon +end + +-- Imgur +function PIXEL.DrawEntImgurOverhead(ent, imgurId, size, angleOverride, posOverride, scaleOverride, colOverride) + if checkDistance(ent) then return end + + if posOverride then + drawOverhead(ent, ent:LocalToWorld(posOverride), text, angleOverride, scaleOverride) + return + end + + local pos = ent:OBBMaxs() + pos:SetUnpacked(0, 0, pos[3] + entOffset) + + drawImgurOverhead(ent, ent:LocalToWorld(pos), imgurId, size, angleOverride, scaleOverride, colOverride) +end + +function PIXEL.DrawNPCImgurOverhead(ent, imgurId, size, angleOverride, offsetOverride, scaleOverride, colOverride) + if checkDistance(ent) then return end + + local eyeId = ent:LookupAttachment("eyes") + if eyeId then + local eyes = ent:GetAttachment(eyeId) + if eyes then + eyes.Pos:Add(offsetOverride or eyeOffset) + drawImgurOverhead(ent, eyes.Pos, imgurId, size, angleOverride, scaleOverride) + return + end + end + + drawImgurOverhead(ent, ent:GetPos() + fallbackOffset, imgurId, size, angleOverride, scaleOverride, colOverride) end \ No newline at end of file From f0a3bb88b450cc36fde04046236062088668f1fa Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 5 Jul 2023 00:41:41 +0100 Subject: [PATCH 144/155] Make icons look a bit nicer --- lua/pixelui/core/cl_sounds.lua | 2 +- lua/pixelui/drawing/cl_overheads.lua | 2 +- lua/pixelui/elements/cl_category.lua | 2 +- lua/pixelui/elements/cl_check_box.lua | 2 +- lua/pixelui/elements/cl_combo_box.lua | 2 +- lua/pixelui/elements/cl_frame.lua | 2 +- lua/pixelui/elements/cl_imgur_button.lua | 2 +- lua/pixelui/elements/cl_menu_option.lua | 2 +- lua/pixelui/elements/cl_number_entry.lua | 4 +- lua/pixelui/elements/cl_state_button.lua | 103 ++++++++++++++++++ .../elements/color_picker_v2/cl_alpha_bar.lua | 2 +- .../color_picker_v2/cl_color_picker_v2.lua | 2 +- lua/pixelui/menus/test/pages/cl_buttons.lua | 3 +- lua/pixelui/menus/test/pages/cl_other.lua | 2 +- lua/pixelui/sh_config.lua | 2 +- 15 files changed, 118 insertions(+), 16 deletions(-) create mode 100644 lua/pixelui/elements/cl_state_button.lua diff --git a/lua/pixelui/core/cl_sounds.lua b/lua/pixelui/core/cl_sounds.lua index c9ea43c..e93b0fc 100644 --- a/lua/pixelui/core/cl_sounds.lua +++ b/lua/pixelui/core/cl_sounds.lua @@ -4,7 +4,7 @@ do if PIXEL.DisableUISounds then return end local soundPath = "pixelui-sounds/" .. type .. "/" .. sound .. ".mp3" - if not file.Exists("sound/" .. soundPath, "GAME") then print(soundPath, "bad") return end + if not file.Exists("sound/" .. soundPath, "GAME") then return end surface.PlaySound(soundPath) end diff --git a/lua/pixelui/drawing/cl_overheads.lua b/lua/pixelui/drawing/cl_overheads.lua index 6ef0f35..f9b7e7f 100644 --- a/lua/pixelui/drawing/cl_overheads.lua +++ b/lua/pixelui/drawing/cl_overheads.lua @@ -54,7 +54,7 @@ local function drawOverhead(ent, pos, text, ang, scale, col) PIXEL.DrawRoundedBox(12, x, y, h, h, PIXEL.Colors.Primary) PIXEL.DrawRoundedBoxEx(12, x + (h - 12), y + h - 20, w + 15, 20, col or PIXEL.Colors.Primary, false, false, false, true) PIXEL.DrawText(text, "UI.Overhead", x + h + 15, y + 8, PIXEL.Colors.PrimaryText) - PIXEL.DrawImgur(x + 10, y + 10, h - 20, h - 20, "j161cDa", color_white) + PIXEL.DrawImgur(x + 10, y + 10, h - 20, h - 20, Icon, color_white) end end3d2d() diff --git a/lua/pixelui/elements/cl_category.lua b/lua/pixelui/elements/cl_category.lua index 79e9a9a..f7b1a7b 100644 --- a/lua/pixelui/elements/cl_category.lua +++ b/lua/pixelui/elements/cl_category.lua @@ -34,7 +34,7 @@ function PANEL:Paint(w, h) PIXEL.DrawSimpleText(self.Title, "UI.CategoryHeader", PIXEL.Scale(10), h / 2, PIXEL.Colors.PrimaryText, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) self.ArrowRotation = lerp(FrameTime() * 10, self.ArrowRotation, self:GetParent():GetExpanded() and 0 or 90) local arrowSize = h * .45 - PIXEL.DrawImgurRotated(w - h * .3 - PIXEL.Scale(4), h / 2, arrowSize, arrowSize, self.ArrowRotation, "30Bvuwi", PIXEL.Colors.PrimaryText) + PIXEL.DrawImgurRotated(w - h * .3 - PIXEL.Scale(4), h / 2, arrowSize, arrowSize, self.ArrowRotation, "IP0UlBl", PIXEL.Colors.PrimaryText) end vgui.Register("PIXEL.CategoryHeader", PANEL, "PIXEL.Button") diff --git a/lua/pixelui/elements/cl_check_box.lua b/lua/pixelui/elements/cl_check_box.lua index 7014487..a2e80c3 100644 --- a/lua/pixelui/elements/cl_check_box.lua +++ b/lua/pixelui/elements/cl_check_box.lua @@ -20,7 +20,7 @@ function PANEL:Init() self:SetIsToggle(true) local boxSize = PIXEL.Scale(20) self:SetSize(boxSize, boxSize) - self:SetImgurID("YvG7VI6") + self:SetImgurID("Qf8Owl7") self:SetNormalColor(PIXEL.Colors.Transparent) self:SetHoverColor(PIXEL.Colors.PrimaryText) self:SetClickColor(PIXEL.Colors.PrimaryText) diff --git a/lua/pixelui/elements/cl_combo_box.lua b/lua/pixelui/elements/cl_combo_box.lua index ccc6d10..14478ff 100644 --- a/lua/pixelui/elements/cl_combo_box.lua +++ b/lua/pixelui/elements/cl_combo_box.lua @@ -229,7 +229,7 @@ end function PANEL:PaintOver(w, h) local dropBtnSize = PIXEL.Scale(8) - PIXEL.DrawImgur(w - dropBtnSize - PIXEL.Scale(8), h / 2 - dropBtnSize / 2, dropBtnSize, dropBtnSize, "30Bvuwi", PIXEL.Colors.PrimaryText) + PIXEL.DrawImgur(w - dropBtnSize - PIXEL.Scale(8), h / 2 - dropBtnSize / 2, dropBtnSize, dropBtnSize, "IP0UlBl", PIXEL.Colors.PrimaryText) end vgui.Register("PIXEL.ComboBox", PANEL, "PIXEL.TextButton") \ No newline at end of file diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 1921a2e..8c629a1 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -30,7 +30,7 @@ PIXEL.RegisterFont("UI.FrameTitle", "Rubik", 20, 700) function PANEL:Init() self.CloseButton = vgui.Create("PIXEL.ImgurButton", self) - self.CloseButton:SetImgurID("z1uAU0b") + self.CloseButton:SetImgurID("ElTlvcf") self.CloseButton:SetNormalColor(PIXEL.Colors.PrimaryText) self.CloseButton:SetHoverColor(PIXEL.Colors.Negative) self.CloseButton:SetClickColor(PIXEL.Colors.Negative) diff --git a/lua/pixelui/elements/cl_imgur_button.lua b/lua/pixelui/elements/cl_imgur_button.lua index 4d42611..29258ca 100644 --- a/lua/pixelui/elements/cl_imgur_button.lua +++ b/lua/pixelui/elements/cl_imgur_button.lua @@ -26,7 +26,7 @@ AccessorFunc(PANEL, "Rounded", "Rounded", FORCE_NUMBER) function PANEL:Init() self.ImageCol = PIXEL.CopyColor(color_white) - self:SetImgurID("635PPvg") + self:SetImgurID("w72Iz3n") self:SetNormalColor(color_white) self:SetHoverColor(color_white) self:SetClickColor(color_white) diff --git a/lua/pixelui/elements/cl_menu_option.lua b/lua/pixelui/elements/cl_menu_option.lua index b218d9e..e0d2274 100644 --- a/lua/pixelui/elements/cl_menu_option.lua +++ b/lua/pixelui/elements/cl_menu_option.lua @@ -78,7 +78,7 @@ function PANEL:Paint(w, h) if not self.SubMenu then return end local dropBtnSize = PIXEL.Scale(8) - PIXEL.DrawImgur(w - dropBtnSize - PIXEL.Scale(6), h / 2 - dropBtnSize / 2, dropBtnSize, dropBtnSize, "gXg3U6X", PIXEL.Colors.PrimaryText) + PIXEL.DrawImgur(w - dropBtnSize - PIXEL.Scale(6), h / 2 - dropBtnSize / 2, dropBtnSize, dropBtnSize, "YTOZJoK", PIXEL.Colors.PrimaryText) end function PANEL:OnPressed(mousecode) diff --git a/lua/pixelui/elements/cl_number_entry.lua b/lua/pixelui/elements/cl_number_entry.lua index 17a75f6..dfa307b 100644 --- a/lua/pixelui/elements/cl_number_entry.lua +++ b/lua/pixelui/elements/cl_number_entry.lua @@ -15,7 +15,7 @@ function PANEL:Init() self:SetHistoryEnabled(false) self:SetUpdateOnType(true) self.UpButton = self:Add("PIXEL.ImgurButton") - self.UpButton:SetImgurID("RD7dJ7x") + self.UpButton:SetImgurID("YW5cZRk") self.UpButton.DoClick = function(s) local current = tonumber(self:GetValue()) if not current then current = self:GetMin() or 0 end @@ -28,7 +28,7 @@ function PANEL:Init() end self.DownButton = self:Add("PIXEL.ImgurButton") - self.DownButton:SetImgurID("Y9Dqinn") + self.DownButton:SetImgurID("IP0UlBl") self.DownButton.DoClick = function(s) local current = tonumber(self:GetValue()) if not current then current = self:GetMin() or 0 end diff --git a/lua/pixelui/elements/cl_state_button.lua b/lua/pixelui/elements/cl_state_button.lua new file mode 100644 index 0000000..30d94ae --- /dev/null +++ b/lua/pixelui/elements/cl_state_button.lua @@ -0,0 +1,103 @@ +--[[ +PIXEL UI +Copyright (C) 2021 Tom O'Sullivan (Tom.bat) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +]] + +local PANEL = {} + +AccessorFunc(PANEL, "Text", "Text", FORCE_STRING) +AccessorFunc(PANEL, "TextAlign", "TextAlign", FORCE_NUMBER) +AccessorFunc(PANEL, "TextSpacing", "TextSpacing", FORCE_NUMBER) +AccessorFunc(PANEL, "Font", "Font", FORCE_STRING) +AccessorFunc(PANEL, "State", "State") + +function PANEL:Init() + self.States = { + ["default"] = { + Color = PIXEL.Colors.PrimaryText, + Icon = nil + }, + ["loading"] = { + Color = PIXEL.Colors.PrimaryText, + Icon = nil + }, + ["disabled"] = { + Color = PIXEL.Colors.PrimaryText, + Icon = "3myjhEM" + }, + ["success"] = { + Color = PIXEL.Colors.Success, + Icon = "Qf8Owl7" + }, + ["failed"] = { + Color = PIXEL.Colors.Warning, + Icon = "qHORTll" + } + } + + self:SetState("default") + self.StateColor = PIXEL.Colors.PrimaryText +end + +function PANEL:SetState(state) + if not self.States[state] then + state = "default" + end + + self.State = state + self:SetIcon(self.States[state].Icon) + + if state == ("success" or "failed") then + timer.Simple(1.5, function() + if IsValid(self) then + self.FadeOut = true + end + end) + end +end + +function PANEL:PaintExtra(w, h) + local textAlign = self:GetTextAlign() + local textX = (textAlign == TEXT_ALIGN_CENTER and w / 2) or (textAlign == TEXT_ALIGN_RIGHT and w - self:GetTextSpacing()) or self:GetTextSpacing() + + local iconSize = self:GetTall() * .6 + + if self:GetIcon() and self:GetState() ~= "loading" then + PIXEL.DrawImgur(PIXEL.Scale(8), h / 2 - iconSize / 2, iconSize, iconSize, self:GetIcon(), self.StateColor) + textX = textX + PIXEL.Scale(8) + elseif self:GetState() == "loading" then + PIXEL.DrawProgressWheel(PIXEL.Scale(8), h / 2 - iconSize / 2, iconSize, iconSize, PIXEL.Colors.PrimaryText) + textX = textX + PIXEL.Scale(8) + end + + if not self:IsEnabled() then + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX + iconSize, h / 2, PIXEL.Colors.DisabledText, textAlign, TEXT_ALIGN_CENTER) + return + end + + PIXEL.DrawSimpleText(self:GetText(), self:GetFont(), textX, h / 2, PIXEL.Colors.PrimaryText, textAlign, TEXT_ALIGN_CENTER) +end + +function PANEL:Think() + if not self.FadeOut then return end + self.StateColor = PIXEL.LerpColor(FrameTime() * 16, self.StateColor, Color(255, 255, 255, 0)) + if self.StateColor.a <= 10 then + self:SetState("default") + self.FadeOut = false + self.StateColor = PIXEL.Colors.PrimaryText + end +end + +vgui.Register("PIXEL.StateButton", PANEL, "PIXEL.TextButton") \ No newline at end of file diff --git a/lua/pixelui/elements/color_picker_v2/cl_alpha_bar.lua b/lua/pixelui/elements/color_picker_v2/cl_alpha_bar.lua index 44f4772..8ca1693 100644 --- a/lua/pixelui/elements/color_picker_v2/cl_alpha_bar.lua +++ b/lua/pixelui/elements/color_picker_v2/cl_alpha_bar.lua @@ -47,7 +47,7 @@ function PANEL:Paint(w, h) for i = 0, w / 2 do local x2 = i * h if x2 > w then break end - PIXEL.DrawImgur(x2, 0, h, h, "RPwfEvZ", color_white) + PIXEL.DrawImgur(x2, 0, h, h, "ewL9tYn", color_white) end PIXEL.DrawSimpleLinearGradient(x, y, w, h, self:GetBaseColor(), Color(200, 200, 200, 0), true) diff --git a/lua/pixelui/elements/color_picker_v2/cl_color_picker_v2.lua b/lua/pixelui/elements/color_picker_v2/cl_color_picker_v2.lua index 29b2382..aa35f04 100644 --- a/lua/pixelui/elements/color_picker_v2/cl_color_picker_v2.lua +++ b/lua/pixelui/elements/color_picker_v2/cl_color_picker_v2.lua @@ -46,7 +46,7 @@ function PANEL:Init() PIXEL.Mask(function() PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, color_white) end, function() - PIXEL.DrawImgur(0, 0, w, h, "RPwfEvZ", color_white) + PIXEL.DrawImgur(0, 0, w, h, "ewL9tYn", color_white) local color = PIXEL.SetColorTransparency(self:GetColor(), self:GetAlpha()) PIXEL.DrawRoundedBox(0, 0, 0, w, h, color) diff --git a/lua/pixelui/menus/test/pages/cl_buttons.lua b/lua/pixelui/menus/test/pages/cl_buttons.lua index 44e1878..b12599f 100644 --- a/lua/pixelui/menus/test/pages/cl_buttons.lua +++ b/lua/pixelui/menus/test/pages/cl_buttons.lua @@ -46,8 +46,7 @@ function PANEL:Init() end end -function PANEL:PaintMore(w,h) - +function PANEL:PaintOver(w,h) end vgui.Register("PIXEL.Test.Buttons", PANEL) \ No newline at end of file diff --git a/lua/pixelui/menus/test/pages/cl_other.lua b/lua/pixelui/menus/test/pages/cl_other.lua index 8105341..69df902 100644 --- a/lua/pixelui/menus/test/pages/cl_other.lua +++ b/lua/pixelui/menus/test/pages/cl_other.lua @@ -49,7 +49,7 @@ function PANEL:Init() self.ColorPicker:SetAlphaBar(true) self.ScrollPanel.LayoutContent = function(s, w, h) - // self.ColorPicker:SetSize(w / 2 - PIXEL.Scale(50), PIXEL.Scale(120)) + self.ColorPicker:SetSize(w - PIXEL.Scale(250), PIXEL.Scale(120)) self.ColorPicker:SetPos(PIXEL.Scale(50), self.StepCounter:GetY() + self.StepCounter:GetTall() + PIXEL.Scale(10)) end end diff --git a/lua/pixelui/sh_config.lua b/lua/pixelui/sh_config.lua index f156014..67f1df0 100644 --- a/lua/pixelui/sh_config.lua +++ b/lua/pixelui/sh_config.lua @@ -37,4 +37,4 @@ PIXEL.DisableUISounds = false --[[ The Imgur ID of the progress image you want to appear when Imgur content is loading. ]] -PIXEL.ProgressImageID = "635PPvg" \ No newline at end of file +PIXEL.ProgressImageID = "w72Iz3n" \ No newline at end of file From d1d8321bcd2ba65de608fe2b15e3326ac7e4eb8d Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Thu, 6 Jul 2023 02:30:30 +0100 Subject: [PATCH 145/155] a --- lua/pixelui/drawing/cl_text.lua | 35 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/lua/pixelui/drawing/cl_text.lua b/lua/pixelui/drawing/cl_text.lua index 08960dd..9e970a3 100644 --- a/lua/pixelui/drawing/cl_text.lua +++ b/lua/pixelui/drawing/cl_text.lua @@ -24,8 +24,7 @@ local setTextColor = surface.SetTextColor local drawText = surface.DrawText function PIXEL.DrawSimpleText(text, font, x, y, col, xAlign, yAlign) - setFont(font) - local w, h = getTextSize(text) + local w, h = getTextSize(text, font) if xAlign == 1 then x = x - w / 2 @@ -56,8 +55,7 @@ function PIXEL.DrawText(text, font, x, y, col, xAlign, yAlign) local curX = x local curY = y - setFont(font) - local lineHeight = select(2, getTextSize("\n")) + local lineHeight = select(2, getTextSize("\n", font)) local tabWidth = 50 for str in gmatch(text, "[^\n]*") do @@ -68,7 +66,7 @@ function PIXEL.DrawText(text, font, x, y, col, xAlign, yAlign) if #str2 > 0 then drawSimpleText(str2, font, curX, curY, col, xAlign) - curX = curX + getTextSize(str2) + curX = curX + getTextSize(str2, font) end end else @@ -97,11 +95,8 @@ function PIXEL.DrawDualText(title, subtitle, x, y, h) x = x or 0 y = y or 0 - setFont(title[2]) - local tH = select(2, getTextSize(title[1])) - - setFont(subtitle[2]) - local sH = select(2, getTextSize(subtitle[1])) + local tH = select(2, getTextSize(title[1], title[2])) + local sH = select(2, getTextSize(subtitle[1], subtitle[2])) drawShadowText(title[1], title[2], x, y - sH / 2, title[3], title[4], 1, title[5], title[6]) drawShadowText(subtitle[1], subtitle[2], x, y + tH / 2, subtitle[3], subtitle[4], 1, subtitle[5], subtitle[6]) @@ -109,14 +104,14 @@ end local textWrapCache = {} -local function charWrap(text, remainingWidth, maxWidth) +local function charWrap(text, font, remainingWidth, maxWidth) local totalWidth = 0 text = text:gsub(".", function(char) - totalWidth = totalWidth + getTextSize(char) + totalWidth = totalWidth + getTextSize(char, font) if totalWidth >= remainingWidth then - totalWidth = getTextSize(char) + totalWidth = getTextSize(char, font) remainingWidth = maxWidth return "\n" .. char end @@ -133,8 +128,7 @@ function PIXEL.WrapText(text, width, font) --Edit of https://github.com/FPtje/Da local chachedName = text .. width .. font if textWrapCache[chachedName] then return textWrapCache[chachedName] end - setFont(font) - local textWidth = getTextSize(text) + local textWidth = getTextSize(text, font) if textWidth <= width then textWrapCache[chachedName] = text @@ -142,18 +136,18 @@ function PIXEL.WrapText(text, width, font) --Edit of https://github.com/FPtje/Da end local totalWidth = 0 - local spaceWidth = getTextSize(' ') + local spaceWidth = getTextSize(' ', font) text = text:gsub("(%s?[%S]+)", function(word) local char = subString(word, 1, 1) if char == "\n" or char == "\t" then totalWidth = 0 end - local wordlen = getTextSize(word) + local wordlen = getTextSize(word, font) totalWidth = totalWidth + wordlen if wordlen >= width then - local splitWord, splitPoint = charWrap(word, width - (totalWidth - wordlen), width) + local splitWord, splitPoint = charWrap(word, font, width - (totalWidth - wordlen), width) totalWidth = splitPoint return splitWord elseif totalWidth < width then @@ -181,8 +175,7 @@ function PIXEL.EllipsesText(text, width, font) local chachedName = text .. width .. font if ellipsesTextCache[chachedName] then return ellipsesTextCache[chachedName] end - setFont(font) - local textWidth = getTextSize(text) + local textWidth = getTextSize(text, font) if textWidth <= width then ellipsesTextCache[chachedName] = text @@ -193,7 +186,7 @@ function PIXEL.EllipsesText(text, width, font) repeat text = left(text, #text - 1) - textWidth = getTextSize(text .. "...") + textWidth = getTextSize(text .. "...", font) infiniteLoopPrevention = infiniteLoopPrevention + 1 until textWidth <= width or infiniteLoopPrevention > 10000 From 4cdf7f46c3f7909051e6c00756011b749d1f969d Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Thu, 6 Jul 2023 02:40:14 +0100 Subject: [PATCH 146/155] fix: GLuaLint errors --- lua/pixelui/drawing/cl_outlined_box.lua | 1 - .../elements/cl_text_entry_internal.lua | 4 +- lua/pixelui/libraries/cl_arc.lua | 140 +++++++++--------- lua/pixelui/menus/test/pages/cl_buttons.lua | 32 ++-- 4 files changed, 88 insertions(+), 89 deletions(-) diff --git a/lua/pixelui/drawing/cl_outlined_box.lua b/lua/pixelui/drawing/cl_outlined_box.lua index 60302ff..c45643a 100644 --- a/lua/pixelui/drawing/cl_outlined_box.lua +++ b/lua/pixelui/drawing/cl_outlined_box.lua @@ -162,7 +162,6 @@ function PIXEL.DrawOutlinedRoundedBox(borderSize, x, y, w, h, col, thickness) y = top } } --Top Left - } roundedBoxCache[cacheName] = cache diff --git a/lua/pixelui/elements/cl_text_entry_internal.lua b/lua/pixelui/elements/cl_text_entry_internal.lua index 8b32ef3..156e1ae 100644 --- a/lua/pixelui/elements/cl_text_entry_internal.lua +++ b/lua/pixelui/elements/cl_text_entry_internal.lua @@ -248,8 +248,8 @@ function PANEL:AllowInput(value) local parent = self:GetParent() if not parent then return end - if parent.AllowInput then - if parent:AllowInput(value) then return true end + if parent.AllowInput and parent:AllowInput(value) then + return true end end diff --git a/lua/pixelui/libraries/cl_arc.lua b/lua/pixelui/libraries/cl_arc.lua index b157b59..5a4b3c8 100644 --- a/lua/pixelui/libraries/cl_arc.lua +++ b/lua/pixelui/libraries/cl_arc.lua @@ -10,87 +10,87 @@ PIXEL = PIXEL or {} function PIXEL.DrawUncachedArc(cx, cy, radius, thickness, startang, endang, roughness, color) - surface.SetDrawColor(color) - PIXEL.DrawArc(PIXEL.PrecacheArc(cx, cy, radius, thickness, startang, endang, roughness)) + surface.SetDrawColor(color) + PIXEL.DrawArc(PIXEL.PrecacheArc(cx, cy, radius, thickness, startang, endang, roughness)) end function PIXEL.PrecacheArc(cx, cy, radius, thickness, startang, endang, roughness) - local triarc = {} - -- local deg2rad = math.pi / 180 - -- Define step - roughness = math.max(roughness or 1, 1) - local step = roughness - -- Correct start/end ang - startang, endang = startang or 0, endang or 0 - - if startang > endang then - step = math.abs(step) * -1 - end - - -- Create the inner circle's points. - local inner = {} - local r = radius - thickness - - for deg = startang, endang, step do - local rad = math.rad(deg) - -- local rad = deg2rad * deg - local ox, oy = cx + (math.cos(rad) * r), cy + (-math.sin(rad) * r) - - table.insert(inner, { - x = ox, - y = oy, - u = (ox - cx) / radius + .5, - v = (oy - cy) / radius + .5 - }) - end - - -- Create the outer circle's points. - local outer = {} - - for deg = startang, endang, step do - local rad = math.rad(deg) - -- local rad = deg2rad * deg - local ox, oy = cx + (math.cos(rad) * radius), cy + (-math.sin(rad) * radius) - - table.insert(outer, { - x = ox, - y = oy, - u = (ox - cx) / radius + .5, - v = (oy - cy) / radius + .5 - }) - end - - -- Triangulize the points. - -- twice as many triangles as there are degrees. - for tri = 1, #inner * 2 do - local p1, p2, p3 - p1 = outer[math.floor(tri / 2) + 1] - p3 = inner[math.floor((tri + 1) / 2) + 1] - - --if the number is even use outer. - if tri % 2 == 0 then - p2 = outer[math.floor((tri + 1) / 2)] - else - p2 = inner[math.floor((tri + 1) / 2)] - end - - table.insert(triarc, {p1, p2, p3}) - end - -- Return a table of triangles to draw. - - return triarc + local triarc = {} + -- local deg2rad = math.pi / 180 + -- Define step + roughness = math.max(roughness or 1, 1) + local step = roughness + -- Correct start/end ang + startang, endang = startang or 0, endang or 0 + + if startang > endang then + step = math.abs(step) * -1 + end + + -- Create the inner circle's points. + local inner = {} + local r = radius - thickness + + for deg = startang, endang, step do + local rad = math.rad(deg) + -- local rad = deg2rad * deg + local ox, oy = cx + (math.cos(rad) * r), cy + (-math.sin(rad) * r) + + table.insert(inner, { + x = ox, + y = oy, + u = (ox - cx) / radius + .5, + v = (oy - cy) / radius + .5 + }) + end + + -- Create the outer circle's points. + local outer = {} + + for deg = startang, endang, step do + local rad = math.rad(deg) + -- local rad = deg2rad * deg + local ox, oy = cx + (math.cos(rad) * radius), cy + (-math.sin(rad) * radius) + + table.insert(outer, { + x = ox, + y = oy, + u = (ox - cx) / radius + .5, + v = (oy - cy) / radius + .5 + }) + end + + -- Triangulize the points. + -- twice as many triangles as there are degrees. + for tri = 1, #inner * 2 do + local p1, p2, p3 + p1 = outer[math.floor(tri / 2) + 1] + p3 = inner[math.floor((tri + 1) / 2) + 1] + + --if the number is even use outer. + if tri % 2 == 0 then + p2 = outer[math.floor((tri + 1) / 2)] + else + p2 = inner[math.floor((tri + 1) / 2)] + end + + table.insert(triarc, {p1, p2, p3}) + end + -- Return a table of triangles to draw. + + return triarc end --Draw a premade arc. function PIXEL.DrawArc(arc) - for k, v in ipairs(arc) do - surface.DrawPoly(v) - end + for k, v in ipairs(arc) do + surface.DrawPoly(v) + end end -- https://github.com/Threebow/tdlib/blob/master/tdlib.lua#L39 function PIXEL.DrawFilledArc(x, y, ang, p, rad, color, seg) - seg = seg or 80 + seg = seg or 80 ang = (-ang) + 180 local circle = {} diff --git a/lua/pixelui/menus/test/pages/cl_buttons.lua b/lua/pixelui/menus/test/pages/cl_buttons.lua index 2860c7e..0a5bf75 100644 --- a/lua/pixelui/menus/test/pages/cl_buttons.lua +++ b/lua/pixelui/menus/test/pages/cl_buttons.lua @@ -4,22 +4,22 @@ local PANEL = {} function PANEL:Init() - self.Button = vgui.Create("PIXEL.Button", self) - self.Button:Dock(TOP) - self.Button:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.Button:SetTall(sc(50)) - self.Button.DoClick = function() - notification.AddLegacy("Normal Button!", NOTIFY_GENERIC, 5) - end - - self.TextButton = vgui.Create("PIXEL.TextButton", self) - self.TextButton:Dock(TOP) - self.TextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) - self.TextButton:SetTall(sc(50)) - self.TextButton:SetText("Non Clicky Button!") - self.TextButton.DoClick = function() - notification.AddLegacy("Non Clicky Text button!", NOTIFY_GENERIC, 5) - end + self.Button = vgui.Create("PIXEL.Button", self) + self.Button:Dock(TOP) + self.Button:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.Button:SetTall(sc(50)) + self.Button.DoClick = function() + notification.AddLegacy("Normal Button!", NOTIFY_GENERIC, 5) + end + + self.TextButton = vgui.Create("PIXEL.TextButton", self) + self.TextButton:Dock(TOP) + self.TextButton:DockMargin(sc(10), sc(10), sc(10), sc(10)) + self.TextButton:SetTall(sc(50)) + self.TextButton:SetText("Non Clicky Button!") + self.TextButton.DoClick = function() + notification.AddLegacy("Non Clicky Text button!", NOTIFY_GENERIC, 5) + end self.NoSoundButton = vgui.Create("PIXEL.TextButton", self) self.NoSoundButton:Dock(TOP) From 25919867d2c38cee4a7a2af4080400a9533993ed Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Thu, 6 Jul 2023 02:41:26 +0100 Subject: [PATCH 147/155] fix: More glualint stuff --- lua/pixelui/drawing/cl_text.lua | 1 - lua/pixelui/elements/color_picker_v2/cl_saturation_bar.lua | 1 - 2 files changed, 2 deletions(-) diff --git a/lua/pixelui/drawing/cl_text.lua b/lua/pixelui/drawing/cl_text.lua index e628e46..7d9a3c7 100644 --- a/lua/pixelui/drawing/cl_text.lua +++ b/lua/pixelui/drawing/cl_text.lua @@ -16,7 +16,6 @@ --]] local ceil = math.ceil -local setFont = PIXEL.SetFont local getTextSize = PIXEL.GetTextSize local setTextPos = surface.SetTextPos local setTextColor = surface.SetTextColor diff --git a/lua/pixelui/elements/color_picker_v2/cl_saturation_bar.lua b/lua/pixelui/elements/color_picker_v2/cl_saturation_bar.lua index a28aebf..b86f77b 100644 --- a/lua/pixelui/elements/color_picker_v2/cl_saturation_bar.lua +++ b/lua/pixelui/elements/color_picker_v2/cl_saturation_bar.lua @@ -1,5 +1,4 @@ local PANEL = {} -local floor = math.floor local clamp = math.Clamp local scale = PIXEL.Scale From fe89cc507d2ccc34304982976fac9282e6d84d00 Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Thu, 6 Jul 2023 02:46:39 +0100 Subject: [PATCH 148/155] Update VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1892b92..227cea2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.2 +2.0.0 From b30a9e7c970eccbccb59bf4fa2f73e0826b4241e Mon Sep 17 00:00:00 2001 From: Lythium <62567544+Lythium4848@users.noreply.github.com> Date: Thu, 6 Jul 2023 02:47:01 +0100 Subject: [PATCH 149/155] Update version in autorun --- lua/autorun/sh_pixelui_loader.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/autorun/sh_pixelui_loader.lua b/lua/autorun/sh_pixelui_loader.lua index 667c653..e261ab9 100644 --- a/lua/autorun/sh_pixelui_loader.lua +++ b/lua/autorun/sh_pixelui_loader.lua @@ -17,7 +17,7 @@ PIXEL = PIXEL or {} PIXEL.UI = PIXEL.UI or {} -PIXEL.UI.Version = "1.3.1" +PIXEL.UI.Version = "2.0.0" PIXEL.Themes = PIXEL.Themes or {} @@ -100,4 +100,4 @@ hook.Add("Think", "PIXEL.UI.VersionChecker", function() return end end) -end) \ No newline at end of file +end) From 90d06324a0546173c68cadd56ddce977392c2bdc Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sat, 15 Jul 2023 16:15:46 +0100 Subject: [PATCH 150/155] fix: Button color being a bit weird --- lua/pixelui/elements/cl_button.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_button.lua b/lua/pixelui/elements/cl_button.lua index 7428c8e..e29a41e 100644 --- a/lua/pixelui/elements/cl_button.lua +++ b/lua/pixelui/elements/cl_button.lua @@ -124,7 +124,7 @@ function PANEL:Paint(w, h) self.BackgroundCol = PIXEL.LerpColor(FrameTime() * 12, self.BackgroundCol, bgCol) - PIXEL.DrawFullRoundedBox(8, 0, 0, w, h, self.BackgroundCol) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.BackgroundCol) self:PaintExtra(w, h) end From f22510f4a6584173d3134457ae251746380bdd1e Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 16 Jul 2023 02:34:03 +0100 Subject: [PATCH 151/155] Slight optimization with text entry --- lua/pixelui/elements/cl_text_entry.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_text_entry.lua b/lua/pixelui/elements/cl_text_entry.lua index 04d17d3..7053855 100644 --- a/lua/pixelui/elements/cl_text_entry.lua +++ b/lua/pixelui/elements/cl_text_entry.lua @@ -48,7 +48,7 @@ end function PANEL:Paint(w, h) local outlineThickness = PIXEL.Scale(1) - PIXEL.DrawFullOutlinedRoundedBox(8, 0, 0, w, h, self.OutlineCol, outlineThickness) + PIXEL.DrawRoundedBox(8, 0, 0, w, h, self.OutlineCol) local col = PIXEL.Colors.Transparent if self:IsEditing() then From 0a5ec443e0b6583992eabd52259ce89d9315a58c Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Sun, 16 Jul 2023 02:34:11 +0100 Subject: [PATCH 152/155] fix: Color not changing on state button --- lua/pixelui/elements/cl_state_button.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_state_button.lua b/lua/pixelui/elements/cl_state_button.lua index 30d94ae..79e12ac 100644 --- a/lua/pixelui/elements/cl_state_button.lua +++ b/lua/pixelui/elements/cl_state_button.lua @@ -42,7 +42,7 @@ function PANEL:Init() Icon = "Qf8Owl7" }, ["failed"] = { - Color = PIXEL.Colors.Warning, + Color = PIXEL.Colors.Negative, Icon = "qHORTll" } } @@ -57,6 +57,7 @@ function PANEL:SetState(state) end self.State = state + self.StateColor = self.States[state].Color self:SetIcon(self.States[state].Icon) if state == ("success" or "failed") then From 2ecbe1073b5bda8ab043c4ac0198fdb23028911f Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Mon, 17 Jul 2023 17:36:53 +0100 Subject: [PATCH 153/155] fix: Wrong color on PIXEL.StateButton --- lua/pixelui/elements/cl_state_button.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/pixelui/elements/cl_state_button.lua b/lua/pixelui/elements/cl_state_button.lua index 79e12ac..d43d37f 100644 --- a/lua/pixelui/elements/cl_state_button.lua +++ b/lua/pixelui/elements/cl_state_button.lua @@ -38,7 +38,7 @@ function PANEL:Init() Icon = "3myjhEM" }, ["success"] = { - Color = PIXEL.Colors.Success, + Color = PIXEL.Colors.Positive, Icon = "Qf8Owl7" }, ["failed"] = { From 954ca92862a2372e017ef5b70334378a57f9143e Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 2 Aug 2023 03:28:08 +0100 Subject: [PATCH 154/155] feat: Scaling function for 1440p as normal one i cant fix --- lua/pixelui/core/cl_scaling.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lua/pixelui/core/cl_scaling.lua b/lua/pixelui/core/cl_scaling.lua index d59c274..d29236c 100644 --- a/lua/pixelui/core/cl_scaling.lua +++ b/lua/pixelui/core/cl_scaling.lua @@ -15,9 +15,13 @@ along with this program. If not, see . --]] -local scrH = ScrH() +local scrH = ScrH +local max = math.max function PIXEL.Scale(value) - return value * (scrH / 1080) + return max(value * (scrH() / 1080), 1) +end +function PIXEL.Scale1440(value) + return max(value * (scrH() / 1440), 1) end local constants = {} From b7b7b496203e2a85beea8e99f20fc38d14656c6b Mon Sep 17 00:00:00 2001 From: Lythium4848 <62567544+Lythium4848@users.noreply.github.com> Date: Wed, 2 Aug 2023 03:28:17 +0100 Subject: [PATCH 155/155] fix: Padding on frame --- lua/pixelui/elements/cl_frame.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lua/pixelui/elements/cl_frame.lua b/lua/pixelui/elements/cl_frame.lua index 288f800..66cb5f0 100644 --- a/lua/pixelui/elements/cl_frame.lua +++ b/lua/pixelui/elements/cl_frame.lua @@ -241,7 +241,7 @@ function PANEL:PerformLayout(w, h) end self.ContentPadding = PIXEL.Scale(8) - self:DockPadding(self.SideBar and PIXEL.Scale(200) or self.ContentPadding, self.HeaderH + self.ContentPadding, self.ContentPadding, self.ContentPadding) + self:DockPadding(self.SideBar and PIXEL.Scale(200) or self.ContentPadding, self.HeaderH, self.ContentPadding, self.ContentPadding) self:LayoutContent(w, h) end @@ -265,8 +265,8 @@ end function PANEL:Paint(w, h) PIXEL.DrawRoundedBox(8, 0, 0, w, h, PIXEL.Colors.Header) - local contentX, contentY = self.SideBar and PIXEL.Scale(200) or self.ContentPadding, self.HeaderH + self.ContentPadding - PIXEL.DrawRoundedBoxEx(8, contentX, contentY, w - contentX - self.ContentPadding, h - contentY - self.ContentPadding, PIXEL.Colors.Background, true, true, true, true) + local contentX, contentY = self.SideBar and PIXEL.Scale(200) or self.ContentPadding, self.HeaderH + PIXEL.DrawRoundedBoxEx(8, contentX, contentY, w - contentX - self.ContentPadding, h - contentY, PIXEL.Colors.Background, true, true, true, true) self:PaintHeader(0, 0, w, self.HeaderH) self:PaintMore(w, h) end