From 464fcbb1df1494b976b96c3d1e02906ebafc607f Mon Sep 17 00:00:00 2001 From: omicron Date: Sat, 1 Apr 2023 05:19:03 +0200 Subject: [PATCH] Allow mouse keybinds to be configured --- src/frames.lua | 28 +++++++++++ src/types/unitframe.lua | 104 +++++++++++++++++++++++++++++----------- 2 files changed, 105 insertions(+), 27 deletions(-) diff --git a/src/frames.lua b/src/frames.lua index 0220ac3..d3cc38c 100644 --- a/src/frames.lua +++ b/src/frames.lua @@ -31,6 +31,33 @@ local function RangeConfig() end end +local function MouseConfig() + local _, class = UnitClass("player") + if class == "SHAMAN" then + return { + -- No modifier + {button="mouse1", mods={}, kind="target"}, + {button="mouse2", mods={}, kind="macro", data="/use [@UNIT,dead,help]Ancestral Vision; [@UNIT,help]Chain Heal"}, + {button="mouse3", mods={}, kind="macro", data="/use [@UNIT,dead,help]Ancestral Spirit; [@UNIT,help]Purify Spirit"}, + {button="wheel-up", mods={}, kind="macro", data="/use [@UNIT,help]Healing Surge"}, + {button="wheel-down", mods={}, kind="macro", data="/use [@UNIT,help]Riptide"}, + + -- alt + {button="wheel-up", mods={alt=true}, kind="spell", data="Healing Wave"}, + {button="wheel-down", mods={alt=true}, kind="spell", data="Earth Shield"}, + + -- Shift + {button="mouse2", mods={shift=true}, kind="togglemenu"}, + } + else + return { + -- Super basic defaults + {button="mouse1", mods={}, kind="target"}, + {button="mouse2", mods={shift=true}, kind="togglemenu"}, + } + end +end + local types = omif.GetModule("types") local UnitFrame = types.UnitFrame local UnitGroup = types.UnitGroup @@ -100,6 +127,7 @@ function CreateFrames() height = 45, }, range = RangeConfig(), + mouse = MouseConfig(), hideInRaid = true, } diff --git a/src/types/unitframe.lua b/src/types/unitframe.lua index 36ba998..b689ac0 100644 --- a/src/types/unitframe.lua +++ b/src/types/unitframe.lua @@ -58,6 +58,8 @@ function UnitFrame:Init(unit, config) local secure = self:CreateSecureFrame(width, height) secure:Hide() + self:SetMouseBinds(config.mouse) + self.hp = StatusBar:new(self, width, height, 0, true) self.power = StatusBar:new(self, width, 6, 2, false) self.power:Hide() @@ -185,21 +187,51 @@ function UnitFrame:SetMacroAction(button, macro) secure:SetAttribute(attributeName, macro:gsub("@UNIT", "@" .. self.unit)) end -function UnitFrame:PrepareWheelBinds() +local function ModifiersToPrefix(mods) + if not mods then + return "" + end + + local result = {} + if mods.ctrl then + table.insert(result, "CTRL-") + end + if mods.shift then + table.insert(result, "SHIFT-") + end + if mods.alt then + table.insert(result, "ALT-") + end + return table.concat(result, "") +end + +function UnitFrame:PrepareWheelBinds(bindings) -- By default you can't use the SecureUnitButtonTemplate to handle scroll -- wheel "clicks". We solve this by using SecureHandler*Template to bind -- scroll wheel to the current unit frame button when the mouse enters and -- to unbind it when the mouse leaves. When the keybind is triggered the -- button will receive a click with a custom button name - + + -- Build a table with all lines of the scroll wheel + modifier combinations + -- we want to bind, then concat it with newlines into a full script + local unit = self.unit + local bindScript = { + [[self:ClearBindings()]], + } + for _, bind in ipairs(bindings) do + if bind.button == "wheel-up" or bind.button == "wheel-down" then + local prefix = ModifiersToPrefix(bind.mods) + local button = bind.button == "wheel-up" and "MOUSEWHEELUP" or "MOUSEWHEELDOWN" + table.insert(bindScript, + string.format([[self:SetBindingClick(false, "%s%s", "OmicronSecureFrame%s", "%s%s")]], + prefix, button, unit, prefix, bind.button + ) + ) + end + end + local secure = self.secureFrame - local bindScript = ([[ - self:ClearBindings() - self:SetBindingClick(false, "MOUSEWHEELUP", "BUTTONNAME", "wheel-up") - self:SetBindingClick(false, "MOUSEWHEELDOWN", "BUTTONNAME", "wheel-down") - self:SetBindingClick(false, "ALT-MOUSEWHEELUP", "BUTTONNAME", "alt-wheel-up") - self:SetBindingClick(false, "ALT-MOUSEWHEELDOWN", "BUTTONNAME", "alt-wheel-down") - ]]):gsub("BUTTONNAME", "OmicronSecureFrame" .. self.unit) + local bindScript = table.concat(bindScript, "\n") local removeBindScript = [[ self:ClearBindings() @@ -210,6 +242,42 @@ function UnitFrame:PrepareWheelBinds() secure:SetAttribute("_onhide", removeBindScript) end +function UnitFrame:SetMouseBinds(binds) + local secure = self.secureFrame + local unit = self.unit + + secure:RegisterForClicks("AnyDown") + self:PrepareWheelBinds(binds) + + for _, bind in ipairs(binds) do + local prefix = ModifiersToPrefix(bind.mods) + local button + -- This is kind of a mess but there are two options for attribute names + -- in the normal click case (mouse1, mouse2, etc) we have to put the + -- modifiers before type so it would become SHIFT-type1 for mouse1 with + -- shift + -- + -- Since scroll wheel is not supported here and we manually create + -- click events with global scroll wheel binds while we are moused over + -- the unit frame they receive the modifiers after the type so it would become + -- type-SHIFT-wheel-up for wheel-up with shift + if bind.button:find("mouse", 1, true) == 1 then + button = prefix .. bind.button:gsub("^mouse", "type") + elseif bind.button:find("wheel", 1, true) == 1 then + button = "type-" .. prefix .. bind.button + else + error("Keybinds were invalid") + end + if bind.kind == "macro" then + self:SetMacroAction(button, bind.data) + elseif bind.kind == "spell" then + self:SetSpellAction(button, bind.data) + else + secure:SetAttribute(button, bind.kind) + end + end +end + function UnitFrame:CreateSecureFrame(width, height) local name = "OmicronSecureFrame" .. self.unit local templates = table.concat({ @@ -222,26 +290,8 @@ function UnitFrame:CreateSecureFrame(width, height) secure:SetFrameStrata("MEDIUM") secure:SetFrameLevel(0) secure:SetAttribute("unit", self.unit) - secure:SetSize(width, height) - secure:RegisterForClicks("AnyDown") - self:PrepareWheelBinds() - - -- No modifiers - secure:SetAttribute("type1", "target") - self:SetMacroAction("type2", "/use [@UNIT,dead,help]Ancestral Vision; [@UNIT]Chain Heal") - self:SetMacroAction("type3", "/use [@UNIT,dead,help]Ancestral Spirit; [@UNIT]Purify Spirit") - self:SetMacroAction("type-wheel-up", "/use [@UNIT]Healing Surge") - self:SetMacroAction("type-wheel-down", "/use [@UNIT,help]Riptide") - - -- alt - self:SetSpellAction("type-alt-wheel-up", "Healing Wave") - self:SetSpellAction("type-alt-wheel-down", "Earth Shield") - - -- Shift - secure:SetAttribute("SHIFT-type2", "togglemenu") - return secure end