Mercurial > wow > reaction
view lib/LibKeyBound-1.0/LibKeyBound-1.0.lua @ 88:fc83b3f5b322
Added keybindings using LibKeyBound-1.0, with modifications for Override bindings instead of standard bindings.
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Sun, 31 Aug 2008 06:02:18 +0000 |
parents | |
children |
line wrap: on
line source
--[[ Name: LibKeyBound-1.0 Revision: $Rev: 76300 $ Author(s): Gello, Maul, Toadkiller, Tuller Website: http://www.wowace.com/wiki/LibKeyBound-1.0 Documentation: http://www.wowace.com/wiki/LibKeyBound-1.0 SVN: http://svn.wowace.com/wowace/trunk/LibKeyBound-1.0 Description: An intuitive keybindings system: mouseover frame, click keys or buttons. Dependencies: CallbackHandler-1.0 --]] local MAJOR = "LibKeyBound-1.0" local MINOR = "$Revision: 76300 $" --[[ LibKeyBound-1.0 ClickBinder by Gello and TrinityBinder by Maul -> keyBound by Tuller -> LibKeyBound library by Toadkiller Functions needed to implement button:GetHotkey() - returns the current hotkey assigned to the given button Functions to implement if using a custom keybindings system: button:SetKey(key) - binds the given key to the given button button:FreeKey(key) - unbinds the given key from all other buttons button:ClearBindings() - removes all keys bound to the given button button:GetBindings() - returns a string listing all bindings of the given button button:GetActionName() - what we're binding to, used for printing --]] local LibKeyBound, oldminor = LibStub:NewLibrary(MAJOR, MINOR) if not LibKeyBound then return end -- no upgrade needed local _G = _G -- CallbackHandler LibKeyBound.events = LibKeyBound.events or _G.LibStub("CallbackHandler-1.0"):New(LibKeyBound) local L = LibKeyBoundLocale10 LibKeyBound.L = L -- ToDo delete global LibKeyBoundLocale10 at some point LibKeyBound.Binder = LibKeyBound.Binder or {} -- #NODOC function LibKeyBound:Initialize() do local f = CreateFrame("Frame", "KeyboundDialog", UIParent) f:SetFrameStrata("DIALOG") f:SetToplevel(true); f:EnableMouse(true) f:SetWidth(360); f:SetHeight(140) f:SetBackdrop{ bgFile="Interface\\DialogFrame\\UI-DialogBox-Background" , edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, insets = {left = 11, right = 12, top = 12, bottom = 11}, tileSize = 32, edgeSize = 32, } f:SetPoint("TOP", 0, -24) f:Hide() local tr = f:CreateTitleRegion() tr:SetAllPoints(f) f:SetClampedToScreen(true) local text = f:CreateFontString("ARTWORK") text:SetFontObject("GameFontHighlight") text:SetPoint("TOP", 0, -16) text:SetWidth(252); text:SetHeight(0) text:SetText(format(L.BindingsHelp, GetBindingText("ESCAPE", "KEY_"))) -- Per character bindings checkbox local perChar = CreateFrame("CheckButton", "KeyboundDialogCheck", f, "OptionsCheckButtonTemplate") getglobal(perChar:GetName() .. "Text"):SetText(CHARACTER_SPECIFIC_KEYBINDINGS) perChar:SetScript("OnShow", function(self) self:SetChecked(GetCurrentBindingSet() == 2) end) local current perChar:SetScript("OnClick", function(self) current = (perChar:GetChecked() and 2) or 1 LoadBindings(current) end) -- local added f:SetScript("OnShow", function(self) -- if (not added) then -- UISpecialFrames[#UISpecialFrames + 1] = self:GetName() -- added = true -- end -- PlaySound("igCharacterInfoOpen") end) f:SetScript("OnHide", function(self) -- PlaySound("igCharacterInfoClose") end) -- Okay bindings checkbox local okayBindings = CreateFrame("CheckButton", "KeyboundDialogOkay", f, "OptionsButtonTemplate") getglobal(okayBindings:GetName() .. "Text"):SetText(OKAY) okayBindings:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -12, 14) okayBindings:SetScript("OnClick", function(self) current = (perChar:GetChecked() and 2) or 1 if InCombatLockdown() then self:RegisterEvent("PLAYER_REGEN_ENABLED") else -- DEFAULT_CHAT_FRAME:AddMessage("okayBindings " .. tostring(current)) SaveBindings(current) LibKeyBound:Deactivate() end end) okayBindings:SetScript("OnHide", function(self) current = (perChar:GetChecked() and 2) or 1 if InCombatLockdown() then self:RegisterEvent("PLAYER_REGEN_ENABLED") else SaveBindings(current) end end) okayBindings:SetScript("OnEvent", function(self, event) -- DEFAULT_CHAT_FRAME:AddMessage("okayBindings delayed " .. tostring(current)) SaveBindings(current) self:UnregisterEvent(event) LibKeyBound:Deactivate() end) -- Cancel bindings checkbox local cancelBindings = CreateFrame("CheckButton", "KeyboundDialogCancel", f, "OptionsButtonTemplate") getglobal(cancelBindings:GetName() .. "Text"):SetText(CANCEL) cancelBindings:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 12, 14) cancelBindings:SetScript("OnClick", function(self) if InCombatLockdown() then self:RegisterEvent("PLAYER_REGEN_ENABLED") else -- DEFAULT_CHAT_FRAME:AddMessage("cancelBindings ") LoadBindings(GetCurrentBindingSet()) LibKeyBound:Deactivate() end end) cancelBindings:SetScript("OnEvent", function(self, event) -- DEFAULT_CHAT_FRAME:AddMessage("cancelBindings delayed ") LoadBindings(GetCurrentBindingSet()) self:UnregisterEvent(event) LibKeyBound:Deactivate() end) perChar:SetPoint("BOTTOMLEFT", cancelBindings, "TOPLEFT", 0, 4) self.dialog = f end SlashCmdList["LibKeyBoundSlashCOMMAND"] = function() self:Toggle() end SLASH_LibKeyBoundSlashCOMMAND1 = "/libkeybound" SLASH_LibKeyBoundSlashCOMMAND2 = "/kb" SLASH_LibKeyBoundSlashCOMMAND3 = "/lkb" LibKeyBound.initialized = true end -- Default color to indicate bindable frames in your mod. LibKeyBound.colorKeyBoundMode = LibKeyBound.colorKeyBoundMode or { 0, 1, 1, 0.5 } --[[ LibKeyBound:SetColorKeyBoundMode([r][, g][, b][, a]) --]] --[[ Arguments: number - red, default 0 number - green, default 0 number - blue, default 0 number - alpha, default 1 Example: if (MyMod.keyBoundMode) then overlayFrame:SetBackdropColor(LibKeyBound:GetColorKeyBoundMode()) end ... local r, g, b, a = LibKeyBound:GetColorKeyBoundMode() Notes: * Returns the color to use on your participating buttons during KeyBound Mode * Values are unpacked and ready to use as color arguments --]] function LibKeyBound:SetColorKeyBoundMode(r, g, b, a) r, g, b, a = r or 0, g or 0, b or 0, a or 1 LibKeyBound.colorKeyBoundMode[1] = r LibKeyBound.colorKeyBoundMode[2] = g LibKeyBound.colorKeyBoundMode[3] = b LibKeyBound.colorKeyBoundMode[4] = a LibKeyBound.events:Fire("LIBKEYBOUND_MODE_COLOR_CHANGED") end --[[ Returns: * number - red * number - green * number - blue * number - alpha Example: if (MyMod.keyBoundMode) then overlayFrame:SetBackdropColor(LibKeyBound:GetColorKeyBoundMode()) end ... local r, g, b, a = LibKeyBound:GetColorKeyBoundMode() Notes: * Returns the color to use on your participating buttons during KeyBound Mode * Values are unpacked and ready to use as color arguments --]] function LibKeyBound:GetColorKeyBoundMode() return unpack(LibKeyBound.colorKeyBoundMode) end function LibKeyBound:PLAYER_REGEN_ENABLED() if self.enabled then UIErrorsFrame:AddMessage(L.CombatBindingsEnabled, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME) self.dialog:Hide() end end function LibKeyBound:PLAYER_REGEN_DISABLED() if self.enabled then self:Set(nil) UIErrorsFrame:AddMessage(L.CombatBindingsDisabled, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME) self.dialog:Show() end end --[[ Notes: * Switches KeyBound Mode between on and off Example: local LibKeyBound = LibStub("LibKeyBound-1.0") LibKeyBound:Toggle() --]] function LibKeyBound:Toggle() if (LibKeyBound:IsShown()) then LibKeyBound:Deactivate() else LibKeyBound:Activate() end end --[[ Notes: * Switches KeyBound Mode to on Example: local LibKeyBound = LibStub("LibKeyBound-1.0") LibKeyBound:Activate() --]] function LibKeyBound:Activate() if not self:IsShown() then if InCombatLockdown() then UIErrorsFrame:AddMessage(L.CannotBindInCombat, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME) else self.enabled = true if not self.frame then self.frame = LibKeyBound.Binder:Create() end self:Set(nil) self.dialog:Show() self.events:Fire("LIBKEYBOUND_ENABLED") end end end --[[ Notes: * Switches KeyBound Mode to off Example: local LibKeyBound = LibStub("LibKeyBound-1.0") LibKeyBound:Deactivate() --]] function LibKeyBound:Deactivate() if self:IsShown() then self.enabled = nil self:Set(nil) self.dialog:Hide() self.events:Fire("LIBKEYBOUND_DISABLED") end end --[[ Returns: boolean - true if KeyBound Mode is currently on Example: local LibKeyBound = LibStub("LibKeyBound-1.0") local isKeyBoundMode = LibKeyBound:IsShown() if (isKeyBoundMode) then -- Do something else -- Do another thing end Notes: * Is KeyBound Mode currently on --]] function LibKeyBound:IsShown() return self.enabled end --[[ Arguments: table - the button frame Example: local button = this LibKeyBound:Set(button) Notes: * Sets up button for keybinding * Call this in your OnEnter script for the button * Current bindings are shown in the tooltip * Primary binding is shown in green in the button text --]] function LibKeyBound:Set(button) local bindFrame = self.frame if button and self:IsShown() and not InCombatLockdown() then bindFrame.button = button bindFrame:SetAllPoints(button) bindFrame.text:SetFontObject("GameFontNormalLarge") bindFrame.text:SetText(button:GetHotkey()) if bindFrame.text:GetStringWidth() > bindFrame:GetWidth() then bindFrame.text:SetFontObject("GameFontNormal") end bindFrame:Show() bindFrame:OnEnter() elseif bindFrame then bindFrame.button = nil bindFrame:ClearAllPoints() bindFrame:Hide() end end --[[ Arguments: string - the keyString to shorten Returns: string - the shortened displayString Example: local key1 = GetBindingKey(button:GetName()) local displayKey = LibKeyBound:ToShortKey(key1) return displayKey Notes: * Shortens the key text (returned from GetBindingKey etc.) * Result is suitable for display on a button * Can be used for your button:GetHotkey() return value --]] function LibKeyBound:ToShortKey(key) if key then key = key:upper() key = key:gsub(" ", "") key = key:gsub("ALT%-", L["Alt"]) key = key:gsub("CTRL%-", L["Ctrl"]) key = key:gsub("SHIFT%-", L["Shift"]) key = key:gsub("NUMPAD", L["NumPad"]) key = key:gsub("PLUS", "%+") key = key:gsub("MINUS", "%-") key = key:gsub("MULTIPLY", "%*") key = key:gsub("DIVIDE", "%/") key = key:gsub("BACKSPACE", L["Backspace"]) key = key:gsub("BUTTON3", L["Button3"]) key = key:gsub("BUTTON4", L["Button4"]) key = key:gsub("BUTTON5", L["Button5"]) key = key:gsub("CAPSLOCK", L["Capslock"]) key = key:gsub("CLEAR", L["Clear"]) key = key:gsub("DELETE", L["Delete"]) key = key:gsub("END", L["End"]) key = key:gsub("HOME", L["Home"]) key = key:gsub("INSERT", L["Insert"]) key = key:gsub("MOUSEWHEELDOWN", L["Mouse Wheel Down"]) key = key:gsub("MOUSEWHEELUP", L["Mouse Wheel Up"]) key = key:gsub("NUMLOCK", L["Num Lock"]) key = key:gsub("PAGEDOWN", L["Page Down"]) key = key:gsub("PAGEUP", L["Page Up"]) key = key:gsub("SCROLLLOCK", L["Scroll Lock"]) key = key:gsub("SPACEBAR", L["Spacebar"]) key = key:gsub("TAB", L["Tab"]) key = key:gsub("DOWNARROW", L["Down Arrow"]) key = key:gsub("LEFTARROW", L["Left Arrow"]) key = key:gsub("RIGHTARROW", L["Right Arrow"]) key = key:gsub("UPARROW", L["Up Arrow"]) return key end end --[[ Binder Widget ]]-- function LibKeyBound.Binder:Create() local binder = CreateFrame("Button") binder:RegisterForClicks("anyUp") binder:SetFrameStrata("DIALOG") binder:EnableKeyboard(true) binder:EnableMouseWheel(true) for k,v in pairs(self) do binder[k] = v end local bg = binder:CreateTexture() bg:SetTexture(0, 0, 0, 0.5) bg:SetAllPoints(binder) local text = binder:CreateFontString("OVERLAY") text:SetFontObject("GameFontNormalLarge") text:SetTextColor(0, 1, 0) text:SetAllPoints(binder) binder.text = text binder:SetScript("OnClick", self.OnKeyDown) binder:SetScript("OnKeyDown", self.OnKeyDown) binder:SetScript("OnMouseWheel", self.OnMouseWheel) binder:SetScript("OnEnter", self.OnEnter) binder:SetScript("OnLeave", self.OnLeave) binder:SetScript("OnHide", self.OnHide) binder:Hide() return binder end function LibKeyBound.Binder:OnHide() LibKeyBound:Set(nil) end function LibKeyBound.Binder:OnKeyDown(key) local button = self.button if not button then return end if (key == "UNKNOWN" or key == "LSHIFT" or key == "RSHIFT" or key == "LCTRL" or key == "RCTRL" or key == "LALT" or key == "RALT" or key == "LeftButton" or key == "RightButton") then return end local screenshotKey = GetBindingKey("SCREENSHOT") if screenshotKey and key == screenshotKey then Screenshot() return end local openChatKey = GetBindingKey("OPENCHAT") if openChatKey and key == openChatKey then ChatFrameEditBox:Show() return end if key == "MiddleButton" then key = "BUTTON3" elseif key == "Button4" then key = "BUTTON4" elseif key == "Button5" then key = "BUTTON5" end if key == "ESCAPE" then self:ClearBindings(button) LibKeyBound:Set(button) return end if IsShiftKeyDown() then key = "SHIFT-" .. key end if IsControlKeyDown() then key = "CTRL-" .. key end if IsAltKeyDown() then key = "ALT-" .. key end if MouseIsOver(button) then self:SetKey(button, key) LibKeyBound:Set(button) end end function LibKeyBound.Binder:OnMouseWheel(arg1) if arg1 > 0 then self:OnKeyDown("MOUSEWHEELUP") else self:OnKeyDown("MOUSEWHEELDOWN") end end function LibKeyBound.Binder:OnEnter() local button = self.button if button and not InCombatLockdown() then if self:GetRight() >= (GetScreenWidth() / 2) then GameTooltip:SetOwner(self, "ANCHOR_LEFT") else GameTooltip:SetOwner(self, "ANCHOR_RIGHT") end if button.GetActionName then GameTooltip:SetText(button:GetActionName(), 1, 1, 1) else GameTooltip:SetText(button:GetName(), 1, 1, 1) end local bindings = self:GetBindings(button) if bindings then GameTooltip:AddLine(bindings, 0, 1, 0) GameTooltip:AddLine(L.ClearTip) else GameTooltip:AddLine(L.NoKeysBoundTip, 0, 1, 0) end GameTooltip:Show() else GameTooltip:Hide() end end function LibKeyBound.Binder:OnLeave() LibKeyBound:Set(nil) GameTooltip:Hide() end --[[ Update Functions ]]-- function LibKeyBound.Binder:ToBinding(button) return format("CLICK %s:LeftButton", button:GetName()) end function LibKeyBound.Binder:FreeKey(button, key) local msg if button.FreeKey then local action = button:FreeKey(key) if button:FreeKey(key) then msg = format(L.UnboundKey, GetBindingText(key, "KEY_"), action) end else local action = GetBindingAction(key) if action and action ~= "" and action ~= self:ToBinding(button) then msg = format(L.UnboundKey, GetBindingText(key, "KEY_"), action) end end if msg then UIErrorsFrame:AddMessage(msg, 1, 0.82, 0, 1, UIERRORS_HOLD_TIME) end end function LibKeyBound.Binder:SetKey(button, key) if InCombatLockdown() then UIErrorsFrame:AddMessage(L.CannotBindInCombat, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME) else self:FreeKey(button, key) if button.SetKey then button:SetKey(key) else SetBindingClick(key, button:GetName(), "LeftButton") end local msg if button.GetActionName then msg = format(L.BoundKey, GetBindingText(key, "KEY_"), button:GetActionName()) else msg = format(L.BoundKey, GetBindingText(key, "KEY_"), button:GetName()) end UIErrorsFrame:AddMessage(msg, 1, 1, 1, 1, UIERRORS_HOLD_TIME) end end function LibKeyBound.Binder:ClearBindings(button) if InCombatLockdown() then UIErrorsFrame:AddMessage(L.CannotBindInCombat, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME) else if button.ClearBindings then button:ClearBindings() else local binding = self:ToBinding(button) while (GetBindingKey(binding)) do SetBinding(GetBindingKey(binding), nil) end end local msg if button.GetActionName then msg = format(L.ClearedBindings, button:GetActionName()) else msg = format(L.ClearedBindings, button:GetName()) end UIErrorsFrame:AddMessage(msg, 1, 1, 1, 1, UIERRORS_HOLD_TIME) end end function LibKeyBound.Binder:GetBindings(button) if button.GetBindings then return button:GetBindings() end local keys local binding = self:ToBinding(button) for i = 1, select("#", GetBindingKey(binding)) do local hotKey = select(i, GetBindingKey(binding)) if keys then keys = keys .. ", " .. GetBindingText(hotKey, "KEY_") else keys = GetBindingText(hotKey, "KEY_") end end return keys end LibKeyBound.EventButton = LibKeyBound.EventButton or CreateFrame("Frame") do local EventButton = LibKeyBound.EventButton EventButton:UnregisterAllEvents() EventButton:SetScript("OnEvent", function(self, event, addon) if (event == "PLAYER_REGEN_DISABLED") then LibKeyBound:PLAYER_REGEN_DISABLED() elseif (event == "PLAYER_REGEN_ENABLED") then LibKeyBound:PLAYER_REGEN_ENABLED() elseif (event == "PLAYER_LOGIN" and not LibKeyBound.initialized) then LibKeyBound:Initialize() EventButton:UnregisterEvent("PLAYER_LOGIN") end end) if IsLoggedIn() and not LibKeyBound.initialized then LibKeyBound:Initialize() elseif not LibKeyBound.initialized then EventButton:RegisterEvent("PLAYER_LOGIN") end EventButton:RegisterEvent("PLAYER_REGEN_ENABLED") EventButton:RegisterEvent("PLAYER_REGEN_DISABLED") end