--[[ | This file was obtained through the combined efforts | of Madbluntz & Plymouth Antiquarian Society. | | Credits: lifestorm, Gregory Wayne Rossel JR., | Maloy, DrPepper10 @ RIP, Atle! | | Visit for more: https://plymouth.thetwilightzone.ru/ --]] local math = math local gui = gui local draw = draw local surface = surface local ScrW = ScrW local ScrH = ScrH local IsValid = IsValid local ipairs = ipairs local SUI, NAME = CURRENT_SUI, CURRENT_SUI.name local TDLib = sui.TDLib local FRAME_FONT = SUI.CreateFont("Frame", "Roboto", 18) local Panel = FindMetaTable("Panel") local PANEL = {} AccessorFunc(PANEL, "m_bHeaderHeight", "HeaderHeight", FORCE_NUMBER) AccessorFunc(PANEL, "m_bTitleFont", "TitleFont", FORCE_STRING) AccessorFunc(PANEL, "m_bSizable", "Sizable", FORCE_BOOL) AccessorFunc(PANEL, "m_iMinWidth", "MinWidth", FORCE_NUMBER) AccessorFunc(PANEL, "m_iMinHeight", "MinHeight", FORCE_NUMBER) local header_Think = function(s) local parent = s.parent local sw, sh = ScrW(), ScrH() if s.dragging then local x, y = input.GetCursorPos() x, y = math.Clamp(x, 1, sw - 1), math.Clamp(y, 1, sh - 1) x, y = x - s.dragging[1], y - s.dragging[2] parent:SetPos(x, y) parent:InvalidateLayout(true) parent:OnPosChanged() else local x, y, w, h = parent:GetBounds() parent:SetPos(math.Clamp(x, 5, sw - w - 5), math.Clamp(y, 5, sh - h - 5)) end end local header_OnMousePressed = function(s) local parent = s.parent s.dragging = {gui.MouseX() - parent.x, gui.MouseY() - parent.y} s:MouseCapture(true) end local header_OnMouseReleased = function(s) s.dragging = nil s:MouseCapture(false) end local title_SetBGColor = function(s, c) s:SetVisible(c and true or false) end local title_update_color = function(s) s:SetTextColor(SUI.GetColor("title")) end local close_DoClick = function(s) s.frame:Remove() end function PANEL:Init() local header_buttons = {} self.header_buttons = header_buttons self:Center() self:SetHeaderHeight(28) local header = self:Add("PANEL") header:Dock(TOP) header.Paint = self.HeaderPaint header:SetCursor("sizeall") header.parent = self header.Think = header_Think header.OnMousePressed = header_OnMousePressed header.OnMouseReleased = header_OnMouseReleased self.header = header local title = header:Add(NAME .. ".Label") title:Dock(LEFT) title:DockMargin(6, 2, 0, 2) title:SetText("") title:SetTextColor(SUI.GetColor("title")) title:SizeToContents() title.SetBGColor = title_SetBGColor hook.Add(NAME .. ".ThemeChanged", title, title_update_color) self.title = title self.close = self:AddHeaderButton("https://raw.githubusercontent.com/Srlion/Addons-Data/main/icons/sui/close.png", "close", close_DoClick) self.close.frame = self self:SetSize(SUI.Scale(520), SUI.Scale(364)) self:SetTitleFont(FRAME_FONT) SUI.OnScaleChanged(self, self.ScaleChanged) function self:PerformLayout(w, h) if IsValid(title) then title:SizeToContents() end if IsValid(header) then header:SetTall(SUI.Scale(self:GetHeaderHeight())) end for k, v in ipairs(header_buttons) do if IsValid(v) then v:SetWide(v:GetTall()) local margin = SUI.Scale(4) v.image:DockMargin(margin, margin, margin, margin) end end end end function PANEL:SetSize(w, h) self.real_w, self.real_h = w, h self:ScaleChanged() end function PANEL:HeaderPaint(w, h) draw.RoundedBoxEx(3, 0, 0, w, h, SUI.GetColor("header"), true, true) end local SetSize = Panel.SetSize PANEL.RealSetSize = SetSize function PANEL:ScaleChanged() if self.sizing then return end local new_w, new_h = SUI.Scale(self.real_w), SUI.Scale(self.real_h) self.x, self.y = self.x + (self:GetWide() / 2 - new_w / 2), self.y + (self:GetTall() / 2 - new_h / 2) SetSize(self, new_w, new_h) self:InvalidateLayout(true) end function PANEL:Paint(w, h) if SUI.GetColor("frame_blur") then TDLib.BlurPanel(self) end self:RoundedBox("Background", 3, 0, 0, w, h, SUI.GetColor("frame")) end function PANEL:SetTitleFont(font) self.m_bTitleFont = font self.title:SetFont(font) end function PANEL:SetTitle(text) self.title:SetText(text) self.title:SizeToContents() end function PANEL:AddHeaderButton(image_name, name, callback) local button = self.header:Add("DButton") button:SetText("") button:Dock(RIGHT) button:DockMargin(0, 2, #self.header:GetChildren() == 1 and 4 or 2, 2) local hover = name .. "_hover" local press = name .. "_press" local circle = {} button.Paint = function(s, w, h) if s:IsHovered() then TDLib.DrawCircle(circle, w / 2, h / 2, w / 2, SUI.GetColor(hover)) end if s.Depressed then TDLib.DrawCircle(circle, w / 2, h / 2, w / 2, SUI.GetColor(press)) end end button.DoClick = callback local image = button:Add(NAME .. ".Image") image:Dock(FILL) image:SetMouseInputEnabled(false) image:SetImage(image_name) button.image = image table.insert(self.header_buttons, button) return button end function PANEL:OnMousePressed(_, checking) if not self.m_bSizable then return end local x, y = self:LocalToScreen(0, 0) local w, h = self:GetSize() if gui.MouseX() > (x + w - 20) and gui.MouseY() > (y + h - 20) then if not checking then self.sizing = {gui.MouseX() - w, gui.MouseY() - h} self:MouseCapture(true) end self:SetCursor("sizenwse") return end if checking then self:SetCursor("arrow") end end function PANEL:OnMouseReleased() if not self.m_bSizable then return end self:MouseCapture(false) SUI.CallScaleChanged() self.sizing = nil end function PANEL:Think() if not self.m_bSizable then return end self:OnMousePressed(nil, true) if not self.sizing then return end local sw, sh = ScrW(), ScrH() local cx, cy = input.GetCursorPos() local mousex = math.Clamp(cx, 1, sw - 1) local mousey = math.Clamp(cy, 1, sh - 1) local x = mousex - self.sizing[1] x = math.Clamp(x, self.m_iMinWidth, sw - 10) local y = mousey - self.sizing[2] y = math.Clamp(y, self.m_iMinHeight, sh - 10) self.real_w, self.real_h = x, y SetSize(self, x, y) self:InvalidateLayout(true) self:SetCursor("sizenwse") end function PANEL:OnPosChanged() end local SetVisible = Panel.SetVisible local Remove = Panel.Remove local anim_speed = 0.2 local show = function(s) local w, h = s.real_w, s.real_h if s.anim_scale then w, h = SUI.Scale(w), SUI.Scale(h) end SetVisible(s, true) SetSize(s, w * 1.1, h * 1.1) s:Center() s:Stop() s:SizeTo(w, h, anim_speed, 0, -1) s:MoveTo((ScrW() / 2) - (w / 2), (ScrH() / 2) - (h / 2), anim_speed, 0, -1) s:AlphaTo(255, anim_speed + 0.02, 0) s:MakePopup() end local remove = function(s, hide) if not hide and not s:IsVisible() then Remove(s) return end local w, h = s.real_w, s.real_h if s.anim_scale then w, h = SUI.Scale(w), SUI.Scale(h) end w, h = w * 1.1, h * 1.1 s:Stop() s:SizeTo(w, h, anim_speed, 0, -1) s:MoveTo((ScrW() / 2) - (w / 2), (ScrH() / 2) - (h / 2), anim_speed, 0, -1) s:SetMouseInputEnabled(false) s:SetKeyboardInputEnabled(false) s:AlphaTo(0, anim_speed + 0.02, 0, function() if hide then SetVisible(s, false) else Remove(s) end end) end local hide = function(s) remove(s, true) end function PANEL:AddAnimations(w, h, no_scale) self.anim_scale = not no_scale self.real_w, self.real_h = w, h self:SetAlpha(0) show(self) self.Remove = remove self.Hide = hide self.Show = show end sui.register("Frame", PANEL, "EditablePanel")