You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1667 lines
63 KiB

local _, Cell = ...
local L = Cell.L
local F = Cell.funcs
local P = Cell.pixelPerfectFuncs
local clickCastingsTab = Cell:CreateFrame("CellOptionsFrame_ClickCastingsTab", Cell.frames.optionsFrame, nil, nil, true)
Cell.frames.clickCastingsTab = clickCastingsTab
clickCastingsTab:SetAllPoints(Cell.frames.optionsFrame)
clickCastingsTab:Hide()
local listPane
local bindingsFrame
local listButtons = {}
local clickCastingTable
local loaded
local LoadProfile
local alwaysTargeting, smartResurrection
-------------------------------------------------
-- changes
-------------------------------------------------
local saveBtn, cancelBtn
local deleted, changed = {}, {}
local function CheckChanges()
if F:Getn(deleted) == 0 and F:Getn(changed) == 0 then
saveBtn:SetEnabled(false)
cancelBtn:SetEnabled(false)
for _, b in pairs(listButtons) do
b.unmovable = nil
end
else
saveBtn:SetEnabled(true)
cancelBtn:SetEnabled(true)
for _, b in pairs(listButtons) do
b.unmovable = true
end
end
end
-------------------------------------------------
-- db
-------------------------------------------------
-- https://wow.gamepedia.com/SecureActionButtonTemplate
-- {"shift-type1", "macro", "shift-macrotext1", "/cast [@mouseover] 回春术"}
local slotNames = {
[1] = _G.INVTYPE_HEAD,
[2] = _G.INVTYPE_NECK,
[3] = _G.INVTYPE_SHOULDER,
[4] = _G.INVTYPE_BODY,
[5] = _G.INVTYPE_CHEST,
[6] = _G.INVTYPE_WAIST,
[7] = _G.INVTYPE_LEGS,
[8] = _G.INVTYPE_FEET,
[9] = _G.INVTYPE_WRIST,
[10] = _G.INVTYPE_HAND,
[11] = _G.INVTYPE_FINGER .. " 1",
[12] = _G.INVTYPE_FINGER .. " 2",
[13] = _G.INVTYPE_TRINKET .. " 1",
[14] = _G.INVTYPE_TRINKET .. " 2",
[15] = _G.INVTYPE_CLOAK,
[16] = _G.INVTYPE_WEAPONMAINHAND,
[17] = _G.INVTYPE_WEAPONOFFHAND,
}
-- local modifiers = {"", "shift-", "ctrl-", "alt-", "ctrl-shift-", "alt-shift-", "alt-ctrl-", "alt-ctrl-shift-"}
-- local modifiersDisplay = {"", "Shift|cff777777+|r", "Ctrl|cff777777+|r", "Alt|cff777777+|r", "Ctrl|cff777777+|rShift|cff777777+|r", "Alt|cff777777+|rShift|cff777777+|r", "Alt|cff777777+|rCtrl|cff777777+|r", "Alt|cff777777+|rCtrl|cff777777+|rShift|cff777777+|r"}
-- local keys = {"Left", "Right", "Middle", "Button4", "Button5", "ScrollUp", "ScrollDown"}
local mouseKeyIDs = {
["Left"] = 1,
["Right"] = 2,
["Middle"] = 3,
["Button4"] = 4,
["Button5"] = 5,
-- ["ScrollUp"] = 6,
-- ["ScrollDown"]= 14,
}
local function GetBindingDisplay(modifier, key)
modifier = modifier:gsub("%-", "|cff777777+|r")
modifier = modifier:gsub("alt", "Alt")
modifier = modifier:gsub("ctrl", "Ctrl")
modifier = modifier:gsub("shift", "Shift")
modifier = modifier:gsub("meta", "Command")
if strfind(key, "^NUM") then
key = _G["KEY_"..key]
elseif strlen(key) ~= 1 then
key = L[key]
end
return modifier..key
end
-- shift-Left -> shift-type1
local function GetAttributeKey(modifier, bindKey)
if mouseKeyIDs[bindKey] then -- normal mouse button
return modifier.."type"..mouseKeyIDs[bindKey]
elseif bindKey == "ScrollUp" or bindKey == "ScrollDown" then -- mouse wheel
return modifier.."type-"..strupper(bindKey)
else -- keyboard
modifier = string.gsub(modifier, "alt%-", "alt")
modifier = string.gsub(modifier, "ctrl%-", "ctrl")
modifier = string.gsub(modifier, "shift%-", "shift")
return "type-"..modifier..bindKey
end
end
local function EncodeDB(modifier, bindKey, bindType, bindAction)
local attrType, attrAction
if bindType == "spell" then
attrType = "spell"
attrAction = bindAction
elseif bindType == "macro" then
attrType = "macro"
attrAction = bindAction
elseif bindType == "custom" then
attrType = "macrotext"
attrAction = bindAction
elseif bindType == "item" then
attrType = "item"
attrAction = bindAction
else -- general
attrType = bindAction
-- attrAction = nil
end
if bindKey == "notBound" then
return {"notBound", attrType, attrAction}
else
return {GetAttributeKey(modifier, bindKey), attrType, attrAction}
end
end
local function DecodeKeyboard(fullKey)
fullKey = string.gsub(fullKey, "alt", "alt-")
fullKey = string.gsub(fullKey, "ctrl", "ctrl-")
fullKey = string.gsub(fullKey, "shift", "shift-")
local modifier, key = strmatch(fullKey, "^(.*-)(.+)$")
if not modifier then -- no modifier
modifier = ""
key = fullKey
end
return modifier, key
end
local function DecodeDB(t)
local modifier, bindKey, bindType, bindAction
if t[1] ~= "notBound" then
local dash, key
modifier, dash, key = strmatch(t[1], "^(.*)type(-*)(.+)$")
if dash == "-" then
if key == "SCROLLUP" then
bindKey = "ScrollUp"
elseif key == "SCROLLDOWN" then
bindKey = "ScrollDown"
else
modifier, bindKey = DecodeKeyboard(key)
end
else -- normal mouse button
bindKey = F:GetIndex(mouseKeyIDs, tonumber(key))
end
else
modifier, bindKey = "", "notBound"
end
if not t[3] then
bindType = "general"
bindAction = t[2]
else
bindType = t[2]
bindAction = t[3]
end
return modifier, bindKey, bindType, bindAction
end
-------------------------------------------------
-- mouse wheel & keyboard
-------------------------------------------------
local wrapFrame = CreateFrame("Frame", "CellWrapFrame", nil, "SecureHandlerStateTemplate")
wrapFrame:SetAttribute("_onstate-mouseoverstate", [[
-- print("mouseoverstate", newstate)
if newstate == "false" and mouseoverbutton then
if not mouseoverbutton:IsUnderMouse() then
mouseoverbutton:ClearBindings()
mouseoverbutton = nil
end
end
]])
--! NOTE: not available for unit far away (different map)
RegisterStateDriver(wrapFrame, "mouseoverstate", "[@mouseover, exists] true; false")
--! update togglemenu_nocombat
wrapFrame:SetAttribute("_onstate-combatstate", [[
-- print("combatstate", newstate)
if mouseoverbutton then
local menuKey = mouseoverbutton:GetAttribute("menu")
if menuKey then
if newstate == "true" then
mouseoverbutton:SetAttribute(menuKey, nil)
else
mouseoverbutton:SetAttribute(menuKey, "togglemenu")
end
end
end
]])
RegisterStateDriver(wrapFrame, "combatstate", "[combat] true; false")
local SetBindingClicks
if Cell.isRetail then
SetBindingClicks = function (b)
b:SetAttribute("_onenter", [[
-- print("_onenter")
self:ClearBindings()
self:Run(self:GetAttribute("snippet"))
-- self:SetBindingClick(true, "SHIFT-MOUSEWHEELUP", self, "shiftSCROLLUP")
-- FIXME: --! 如果游戏按键设置(比如“视角”“载具控制”)中绑定了滚轮,那么 self:SetBindingClick(true, "MOUSEWHEELUP", self, "SCROLLUP") 会失效
-- self:SetBindingClick(true, "MOUSEWHEELUP", self, "SCROLLUP")
-- self:SetBindingClick(true, "MOUSEWHEELDOWN", self, "SCROLLDOWN")
-- self:SetBindingClick(true, "SHIFT-B", self, "shiftB")
-- self:SetBindingClick(true, "SHIFT-C", self, "shiftC")
--! update click-casting unit
-- local attrs = self:GetAttribute("cell")
-- -- print(attrs)
-- if attrs then
-- for _, k in pairs(table.new(strsplit("|", attrs))) do
-- self:SetAttribute(k, string.gsub(self:GetAttribute(k), "@%w+", "@"..self:GetAttribute("unit")))
-- end
-- end
--! update togglemenu
local menuKey = self:GetAttribute("menu")
if menuKey then
if PlayerInCombat() then
self:SetAttribute(menuKey, nil)
else
self:SetAttribute(menuKey, "togglemenu")
end
end
]])
wrapFrame:WrapScript(b, "OnEnter", [[
-- print("OnEnter")
if mouseoverbutton then mouseoverbutton:ClearBindings() end --! NOTE: 鼠标放在过远单位上->被挡住->移走->移至可用单位再移出,会发现之前的不可用单位的按键绑定仍未取消
mouseoverbutton = self
]])
--! NOTE: if another frame shows in front of b, _onleave will NOT trigger. Use WrapScript to solve this issue.
b:SetAttribute("_onleave", [[
-- print("_onleave")
self:ClearBindings()
]])
-- wrapFrame:WrapScript(b, "OnLeave", [[
-- -- print("OnLeave")
-- mouseoverbutton = nil
-- ]])
b:SetAttribute("_onhide", [[
self:ClearBindings()
]])
end
else
SetBindingClicks = function(b)
b:SetAttribute("_onenter", [[
-- print("_onenter")
self:ClearBindings()
self:Run(self:GetAttribute("snippet"))
-- self:SetBindingClick(true, "SHIFT-MOUSEWHEELUP", self, "shiftSCROLLUP")
-- FIXME: --! 如果游戏按键设置(比如“视角”“载具控制”)中绑定了滚轮,那么 self:SetBindingClick(true, "MOUSEWHEELUP", self, "SCROLLUP") 会失效
-- self:SetBindingClick(true, "MOUSEWHEELUP", self, "SCROLLUP")
-- self:SetBindingClick(true, "MOUSEWHEELDOWN", self, "SCROLLDOWN")
-- self:SetBindingClick(true, "SHIFT-B", self, "shiftB")
-- self:SetBindingClick(true, "SHIFT-C", self, "shiftC")
--! vehicle
local unit = self:GetAttribute("unit")
local vehicle
if UnitHasVehicleUI(unit) then
if unit == "player" then
vehicle = "pet"
elseif strfind(unit, "^party%d+$") then
vehicle = string.gsub(unit, "party", "partypet")
elseif strfind(unit, "^raid%d+$") then
vehicle = string.gsub(unit, "raid", "raidpet")
end
end
--! update click-casting unit
local clickCastingUnit = vehicle or unit
local attrs = self:GetAttribute("cell")
-- print(attrs)
if attrs then
for _, k in pairs(table.new(strsplit("|", attrs))) do
self:SetAttribute(k, string.gsub(self:GetAttribute(k), "@%w+", "@"..clickCastingUnit))
-- print(self:GetAttribute(k))
end
end
--! update togglemenu
local menuKey = self:GetAttribute("menu")
if menuKey then
if PlayerInCombat() then
self:SetAttribute(menuKey, nil)
else
self:SetAttribute(menuKey, "togglemenu")
end
end
]])
wrapFrame:WrapScript(b, "OnEnter", [[
-- print("OnEnter")
if mouseoverbutton then
--! NOTE: 鼠标放在过远单位上->被挡住->移走->移至可用单位再移出,会发现之前的不可用单位的按键绑定仍未取消
mouseoverbutton:ClearBindings()
--! vehicle (previous button)
local oldUnit = mouseoverbutton:GetAttribute("oldUnit")
if oldUnit then
-- print("wrap restore unit")
mouseoverbutton:SetAttribute("unit", oldUnit)
mouseoverbutton:SetAttribute("oldUnit", nil)
end
end
mouseoverbutton = self
]])
--! NOTE: if another frame shows in front of b, _onleave will NOT trigger. Use WrapScript to solve this issue.
b:SetAttribute("_onleave", [[
-- print("_onleave")
self:ClearBindings()
]])
-- wrapFrame:WrapScript(b, "OnLeave", [[
-- -- print("OnLeave")
-- mouseoverbutton = nil
-- ]])
b:SetAttribute("_onhide", [[
self:ClearBindings()
--! vehicle
local oldUnit = self:GetAttribute("oldUnit")
if oldUnit then
-- print("restore unit")
self:SetAttribute("oldUnit", nil)
self:SetAttribute("unit", oldUnit)
end
]])
end
end
-- FIXME: hope BLZ fix this bug
local function GetMouseWheelBindKey(fullKey, noTypePrefix)
local modifier, key = strmatch(fullKey, "^(.*)type%-(.+)$")
modifier = string.gsub(modifier, "-", "")
if noTypePrefix then
return modifier..key
else
return "type-"..modifier..key -- type-ctrlSCROLLUP
end
end
local function GetBindingSnippet()
local bindingClicks = {}
for _, t in pairs(clickCastingTable) do
if t[1] ~= "notBound" then
local modifier, key = strmatch(t[1], "^(.*)type%-(.+)$")
if key then
-- if key == "SCROLLUP" then
-- bindingClicks[key] = [[self:SetBindingClick(true, "MOUSEWHEELUP", self, "SCROLLUP")]]
-- elseif key == "SCROLLDOWN" then
-- bindingClicks[key] = [[self:SetBindingClick(true, "MOUSEWHEELDOWN", self, "SCROLLDOWN")]]
if key == "SCROLLUP" or key == "SCROLLDOWN" then
key = GetMouseWheelBindKey(t[1], true) -- ctrlSCROLLUP
if not bindingClicks[key] then
local m, k = DecodeKeyboard(key)
k = k == "SCROLLUP" and "MOUSEWHEELUP" or "MOUSEWHEELDOWN"
bindingClicks[key] = [[self:SetBindingClick(true, "]]..strupper(m..k)..[[", self, "]]..key..[[")]]
end
elseif not bindingClicks[key] then
local m, k = DecodeKeyboard(key)
-- override keyboard to click
if k == [[\]] then
key = key:gsub([[\]], [[\\]])
bindingClicks[key] = [[self:SetBindingClick(true, "]]..strupper(m)..[[\\", self, "]]..key..[[")]]
elseif k == [["]] then
key = key:gsub([["]], [[\"]])
bindingClicks[key] = [[self:SetBindingClick(true, "]]..strupper(m)..[[\"", self, "]]..key..[[")]]
else
bindingClicks[key] = [[self:SetBindingClick(true, "]]..strupper(m..k)..[[", self, "]]..key..[[")]]
end
end
end
end
end
local snippet = ""
for _, bindingClick in pairs(bindingClicks) do
snippet = snippet..bindingClick.."\n"
end
return snippet
end
-------------------------------------------------
-- update click-castings
-------------------------------------------------
local previousClickCastings
local function ClearClickCastings(b)
if not previousClickCastings then return end
b:SetAttribute("cell", nil)
b:SetAttribute("menu", nil)
for _, t in pairs(previousClickCastings) do
local bindKey = t[1]
if strfind(bindKey, "SCROLL") then
bindKey = GetMouseWheelBindKey(t[1])
end
b:SetAttribute(bindKey, nil)
local attr = string.gsub(bindKey, "type", "spell")
b:SetAttribute(attr, nil)
attr = string.gsub(bindKey, "type", "macro")
b:SetAttribute(attr, nil)
attr = string.gsub(bindKey, "type", "macrotext")
b:SetAttribute(attr, nil)
attr = string.gsub(bindKey, "type", "item")
b:SetAttribute(attr, nil)
-- attr = string.gsub(bindKey, "type", "click")
-- b:SetAttribute(attr, nil)
-- if t[2] == "spell" then
-- local attr = string.gsub(bindKey, "type", "spell")
-- b:SetAttribute(attr, nil)
-- elseif t[2] == "macro" then
-- local attr = string.gsub(bindKey, "type", "macrotext")
-- b:SetAttribute(attr, nil)
-- end
end
end
--! store attribute keys, update them in _onenter
--! NOTE: 尝试用于修复距离过远目标的点击施法问题,但没有卵用,确认是游戏问题。
--! NOTE: 当目标为敌对时,@范围内/距离稍微超出一点儿的 > 自动自我施法的优先级 > @距离过远的
local function UpdatePlaceholder(b, attr)
if not b:GetAttribute("cell") then
b:SetAttribute("cell", attr)
else
b:SetAttribute("cell", b:GetAttribute("cell").."|"..attr)
end
end
local function ApplyClickCastings(b)
for i, t in pairs(clickCastingTable) do
local bindKey = t[1]
if strfind(bindKey, "SCROLL") then
bindKey = GetMouseWheelBindKey(t[1])
end
if t[2] == "togglemenu_nocombat" then
b:SetAttribute("menu", bindKey)
------------------------------------------------------------------
--* 已修复:实际上载具(宠物按钮)无法选中的原因是没有 SetAttribute("toggleForVehicle", false)
-- elseif Cell.isCata and t[2] == "target" then
-- b:SetAttribute(bindKey, "macro")
-- local attr = string.gsub(bindKey, "type", "macrotext")
-- b:SetAttribute(attr, "/tar [@cell]")
-- UpdatePlaceholder(b, attr)
------------------------------------------------------------------
else
b:SetAttribute(bindKey, t[2])
end
if t[2] == "spell" then
local spellName = F:GetSpellInfo(t[3]) or ""
local condition = ""
if not F:IsSoulstone(spellName) then
condition = F:IsResurrectionForDead(spellName) and ",dead" or ",nodead"
end
local unit = Cell.isRetail and "@mouseover" or "@cell"
-- "sMaRt" resurrection
local sMaRt = ""
if smartResurrection ~= "disabled" and not (F:IsResurrectionForDead(spellName) or F:IsSoulstone(spellName)) then
if strfind(smartResurrection, "^normal") then
local normalResurrection = F:GetNormalResurrection(Cell.vars.playerClass)
if normalResurrection then
if Cell.isRetail then -- mass resurrections
for cond, spell in pairs(normalResurrection) do
sMaRt = sMaRt .. ";["..unit..",dead,nocombat,"..cond.."] "..spell
end
else
sMaRt = sMaRt .. ";["..unit..",dead,nocombat] "..normalResurrection
end
end
end
if strfind(smartResurrection, "combat$") then
if F:GetCombatResurrection(Cell.vars.playerClass) then
sMaRt = sMaRt .. ";["..unit..",dead,combat] "..F:GetCombatResurrection(Cell.vars.playerClass)
end
end
end
--! NOTE: cancels the "blue glowing hand" cursor (cancel the target selection)
local fix = t[3] == 370665 and "" or "\n/stopspelltarget"
if (alwaysTargeting == "left" and bindKey == "type1") or alwaysTargeting == "any" then
b:SetAttribute(bindKey, "macro")
local attr = string.gsub(bindKey, "type", "macrotext")
b:SetAttribute(attr, "/tar ["..unit.."]\n/cast ["..unit..condition.."] "..spellName..sMaRt..fix)
if not Cell.isRetail then UpdatePlaceholder(b, attr) end
else
-- NOTE: "spell" is not ideal, 在无效/过远的目标上会处于“等待选中目标”的状态,即鼠标指针有一圈灰/蓝色材质
-- local attr = string.gsub(bindKey, "type", "spell")
-- b:SetAttribute(attr, spellName)
b:SetAttribute(bindKey, "macro")
local attr = string.gsub(bindKey, "type", "macrotext")
if F:IsSoulstone(spellName) then
b:SetAttribute(attr, "/tar ["..unit.."]\n/cast ["..unit.."] "..spellName.."\n/targetlasttarget")
else
b:SetAttribute(attr, "/cast ["..unit..condition.."] "..spellName..sMaRt..fix)
end
if not Cell.isRetail then UpdatePlaceholder(b, attr) end
end
elseif t[2] == "macro" then
local attr = string.gsub(bindKey, "type", "macro")
b:SetAttribute(attr, GetMacroIndexByName(t[3]))
elseif t[2] == "custom" then
b:SetAttribute(bindKey, "macro")
local attr = string.gsub(bindKey, "type", "macrotext")
b:SetAttribute(attr, t[3])
else
local attr = string.gsub(bindKey, "type", t[2])
b:SetAttribute(attr, t[3])
end
end
end
local function UpdateClickCastings(noReload, onlyqueued)
F:Debug("|cff77ff77UpdateClickCastings:|r useCommon:", Cell.vars.clickCastings["useCommon"])
clickCastingTable = Cell.vars.clickCastings["useCommon"] and Cell.vars.clickCastings["common"] or Cell.vars.clickCastings[Cell.vars.playerSpecID]
-- FIXME: remove this determine statement
if Cell.vars.clickCastings["alwaysTargeting"] then
alwaysTargeting = Cell.vars.clickCastings["alwaysTargeting"][Cell.vars.clickCastings["useCommon"] and "common" or Cell.vars.playerSpecID]
else
alwaysTargeting = "disabled"
end
smartResurrection = Cell.vars.clickCastings["smartResurrection"]
if not noReload then
if clickCastingsTab:IsVisible() then
LoadProfile(Cell.vars.clickCastings["useCommon"])
else
loaded = false
end
end
local snippet = GetBindingSnippet()
F:Debug(snippet)
-- REVIEW:
-- local clickFrames = Cell.clickCastFrames
-- if onlyqueued then
-- clickFrames = Cell.clickCastFrameQueue
-- end
-- for b, val in pairs(clickFrames) do
-- Cell.clickCastFrameQueue[b] = nil
-- -- clear if attribute already set
-- ClearClickCastings(b)
-- if val then
-- -- update bindingClicks
-- b:SetAttribute("snippet", snippet)
-- SetBindingClicks(b)
-- -- load db and set attribute
-- ApplyClickCastings(b)
-- end
-- end
F:IterateAllUnitButtons(function(b)
-- clear if attribute already set
ClearClickCastings(b)
-- update bindingClicks
b:SetAttribute("snippet", snippet)
SetBindingClicks(b)
-- load db and set attribute
ApplyClickCastings(b)
end, false, true)
previousClickCastings = F:Copy(clickCastingTable)
end
Cell:RegisterCallback("UpdateClickCastings", "UpdateClickCastings", UpdateClickCastings)
local function UpdateQueuedClickCastings()
UpdateClickCastings(true, true)
end
Cell:RegisterCallback("UpdateQueuedClickCastings", "UpdateQueuedClickCastings", UpdateQueuedClickCastings)
-------------------------------------------------
-- profiles dropdown
-------------------------------------------------
local profileDropdown
local function CreateProfilePane()
local profilePane = Cell:CreateTitledPane(clickCastingsTab, L["Profiles"], 422, 50)
profilePane:SetPoint("TOPLEFT", 5, -5)
profileDropdown = Cell:CreateDropdown(profilePane, 412)
profileDropdown:SetPoint("TOPLEFT", profilePane, "TOPLEFT", 5, -27)
profileDropdown:SetEnabled(not Cell.isVanilla)
profileDropdown:SetItems({
{
["text"] = L["Use common profile"],
["onClick"] = function()
Cell.vars.clickCastings["useCommon"] = true
Cell:Fire("UpdateClickCastings")
LoadProfile(true)
end,
},
{
["text"] = L["Use separate profile for each spec"],
["onClick"] = function()
Cell.vars.clickCastings["useCommon"] = false
Cell:Fire("UpdateClickCastings")
LoadProfile(false)
end,
}
})
end
-------------------------------------------------
-- always targeting
-------------------------------------------------
local targetingDropdown
local function CreateTargetingPane()
local targetingPane = Cell:CreateTitledPane(clickCastingsTab, L["Always Targeting"], 205, 50)
targetingPane:SetPoint("TOPLEFT", clickCastingsTab, "TOPLEFT", 5, -70)
targetingDropdown = Cell:CreateDropdown(targetingPane, 195)
targetingDropdown:SetPoint("TOPLEFT", targetingPane, "TOPLEFT", 5, -27)
local items = {
{
["text"] = L["Disabled"],
["value"] = "disabled",
["onClick"] = function()
local spec = Cell.vars.clickCastings["useCommon"] and "common" or Cell.vars.playerSpecID
Cell.vars.clickCastings["alwaysTargeting"][spec] = "disabled"
alwaysTargeting = "disabled"
Cell:Fire("UpdateClickCastings", true)
end,
},
{
["text"] = L["Left Spell"],
["value"] = "left",
["onClick"] = function()
local spec = Cell.vars.clickCastings["useCommon"] and "common" or Cell.vars.playerSpecID
Cell.vars.clickCastings["alwaysTargeting"][spec] = "left"
alwaysTargeting = "left"
Cell:Fire("UpdateClickCastings", true)
end,
},
{
["text"] = L["Any Spells"],
["value"] = "any",
["onClick"] = function()
local spec = Cell.vars.clickCastings["useCommon"] and "common" or Cell.vars.playerSpecID
Cell.vars.clickCastings["alwaysTargeting"][spec] = "any"
alwaysTargeting = "any"
Cell:Fire("UpdateClickCastings", true)
end,
}
}
targetingDropdown:SetItems(items)
Cell:SetTooltips(targetingDropdown, "ANCHOR_TOPLEFT", 0, 2, L["Always Targeting"], L["Only available for Spells"])
end
-------------------------------------------------
-- sMaRt resurrection
-------------------------------------------------
local smartResDropdown
local function CreateSmartResPane()
local smartResPane = Cell:CreateTitledPane(clickCastingsTab, L["Smart Resurrection"], 205, 50)
smartResPane:SetPoint("TOPLEFT", clickCastingsTab, "TOPLEFT", 222, -70)
smartResDropdown = Cell:CreateDropdown(smartResPane, 195)
smartResDropdown:SetPoint("TOPLEFT", smartResPane, "TOPLEFT", 5, -27)
local items = {
{
["text"] = L["Disabled"],
["value"] = "disabled",
["onClick"] = function()
Cell.vars.clickCastings["smartResurrection"] = "disabled"
Cell:Fire("UpdateClickCastings", true)
end,
},
{
["text"] = L["Normal"],
["value"] = "normal",
["onClick"] = function()
Cell.vars.clickCastings["smartResurrection"] = "normal"
Cell:Fire("UpdateClickCastings", true)
end,
} ,
{
["text"] = L["Normal + Combat Res"],
["value"] = "normal+combat",
["onClick"] = function()
Cell.vars.clickCastings["smartResurrection"] = "normal+combat"
Cell:Fire("UpdateClickCastings", true)
end,
}
}
smartResDropdown:SetItems(items)
Cell:SetTooltips(smartResDropdown, "ANCHOR_TOPLEFT", 0, 2, L["Smart Resurrection"], L["Replace click-castings of Spell type with resurrection spells on dead units"])
end
-------------------------------------------------
-- menu
-------------------------------------------------
local menu = Cell.menu
local bindingButton
local function CheckChanged(index, b)
if F:Getn(changed[index]) == 1 then -- nothing changed
changed[index] = nil
b:SetChanged(false)
else
b:SetChanged(true)
end
end
local function ShowBindingMenu(index, b)
-- if already in deleted, do nothing
if deleted[index] then return end
P:ClearPoints(bindingButton)
P:Point(bindingButton, "TOPLEFT", b.keyGrid)
bindingButton:Show()
menu:Hide()
bindingButton:SetFunc(function(modifier, key)
F:Debug(modifier, key)
b.keyGrid:SetText(GetBindingDisplay(modifier, key))
changed[index] = changed[index] or {b}
-- check modifier
if modifier ~= b.modifier then
changed[index]["modifier"] = modifier
else
changed[index]["modifier"] = nil
end
-- check bindKey
if key ~= b.bindKey then
changed[index]["bindKey"] = key
else
changed[index]["bindKey"] = nil
end
CheckChanged(index, b)
CheckChanges()
end)
end
local function ShowTypesMenu(index, b)
local parent = select(2, menu:GetPoint(1))
if parent == b.typeGrid and menu:IsShown() then
menu:Hide()
return
end
-- if already in deleted, do nothing
if deleted[index] then return end
local items = {
{
["text"] = L["General"],
["onClick"] = function()
b.typeGrid:SetText(L["General"])
if clickCastingsTab.popupEditBox then clickCastingsTab.popupEditBox:Hide() end
changed[index] = changed[index] or {b}
-- check type
if b.bindType ~= "general" then
changed[index]["bindType"] = "general"
changed[index]["bindAction"] = "target"
b.actionGrid:SetText(L["target"])
else
changed[index]["bindType"] = nil
changed[index]["bindAction"] = nil
b.actionGrid:SetText(L[b.bindAction])
end
CheckChanged(index, b)
CheckChanges()
b:HideIcon()
end,
}, {
["text"] = L["Spell"],
["onClick"] = function()
b.typeGrid:SetText(L["Spell"])
if clickCastingsTab.popupEditBox then clickCastingsTab.popupEditBox:Hide() end
changed[index] = changed[index] or {b}
-- check type
if b.bindType ~= "spell" then
changed[index]["bindType"] = "spell"
changed[index]["bindAction"] = ""
b.actionGrid:SetText("")
b:HideIcon()
else
changed[index]["bindType"] = nil
changed[index]["bindAction"] = nil
b.actionGrid:SetText(b.bindActionDisplay)
b:ShowSpellIcon(b.bindAction)
end
CheckChanged(index, b)
CheckChanges()
end,
}, {
["text"] = L["Macro"],
["onClick"] = function()
b.typeGrid:SetText(L["Macro"])
if clickCastingsTab.popupEditBox then clickCastingsTab.popupEditBox:Hide() end
changed[index] = changed[index] or {b}
-- check type
if b.bindType ~= "macro" then
changed[index]["bindType"] = "macro"
changed[index]["bindAction"] = ""
b.actionGrid:SetText("")
b:HideIcon()
else
changed[index]["bindType"] = nil
changed[index]["bindAction"] = nil
b.actionGrid:SetText(b.bindAction)
b:ShowMacroIcon(b.bindAction)
end
CheckChanged(index, b)
CheckChanges()
end,
}, {
["text"] = L["Custom"],
["onClick"] = function()
b.typeGrid:SetText(L["Custom"])
if clickCastingsTab.popupEditBox then clickCastingsTab.popupEditBox:Hide() end
changed[index] = changed[index] or {b}
-- check type
if b.bindType ~= "custom" then
changed[index]["bindType"] = "custom"
changed[index]["bindAction"] = ""
b.actionGrid:SetText("")
b:HideIcon()
else
changed[index]["bindType"] = nil
changed[index]["bindAction"] = nil
b.actionGrid:SetText(b.bindAction)
b:HideIcon()
end
CheckChanged(index, b)
CheckChanges()
end,
}, {
["text"] = L["Item"],
["onClick"] = function()
b.typeGrid:SetText(L["Item"])
if clickCastingsTab.popupEditBox then clickCastingsTab.popupEditBox:Hide() end
changed[index] = changed[index] or {b}
-- check type
if b.bindType ~= "item" then
changed[index]["bindType"] = "item"
changed[index]["bindAction"] = ""
b.actionGrid:SetText("")
b:HideIcon()
else
changed[index]["bindType"] = nil
changed[index]["bindAction"] = nil
b.actionGrid:SetText(b.bindActionDisplay)
b:ShowItemIcon(b.bindAction)
end
CheckChanged(index, b)
CheckChanges()
end,
},
-- {
-- ["text"] = L["Click"],
-- ["onClick"] = function()
-- b.typeGrid:SetText(L["Click"])
-- if clickCastingsTab.popupEditBox then clickCastingsTab.popupEditBox:Hide() end
-- changed[index] = changed[index] or {b}
-- -- check type
-- if b.bindType ~= "click" then
-- changed[index]["bindType"] = "click"
-- changed[index]["bindAction"] = ""
-- b.actionGrid:SetText("")
-- b:HideIcon()
-- else
-- changed[index]["bindType"] = nil
-- changed[index]["bindAction"] = nil
-- b.actionGrid:SetText(b.bindActionDisplay)
-- b:ShowSpellIcon(b.bindAction)
-- end
-- CheckChanged(index, b)
-- CheckChanges()
-- end,
-- }
}
menu:SetItems(items)
P:ClearPoints(menu)
P:Point(menu, "TOPLEFT", b.typeGrid, "BOTTOMLEFT", 0, -1)
menu:SetWidths(70)
menu:ShowMenu()
bindingButton:Hide()
end
local function ShowActionsMenu(index, b)
local parent = select(2, menu:GetPoint(1))
if parent == b.actionGrid and menu:IsShown() then
menu:Hide()
return
end
-- if already in deleted, do nothing
if deleted[index] then return end
local items
local bindType
if changed[index] and changed[index]["bindType"] then -- changed
bindType = changed[index]["bindType"]
else -- use original
bindType = b.bindType
end
if bindType == "general" then
items = {
{
["text"] = L["Target"],
["onClick"] = function()
changed[index] = changed[index] or {b}
if b.bindAction ~= "target" then
changed[index]["bindAction"] = "target"
b.actionGrid:SetText(L["Target"])
else
changed[index]["bindAction"] = nil
b.actionGrid:SetText(L[b.bindAction])
end
CheckChanged(index, b)
CheckChanges()
end,
},
{
["text"] = L["Focus"],
["onClick"] = function()
changed[index] = changed[index] or {b}
if b.bindAction ~= "focus" then
changed[index]["bindAction"] = "focus"
b.actionGrid:SetText(L["Focus"])
else
changed[index]["bindAction"] = nil
b.actionGrid:SetText(L[b.bindAction])
end
CheckChanged(index, b)
CheckChanges()
end,
},
{
["text"] = L["Assist"],
["onClick"] = function()
changed[index] = changed[index] or {b}
if b.bindAction ~= "assist" then
changed[index]["bindAction"] = "assist"
b.actionGrid:SetText(L["Assist"])
else
changed[index]["bindAction"] = nil
b.actionGrid:SetText(L[b.bindAction])
end
CheckChanged(index, b)
CheckChanges()
end,
},
{
["text"] = L["Menu"],
["onClick"] = function()
changed[index] = changed[index] or {b}
if b.bindAction ~= "togglemenu" then
changed[index]["bindAction"] = "togglemenu"
b.actionGrid:SetText(L["Menu"])
else
changed[index]["bindAction"] = nil
b.actionGrid:SetText(L[b.bindAction])
end
CheckChanged(index, b)
CheckChanges()
end,
},
{
["text"] = L["togglemenu_nocombat"],
["onClick"] = function()
changed[index] = changed[index] or {b}
if b.bindAction ~= "togglemenu_nocombat" then
changed[index]["bindAction"] = "togglemenu_nocombat"
b.actionGrid:SetText(L["togglemenu_nocombat"])
else
changed[index]["bindAction"] = nil
b.actionGrid:SetText(L[b.bindAction])
end
CheckChanged(index, b)
CheckChanges()
end,
},
}
elseif bindType == "custom" then
items = {}
tinsert(items, {
["text"] = L["Edit"],
["onClick"] = function()
local peb = Cell:CreatePopupEditBox(clickCastingsTab, function(text)
changed[index] = changed[index] or {b}
if b.bindAction ~= text then
changed[index]["bindAction"] = text
b.actionGrid:SetText(text)
else
changed[index]["bindAction"] = nil
b.actionGrid:SetText(b.bindAction)
end
CheckChanged(index, b)
CheckChanges()
end, true)
peb:SetPoint("TOPLEFT", b.actionGrid)
peb:SetPoint("TOPRIGHT", b.actionGrid)
P:Height(peb, 20)
-- peb:SetPoint("BOTTOMRIGHT", b.actionGrid)
peb:SetTips("|cffababab"..L["Shift+Enter: add a new line"].."\n"..L["Enter: apply\nESC: discard"])
if b.bindType == "custom" then
if changed[index] and changed[index]["bindAction"] then
peb:ShowEditBox(changed[index]["bindAction"])
else
peb:ShowEditBox(b.bindAction)
end
elseif changed[index] and changed[index]["bindType"] == "custom" then
if changed[index]["bindAction"] then
peb:ShowEditBox(changed[index]["bindAction"])
else
peb:ShowEditBox("")
end
else
peb:ShowEditBox("")
end
peb:SetNumeric(false)
end,
})
tinsert(items, {
["text"] = L["Extra Action Button"],
["onClick"] = function()
changed[index] = changed[index] or {b}
local macrotext = "/stopcasting\n/target mouseover\n/click ExtraActionButton1\n/targetlasttarget"
if b.bindAction ~= macrotext then
changed[index]["bindAction"] = macrotext
b.actionGrid:SetText(macrotext)
else
changed[index]["bindAction"] = nil
b.actionGrid:SetText(b.bindAction)
end
CheckChanged(index, b)
CheckChanges()
end,
})
if (Cell.isVanilla or Cell.isWrath or Cell.isCata) and Cell.vars.playerClass == "WARLOCK" then
tinsert(items, {
["text"] = F:GetSpellInfo(20707),
["onClick"] = function()
changed[index] = changed[index] or {b}
local macrotext = "/stopcasting\n/target mouseover\n/use item:36895\n/targetlasttarget"
if b.bindAction ~= macrotext then
changed[index]["bindAction"] = macrotext
b.actionGrid:SetText(macrotext)
else
changed[index]["bindAction"] = nil
b.actionGrid:SetText(b.bindAction)
end
CheckChanged(index, b)
CheckChanges()
end,
})
end
elseif bindType == "macro" then
items = {}
for _, i in pairs(F:GetMacroIndices()) do
local name, icon = GetMacroInfo(i)
if name then
tinsert(items, {
["text"] = name,
["icon"] = icon,
["onClick"] = function()
changed[index] = changed[index] or {b}
if b.bindAction ~= name then
changed[index]["bindAction"] = name
else
changed[index]["bindAction"] = nil
end
b.actionGrid:SetText(name)
b:ShowIcon(icon)
CheckChanged(index, b)
CheckChanges()
end,
})
end
end
elseif bindType == "item" then
items = {}
for _, slot in ipairs({13, 14, 6, 9, 10}) do
tinsert(items, {
["text"] = slotNames[slot],
["onClick"] = function()
changed[index] = changed[index] or {b}
if b.bindAction ~= slot then
changed[index]["bindAction"] = slot
else
changed[index]["bindAction"] = nil
end
b.actionGrid:SetText(slotNames[slot])
b:ShowItemIcon(slot)
CheckChanged(index, b)
CheckChanges()
end,
})
end
for slot = 1, 17 do
local itemId = GetInventoryItemID("player", slot)
if itemId then -- and C_Item.IsUsableItem(itemId) then
local text = GetInventoryItemLink("player", slot) or ""
text = string.gsub(text, "[%[%]]", "")
tinsert(items, {
["text"] = text,
["icon"] = GetInventoryItemTexture("player", slot),
["onClick"] = function()
changed[index] = changed[index] or {b}
if b.bindAction ~= slot then
changed[index]["bindAction"] = slot
else
changed[index]["bindAction"] = nil
end
b.actionGrid:SetText(slotNames[slot])
b:ShowItemIcon(slot)
CheckChanged(index, b)
CheckChanges()
end,
})
end
end
-- elseif bindType == "click" then
-- items = {{
-- ["text"] = "ExtraActionButton1",
-- ["onClick"] = function()
-- changed[index] = changed[index] or {b}
-- if b.bindAction ~= "ExtraActionButton1" then
-- changed[index]["bindAction"] = "ExtraActionButton1"
-- b.actionGrid:SetText("ExtraActionButton1")
-- else
-- changed[index]["bindAction"] = nil
-- b.actionGrid:SetText(b.bindAction)
-- end
-- CheckChanged(index, b)
-- CheckChanges()
-- end,
-- }}
else -- spell
items = {
{
["text"] = L["Edit"],
["onClick"] = function()
local peb = Cell:CreatePopupEditBox(clickCastingsTab, function(text)
changed[index] = changed[index] or {b}
text = tonumber(text) or ""
if b.bindAction ~= text then
changed[index]["bindAction"] = text
if text == "" then
b.actionGrid:SetText("")
b:HideIcon()
else
b.actionGrid:SetText(F:GetSpellInfo(text) or "|cFFFF3030"..L["Invalid"])
b:ShowSpellIcon(text)
end
else
changed[index]["bindAction"] = nil
if text == "" then
b.actionGrid:SetText("")
b:HideIcon()
else
b.actionGrid:SetText(b.bindActionDisplay)
b:ShowSpellIcon(b.bindAction)
end
end
CheckChanged(index, b)
CheckChanges()
end)
P:Point(peb, "TOPLEFT", b.actionGrid)
P:Point(peb, "BOTTOMRIGHT", b.actionGrid)
peb:SetTips("|cffababab"..L["Input spell id"].."\n"..L["Enter: apply\nESC: discard"])
peb:ShowEditBox(b.bindAction or "")
peb:SetNumeric(true)
if not peb.tooltipAdded then
peb.tooltipAdded = true
peb:SetScript("OnTextChanged", function()
local spellId = tonumber(peb:GetText())
if not spellId then
CellSpellTooltip:Hide()
return
end
local name, icon = F:GetSpellInfo(spellId)
if not name then
CellSpellTooltip:Hide()
return
end
CellSpellTooltip:SetOwner(peb, "ANCHOR_NONE")
CellSpellTooltip:SetPoint("TOPLEFT", peb, "BOTTOMLEFT", 0, -1)
CellSpellTooltip:SetSpellByID(spellId, icon)
CellSpellTooltip:Show()
end)
peb:HookScript("OnHide", function()
CellSpellTooltip:Hide()
end)
end
end,
},
}
-- default spells
local spells = F:GetClickCastingSpellList(Cell.vars.playerClass, Cell.vars.playerSpecID)
-- texplore(spells)
-- {icon, name, type(C/S/P), id}
for _, t in ipairs(spells) do
tinsert(items, {
--! CANNOT use "|T****|t", if too many items (over 10?), it will cause game stuck!! I don't know why!
-- ["text"] = "|T"..t[1]..":12:12:0:0:12:12:1:11:1:11|t "..t[2]..(t[3] and (" |cff777777("..t[3]..")") or ""),
["text"] = t[2]..(t[3] and (" |cff777777("..t[3]..")") or ""),
["icon"] = t[1],
["onClick"] = function()
changed[index] = changed[index] or {b}
if b.bindAction ~= t[4] then
changed[index]["bindAction"] = t[4]
b.actionGrid:SetText(t[2])
b:ShowSpellIcon(t[4])
else
changed[index]["bindAction"] = nil
b.actionGrid:SetText(b.bindActionDisplay)
b:ShowSpellIcon(b.bindAction)
end
CheckChanged(index, b)
CheckChanges()
end,
})
end
end
menu:SetWidths(b.actionGrid:GetWidth())
menu:SetItems(items, 15)
P:ClearPoints(menu)
P:Point(menu, "TOPLEFT", b.actionGrid, "BOTTOMLEFT", 0, -1)
menu:ShowMenu()
bindingButton:Hide()
end
-------------------------------------------------
-- list pane
-------------------------------------------------
local CreateBindingListButton
local last
local function UpdateCurrentText(isCommon)
if isCommon then
listPane:SetTitle(L["Current Profile"]..": "..L["Common"])
else
if Cell.isRetail then
listPane:SetTitle(L["Current Profile"]..": ".."|T"..Cell.vars.playerSpecIcon..":12:12:0:1:12:12:1:11:1:11|t "..Cell.vars.playerSpecName)
elseif Cell.isCata or Cell.isWrath then
local name, icon = F:GetActiveTalentInfo()
listPane:SetTitle(L["Current Profile"]..": ".."|T"..icon..":12:12:0:1:12:12:1:11:1:11|t "..name)
end
end
end
local function CreateListPane()
listPane = Cell:CreateTitledPane(clickCastingsTab, L["Current Profile"], 422, 451)
listPane:SetPoint("BOTTOMLEFT", clickCastingsTab, 5, 5)
local hint = Cell:CreateButton(listPane, nil, "accent-hover", {17, 17}, nil, nil, nil, nil, nil,
L["Click-Castings"],
"|cffffb5c5"..L["Left-Click"]..":|r "..strlower(L["Edit"]),
"|cffffb5c5"..L["Right-Click"]..":|r "..strlower(L["Delete"]),
"|cffffb5c5"..L["Left-Drag"]..":|r "..L["change the order"]
)
hint:SetPoint("TOPRIGHT")
hint.tex = hint:CreateTexture(nil, "ARTWORK")
hint.tex:SetAllPoints(hint)
hint.tex:SetTexture("Interface\\AddOns\\Cell\\Media\\Icons\\info2.tga")
local export = Cell:CreateButton(listPane, nil, "accent-hover", {27, 17}, nil, nil, nil, nil, nil, L["Export"])
export:SetPoint("TOPRIGHT", hint, "TOPLEFT", -1, 0)
export:SetTexture("Interface\\AddOns\\Cell\\Media\\Icons\\export", {15, 15}, {"CENTER", 0, 0})
export:SetScript("OnClick", function()
F:ShowClickCastingExportFrame(clickCastingTable)
end)
local import = Cell:CreateButton(listPane, nil, "accent-hover", {27, 17}, nil, nil, nil, nil, nil, L["Import"])
import:SetPoint("TOPRIGHT", export, "TOPLEFT", -1, 0)
import:SetTexture("Interface\\AddOns\\Cell\\Media\\Icons\\import", {15, 15}, {"CENTER", 0, 0})
import:SetScript("OnClick", function()
F:ShowClickCastingImportFrame()
end)
bindingButton = Cell:CreateBindingButton(listPane, 130)
-- bindings frame
bindingsFrame = Cell:CreateFrame("ClickCastingsTab_BindingsFrame", listPane)
bindingsFrame:SetPoint("TOPLEFT", 0, -27)
bindingsFrame:SetPoint("BOTTOMRIGHT", 0, 19)
bindingsFrame:Show()
Cell:CreateScrollFrame(bindingsFrame, -5, 5)
bindingsFrame.scrollFrame:SetScrollStep(25)
-- new & save & cancel
local newBtn = Cell:CreateButton(listPane, L["New"], "blue-hover", {141, 20})
newBtn:SetPoint("TOPLEFT", bindingsFrame, "BOTTOMLEFT", 0, P:Scale(1))
newBtn:SetScript("OnClick", function()
local index = #clickCastingTable+1
local b = CreateBindingListButton("", "notBound", "general", "target", index)
tinsert(clickCastingTable, EncodeDB("", "notBound", "general", "target"))
b:SetPoint("TOP", 0, P:Scale(-20)*(index-1)+P:Scale(-5)*(index-1))
menu:Hide()
bindingButton:Hide()
-- scroll
bindingsFrame.scrollFrame:SetContentHeight(P:Scale(20), #clickCastingTable, P:Scale(5))
bindingsFrame.scrollFrame:ScrollToBottom()
end)
saveBtn = Cell:CreateButton(listPane, L["Save"], "green-hover", {142, 20})
saveBtn:SetPoint("TOPLEFT", newBtn, "TOPRIGHT", P:Scale(-1), 0)
saveBtn:SetEnabled(false)
saveBtn:SetScript("OnClick", function()
-- deleted
local deletedIndices = {}
for index, b in pairs(deleted) do
if changed[index] then changed[index] = nil end -- if duplicated in changed, remove it
-- clickCastingTable[index] = nil -- update db
tinsert(deletedIndices, index)
end
-- changed
for index, t in pairs(changed) do
local b = t[1]
local modifier = t["modifier"] or b.modifier
local bindKey = t["bindKey"] or b.bindKey
local bindType = t["bindType"] or b.bindType
local bindAction = t["bindAction"] or b.bindAction
clickCastingTable[index] = EncodeDB(modifier, bindKey, bindType, bindAction)
-- texplore(clickCastingTable[index])
end
-- delete!
table.sort(deletedIndices)
for i, index in pairs(deletedIndices) do
tremove(clickCastingTable, index-i+1) -- continuous table index
end
-- reload
Cell:Fire("UpdateClickCastings")
wipe(deleted)
wipe(changed)
CheckChanges()
menu:Hide()
if clickCastingsTab.popupEditBox then clickCastingsTab.popupEditBox:Hide() end
end)
cancelBtn = Cell:CreateButton(listPane, L["Cancel"], "red-hover", {141, 20})
cancelBtn:SetPoint("TOPLEFT", saveBtn, "TOPRIGHT", P:Scale(-1), 0)
cancelBtn:SetEnabled(false)
cancelBtn:SetScript("OnClick", function()
-- deleted
for index, b in pairs(deleted) do
b:SetAlpha(1)
b:SetChanged(false)
end
-- changed
for index, t in pairs(changed) do
t[1]:SetChanged(false)
t[1].keyGrid:SetText(GetBindingDisplay(t[1].modifier, t[1].bindKey))
t[1].typeGrid:SetText(L[F:UpperFirst(t[1].bindType)])
t[1].actionGrid:SetText(t[1].bindActionDisplay)
-- restore icon
if t[1].bindType == "spell" then
t[1]:ShowSpellIcon(t[1].bindAction)
elseif t[1].bindType == "item" then
t[1]:ShowItemIcon(t[1].bindAction)
elseif t[1].bindType == "macro" then
t[1]:ShowMacroIcon(t[1].bindAction)
else
t[1]:HideIcon()
end
end
wipe(deleted)
wipe(changed)
CheckChanges()
menu:Hide()
if clickCastingsTab.popupEditBox then clickCastingsTab.popupEditBox:Hide() end
end)
end
-------------------------------------------------
-- bindings frame
-------------------------------------------------
CreateBindingListButton = function(modifier, bindKey, bindType, bindAction, i)
if not listButtons[i] then
listButtons[i] = Cell:CreateBindingListButton(bindingsFrame.scrollFrame.content, "", "", "", "")
end
local b = listButtons[i]
b:SetParent(bindingsFrame.scrollFrame.content)
b:SetAlpha(1)
b:SetChanged(false)
b:Show()
b.modifier, b.bindKey, b.bindType, b.bindAction = modifier, bindKey, bindType, bindAction
b.clickCastingIndex = i
b.typeGrid:SetText(L[F:UpperFirst(bindType)])
if bindType == "general" then
b.bindActionDisplay = L[bindAction]
b:HideIcon()
elseif bindType == "spell" then
if bindAction ~= "" then
if type(bindAction) ~= "number" then
b.bindActionDisplay = "|cFFFF3030"..L["Invalid"]
b:ShowSpellIcon()
else
b.bindActionDisplay = F:GetSpellInfo(bindAction) or "|cFFFF3030"..L["Invalid"]
b:ShowSpellIcon(bindAction)
end
else
b.bindActionDisplay = ""
b:HideIcon()
end
elseif bindType == "item" then
if bindAction ~= "" then
b.bindActionDisplay = slotNames[bindAction]
b:ShowItemIcon(bindAction)
else
b.bindActionDisplay = ""
b:HideIcon()
end
elseif bindType == "macro" then
-- NOTE: GetMacroInfo("name") seems no returns
local name, icon = GetMacroInfo(GetMacroIndexByName(bindAction))
if name then
b.bindActionDisplay = name
else
b.bindActionDisplay = "|cFFFF3030"..L["Invalid"]
end
b:ShowIcon(icon)
elseif bindType == "custom" then
b.bindActionDisplay = bindAction
b:HideIcon()
b.typeGrid:SetText(L["Custom"])
end
b.keyGrid:SetText(GetBindingDisplay(modifier, bindKey))
b.actionGrid:SetText(b.bindActionDisplay)
b:SetPoint("LEFT", 5, 0)
b:SetPoint("RIGHT", -5, 0)
b:SetScript("OnClick", function(self, button, down)
if button == "RightButton" then
if deleted[i] then
deleted[i] = nil
if not changed[i] then
b:SetChanged(false)
end
b:SetAlpha(1)
else
deleted[i] = b
b:SetChanged(true)
b:SetAlpha(0.3)
end
CheckChanges()
end
end)
b.keyGrid:SetScript("OnClick", function(self, button, down)
if button == "RightButton" then
b:GetScript("OnClick")(b, button, down)
else
ShowBindingMenu(i, b)
end
end)
b.typeGrid:SetScript("OnClick", function(self, button, down)
if button == "RightButton" then
b:GetScript("OnClick")(b, button, down)
else
ShowTypesMenu(i, b)
end
end)
b.actionGrid:SetScript("OnClick", function(self, button, down)
if button == "RightButton" then
b:GetScript("OnClick")(b, button, down)
else
ShowActionsMenu(i, b)
end
end)
return b
end
LoadProfile = function(isCommon)
targetingDropdown:SetSelectedValue(alwaysTargeting)
UpdateCurrentText(isCommon)
last = nil
bindingsFrame.scrollFrame:Reset()
-- F:Debug("-- Load clickCastings start --------------")
for i, t in pairs(clickCastingTable) do
-- F:Debug(table.concat(t, ","))
local modifier, bindKey, bindType, bindAction = DecodeDB(t)
local b = CreateBindingListButton(modifier, bindKey, bindType, bindAction, i)
b:SetPoint("TOP", 0, P:Scale(-20)*(i-1)+P:Scale(-5)*(i-1))
end
-- hide unused
for i = #clickCastingTable+1, #listButtons do
listButtons[i]:Hide()
end
-- F:Debug("-- Load clickCastings end ----------------")
bindingsFrame.scrollFrame:SetContentHeight(P:Scale(20), #clickCastingTable, P:Scale(5))
menu:Hide()
wipe(deleted)
wipe(changed)
end
function F:MoveClickCastings(from, to)
F:Debug(from, "->", to)
if from and to then
local temp = clickCastingTable[from]
tremove(clickCastingTable, from)
tinsert(clickCastingTable, to, temp)
end
LoadProfile(Cell.vars.clickCastings["useCommon"])
end
-------------------------------------------------
-- check conflicts
-------------------------------------------------
function CheckConflicts()
local selfCast = GetModifiedClick("SELFCAST")
-- local focusCast = GetModifiedClick("FOCUSCAST")
local selfCastMsg, focusCastMsg
if selfCast ~= "NONE" then
selfCastMsg = AUTO_SELF_CAST_KEY_TEXT..": |cFFFFD100"..selfCast.."|r\n"
end
-- if focusCast ~= "NONE" then
-- focusCastMsg = FOCUS_CAST_KEY_TEXT..": |cFFFFD100"..focusCast.."|r\n"
-- end
if selfCastMsg or focusCastMsg then
local msg = "|cFFFF3030"..L["Conflicts Detected!"].."|r\n"..(selfCastMsg or "")..(focusCastMsg or "")..
"\n|cFFFF3030"..L["Yes"].."|r - "..L["Remove"].."\n".."|cFFFF3030"..L["No"].."|r - "..L["Cancel"]
local popup = Cell:CreateConfirmPopup(clickCastingsTab, 200, msg, function(self)
if Cell.isRetail then
--! NOTE: show-set-hide or commit
-- ShowUIPanel(SettingsPanel)
-- Settings.OpenToCategory(8)
Settings.SetValue("SELFCAST", "NONE", true)
-- HideUIPanel(SettingsPanel)
SettingsPanel:Commit()
else
SetModifiedClick("SELFCAST", "NONE")
-- SetModifiedClick("FOCUSCAST", "NONE")
SaveBindings(GetCurrentBindingSet())
end
end, nil, true)
popup:SetPoint("TOPLEFT", 117, -90)
end
end
-------------------------------------------------
-- functions
-------------------------------------------------
local init
local function ShowTab(tab)
if tab == "clickCastings" then
if not init then
init = true
CreateProfilePane()
CreateTargetingPane()
CreateSmartResPane()
CreateListPane()
F:ApplyCombatProtectionToFrame(clickCastingsTab)
end
clickCastingsTab:Show()
else
clickCastingsTab:Hide()
end
end
Cell:RegisterCallback("ShowOptionsTab", "ClickCastingsTab_ShowTab", ShowTab)
clickCastingsTab:SetScript("OnShow", function()
CheckConflicts()
if loaded then return end
loaded = true
local isCommon = Cell.vars.clickCastings["useCommon"]
profileDropdown:SetSelectedItem(isCommon and 1 or 2)
-- UpdateCurrentText(isCommon)
LoadProfile(isCommon)
smartResDropdown:SetSelectedValue(Cell.vars.clickCastings["smartResurrection"])
menu:SetMenuParent(clickCastingsTab)
-- texplore(changed)
end)
function F:UpdateClickCastingProfileLabel()
if loaded then
UpdateCurrentText(Cell.vars.clickCastings["useCommon"])
end
end