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