Mercurial > wow > reaction
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/LibKeyBound-1.0/LibKeyBound-1.0.lua Sun Aug 31 06:02:18 2008 +0000 @@ -0,0 +1,659 @@ +--[[ +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