Add modules/hoverbind.lua
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
pfUI:RegisterModule("hoverbind", "vanilla:tbc", function ()
|
||||
local keymap = {
|
||||
-- buttons to binding association
|
||||
["pfActionBarMainButton"] = "ACTIONBUTTON",
|
||||
["pfActionBarTopButton"] = "MULTIACTIONBAR1BUTTON",
|
||||
["pfActionBarLeftButton"] = "MULTIACTIONBAR2BUTTON",
|
||||
["pfActionBarRightButton"] = "MULTIACTIONBAR3BUTTON",
|
||||
["pfActionBarVerticalButton"] = "MULTIACTIONBAR4BUTTON",
|
||||
["pfActionBarStancesButton"] = "SHAPESHIFTBUTTON",
|
||||
["pfActionBarPetButton"] = "BONUSACTIONBUTTON",
|
||||
|
||||
-- special buttons
|
||||
["pfActionBarPagingButton"] = "PFPAGING",
|
||||
["pfActionBarStanceBar1Button"] = "PFSTANCEONE",
|
||||
["pfActionBarStanceBar2Button"] = "PFSTANCETWO",
|
||||
["pfActionBarStanceBar3Button"] = "PFSTANCETHREE",
|
||||
["pfActionBarStanceBar4Button"] = "PFSTANCEFOUR",
|
||||
}
|
||||
|
||||
local mousebuttonmap = {
|
||||
["LeftButton"] = "BUTTON1",
|
||||
["RightButton"] = "BUTTON2",
|
||||
["MiddleButton"] = "BUTTON3",
|
||||
["Button4"] = "BUTTON4",
|
||||
["Button5"] = "BUTTON5",
|
||||
}
|
||||
|
||||
local mousewheelmap = {
|
||||
[1] = "MOUSEWHEELUP",
|
||||
[-1] = "MOUSEWHEELDOWN",
|
||||
}
|
||||
|
||||
local modifiers = {
|
||||
["ALT"] = "ALT-",
|
||||
["CTRL"] = "CTRL-",
|
||||
["SHIFT"] = "SHIFT-"
|
||||
}
|
||||
|
||||
-- We don't allow binding these keys without any modifiers
|
||||
local blockedKeys = {
|
||||
"LeftButton",
|
||||
"RightButton",
|
||||
}
|
||||
|
||||
pfUI.hoverbind = CreateFrame("Frame","pfKeyBindingFrame",UIParent)
|
||||
pfUI.hoverbind:Hide()
|
||||
pfUI.hoverbind:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
pfUI.hoverbind:EnableMouse(true)
|
||||
pfUI.hoverbind.edit = CreateFrame("Button", "pfKeyBindingFrameEdit", pfUI.hoverbind)
|
||||
pfUI.hoverbind.edit:SetFrameStrata("BACKGROUND")
|
||||
pfUI.hoverbind.edit:SetAllPoints(UIParent)
|
||||
pfUI.hoverbind.edit.tex = pfUI.hoverbind.edit:CreateTexture("pfKeyBindShade", "BACKGROUND")
|
||||
pfUI.hoverbind.edit.tex:SetAllPoints(pfUI.hoverbind.edit)
|
||||
pfUI.hoverbind.edit.tex:SetTexture(0,0,0,.5)
|
||||
pfUI.hoverbind.edit:SetScript("OnClick", function()
|
||||
pfUI.hoverbind:Hide()
|
||||
end)
|
||||
|
||||
pfUI.hoverbind:SetScript("OnMouseUp",function(...)
|
||||
pfUI.hoverbind:Hide()
|
||||
end)
|
||||
|
||||
pfUI.hoverbind:SetScript("OnShow", function()
|
||||
if pfUI.bars then
|
||||
pfUI.bars:UpdateGrid(1)
|
||||
pfUI.bars:UpdateGrid(1, "PET")
|
||||
end
|
||||
|
||||
-- Initialize hoverbind frames on first show. We can't do this before because the action
|
||||
-- bars might not exist yet when this module is loaded.
|
||||
if not pfUI.hoverbind.frames then
|
||||
pfUI.hoverbind.frames = pfUI.hoverbind:CreateHoverbindFrames()
|
||||
end
|
||||
|
||||
pfUI.gui:Hide()
|
||||
pfUI.hoverbind.edit:Show()
|
||||
pfUI.hoverbind:ShowHoverbindFrames()
|
||||
|
||||
local txt = T["|cff33ffccKeybind Mode|r\nThis mode allows you to bind keyboard shortcuts to your actionbars.\nBy hovering a button with your cursor and pressing a key, the key will be assigned to that button.\nHit Escape on a button to remove bindings.\n\nPress Escape or click on an empty area to leave the keybind mode."]
|
||||
CreateInfoBox(txt, 30, pfUI.hoverbind.edit)
|
||||
end)
|
||||
|
||||
pfUI.hoverbind:SetScript("OnHide",function()
|
||||
if pfUI.bars then
|
||||
pfUI.bars:UpdateGrid(0)
|
||||
pfUI.bars:UpdateGrid(0, "PET")
|
||||
end
|
||||
pfUI.hoverbind:HideHoverbindFrames()
|
||||
pfUI.hoverbind.edit:Hide()
|
||||
pfUI.gui:Show()
|
||||
end)
|
||||
|
||||
function pfUI.hoverbind:GetBinding(button_name)
|
||||
local found,_,buttontype,buttonindex = string.find(button_name,"^(.-)(%d+)$")
|
||||
if found then
|
||||
if keymap[buttontype] then
|
||||
return string.format("%s%d",keymap[buttontype],buttonindex)
|
||||
elseif buttontype == "ActionButton" then
|
||||
return string.format("ACTIONBUTTON%d",buttonindex)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function pfUI.hoverbind:GetPrefix()
|
||||
return string.format("%s%s%s",
|
||||
(IsAltKeyDown() and modifiers.ALT or ""),
|
||||
(IsControlKeyDown() and modifiers.CTRL or ""),
|
||||
(IsShiftKeyDown() and modifiers.SHIFT or ""))
|
||||
end
|
||||
|
||||
-- Loops over all actionbar buttons and creates an invisible overlapping hoverbind frame
|
||||
-- for each of them. These hoverbind frames receive all key, mouse and mouse wheel events
|
||||
-- so we can bind the respective key, mouse button or mouse wheel direction to the underlying
|
||||
-- actionbar button. They should only be shown when hoverbind is active, otherwise the
|
||||
-- underlying actionbar buttons can't be clicked anymore.
|
||||
function pfUI.hoverbind:CreateHoverbindFrames()
|
||||
if not pfUI.bars then return end
|
||||
|
||||
local frames = {}
|
||||
|
||||
for i=1,12 do
|
||||
for j=1,12 do
|
||||
local button = pfUI.bars[i][j]
|
||||
if button then
|
||||
local frame = CreateFrame("Frame", button:GetName() .. "HoverbindFrame", button)
|
||||
frame:SetAllPoints(button)
|
||||
frame:EnableKeyboard(true)
|
||||
frame:EnableMouse(true)
|
||||
frame:EnableMouseWheel(true)
|
||||
frame:Hide()
|
||||
|
||||
-- Store the actionbar button on the overlaying hoverbind frame so we can reference
|
||||
-- them in the hoverbind handler to create the key/mouse binding. We need this
|
||||
-- because the hoverbind frames "steal" the mouse focus from the actual buttons.
|
||||
frame.button = button
|
||||
|
||||
local function GetHoverbindHandler(map)
|
||||
return function()
|
||||
if modifiers[arg1] then return end -- ignore single modifier keyup
|
||||
|
||||
local prefix = pfUI.hoverbind:GetPrefix()
|
||||
|
||||
-- Don't allow binding certain buttons without modifiers
|
||||
if not prefix or prefix == "" then
|
||||
for _, blockedKey in ipairs(blockedKeys) do
|
||||
if arg1 == blockedKey then return end
|
||||
end
|
||||
end
|
||||
|
||||
local frame = GetMouseFocus()
|
||||
local hovername = (frame and frame.button and frame.button.GetName) and frame.button:GetName() or ""
|
||||
local binding = pfUI.hoverbind:GetBinding(hovername)
|
||||
if arg1 == "ESCAPE" and not binding then pfUI.hoverbind:Hide() return end
|
||||
if binding then
|
||||
if arg1 == "ESCAPE" then
|
||||
-- Remove existing binding
|
||||
local key = (GetBindingKey(binding))
|
||||
if (key) then
|
||||
SetBinding(key)
|
||||
SaveBindings(GetCurrentBindingSet())
|
||||
end
|
||||
else
|
||||
-- Create new binding
|
||||
local key = map and map[arg1] or arg1
|
||||
if (SetBinding(prefix..key, binding)) then
|
||||
SaveBindings(GetCurrentBindingSet())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
frame:SetScript("OnKeyUp", GetHoverbindHandler())
|
||||
frame:SetScript("OnMouseUp", GetHoverbindHandler(mousebuttonmap))
|
||||
frame:SetScript("OnMouseWheel", GetHoverbindHandler(mousewheelmap))
|
||||
|
||||
-- Explicitly call the corresponding button's onEnter/onLeave handlers to show/hide
|
||||
-- its highlight and tooltip. This is necessary because the actual buttons don't
|
||||
-- receive any mouse events in hoverbind mode since those are swallowed by the
|
||||
-- overlapping hoverbind frames.
|
||||
frame:SetScript("OnEnter", function()
|
||||
pfUI.bars.ButtonEnter(button)
|
||||
end)
|
||||
frame:SetScript("OnLeave", function()
|
||||
pfUI.bars.ButtonLeave(button)
|
||||
end)
|
||||
|
||||
table.insert(frames, frame)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return frames
|
||||
end
|
||||
|
||||
function pfUI.hoverbind:ShowHoverbindFrames()
|
||||
if not pfUI.hoverbind.frames then return end
|
||||
for _, frame in ipairs(pfUI.hoverbind.frames) do
|
||||
frame:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function pfUI.hoverbind:HideHoverbindFrames()
|
||||
if not pfUI.hoverbind.frames then return end
|
||||
for _, frame in ipairs(pfUI.hoverbind.frames) do
|
||||
frame:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
pfUI.hoverbind:SetScript("OnEvent",function()
|
||||
-- disable hoverbind so player gets back control of their keyboard to fight
|
||||
pfUI.hoverbind:Hide()
|
||||
end)
|
||||
end)
|
||||
Reference in New Issue
Block a user