-- Garry's Mod Binder - Radial Menu Tab local PANEL = {} function PANEL:Init() self:Dock(FILL) self:DockMargin(40, 20, 40, 20) self.Paint = function() end self.Header = vgui.Create("DPanel", self) self.Header:Dock(TOP) self.Header:SetHeight(80) self.Header.Paint = function(s, w, h) draw.SimpleText(Binder.GetPhrase("radial_config"), "Binder_Title", 0, 10, Color(255, 255, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP) draw.SimpleText(Binder.GetPhrase("radial_desc"), "Binder_Small", 0, 40, Color(255, 255, 255, 100), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP) end self.RadialContainer = vgui.Create("DPanel", self) self.RadialContainer:Dock(FILL) self.RadialContainer.Paint = function(s, w, h) local cx, cy = w / 2, h / 2 draw.NoTexture() surface.SetDrawColor(Color(255, 255, 255, 10)) surface.DrawCircle(cx, cy, 40, 255, 255, 255, 255) draw.SimpleText(Binder.GetPhrase("radial_center"), "Binder_Small", cx, cy, Color(255, 255, 255, 150), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end self.Segments = {} self:BuildSegments() self:Refresh() end function PANEL:GetActiveProfile() for _, p in ipairs(Binder.Profiles or {}) do if p.Active then return p end end return nil end function PANEL:BuildSegments() local cx, cy = 0, 0 -- Will be updated in PerformLayout local radius = 120 for i = 1, 8 do local btn = vgui.Create("DButton", self.RadialContainer) btn:SetSize(80, 80) btn:SetText("") btn.Slot = i btn.Paint = function(s, w, h) local bgColor = s:IsHovered() and Binder.Config.AccentColor or Color(40, 40, 45) draw.RoundedBox(20, 0, 0, w, h, bgColor) local activeProf = self:GetActiveProfile() local text = Binder.GetPhrase("slot", i) if activeProf and activeProf.Radial and activeProf.Radial[i] then text = activeProf.Radial[i].Label end draw.SimpleText(text, "Binder_Small", w/2, h/2, Color(255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end btn.DoClick = function(s) self:PromptSegment(s.Slot) end table.insert(self.Segments, btn) end end function PANEL:Refresh() -- Nothing inherently needed here unless we drastically change profile end function PANEL:PerformLayout(w, h) local cx, cy = w / 2, (h - 80) / 2 local radius = 120 for i, btn in ipairs(self.Segments) do local angle = (i - 1) * (360 / 8) - 90 -- Start at top local rad = math.rad(angle) local lx, ly = cx + math.cos(rad) * radius, cy + math.sin(rad) * radius btn:SetPos(lx - 40, ly - 40) end end function PANEL:PromptSegment(slot) local profile = self:GetActiveProfile() if not profile then return end profile.Radial = profile.Radial or {} local currentLabel = profile.Radial[slot] and profile.Radial[slot].Label or "" local currentCmd = profile.Radial[slot] and profile.Radial[slot].Command or "" local frame = vgui.Create("DFrame") frame:SetTitle("Configure Radial Slot " .. slot) frame:SetSize(300, 150) frame:Center() frame:MakePopup() local lbl1 = vgui.Create("DLabel", frame) lbl1:SetPos(10, 30) lbl1:SetText("Label (Text):") lbl1:SizeToContents() local txtLabel = vgui.Create("DTextEntry", frame) txtLabel:SetPos(10, 50) txtLabel:SetSize(280, 20) txtLabel:SetText(currentLabel) local lbl2 = vgui.Create("DLabel", frame) lbl2:SetPos(10, 80) lbl2:SetText("Console Command:") lbl2:SizeToContents() local txtCmd = vgui.Create("DTextEntry", frame) txtCmd:SetPos(10, 100) txtCmd:SetSize(280, 20) txtCmd:SetText(currentCmd) local saveBtn = vgui.Create("DButton", frame) saveBtn:SetPos(10, 125) saveBtn:SetSize(135, 20) saveBtn:SetText("Save") saveBtn.DoClick = function() local l = txtLabel:GetValue() local c = txtCmd:GetValue() if l == "" or c == "" then profile.Radial[slot] = nil else profile.Radial[slot] = { Label = l, Command = c } end Binder.SaveToServer() self:Refresh() frame:Remove() end local clearBtn = vgui.Create("DButton", frame) clearBtn:SetPos(155, 125) clearBtn:SetSize(135, 20) clearBtn:SetText("Clear Slot") clearBtn.DoClick = function() profile.Radial[slot] = nil Binder.SaveToServer() self:Refresh() frame:Remove() end end vgui.Register("Binder_RadialTab", PANEL, "EditablePanel")