Tercio@23: --[[----------------------------------------------------------------------------- Tercio@23: Keybinding Widget Tercio@23: Set Keybindings in the Config UI. Tercio@23: -------------------------------------------------------------------------------]] Tercio@23: local Type, Version = "Keybinding", 24 Tercio@23: local AceGUI = LibStub and LibStub("AceGUI-3.0", true) Tercio@23: if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end Tercio@23: Tercio@23: -- Lua APIs Tercio@23: local pairs = pairs Tercio@23: Tercio@23: -- WoW APIs Tercio@23: local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown Tercio@23: local CreateFrame, UIParent = CreateFrame, UIParent Tercio@23: Tercio@23: -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded Tercio@23: -- List them here for Mikk's FindGlobals script Tercio@23: -- GLOBALS: NOT_BOUND Tercio@23: Tercio@23: local wowMoP Tercio@23: do Tercio@23: local _, _, _, interface = GetBuildInfo() Tercio@23: wowMoP = (interface >= 50000) Tercio@23: end Tercio@23: Tercio@23: --[[----------------------------------------------------------------------------- Tercio@23: Scripts Tercio@23: -------------------------------------------------------------------------------]] Tercio@23: Tercio@23: local function Control_OnEnter(frame) Tercio@23: frame.obj:Fire("OnEnter") Tercio@23: end Tercio@23: Tercio@23: local function Control_OnLeave(frame) Tercio@23: frame.obj:Fire("OnLeave") Tercio@23: end Tercio@23: Tercio@23: local function Keybinding_OnClick(frame, button) Tercio@23: if button == "LeftButton" or button == "RightButton" then Tercio@23: local self = frame.obj Tercio@23: if self.waitingForKey then Tercio@23: frame:EnableKeyboard(false) Tercio@23: self.msgframe:Hide() Tercio@23: frame:UnlockHighlight() Tercio@23: self.waitingForKey = nil Tercio@23: else Tercio@23: frame:EnableKeyboard(true) Tercio@23: self.msgframe:Show() Tercio@23: frame:LockHighlight() Tercio@23: self.waitingForKey = true Tercio@23: end Tercio@23: end Tercio@23: AceGUI:ClearFocus() Tercio@23: end Tercio@23: Tercio@23: local ignoreKeys = { Tercio@23: ["BUTTON1"] = true, ["BUTTON2"] = true, Tercio@23: ["UNKNOWN"] = true, Tercio@23: ["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true, Tercio@23: ["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true, Tercio@23: } Tercio@23: local function Keybinding_OnKeyDown(frame, key) Tercio@23: local self = frame.obj Tercio@23: if self.waitingForKey then Tercio@23: local keyPressed = key Tercio@23: if keyPressed == "ESCAPE" then Tercio@23: keyPressed = "" Tercio@23: else Tercio@23: if ignoreKeys[keyPressed] then return end Tercio@23: if IsShiftKeyDown() then Tercio@23: keyPressed = "SHIFT-"..keyPressed Tercio@23: end Tercio@23: if IsControlKeyDown() then Tercio@23: keyPressed = "CTRL-"..keyPressed Tercio@23: end Tercio@23: if IsAltKeyDown() then Tercio@23: keyPressed = "ALT-"..keyPressed Tercio@23: end Tercio@23: end Tercio@23: Tercio@23: frame:EnableKeyboard(false) Tercio@23: self.msgframe:Hide() Tercio@23: frame:UnlockHighlight() Tercio@23: self.waitingForKey = nil Tercio@23: Tercio@23: if not self.disabled then Tercio@23: self:SetKey(keyPressed) Tercio@23: self:Fire("OnKeyChanged", keyPressed) Tercio@23: end Tercio@23: end Tercio@23: end Tercio@23: Tercio@23: local function Keybinding_OnMouseDown(frame, button) Tercio@23: if button == "LeftButton" or button == "RightButton" then Tercio@23: return Tercio@23: elseif button == "MiddleButton" then Tercio@23: button = "BUTTON3" Tercio@23: elseif button == "Button4" then Tercio@23: button = "BUTTON4" Tercio@23: elseif button == "Button5" then Tercio@23: button = "BUTTON5" Tercio@23: end Tercio@23: Keybinding_OnKeyDown(frame, button) Tercio@23: end Tercio@23: Tercio@23: --[[----------------------------------------------------------------------------- Tercio@23: Methods Tercio@23: -------------------------------------------------------------------------------]] Tercio@23: local methods = { Tercio@23: ["OnAcquire"] = function(self) Tercio@23: self:SetWidth(200) Tercio@23: self:SetLabel("") Tercio@23: self:SetKey("") Tercio@23: self.waitingForKey = nil Tercio@23: self.msgframe:Hide() Tercio@23: self:SetDisabled(false) Tercio@23: self.button:EnableKeyboard(false) Tercio@23: end, Tercio@23: Tercio@23: -- ["OnRelease"] = nil, Tercio@23: Tercio@23: ["SetDisabled"] = function(self, disabled) Tercio@23: self.disabled = disabled Tercio@23: if disabled then Tercio@23: self.button:Disable() Tercio@23: self.label:SetTextColor(0.5,0.5,0.5) Tercio@23: else Tercio@23: self.button:Enable() Tercio@23: self.label:SetTextColor(1,1,1) Tercio@23: end Tercio@23: end, Tercio@23: Tercio@23: ["SetKey"] = function(self, key) Tercio@23: if (key or "") == "" then Tercio@23: self.button:SetText(NOT_BOUND) Tercio@23: self.button:SetNormalFontObject("GameFontNormal") Tercio@23: else Tercio@23: self.button:SetText(key) Tercio@23: self.button:SetNormalFontObject("GameFontHighlight") Tercio@23: end Tercio@23: end, Tercio@23: Tercio@23: ["GetKey"] = function(self) Tercio@23: local key = self.button:GetText() Tercio@23: if key == NOT_BOUND then Tercio@23: key = nil Tercio@23: end Tercio@23: return key Tercio@23: end, Tercio@23: Tercio@23: ["SetLabel"] = function(self, label) Tercio@23: self.label:SetText(label or "") Tercio@23: if (label or "") == "" then Tercio@23: self.alignoffset = nil Tercio@23: self:SetHeight(24) Tercio@23: else Tercio@23: self.alignoffset = 30 Tercio@23: self:SetHeight(44) Tercio@23: end Tercio@23: end, Tercio@23: } Tercio@23: Tercio@23: --[[----------------------------------------------------------------------------- Tercio@23: Constructor Tercio@23: -------------------------------------------------------------------------------]] Tercio@23: Tercio@23: local ControlBackdrop = { Tercio@23: bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", Tercio@23: edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", Tercio@23: tile = true, tileSize = 16, edgeSize = 16, Tercio@23: insets = { left = 3, right = 3, top = 3, bottom = 3 } Tercio@23: } Tercio@23: Tercio@23: local function keybindingMsgFixWidth(frame) Tercio@23: frame:SetWidth(frame.msg:GetWidth() + 10) Tercio@23: frame:SetScript("OnUpdate", nil) Tercio@23: end Tercio@23: Tercio@23: local function Constructor() Tercio@23: local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type) Tercio@23: Tercio@23: local frame = CreateFrame("Frame", nil, UIParent) Tercio@23: local button = CreateFrame("Button", name, frame, wowMoP and "UIPanelButtonTemplate" or "UIPanelButtonTemplate2") Tercio@23: Tercio@23: button:EnableMouse(true) Tercio@23: button:RegisterForClicks("AnyDown") Tercio@23: button:SetScript("OnEnter", Control_OnEnter) Tercio@23: button:SetScript("OnLeave", Control_OnLeave) Tercio@23: button:SetScript("OnClick", Keybinding_OnClick) Tercio@23: button:SetScript("OnKeyDown", Keybinding_OnKeyDown) Tercio@23: button:SetScript("OnMouseDown", Keybinding_OnMouseDown) Tercio@23: button:SetPoint("BOTTOMLEFT") Tercio@23: button:SetPoint("BOTTOMRIGHT") Tercio@23: button:SetHeight(24) Tercio@23: button:EnableKeyboard(false) Tercio@23: Tercio@23: local text = button:GetFontString() Tercio@23: text:SetPoint("LEFT", 7, 0) Tercio@23: text:SetPoint("RIGHT", -7, 0) Tercio@23: Tercio@23: local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight") Tercio@23: label:SetPoint("TOPLEFT") Tercio@23: label:SetPoint("TOPRIGHT") Tercio@23: label:SetJustifyH("CENTER") Tercio@23: label:SetHeight(18) Tercio@23: Tercio@23: local msgframe = CreateFrame("Frame", nil, UIParent) Tercio@23: msgframe:SetHeight(30) Tercio@23: msgframe:SetBackdrop(ControlBackdrop) Tercio@23: msgframe:SetBackdropColor(0,0,0) Tercio@23: msgframe:SetFrameStrata("FULLSCREEN_DIALOG") Tercio@23: msgframe:SetFrameLevel(1000) Tercio@23: msgframe:SetToplevel(true) Tercio@23: Tercio@23: local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal") Tercio@23: msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.") Tercio@23: msgframe.msg = msg Tercio@23: msg:SetPoint("TOPLEFT", 5, -5) Tercio@23: msgframe:SetScript("OnUpdate", keybindingMsgFixWidth) Tercio@23: msgframe:SetPoint("BOTTOM", button, "TOP") Tercio@23: msgframe:Hide() Tercio@23: Tercio@23: local widget = { Tercio@23: button = button, Tercio@23: label = label, Tercio@23: msgframe = msgframe, Tercio@23: frame = frame, Tercio@23: alignoffset = 30, Tercio@23: type = Type Tercio@23: } Tercio@23: for method, func in pairs(methods) do Tercio@23: widget[method] = func Tercio@23: end Tercio@23: button.obj = widget Tercio@23: Tercio@23: return AceGUI:RegisterAsWidget(widget) Tercio@23: end Tercio@23: Tercio@23: AceGUI:RegisterWidgetType(Type, Constructor, Version)