Skip to content

Instantly share code, notes, and snippets.

@meepen
Created April 19, 2016 23:33
Show Gist options
  • Save meepen/4b591bf1e26ec9ad97df244a6f265d29 to your computer and use it in GitHub Desktop.
Save meepen/4b591bf1e26ec9ad97df244a6f265d29 to your computer and use it in GitHub Desktop.
base circular divided panel for gmod
DEFINE_BASECLASS "EditablePanel"
local mat = surface.GetTextureID("vgui/white")
function PANEL:Init()
self.ObjectCount = 3
self:InvalidateLayout(true)
end
function PANEL:SetObjectCount(n)
self.ObjectCount = n
self:InvalidateLayout(true)
end
function PANEL:PerformLayout(w, h)
w = math.min(w, h)
local r = w / 2
local obj = {}
for i = 1, w * 2 do
-- clockwise
local d = math.rad(-i / w * 180)
obj[i] = {
x = math.sin(d) * r + r,
y = math.cos(d) * r + r,
}
end
self.Poly = obj
local lines = {}
for i = 1, self.ObjectCount do
local pos = Angle(0,360 / self.ObjectCount * i, 0):Forward():GetNormalized() * r
lines[i] = {
x = pos.x + r,
y = pos.y + r
}
end
self.Lines = lines
end
function PANEL:GetLeftRightAt(y)
local dist = y / (self:GetWide() / 2)
if (dist < 0) then
dist = -dist
end
dist = 1 - dist
dist = math.sin(math.acos(dist))
local left = self:GetWide() * (0.5 - dist / 2)
return self:GetWide() * (0.5 - dist / 2), self:GetWide() * (0.5 + dist / 2)
end
function PANEL:TestMouseInside()
if (vgui.GetHoveredPanel() ~= self) then
return false
end
local leftx, rightx = self:GetLeftRightAt(gui.MouseY() - select(2, self:GetPos()))
local x = gui.MouseX() - self:GetPos()
return (leftx > x and 1 or 0) + (rightx > x and 1 or 0) == 1
end
function PANEL:GetPointedObject()
local mouse = Vector(gui.MousePos())
local w, h = self:GetWide() / 2, self:GetTall() / 2
w = math.min(w, h)
local middle = Vector(w, w)
local ang = (middle - mouse):Angle()
ang = math.NormalizeAngle(ang.y) + 180
local r = math.floor(ang / (360 / self.ObjectCount)) + 1
return r
end
function PANEL:Think()
self.IsHovered = self:TestMouseInside()
self.WasReleased = self.IsClicked
self.IsClicked = self.IsHovered and input.IsMouseDown(MOUSE_LEFT)
self.WasReleased = self.WasReleased and not self.IsClicked
if (self.WasReleased) then
self:OnClick()
end
end
function PANEL:Paint(w, h)
local drawc = Color(255,255,255,255)
if (self.IsHovered) then
drawc = Color(180,180,180,255)
surface.SetTextColor(255,128,128,255)
else
surface.SetTextColor(255,128,128,255)
end
surface.SetDrawColor(drawc)
surface.SetTexture(mat)
surface.DrawPoly(self.Poly)
surface.SetDrawColor(0,0,0,255)
for i = 1, self.ObjectCount do
surface.DrawLine(w / 2, h / 2, self.Lines[i].x, self.Lines[i].y)
end
surface.SetFont "DermaDefault"
local text = ("Pointing at %i"):format(self:GetPointedObject())
local left, right = self:GetLeftRightAt(h / 2)
local textw, texth = surface.GetTextSize(text)
surface.SetTextPos((right + left) / 2 - textw / 2, h / 2 - texth / 2)
surface.DrawText(text)
end
function PANEL:OnClick()
self:DoClick()
end
function PANEL:DoClick()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment