Created
April 19, 2016 23:33
-
-
Save meepen/4b591bf1e26ec9ad97df244a6f265d29 to your computer and use it in GitHub Desktop.
base circular divided panel for gmod
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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