Gui Helper - инструмент для поиска позиций на экране и позволяет не делать интерфейс на глаз , а получить точные координаты .
Аддон в мастерской
-- GUI Helper by [Vasilich] and Команда КЭП
local helper = {}
helper.enabled = false
helper.mode = "info"
helper.drawing = false
helper.startPos = nil
helper.currentPos = nil
helper.selectedInfo = nil
helper.mouseX, helper.mouseY = 0, 0
helper.mouseDown = false
helper.lastMouseDown = false
helper.hoverInfo = nil
concommand.Add("guihelper_toggle", function()
helper.enabled = not helper.enabled
if helper.enabled then
hook.Add("HUDPaint", "GUIHelper_HUDPaint", function() helper:Paint() end)
hook.Add("Think", "GUIHelper_Think", function() helper:Think() end)
print("[GUI Helper] Включён")
else
hook.Remove("HUDPaint", "GUIHelper_HUDPaint")
hook.Remove("Think", "GUIHelper_Think")
helper.drawing = false
helper.selectedInfo = nil
print("[GUI Helper] Выключен")
end
end)
concommand.Add("guihelper_mode", function(ply, cmd, args)
if #args < 1 then
print("Использование: guihelper_mode <info|rect|circle>")
return
end
local mode = args[1]:lower()
if mode == "info" or mode == "rect" or mode == "circle" then
helper.mode = mode
helper.drawing = false
helper.selectedInfo = nil
print("[GUI Helper] Режим установлен: " .. mode)
else
print("Неверный режим. Используйте info, rect или circle.")
end
end)
concommand.Add("guihelper_copy", function()
if helper.selectedInfo then
SetClipboardText(helper:FormatInfo(helper.selectedInfo))
print("[GUI Helper] Скопировано в буфер обмена: " .. helper:FormatInfo(helper.selectedInfo))
else
print("[GUI Helper] Нет выделения для копирования.")
end
end)
concommand.Add("guihelper_output", function()
if helper.selectedInfo then
print("[GUI Helper] Выделение: " .. helper:FormatInfo(helper.selectedInfo))
else
print("[GUI Helper] Нет выделения.")
end
end)
function helper:FormatInfo(info)
if self.mode == "info" and info.panelClass then
if info.parentClass then
return string.format("panel:SetPos(%d, %d) --[[ относительно родителя: %s ]] panel:SetSize(%d, %d)",
info.relX, info.relY, info.parentClass, info.w, info.h)
else
return string.format("panel:SetPos(%d, %d) --[[ экранные координаты ]] panel:SetSize(%d, %d)",
info.x, info.y, info.w, info.h)
end
elseif self.mode == "rect" then
return string.format("-- Прямоугольник: %d, %d, %d, %d", info.x, info.y, info.w, info.h)
elseif self.mode == "circle" then
return string.format("-- Центр: (%d, %d), радиус: %d", info.x, info.y, info.r)
end
return ""
end
function helper:Think()
self.mouseX, self.mouseY = gui.MousePos()
local hover = vgui.GetHoveredPanel()
if hover and IsValid(hover) then
local class = "unknown"
local success, result = pcall(function() return hover:GetClass() end)
if success then class = result end
local x, y = 0, 0
success, result = pcall(function() return hover:LocalToScreen(0, 0) end)
if success and type(result) == "table" then
x, y = result[1] or 0, result[2] or 0
end
local w, h = 0, 0
success, result = pcall(function() return hover:GetSize() end)
if success and type(result) == "table" then
w, h = result[1] or 0, result[2] or 0
end
local relX, relY = 0, 0
success, result = pcall(function() return hover:GetPos() end)
if success and type(result) == "table" then
relX, relY = result[1] or 0, result[2] or 0
end
local parentClass = nil
local parent = hover:GetParent()
if parent and IsValid(parent) then
success, result = pcall(function() return parent:GetClass() end)
if success then parentClass = result end
end
self.hoverInfo = {
class = class,
x = x,
y = y,
relX = relX,
relY = relY,
w = w,
h = h,
parentClass = parentClass
}
if self.mode == "info" then
self.selectedInfo = {
panelClass = class,
parentClass = parentClass,
x = x,
y = y,
relX = relX,
relY = relY,
w = w,
h = h
}
end
else
self.hoverInfo = nil
end
self.mouseDown = input.IsMouseDown(MOUSE_LEFT)
if self.mode == "rect" or self.mode == "circle" then
if self.mouseDown and not self.lastMouseDown then
self.drawing = true
self.startPos = { x = self.mouseX, y = self.mouseY }
self.currentPos = self.startPos
self.selectedInfo = nil
elseif not self.mouseDown and self.lastMouseDown then
if self.drawing then
self.drawing = false
if self.mode == "rect" then
local x1 = math.min(self.startPos.x, self.currentPos.x)
local y1 = math.min(self.startPos.y, self.currentPos.y)
local x2 = math.max(self.startPos.x, self.currentPos.x)
local y2 = math.max(self.startPos.y, self.currentPos.y)
self.selectedInfo = {
x = x1,
y = y1,
w = x2 - x1,
h = y2 - y1
}
elseif self.mode == "circle" then
local dx = self.currentPos.x - self.startPos.x
local dy = self.currentPos.y - self.startPos.y
local radius = math.sqrt(dx*dx + dy*dy)
self.selectedInfo = {
x = self.startPos.x,
y = self.startPos.y,
r = math.floor(radius)
}
end
end
end
if self.drawing then
self.currentPos = { x = self.mouseX, y = self.mouseY }
end
end
self.lastMouseDown = self.mouseDown
end
function helper:Paint()
surface.SetFont("Default")
surface.SetTextColor(255,255,255,255)
surface.SetTextPos(10, 60)
surface.DrawText(string.format("Мышь: %d, %d", self.mouseX, self.mouseY))
if self.hoverInfo then
local info = self.hoverInfo
surface.SetDrawColor(255,0,0,255)
surface.DrawOutlinedRect(info.x, info.y, info.w, info.h)
surface.SetTextColor(255,255,0,255)
surface.SetTextPos(10, 30)
surface.DrawText(string.format("Панель: %s | Позиция: %d, %d | Размер: %d, %d",
info.class, info.x, info.y, info.w, info.h))
end
if self.drawing and self.startPos and self.currentPos then
surface.SetDrawColor(0,255,0,255)
if self.mode == "rect" then
local x1 = self.startPos.x
local y1 = self.startPos.y
local x2 = self.currentPos.x
local y2 = self.currentPos.y
surface.DrawOutlinedRect(math.min(x1, x2), math.min(y1, y2), math.abs(x2-x1), math.abs(y2-y1))
surface.SetTextColor(0,255,0,255)
surface.SetTextPos(x2+5, y2+5)
surface.DrawText(string.format("%d x %d", math.abs(x2-x1), math.abs(y2-y1)))
elseif self.mode == "circle" then
local cx, cy = self.startPos.x, self.startPos.y
local dx, dy = self.currentPos.x - cx, self.currentPos.y - cy
local radius = math.sqrt(dx*dx + dy*dy)
local segments = 36
local points = {}
for i = 0, segments do
local a = 2 * math.pi * i / segments
table.insert(points, {x = cx + radius * math.cos(a), y = cy + radius * math.sin(a)})
end
surface.DrawPoly(points)
surface.DrawLine(cx, cy, self.currentPos.x, self.currentPos.y)
surface.SetTextColor(0,255,0,255)
surface.SetTextPos(self.currentPos.x+5, self.currentPos.y+5)
surface.DrawText(string.format("r = %d", math.floor(radius)))
end
end
if self.selectedInfo then
surface.SetTextColor(255,255,255,255)
surface.SetTextPos(10, 50)
surface.DrawText("Выделено: " .. self:FormatInfo(self.selectedInfo))
end
surface.SetTextColor(200,200,200,255)
surface.SetTextPos(10, ScrH() - 60)
surface.DrawText("GUI Helper ВКЛ | Режим: " .. self.mode)
surface.SetTextPos(10, ScrH() - 45)
surface.DrawText("Команды: guihelper_mode <info|rect|circle>, guihelper_copy, guihelper_output")
end