Files
VnUtest/garrysmod/addons/Binder/lua/binder/vgui/cl_keybind_tab.lua
2026-03-31 10:27:04 +03:00

205 lines
7.2 KiB
Lua

-- Garry's Mod Binder - Keybinds Tab (Virtual Keyboard)
local PANEL = {}
local KEY_LAYOUT = {
{"ESC", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"},
{"~", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "BKSP"},
{"TAB", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\"},
{"CAPS", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "ENTER"},
{"SHIFT", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "SHIFT"},
{"CTRL", "WIN", "ALT", "SPACE", "ALT", "WIN", "MENU"}
}
local KEY_SPECIAL = {
{"PRSC", "SCRLK", "PAUSE"},
{"INS", "HOME", "PGUP"},
{"DEL", "END", "PGDN"},
{""},
{"", "", ""}
}
local NUM_PAD = {
{"NUM", "/", "*", "-"},
{"7", "8", "9", "+"},
{"4", "5", "6"},
{"1", "2", "3", "ENT"},
{"0", "."}
}
local STRING_TO_KEY = {
["ESC"] = KEY_ESCAPE, ["~"] = KEY_TILDE, ["-"] = KEY_MINUS, ["="] = KEY_EQUAL, ["BKSP"] = KEY_BACKSPACE, ["TAB"] = KEY_TAB,
["["] = KEY_LBRACKET, ["]"] = KEY_RBRACKET, ["\\"] = KEY_BACKSLASH, ["CAPS"] = KEY_CAPSLOCK, [";"] = KEY_SEMICOLON,
["'"] = KEY_APOSTROPHE, ["ENTER"] = KEY_ENTER, ["SHIFT"] = KEY_LSHIFT, [","] = KEY_COMMA, ["."] = KEY_PERIOD,
["/"] = KEY_SLASH, ["CTRL"] = KEY_LCONTROL, ["WIN"] = KEY_LWIN, ["ALT"] = KEY_LALT, ["SPACE"] = KEY_SPACE,
["MENU"] = KEY_APP,
["PRSC"] = KEY_SYSRQ, ["SCRLK"] = KEY_SCROLLLOCK, ["PAUSE"] = KEY_BREAK, ["INS"] = KEY_INSERT, ["HOME"] = KEY_HOME,
["PGUP"] = KEY_PAGEUP, ["DEL"] = KEY_DELETE, ["END"] = KEY_END, ["PGDN"] = KEY_PAGEDOWN,
[""] = KEY_UP, [""] = KEY_LEFT, [""] = KEY_DOWN, [""] = KEY_RIGHT,
["NUM"] = KEY_NUMLOCK, ["/"] = KEY_PAD_DIVIDE, ["*"] = KEY_PAD_MULTIPLY, ["-"] = KEY_PAD_MINUS, ["+"] = KEY_PAD_PLUS,
["ENT"] = KEY_PAD_ENTER, ["."] = KEY_PAD_DECIMAL,
["1"] = KEY_1, ["2"] = KEY_2, ["3"] = KEY_3, ["4"] = KEY_4, ["5"] = KEY_5, ["6"] = KEY_6, ["7"] = KEY_7, ["8"] = KEY_8, ["9"] = KEY_9, ["0"] = KEY_0,
}
-- Add letters and F-keys
for i = 1, 26 do STRING_TO_KEY[string.char(64 + i)] = _G["KEY_" .. string.char(64 + i)] end
for i = 1, 12 do STRING_TO_KEY["F" .. i] = _G["KEY_F" .. i] end
function PANEL:Init()
self:Dock(FILL)
self:DockMargin(20, 20, 20, 20)
self.Paint = function() end
self.InfoBar = vgui.Create("DPanel", self)
self.InfoBar:Dock(TOP)
self.InfoBar:SetHeight(40)
self.InfoBar.Paint = function(s, w, h)
draw.RoundedBox(0, 0, 0, w, h, Color(255, 255, 255, 5))
local activeProf = self:GetActiveProfile()
local name = activeProf and activeProf.Name or "No Active Profile"
local bindCount = activeProf and table.Count(activeProf.Binds or {}) or 0
draw.SimpleText(name, "Binder_Main", 50, h / 2, Color(255, 255, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText(Binder.GetPhrase("binds_count", bindCount), "Binder_Small", w - 20, h / 2, Color(255, 255, 255, 100), TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
end
self.KeyboardContainer = vgui.Create("DPanel", self)
self.KeyboardContainer:Dock(FILL)
self.KeyboardContainer:DockMargin(0, 40, 0, 0)
self.KeyboardContainer.Paint = function() end
self.KeyButtons = {}
self:BuildKeyboard()
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:Refresh()
local profile = self:GetActiveProfile()
local binds = profile and profile.Binds or {}
for _, btnData in ipairs(self.KeyButtons) do
local isBound = binds[btnData.enum] != nil
btnData.btn.IsActiveNode = isBound
end
end
function PANEL:PromptBind(keyStr, keyEnum)
local profile = self:GetActiveProfile()
if not profile then return end
local currentCmd = profile.Binds[keyEnum] or ""
Derma_StringRequest(
"Bind " .. keyStr,
"Enter console command to execute on press (e.g., 'say /raid'):\nLeave blank to unbind.",
currentCmd,
function(text)
if text == "" then
profile.Binds[keyEnum] = nil
else
profile.Binds[keyEnum] = text
end
Binder.SaveToServer()
self:Refresh()
end
)
end
function PANEL:CreateKey(parent, text, x, y, w, h)
local btn = vgui.Create("DButton", parent)
btn:SetSize(w or 35, h or 35)
btn:SetPos(x, y)
btn:SetText("")
btn.IsActiveNode = false
local keyEnum = STRING_TO_KEY[text]
btn.Paint = function(s, bw, bh)
local bgColor = s.IsActiveNode and Binder.Config.AccentColor or Color(40, 40, 40)
if s:IsHovered() then
bgColor = Color(bgColor.r + 20, bgColor.g + 20, bgColor.b + 20)
end
draw.RoundedBox(4, 0, 0, bw, bh, bgColor)
draw.SimpleText(text, "Binder_Key", bw / 2, bh / 2, Color(255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
btn.DoClick = function()
if keyEnum then
self:PromptBind(text, keyEnum)
else
print("Binder: Unmapped key - " .. text)
end
end
table.insert(self.KeyButtons, {btn = btn, sysName = text, enum = keyEnum})
end
function PANEL:BuildKeyboard()
local startX, startY = 10, 10
local keySize = 38
local spacing = 4
-- Main Block
for r, row in ipairs(KEY_LAYOUT) do
local rx = startX
local ry = startY + (r - 1) * (keySize + spacing)
-- Adjustments
if r == 1 then ry = ry - 5 end
for k, key in ipairs(row) do
local kw = keySize
if key == "BKSP" then kw = keySize * 2 + spacing
elseif key == "TAB" then kw = keySize * 1.5
elseif key == "CAPS" then kw = keySize * 1.8
elseif key == "ENTER" then kw = keySize * 1.8
elseif key == "SHIFT" then kw = keySize * 2.3
elseif key == "SPACE" then kw = keySize * 5 + spacing * 4
elseif key == "CTRL" or key == "ALT" or key == "WIN" then kw = keySize * 1.2
end
self:CreateKey(self.KeyboardContainer, key, rx, ry, kw, keySize)
rx = rx + kw + spacing
end
end
-- Special Keys Block
local specX = startX + 15 * (keySize + spacing)
for r, row in ipairs(KEY_SPECIAL) do
local rx = specX
local ry = startY + (r - 1) * (keySize + spacing)
if r == 4 then rx = rx + keySize + spacing end
for k, key in ipairs(row) do
self:CreateKey(self.KeyboardContainer, key, rx, ry, keySize, keySize)
rx = rx + keySize + spacing
end
end
-- Num Pad
local numX = specX + 4 * (keySize + spacing)
for r, row in ipairs(NUM_PAD) do
local rx = numX
local ry = startY + (r - 1) * (keySize + spacing)
for k, key in ipairs(row) do
local kh = keySize
if key == "+" or key == "ENT" then kh = keySize * 2 + spacing end
local kw = keySize
if key == "0" then kw = keySize * 2 + spacing end
self:CreateKey(self.KeyboardContainer, key, rx, ry, kw, kh)
rx = rx + kw + spacing
end
end
end
vgui.Register("Binder_KeybindsTab", PANEL, "EditablePanel")