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.
1549 lines
60 KiB
1549 lines
60 KiB
|
2 years ago
|
---@type detailsframework
|
||
|
|
local detailsFramework = _G["DetailsFramework"]
|
||
|
|
if (not detailsFramework or not DetailsFrameworkCanLoad) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
--[=[[
|
||
|
|
bugs:
|
||
|
|
-t verificar se esta mostrando o indicador de keybinds repetidas
|
||
|
|
-t fazer o sort de maneira que fique melhor
|
||
|
|
-t fazer um indicador dizendo que a keybind esta desabilitada por causa da load condition
|
||
|
|
-t fazer o debug do puf mostrar as keybinds (string)
|
||
|
|
- quando iniciar uma edição, fazer um indicador the diga que aquela linha esta esta sendo editada
|
||
|
|
- transferir o montagem do código seguro das keybinds no puf para o framework
|
||
|
|
|
||
|
|
tried to edit a spell binding:
|
||
|
|
2x Details/Libs/DF/keybind.lua:1080: attempt to index local 'actionId' (a number value)
|
||
|
|
[string "@Details/Libs/DF/keybind.lua"]:1160: in function <Details/Libs/DF/keybind.lua:1143>
|
||
|
|
[string "=[C]"]: in function `xpcall'
|
||
|
|
[string "@Details/Libs/DF/fw.lua"]:4864: in function `CoreDispatch'
|
||
|
|
[string "@Details/Libs/DF/button.lua"]:720: in function <Details/Libs/DF/button.lua:656>
|
||
|
|
--]=]
|
||
|
|
|
||
|
|
local _
|
||
|
|
local IsShiftKeyDown = _G["IsShiftKeyDown"]
|
||
|
|
local IsControlKeyDown = _G["IsControlKeyDown"]
|
||
|
|
local IsAltKeyDown = _G["IsAltKeyDown"]
|
||
|
|
local CreateFrame = _G["CreateFrame"]
|
||
|
|
local GetSpellInfo = _G["GetSpellInfo"]
|
||
|
|
local unpack = unpack ---@diagnostic disable-line
|
||
|
|
|
||
|
|
---@alias actionidentifier string a string in the format of "spell-spellId" or "macro-macroName" or "system-target", etc, used to pass information about the action more easily
|
||
|
|
|
||
|
|
---@class keybind_scroll_data : {key1:string, key2:any, key3:any, key4:string, key5:boolean, key6:number, key7:string}
|
||
|
|
|
||
|
|
---@class df_keybind : table
|
||
|
|
---@field name string
|
||
|
|
---@field action string|number
|
||
|
|
---@field keybind string
|
||
|
|
---@field macro string
|
||
|
|
---@field conditions table
|
||
|
|
---@field icon any
|
||
|
|
|
||
|
|
---@class df_editkeybindframe : frame
|
||
|
|
---@field bIsEditing boolean
|
||
|
|
---@field actionIdentifier actionidentifier
|
||
|
|
---@field conditionsFailLoadReasonText fontstring
|
||
|
|
---@field keybindTable df_keybind
|
||
|
|
---@field nameEditBox df_textentry
|
||
|
|
---@field iconPickerButton df_button
|
||
|
|
---@field conditionsButton df_button
|
||
|
|
---@field editMacroEditBox df_luaeditor
|
||
|
|
---@field cancelButton df_button
|
||
|
|
---@field saveButton df_button
|
||
|
|
---@field deleteMacroButton df_button
|
||
|
|
---@field Disable fun(self:df_editkeybindframe)
|
||
|
|
---@field Enable fun(self:df_editkeybindframe)
|
||
|
|
|
||
|
|
---@class df_selectkeybindbutton : button
|
||
|
|
---@field actionIdentifier actionidentifier
|
||
|
|
---@field keybindTable df_keybind
|
||
|
|
---@field keybindScrollData keybind_scroll_data
|
||
|
|
|
||
|
|
---@class df_keybindscrollline : frame, df_headerfunctions
|
||
|
|
---@field bIsSeparator boolean
|
||
|
|
---@field keybindScrollLine boolean
|
||
|
|
---@field backgroundTexture texture
|
||
|
|
---@field highlightTexture texture
|
||
|
|
---@field separatorTitleText fontstring
|
||
|
|
---@field spellIconTexture texture
|
||
|
|
---@field actionNameFontString fontstring
|
||
|
|
---@field setKeybindButton df_button
|
||
|
|
---@field clearKeybindButton df_button
|
||
|
|
---@field editKeybindSettingsButton df_button
|
||
|
|
---@field SetAsSeparator function
|
||
|
|
|
||
|
|
local keybindPrototype = {
|
||
|
|
name = "", --a name or alias to call this keybind
|
||
|
|
action = "", --which action this keybind will do, can be a spellId for spell casting, a macro text or targetting like "target", "focus", "togglemenu"
|
||
|
|
keybind = "",
|
||
|
|
macro = "",
|
||
|
|
conditions = detailsFramework:UpdateLoadConditionsTable({}),
|
||
|
|
icon = "",
|
||
|
|
}
|
||
|
|
|
||
|
|
---@type {action: string, keybind: string, icon: string, name: string}[]
|
||
|
|
local defaultMouseKeybinds = {
|
||
|
|
{action = "target", name = _G["TARGET"], keybind = "type1", icon = [[Interface\MINIMAP\TRACKING\Target]]}, --default: left mouse button
|
||
|
|
{action = "togglemenu", name = _G["SLASH_TEXTTOSPEECH_MENU"], keybind = "type2", icon = [[Interface\BUTTONS\UI-GuildButton-PublicNote-Up]]}, --default: right mouse button
|
||
|
|
{action = "focus", name = _G["FOCUS"], keybind = "type3", icon = [[Interface\MINIMAP\TRACKING\Focus]]} --default: middle mouse button
|
||
|
|
}
|
||
|
|
|
||
|
|
local defaultMouseKeybindsKV = {
|
||
|
|
["target"] = defaultMouseKeybinds[1],
|
||
|
|
["togglemenu"] = defaultMouseKeybinds[2],
|
||
|
|
["focus"] = defaultMouseKeybinds[3],
|
||
|
|
}
|
||
|
|
|
||
|
|
---@class df_keybindscroll : df_scrollbox
|
||
|
|
---@field UpdateScroll fun(self:df_keybindscroll)
|
||
|
|
|
||
|
|
---@class df_keybindframe : frame, df_optionsmixin
|
||
|
|
---@field options table
|
||
|
|
---@field data table
|
||
|
|
---@field keybindData table
|
||
|
|
---@field keybindScrollData keybind_scroll_data
|
||
|
|
---@field Header df_headerframe
|
||
|
|
---@field actionId number? the actionId is the spell Id or an actionId or a macro text
|
||
|
|
---@field button button? the button which got clicked to start editing a keybind
|
||
|
|
---@field bIsListening boolean if the frame is wayting the user to press a keybind (listening key inputs)
|
||
|
|
---@field bIsKeybindFrame boolean
|
||
|
|
---@field keybindScroll df_keybindscroll
|
||
|
|
---@field keybindListener frame
|
||
|
|
---@field editKeybindFrame df_editkeybindframe
|
||
|
|
---@field callback function
|
||
|
|
---@field ClearKeybind fun(self:button, buttonPresed:string, actionIdentifier:actionidentifier, keybindTable:any)
|
||
|
|
---@field CreateKeybindScroll fun(self:df_keybindframe)
|
||
|
|
---@field CreateKeybindListener fun(self:df_keybindframe)
|
||
|
|
---@field CreateEditPanel fun(self:df_keybindframe)
|
||
|
|
---@field CreateKeybindScrollLine fun(self:df_keybindframe, index:number)
|
||
|
|
---@field DeleteMacro fun(self:df_keybindframe)
|
||
|
|
---@field FindKeybindTable fun(self:df_keybindframe, keybindType:string, actionId:any, actionIdentifier:actionidentifier?) : df_keybind?, number?
|
||
|
|
---@field GetEditPanel fun(self:df_keybindframe) : df_editkeybindframe
|
||
|
|
---@field GetPressedModifiers fun() : string
|
||
|
|
---@field GetListeningActionId fun(self:df_keybindframe) : number
|
||
|
|
---@field GetListeningState fun(self:df_keybindframe) : boolean, any, button, keybind_scroll_data
|
||
|
|
---@field GetKeybindData fun(self:df_keybindframe) : df_keybind[]
|
||
|
|
---@field GetKeybindListener fun(self:df_keybindframe) : frame
|
||
|
|
---@field GetKeybindScroll fun(self:df_keybindframe) : df_keybindscroll
|
||
|
|
---@field GetKeybindCallback fun(self:df_keybindframe):function
|
||
|
|
---@field GetKeybindModifiers fun(keybind:string) : string
|
||
|
|
---@field GetKeybindTypeAndActionFromIdentifier fun(self:df_keybindframe, actionIdentifier:actionidentifier) : string, any
|
||
|
|
---@field IsListening fun(self:df_keybindframe) : boolean
|
||
|
|
---@field IsEditingKeybindSettings fun(self:df_keybindframe) : boolean, string, df_keybind
|
||
|
|
---@field IsKeybindActionMacro fun(self:df_keybindframe, actionId:any) : boolean
|
||
|
|
---@field CallKeybindChangeCallback fun(self:df_keybindframe, type:string, keybindTable:df_keybind?, keybindPressed:string?, removedIndex:number?, macroText:string?)
|
||
|
|
---@field OnKeybindNameChange fun(self:df_keybindframe, name:string)
|
||
|
|
---@field OnKeybindMacroChange fun(self:df_keybindframe, macroText:string)
|
||
|
|
---@field OnKeybindIconChange fun(self:df_keybindframe, iconTexture:string)
|
||
|
|
---@field OnUserClickedToChooseKeybind fun(self:df_keybindframe, button:button, actionIdentifier:actionidentifier, keybindTable:df_keybind|false)
|
||
|
|
---@field OnUserPressedKeybind fun(self:df_keybindframe, key:string)
|
||
|
|
---@field SaveKeybindToKeybindData fun(self:df_keybindframe, actionId:any, pressedKeybind:any, bJustCreated:boolean)
|
||
|
|
---@field SetClearButtonsEnabled fun(self:df_keybindframe, enabled:boolean)
|
||
|
|
---@field SetEditButtonsEnabled fun(self:df_keybindframe, enabled:boolean)
|
||
|
|
---@field SetListeningState fun(self:df_keybindframe, value:boolean, actionIdentifier:actionidentifier?, button:button?, keybindScrollData:keybind_scroll_data?)
|
||
|
|
---@field SetKeybindData fun(self:df_keybindframe, keybindData:table)
|
||
|
|
---@field SetKeybindCallback fun(self:df_keybindframe, callback:function)
|
||
|
|
---@field StartEditingKeybindSettings fun(self:frame, button:string, actionIdentifier:actionidentifier, keybindTable:df_keybind)
|
||
|
|
---@field StopEditingKeybindSettings fun(self:df_keybindframe)
|
||
|
|
---@field SwitchSpec fun(self:button, button:string, newSpecId:number)
|
||
|
|
|
||
|
|
detailsFramework:NewColor("BLIZZ_OPTIONS_COLOR", 1, 0.8196, 0, 1)
|
||
|
|
|
||
|
|
local DARK_BUTTON_TEMPLATE = detailsFramework:InstallTemplate("button", "DARK_BUTTON_TEMPLATE", {backdropcolor = {.1, .1, .1, .98}}, "OPTIONS_BUTTON_TEMPLATE")
|
||
|
|
|
||
|
|
---only called from OnUserPressedKeybind() when the a keybindTable is not found for the action
|
||
|
|
---@return df_keybind
|
||
|
|
local createNewKeybindTable = function(name, keybind, macro, actionId, iconTexture)
|
||
|
|
---@type df_keybind
|
||
|
|
local newMacroTable = detailsFramework.table.copy({}, keybindPrototype)
|
||
|
|
newMacroTable.name = name or "My New Macro" --if a name isn't passed, it's a macro
|
||
|
|
newMacroTable.keybind = keybind or ""
|
||
|
|
newMacroTable.macro = macro or ""
|
||
|
|
newMacroTable.action = actionId
|
||
|
|
newMacroTable.icon = iconTexture or ""
|
||
|
|
return newMacroTable
|
||
|
|
end
|
||
|
|
|
||
|
|
---return a number representing the sort order of a spell
|
||
|
|
---@param keybindData any
|
||
|
|
---@param spellName string
|
||
|
|
---@param bIsAvailable any
|
||
|
|
---@return number
|
||
|
|
local getSpellSortOrder = function(keybindData, spellName, bIsAvailable)
|
||
|
|
local sortScore = 0
|
||
|
|
|
||
|
|
if (not bIsAvailable) then
|
||
|
|
sortScore = sortScore + 5000
|
||
|
|
end
|
||
|
|
|
||
|
|
if (not keybindData) then
|
||
|
|
sortScore = sortScore + 300
|
||
|
|
end
|
||
|
|
|
||
|
|
sortScore = sortScore + string.byte(spellName)
|
||
|
|
return sortScore
|
||
|
|
end
|
||
|
|
|
||
|
|
local default_options = {
|
||
|
|
width = 580,
|
||
|
|
height = 500,
|
||
|
|
edit_width = 400,
|
||
|
|
edit_height = 0,
|
||
|
|
scroll_width = 580,
|
||
|
|
scroll_height = 480,
|
||
|
|
amount_lines = 18,
|
||
|
|
line_height = 26,
|
||
|
|
show_spells = true,
|
||
|
|
show_unitcontrols = true,
|
||
|
|
show_macros = true,
|
||
|
|
can_modify_keybind_data = true, --if false, won't change the data table passed on the constructor or the one returned by GetKeybindData
|
||
|
|
}
|
||
|
|
|
||
|
|
local headerTable = {
|
||
|
|
{text = "", width = 34}, --spell icon
|
||
|
|
{text = "", width = 200},
|
||
|
|
{text = "Keybind", width = 260},
|
||
|
|
{text = "Clear", width = 40},
|
||
|
|
{text = "Edit", width = 40},
|
||
|
|
}
|
||
|
|
local headerOptions = {
|
||
|
|
padding = 2,
|
||
|
|
backdrop_color = {0, 0, 0, 0},
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
local ignoredKeys = {
|
||
|
|
["LSHIFT"] = true,
|
||
|
|
["RSHIFT"] = true,
|
||
|
|
["LCTRL"] = true,
|
||
|
|
["RCTRL"] = true,
|
||
|
|
["LALT"] = true,
|
||
|
|
["RALT"] = true,
|
||
|
|
["UNKNOWN"] = true,
|
||
|
|
}
|
||
|
|
|
||
|
|
local mouseButtonToClickType = {
|
||
|
|
["LeftButton"] = "type1",
|
||
|
|
["RightButton"] = "type2",
|
||
|
|
["MiddleButton"] = "type3",
|
||
|
|
["Button4"] = "type4",
|
||
|
|
["Button5"] = "type5",
|
||
|
|
["Button6"] = "type6",
|
||
|
|
["Button7"] = "type7",
|
||
|
|
["Button8"] = "type8",
|
||
|
|
["Button9"] = "type9",
|
||
|
|
["Button10"] = "type10",
|
||
|
|
["Button11"] = "type11",
|
||
|
|
["Button12"] = "type12",
|
||
|
|
["Button13"] = "type13",
|
||
|
|
["Button14"] = "type14",
|
||
|
|
["Button15"] = "type15",
|
||
|
|
["Button16"] = "type16",
|
||
|
|
}
|
||
|
|
|
||
|
|
local roundedCornerPreset = {
|
||
|
|
roundness = 5,
|
||
|
|
color = {.075, .075, .075, 1},
|
||
|
|
border_color = {.05, .05, .05, 1},
|
||
|
|
horizontal_border_size_offset = 8,
|
||
|
|
}
|
||
|
|
|
||
|
|
--> helpers
|
||
|
|
local getMainFrame = function(UIObject)
|
||
|
|
if (UIObject.bIsKeybindFrame) then
|
||
|
|
return UIObject
|
||
|
|
end
|
||
|
|
|
||
|
|
local parentFrame = UIObject:GetParent()
|
||
|
|
|
||
|
|
for i = 1, 5 do
|
||
|
|
if (parentFrame.bIsKeybindFrame) then
|
||
|
|
return parentFrame
|
||
|
|
end
|
||
|
|
parentFrame = parentFrame:GetParent()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local setAsSeparator = function(line, bIsSeparator, titleText)
|
||
|
|
if (bIsSeparator) then
|
||
|
|
line.spellIconTexture:Hide()
|
||
|
|
line.actionNameFontString:Hide()
|
||
|
|
line.setKeybindButton:Hide()
|
||
|
|
line.clearKeybindButton:Hide()
|
||
|
|
line.editKeybindSettingsButton:Hide()
|
||
|
|
line.separatorTitleText:Show()
|
||
|
|
line.separatorTitleText:SetText(titleText)
|
||
|
|
line.bIsSeparator = true
|
||
|
|
line.backgroundTexture:Hide()
|
||
|
|
else
|
||
|
|
line.spellIconTexture:Show()
|
||
|
|
line.actionNameFontString:Show()
|
||
|
|
line.setKeybindButton:Show()
|
||
|
|
line.clearKeybindButton:Show()
|
||
|
|
line.editKeybindSettingsButton:Show()
|
||
|
|
line.separatorTitleText:Hide()
|
||
|
|
line.bIsSeparator = false
|
||
|
|
line.backgroundTexture:Show()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
---@class df_keybindmixin
|
||
|
|
detailsFramework.KeybindMixin = {
|
||
|
|
bIsListening = false,
|
||
|
|
CurrentKeybindEditingSet = {},
|
||
|
|
|
||
|
|
---and the player change spec, the list of spells will change, hence need to update the keybind list if the panel is open
|
||
|
|
--if isn't open, the keybinds will be updated when the panel is opened
|
||
|
|
OnSpecChanged = function(self, button, newSpecId) --switch_spec
|
||
|
|
--quick hide and show as a feedback to the player that the spec was changed
|
||
|
|
--C_Timer.After (.04, function() EnemyGridOptionsPanelFrameKeybindScroill:Hide() end) --!need to defined the scroll frame
|
||
|
|
--C_Timer.After (.06, function() EnemyGridOptionsPanelFrameKeybindScroill:Show() end) --!need to defined the scroll frame
|
||
|
|
--EnemyGridOptionsPanelFrameKeybindScroill:UpdateScroll() --!need to defined the scroll frame
|
||
|
|
end,
|
||
|
|
|
||
|
|
---return true if the keybindFrame is waiting for the player to press a keybind
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@return boolean bIsListening
|
||
|
|
IsListening = function(self)
|
||
|
|
return self.bIsListening
|
||
|
|
end,
|
||
|
|
|
||
|
|
---return the actionId which the frame is currently listening for a keybind
|
||
|
|
---@param self df_keybindframe
|
||
|
|
GetListeningActionId = function(self)
|
||
|
|
return self.actionId
|
||
|
|
end,
|
||
|
|
|
||
|
|
---set the keybindFrame to listen for a keybind
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param value boolean
|
||
|
|
---@param actionId number?
|
||
|
|
---@param button button?
|
||
|
|
SetListeningState = function(self, value, actionId, button, keybindScrollData)
|
||
|
|
self.bIsListening = value
|
||
|
|
self.actionId = actionId
|
||
|
|
self.button = button
|
||
|
|
self.keybindScrollData = keybindScrollData
|
||
|
|
|
||
|
|
self:SetClearButtonsEnabled(not value)
|
||
|
|
self:SetEditButtonsEnabled(not value)
|
||
|
|
end,
|
||
|
|
|
||
|
|
---get the listening state
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@return boolean
|
||
|
|
---@return number
|
||
|
|
---@return button
|
||
|
|
---@return keybind_scroll_data
|
||
|
|
GetListeningState = function(self)
|
||
|
|
return self.bIsListening, self.actionId, self.button, self.keybindScrollData
|
||
|
|
end,
|
||
|
|
|
||
|
|
---return the frame which wait for keybinds
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@return frame
|
||
|
|
GetKeybindListener = function(self)
|
||
|
|
return self.keybindListener
|
||
|
|
end,
|
||
|
|
|
||
|
|
---get the scroll frame
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@return df_keybindscroll
|
||
|
|
GetKeybindScroll = function(self)
|
||
|
|
return self.keybindScroll
|
||
|
|
end,
|
||
|
|
|
||
|
|
---keybind listener is the frame which reads the key pressed by the player when setting a keybind for an ability
|
||
|
|
CreateKeybindListener = function(self)
|
||
|
|
local keybindListener = CreateFrame ("frame", nil, self, "BackdropTemplate")
|
||
|
|
keybindListener:SetFrameStrata("tooltip")
|
||
|
|
keybindListener:SetSize(200, 60)
|
||
|
|
detailsFramework:ApplyStandardBackdrop(keybindListener)
|
||
|
|
|
||
|
|
self.keybindListener = keybindListener
|
||
|
|
|
||
|
|
keybindListener.text = detailsFramework:CreateLabel(keybindListener, "- Press a keyboard key to bind.\n- Click to bind a mouse button.\n- Press escape to cancel.", 11, "orange")
|
||
|
|
keybindListener.text:SetPoint("center", keybindListener, "center", 0, 0)
|
||
|
|
keybindListener:Hide()
|
||
|
|
end,
|
||
|
|
|
||
|
|
---callback from the clear button
|
||
|
|
---@param self button
|
||
|
|
---@param button any
|
||
|
|
---@param actionIdentifier string
|
||
|
|
---@param keybindTable any
|
||
|
|
ClearKeybind = function(self, button, actionIdentifier, keybindTable) --~clear
|
||
|
|
if (not keybindTable) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
---@type df_keybindframe
|
||
|
|
local keyBindFrame = getMainFrame(self)
|
||
|
|
|
||
|
|
local keybindType, actionId = keyBindFrame:GetKeybindTypeAndActionFromIdentifier(actionIdentifier)
|
||
|
|
local _, index = keyBindFrame:FindKeybindTable(keybindType, actionId, actionIdentifier)
|
||
|
|
|
||
|
|
if (index) then
|
||
|
|
if (keybindType == "macro") then
|
||
|
|
keybindTable.keybind = ""
|
||
|
|
else
|
||
|
|
if (keyBindFrame.options.can_modify_keybind_data) then
|
||
|
|
local keybindData = keyBindFrame:GetKeybindData()
|
||
|
|
table.remove(keybindData, index)
|
||
|
|
end
|
||
|
|
keyBindFrame:CallKeybindChangeCallback("removed", nil, nil, index)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local bIsEditingKeybind = keyBindFrame:IsEditingKeybindSettings()
|
||
|
|
if (bIsEditingKeybind) then
|
||
|
|
keyBindFrame:StopEditingKeybindSettings()
|
||
|
|
end
|
||
|
|
|
||
|
|
local keybindScroll = keyBindFrame:GetKeybindScroll()
|
||
|
|
keybindScroll:UpdateScroll()
|
||
|
|
end,
|
||
|
|
|
||
|
|
---@param self df_keybindframe
|
||
|
|
DeleteMacro = function(self)
|
||
|
|
local bIsEditingKeybind, actionIdentifier, keybindTable = self:IsEditingKeybindSettings()
|
||
|
|
if (not bIsEditingKeybind) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if (not self:IsKeybindActionMacro(keybindTable.action)) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local _, index = self:FindKeybindTable("macro", keybindTable.action, actionIdentifier)
|
||
|
|
|
||
|
|
if (index) then
|
||
|
|
if (self.options.can_modify_keybind_data) then
|
||
|
|
local keybindData = self:GetKeybindData()
|
||
|
|
table.remove(keybindData, index)
|
||
|
|
end
|
||
|
|
|
||
|
|
self:CallKeybindChangeCallback("removed", nil, nil, index)
|
||
|
|
end
|
||
|
|
|
||
|
|
self:StopEditingKeybindSettings()
|
||
|
|
|
||
|
|
local keybindScroll = self:GetKeybindScroll()
|
||
|
|
keybindScroll:UpdateScroll()
|
||
|
|
end,
|
||
|
|
|
||
|
|
---return a string with the modifiers of a keybind
|
||
|
|
---@param keybind string
|
||
|
|
---@return string
|
||
|
|
GetKeybindModifiers = function(keybind)
|
||
|
|
local modifier = ""
|
||
|
|
keybind = string.upper(keybind)
|
||
|
|
|
||
|
|
if (keybind:find("SHIFT-")) then
|
||
|
|
modifier = "SHIFT-"
|
||
|
|
end
|
||
|
|
|
||
|
|
if (keybind:find("CTRL-")) then
|
||
|
|
modifier = modifier .. "CTRL-"
|
||
|
|
end
|
||
|
|
|
||
|
|
if (keybind:find("ALT-")) then
|
||
|
|
modifier = modifier .. "ALT-"
|
||
|
|
end
|
||
|
|
|
||
|
|
return modifier
|
||
|
|
end,
|
||
|
|
|
||
|
|
---return a string with the modifiers of the key pressed by the player
|
||
|
|
---@return string
|
||
|
|
GetPressedModifiers = function()
|
||
|
|
return (IsShiftKeyDown() and "SHIFT-" or "") .. (IsControlKeyDown() and "CTRL-" or "") .. (IsAltKeyDown() and "ALT-" or "")
|
||
|
|
end,
|
||
|
|
|
||
|
|
---comment
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param keybindTable df_keybind
|
||
|
|
---@param pressedKeybind any
|
||
|
|
---@param bKeybindJustCreated boolean
|
||
|
|
SaveKeybindToKeybindData = function(self, keybindTable, pressedKeybind, bKeybindJustCreated)
|
||
|
|
local keybindData = self:GetKeybindData() --from savedVariables
|
||
|
|
|
||
|
|
--if the keybindTable was created by the function which called this function, then need to add the keybind into the saved variables table
|
||
|
|
if (bKeybindJustCreated) then
|
||
|
|
table.insert(keybindData, keybindTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
keybindTable.keybind = pressedKeybind
|
||
|
|
end,
|
||
|
|
|
||
|
|
---return the keybindData table if exists
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param keybindType string
|
||
|
|
---@param actionId any
|
||
|
|
---@param actionIdentifier actionidentifier?
|
||
|
|
---@return df_keybind?, number?
|
||
|
|
FindKeybindTable = function(self, keybindType, actionId, actionIdentifier)
|
||
|
|
local keybindData = self:GetKeybindData()
|
||
|
|
|
||
|
|
if (keybindType == "spell" or keybindType == "system") then
|
||
|
|
for i = 1, #keybindData do
|
||
|
|
local keybindTable = keybindData[i]
|
||
|
|
if (keybindTable.action == actionId) then
|
||
|
|
return keybindTable, i
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if (keybindType == "macro") then
|
||
|
|
for i = 1, #keybindData do
|
||
|
|
local keybindTable = keybindData[i]
|
||
|
|
if (keybindTable.action == actionIdentifier) then
|
||
|
|
return keybindTable, i
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
---comment
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param actionIdentifier any
|
||
|
|
---@return string
|
||
|
|
---@return string|number
|
||
|
|
GetKeybindTypeAndActionFromIdentifier = function(self, actionIdentifier)
|
||
|
|
---@type string, string
|
||
|
|
local keybindType, actionId = actionIdentifier:match("([^%-]+)%-(.+)")
|
||
|
|
if (keybindType == "spell") then
|
||
|
|
return keybindType, tonumber(actionId) and tonumber(actionId) or 0
|
||
|
|
end
|
||
|
|
return keybindType, actionId
|
||
|
|
end,
|
||
|
|
|
||
|
|
---when the user selected a keybind for an action, this function is called
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param keyPressed any keyboard or mouse key to be used to perform the choosen action
|
||
|
|
OnUserPressedKeybind = function(self, keyPressed) --called from OnUserClickedToChooseKeybind and from OnKeyDown() script
|
||
|
|
--if the player presses a control key, ignore it
|
||
|
|
if (ignoredKeys[keyPressed]) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local keybindListener = self:GetKeybindListener()
|
||
|
|
|
||
|
|
--exit the process if 'esc' is pressed
|
||
|
|
if (keyPressed == "ESCAPE") then
|
||
|
|
self:SetListeningState(false)
|
||
|
|
keybindListener:Hide()
|
||
|
|
self:SetScript("OnKeyDown", nil)
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local modifiers = self:GetPressedModifiers()
|
||
|
|
local pressedKeybind = modifiers .. keyPressed
|
||
|
|
local bIsListening, actionIdentifier, button, keybindScrollData = self:GetListeningState()
|
||
|
|
local bKeybindJustCreated = false
|
||
|
|
|
||
|
|
--keybindType can be 'macro', 'spell' or 'system'
|
||
|
|
--actionId can be a spellId, a macro name or some other action like 'target' 'focus' 'togglemenu'
|
||
|
|
local keybindType, actionId = self:GetKeybindTypeAndActionFromIdentifier(actionIdentifier)
|
||
|
|
local keybindTable = self:FindKeybindTable(keybindType, actionId, actionIdentifier)
|
||
|
|
|
||
|
|
if (not keybindTable) then
|
||
|
|
local iconTexture = keybindScrollData[2]
|
||
|
|
--create a new keybindTable
|
||
|
|
if (keybindType == "spell") then
|
||
|
|
local spellId = actionId
|
||
|
|
local spellName = GetSpellInfo(spellId)
|
||
|
|
if (spellName) then
|
||
|
|
--actionId is the spellId
|
||
|
|
keybindTable = createNewKeybindTable(spellName, pressedKeybind, "", actionId, iconTexture)
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif (keybindType == "system") then
|
||
|
|
local defaultKeybind = defaultMouseKeybindsKV[actionId]
|
||
|
|
--actionId is an action like 'target' 'focus' 'togglemenu'
|
||
|
|
keybindTable = createNewKeybindTable(defaultKeybind.name, pressedKeybind, "", actionId, iconTexture)
|
||
|
|
|
||
|
|
elseif (keybindType == "macro") then
|
||
|
|
local macroName = "New Macro"
|
||
|
|
--actionId is the word 'macro'
|
||
|
|
keybindTable = createNewKeybindTable(macroName, pressedKeybind, "/say hi", "macro", iconTexture)
|
||
|
|
end
|
||
|
|
|
||
|
|
bKeybindJustCreated = true
|
||
|
|
end
|
||
|
|
|
||
|
|
if (self.options.can_modify_keybind_data) then
|
||
|
|
--if the options for this frame allows it to change the keybind in the addon savedVariables, then do it
|
||
|
|
self:SaveKeybindToKeybindData(keybindTable, pressedKeybind, bKeybindJustCreated)
|
||
|
|
end
|
||
|
|
|
||
|
|
self:CallKeybindChangeCallback("modified", keybindTable, pressedKeybind)
|
||
|
|
|
||
|
|
self:SetListeningState(false)
|
||
|
|
self:SetScript("OnKeyDown", nil)
|
||
|
|
keybindListener:Hide()
|
||
|
|
|
||
|
|
--dumpt({"modifier", modifier, "newKeybind", newKeybind, "actionId", actionId})
|
||
|
|
|
||
|
|
local keybindScroll = self:GetKeybindScroll()
|
||
|
|
keybindScroll:UpdateScroll()
|
||
|
|
end,
|
||
|
|
|
||
|
|
---callback for when the user click in to define a keybind to an action
|
||
|
|
---@param self df_selectkeybindbutton
|
||
|
|
---@param button any
|
||
|
|
---@param actionIdentifier actionidentifier
|
||
|
|
---@param keybindTable df_keybindframe
|
||
|
|
OnUserClickedToChooseKeybind = function(self, button, actionIdentifier, keybindTable)
|
||
|
|
---@type df_keybindframe
|
||
|
|
local keyBindFrame = getMainFrame(self)
|
||
|
|
local bIsListening, _, frameButton = keyBindFrame:GetListeningState()
|
||
|
|
|
||
|
|
--if the listener is already listening for a keybind while the player clicks on another OnUserClickedToChooseKeybind button, then cancel the previous listener
|
||
|
|
if (bIsListening and (self == frameButton)) then
|
||
|
|
--if the frame is already listening, it could be a mouse click to set the keybind
|
||
|
|
local clickType = mouseButtonToClickType[button]
|
||
|
|
keyBindFrame:OnUserPressedKeybind(clickType)
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
bIsListening = true
|
||
|
|
|
||
|
|
local keybindScrollData = self.keybindScrollData
|
||
|
|
keyBindFrame:SetListeningState(bIsListening, actionIdentifier, self, keybindScrollData)
|
||
|
|
keyBindFrame:SetScript("OnKeyDown", keyBindFrame.OnUserPressedKeybind)
|
||
|
|
|
||
|
|
local keybindListener = keyBindFrame:GetKeybindListener()
|
||
|
|
keybindListener:ClearAllPoints()
|
||
|
|
keybindListener:SetPoint("bottom", self, "top", 0, 0)
|
||
|
|
keybindListener:Show()
|
||
|
|
|
||
|
|
local bIsEditingKeybind = keyBindFrame:IsEditingKeybindSettings()
|
||
|
|
if (bIsEditingKeybind) then
|
||
|
|
keyBindFrame:StopEditingKeybindSettings()
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
SetClearButtonsEnabled = function(self, bIsEnabled)
|
||
|
|
local keybindScroll = self:GetKeybindScroll()
|
||
|
|
local lines = keybindScroll:GetLines()
|
||
|
|
for i = 1, #lines do
|
||
|
|
local line = lines[i]
|
||
|
|
if (bIsEnabled) then
|
||
|
|
--can only set enabled if the keybind isn't empty
|
||
|
|
if (line.setKeybindButton.text ~= "") then
|
||
|
|
line.clearKeybindButton:Enable()
|
||
|
|
end
|
||
|
|
else
|
||
|
|
line.clearKeybindButton:Disable()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
SetEditButtonsEnabled = function(self, bIsEnabled)
|
||
|
|
local keybindScroll = self:GetKeybindScroll()
|
||
|
|
local lines = keybindScroll:GetLines()
|
||
|
|
for i = 1, #lines do
|
||
|
|
local line = lines[i]
|
||
|
|
if (bIsEnabled) then
|
||
|
|
--can only set enabled if the keybind isn't empty
|
||
|
|
if (line.setKeybindButton.text ~= "") then
|
||
|
|
line.editKeybindSettingsButton:Enable()
|
||
|
|
end
|
||
|
|
else
|
||
|
|
line.editKeybindSettingsButton:Disable()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
RefreshKeybindScroll = function(self, scrollData, offset, totalLines) --~refresh
|
||
|
|
local keyBindFrame = getMainFrame(self)
|
||
|
|
|
||
|
|
---@type table<string, any[]>
|
||
|
|
local repeatedKeybinds = {}
|
||
|
|
|
||
|
|
---@cast scrollData keybind_scroll_data[]
|
||
|
|
|
||
|
|
--build a list of repeated keybinds
|
||
|
|
for index = 1, #scrollData do
|
||
|
|
local keybindScrollData = scrollData[index]
|
||
|
|
local actionName, iconTexture, actionId, keybindData, bIsAvailable = unpack(keybindScrollData)
|
||
|
|
---@cast keybindData df_keybind
|
||
|
|
|
||
|
|
if (bIsAvailable) then
|
||
|
|
if (type(keybindData) == "table" and keybindData.keybind and keybindData.keybind ~= "") then
|
||
|
|
repeatedKeybinds[keybindData.keybind] = repeatedKeybinds[keybindData.keybind] or {}
|
||
|
|
table.insert(repeatedKeybinds[keybindData.keybind], keybindData)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
--local bIsListening = keyBindFrame:GetListeningState()
|
||
|
|
--local bIsEditingKeybind = keyBindFrame:IsEditingKeybindSettings()
|
||
|
|
|
||
|
|
local lastKeybindActionType = ""
|
||
|
|
|
||
|
|
--refresh the scroll bar
|
||
|
|
for i = 1, totalLines do
|
||
|
|
local index = i + offset
|
||
|
|
---@type keybind_scroll_data
|
||
|
|
local keybindScrollData = scrollData[index]
|
||
|
|
|
||
|
|
if (keybindScrollData) then
|
||
|
|
local line = self:GetLine(i)
|
||
|
|
|
||
|
|
---@type string, number, any, df_keybind|false, boolean, number, string
|
||
|
|
local actionName, iconTexture, actionId, keybindTable, bIsAvailable, sortNumber, actionIdentifier = unpack(keybindScrollData)
|
||
|
|
|
||
|
|
if (actionName == "@separator") then
|
||
|
|
line:SetAsSeparator(true, iconTexture)
|
||
|
|
else
|
||
|
|
line:SetAsSeparator(false)
|
||
|
|
--if the keybindData doesn't exists, means the user did not set a keybind for this action yet
|
||
|
|
--in this case keybindData is a false boolean
|
||
|
|
--keydindText is the text showing which keyboard or mouse button need to be pressed to activate the action
|
||
|
|
--if the keybind isn't set, use an empty string
|
||
|
|
local keydindText = keybindTable and keybindTable.keybind or ""
|
||
|
|
|
||
|
|
keydindText = keydindText:gsub("type1", _G["LEFT_BUTTON_STRING"])
|
||
|
|
keydindText = keydindText:gsub("type2", _G["RIGHT_BUTTON_STRING"])
|
||
|
|
keydindText = keydindText:gsub("type3", _G["MIDDLE_BUTTON_STRING"])
|
||
|
|
|
||
|
|
if (keydindText:match("type%d")) then
|
||
|
|
local buttonId = keydindText:match("type(%d)")
|
||
|
|
buttonId = tonumber(buttonId)
|
||
|
|
if (buttonId) then
|
||
|
|
local buttonName = _G["BUTTON_" .. buttonId .. "_STRING"]
|
||
|
|
if (buttonName and type(buttonName) == "string") then
|
||
|
|
keydindText = keydindText:gsub("type" .. buttonId, buttonName)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
keydindText = keydindText:gsub("%-", " - ")
|
||
|
|
|
||
|
|
line.setKeybindButton.text = keydindText
|
||
|
|
|
||
|
|
--start editing keybind button
|
||
|
|
line.setKeybindButton:SetClickFunction(keyBindFrame.OnUserClickedToChooseKeybind, actionIdentifier, keybindTable, "left")
|
||
|
|
line.setKeybindButton:SetClickFunction(keyBindFrame.OnUserClickedToChooseKeybind, actionIdentifier, keybindTable, "right")
|
||
|
|
|
||
|
|
--clear keybind button
|
||
|
|
if (keydindText ~= "") then
|
||
|
|
line.clearKeybindButton:Enable()
|
||
|
|
line.clearKeybindButton:SetClickFunction(keyBindFrame.ClearKeybind, actionIdentifier, keybindTable)
|
||
|
|
line.editKeybindSettingsButton:Enable()
|
||
|
|
line.editKeybindSettingsButton:SetClickFunction(keyBindFrame.StartEditingKeybindSettings, actionIdentifier, keybindTable)
|
||
|
|
else
|
||
|
|
line.clearKeybindButton:Disable()
|
||
|
|
line.editKeybindSettingsButton:Disable()
|
||
|
|
end
|
||
|
|
|
||
|
|
local setKeybindButtonWidget = line.setKeybindButton.widget
|
||
|
|
setKeybindButtonWidget.keybindScrollData = keybindScrollData
|
||
|
|
|
||
|
|
line.spellIconTexture:SetTexture(iconTexture)
|
||
|
|
|
||
|
|
if (not bIsAvailable) then
|
||
|
|
line.spellIconTexture:SetDesaturated(true)
|
||
|
|
line.setKeybindButton.widget:SetColor(0, 0, 0, 0.1)
|
||
|
|
detailsFramework:SetFontColor(line.actionNameFontString, "gray")
|
||
|
|
else
|
||
|
|
line.spellIconTexture:SetDesaturated(false)
|
||
|
|
line.setKeybindButton.widget:SetColor(unpack(roundedCornerPreset.color))
|
||
|
|
detailsFramework:SetFontColor(line.actionNameFontString, "BLIZZ_OPTIONS_COLOR")
|
||
|
|
end
|
||
|
|
|
||
|
|
line.spellIconTexture:SetTexCoord(.1, .9, .1, .9)
|
||
|
|
line.actionNameFontString:SetText(actionName)
|
||
|
|
|
||
|
|
line.setKeybindButton.widget:SetBorderCornerColor(0, 0, 0, 0)
|
||
|
|
|
||
|
|
--check for repeated keybind
|
||
|
|
if (keybindTable and bIsAvailable) then
|
||
|
|
local keybind = keybindTable.keybind
|
||
|
|
local keybindTables = repeatedKeybinds[keybind]
|
||
|
|
if (keybindTables and #keybindTables > 1) then
|
||
|
|
line.setKeybindButton.widget:SetBorderCornerColor(1, .68, 0, 1)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
---run when the mouse enters a scroll line
|
||
|
|
---@param self df_keybindscrollline
|
||
|
|
OnEnterScrollLine = function(self)
|
||
|
|
local keyBindFrame = getMainFrame(self)
|
||
|
|
local editPanel = keyBindFrame:GetEditPanel()
|
||
|
|
editPanel.conditionsFailLoadReasonText:SetText("")
|
||
|
|
|
||
|
|
if (self.bIsSeparator) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if (not self.keybindScrollLine) then
|
||
|
|
--when the mouse enters a child frame, the self is the child frame, not the scroll line
|
||
|
|
self = self:GetParent() ---@diagnostic disable-line getting the parent from df_keybindscrollline would result in type frame making invalid convertion
|
||
|
|
---@cast self df_keybindscrollline
|
||
|
|
end
|
||
|
|
|
||
|
|
self.highlightTexture:Show()
|
||
|
|
|
||
|
|
--if the keybind is a macro, preview the macro text in the edit panel's lua edit box
|
||
|
|
local bIsEditingKeybind = keyBindFrame:IsEditingKeybindSettings()
|
||
|
|
|
||
|
|
if (not bIsEditingKeybind) then
|
||
|
|
local keybindScrollData = self.setKeybindButton.widget["keybindScrollData"]
|
||
|
|
if (keybindScrollData) then
|
||
|
|
local actionName, iconTexture, actionId, keybindTable, bIsAvailable, sortNumber, actionIdentifier = unpack(keybindScrollData)
|
||
|
|
---@cast keybindTable df_keybind
|
||
|
|
if (actionName ~= "@separator" and keybindTable) then
|
||
|
|
if (keybindTable.macro and keybindTable.macro ~= "") then
|
||
|
|
---@type df_editkeybindframe
|
||
|
|
editPanel.editMacroEditBox:SetText(keybindTable.macro)
|
||
|
|
end
|
||
|
|
|
||
|
|
local loadCondition = keybindTable.conditions
|
||
|
|
local bCanLoad, reason = detailsFramework:PassLoadFilters(loadCondition)
|
||
|
|
|
||
|
|
if (not bCanLoad) then
|
||
|
|
editPanel.conditionsFailLoadReasonText:SetText("This keybind can't be loaded because it's conditions are not met:\n- " .. (reason or ""))
|
||
|
|
else
|
||
|
|
editPanel.conditionsFailLoadReasonText:SetText("")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
---run when the mouse leaves a scroll line
|
||
|
|
---@param self df_keybindscrollline
|
||
|
|
OnLeaveScrollLine = function(self)
|
||
|
|
if (self.bIsSeparator) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if (not self.keybindScrollLine) then
|
||
|
|
--when the mouse enters a child frame, the self is the child frame, not the scroll line
|
||
|
|
self = self:GetParent() ---@diagnostic disable-line getting the parent from df_keybindscrollline would result in type frame making invalid convertion
|
||
|
|
---@cast self df_keybindscrollline
|
||
|
|
end
|
||
|
|
|
||
|
|
self.highlightTexture:Hide()
|
||
|
|
|
||
|
|
--if the keybind is a macro, a preview might be showing in the edit panel's lua edit box, hide it
|
||
|
|
local keyBindFrame = getMainFrame(self)
|
||
|
|
local bIsEditingKeybind = keyBindFrame:IsEditingKeybindSettings()
|
||
|
|
|
||
|
|
if (not bIsEditingKeybind) then
|
||
|
|
local editPanel = keyBindFrame:GetEditPanel()
|
||
|
|
editPanel.editMacroEditBox:SetText("")
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
---@param keybindScroll frame
|
||
|
|
---@param index number
|
||
|
|
CreateKeybindScrollLine = function(keybindScroll, index) --~create
|
||
|
|
local keyBindFrame = getMainFrame(keybindScroll)
|
||
|
|
|
||
|
|
---@type df_keybindscrollline
|
||
|
|
local line = CreateFrame("frame", "$parentLine" .. index, keybindScroll)
|
||
|
|
line:SetSize(keyBindFrame.options.width - 10, keyBindFrame.options.line_height)
|
||
|
|
line:SetPoint("topleft", keyBindFrame, "topleft", 1, -22 - (index-1) * keyBindFrame.options.line_height)
|
||
|
|
line:EnableMouse(true)
|
||
|
|
line.keybindScrollLine = true
|
||
|
|
|
||
|
|
--detailsFramework:ApplyStandardBackdrop(line, index % 2 == 0)
|
||
|
|
--line:SetBackdropBorderColor(0, 0, 0, 0)
|
||
|
|
|
||
|
|
line.backgroundTexture = line:CreateTexture("$parentBackgroundTexture", "background")
|
||
|
|
line.backgroundTexture:SetAllPoints()
|
||
|
|
|
||
|
|
if (index % 2 == 0) then
|
||
|
|
line.backgroundTexture:SetColorTexture(0, 0, 0, 0.1)
|
||
|
|
else
|
||
|
|
line.backgroundTexture:SetColorTexture(0, 0, 0, 0)
|
||
|
|
end
|
||
|
|
|
||
|
|
line.highlightTexture = line:CreateTexture(nil, "border")
|
||
|
|
line.highlightTexture:SetAllPoints()
|
||
|
|
line.highlightTexture:SetColorTexture(1, 1, 1, .1)
|
||
|
|
line.highlightTexture:Hide()
|
||
|
|
|
||
|
|
line:SetScript("OnEnter", keyBindFrame.OnEnterScrollLine)
|
||
|
|
line:SetScript("OnLeave", keyBindFrame.OnLeaveScrollLine)
|
||
|
|
|
||
|
|
detailsFramework:Mixin(line, detailsFramework.HeaderFunctions)
|
||
|
|
|
||
|
|
local options_text_template = detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||
|
|
local options_dropdown_template = detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||
|
|
local options_switch_template = detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||
|
|
local options_slider_template = detailsFramework:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||
|
|
local options_button_template = detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||
|
|
|
||
|
|
line.separatorTitleText = line:CreateFontString("$parentSeparatorTitleText", "overlay", "GameFontNormal")
|
||
|
|
line.separatorTitleText:SetPoint("center", line, "center", 0, 0)
|
||
|
|
|
||
|
|
line.spellIconTexture = line:CreateTexture("$parentIcon", "overlay")
|
||
|
|
line.spellIconTexture:SetSize(keyBindFrame.options.line_height - 2, keyBindFrame.options.line_height - 2)
|
||
|
|
|
||
|
|
line.actionNameFontString = line:CreateFontString("$parentName", "overlay", "GameFontNormal")
|
||
|
|
detailsFramework:SetFontColor(line.actionNameFontString, "BLIZZ_OPTIONS_COLOR")
|
||
|
|
detailsFramework:SetFontSize(line.actionNameFontString, 12)
|
||
|
|
|
||
|
|
---@type df_button
|
||
|
|
line.setKeybindButton = detailsFramework:CreateButton(line, function()end, headerTable[3].width, keyBindFrame.options.line_height-6, "", nil, nil, nil, "SetNewKeybindButton", "$parentSetNewKeybindButton", 0, nil, options_text_template)
|
||
|
|
line.setKeybindButton.textcolor = "white"
|
||
|
|
line.setKeybindButton.textsize = 10
|
||
|
|
line.setKeybindButton:SetHook("OnEnter", keyBindFrame.OnEnterScrollLine)
|
||
|
|
line.setKeybindButton:SetHook("OnLeave", keyBindFrame.OnLeaveScrollLine)
|
||
|
|
|
||
|
|
detailsFramework:AddRoundedCornersToFrame(line.setKeybindButton, roundedCornerPreset)
|
||
|
|
|
||
|
|
---@type df_button
|
||
|
|
line.clearKeybindButton = detailsFramework:CreateButton(line, keyBindFrame.ClearKeybind, 16, keyBindFrame.options.line_height-2, "", nil, nil, nil, "DeleteKeybindButton", "$parentDeleteKeybindButton", 2, nil, options_text_template)
|
||
|
|
line.clearKeybindButton:SetBackdropBorderColor(0, 0, 0, 0)
|
||
|
|
line.clearKeybindButton:SetIcon([[Interface\COMMON\CommonIcons]], nil, nil, nil, {0.1264, 0.2514, 0.5048, 0.7548}, nil, nil, 4)
|
||
|
|
|
||
|
|
---@type df_button
|
||
|
|
line.editKeybindSettingsButton = detailsFramework:CreateButton(line, keyBindFrame.StartEditingKeybindSettings, 16, keyBindFrame.options.line_height-2, "", nil, nil, nil, "EditKeybindButton", "$parentEditKeybindButton", 2, nil, options_text_template)
|
||
|
|
line.editKeybindSettingsButton:SetBackdropBorderColor(0, 0, 0, 0)
|
||
|
|
line.editKeybindSettingsButton:SetIcon([[Interface\BUTTONS\UI-GuildButton-PublicNote-Disabled]])
|
||
|
|
|
||
|
|
line:AddFrameToHeaderAlignment(line.spellIconTexture)
|
||
|
|
line:AddFrameToHeaderAlignment(line.actionNameFontString)
|
||
|
|
line:AddFrameToHeaderAlignment(line.setKeybindButton)
|
||
|
|
line:AddFrameToHeaderAlignment(line.clearKeybindButton)
|
||
|
|
line:AddFrameToHeaderAlignment(line.editKeybindSettingsButton)
|
||
|
|
|
||
|
|
line:AlignWithHeader(keyBindFrame.Header, "left")
|
||
|
|
|
||
|
|
line.SetAsSeparator = setAsSeparator
|
||
|
|
|
||
|
|
return line
|
||
|
|
end,
|
||
|
|
|
||
|
|
---comment
|
||
|
|
---@param self df_keybindframe
|
||
|
|
CreateKeybindScroll = function(self) --~scroll
|
||
|
|
local scroll_width = self.options.scroll_width
|
||
|
|
local scroll_height = self.options.scroll_height
|
||
|
|
local scroll_lines = self.options.amount_lines
|
||
|
|
local scroll_line_height = self.options.line_height
|
||
|
|
|
||
|
|
--~header
|
||
|
|
---@type df_headerframe
|
||
|
|
self.Header = DetailsFramework:CreateHeader(self, headerTable, headerOptions)
|
||
|
|
self.Header:SetPoint("topleft", self, "topleft", 0, 0)
|
||
|
|
|
||
|
|
local onClickCreateMacroButton = function() --~macro
|
||
|
|
local newMacroName = "New @Macro (" .. math.random(10000, 99999) .. ")"
|
||
|
|
local actionIdentifier = "macro-" .. newMacroName
|
||
|
|
|
||
|
|
local keybindTable = createNewKeybindTable(newMacroName, "", "/say Hi", actionIdentifier, 136377)
|
||
|
|
local pressedKeybind = ""
|
||
|
|
|
||
|
|
if (self.options.can_modify_keybind_data) then
|
||
|
|
--if the options for this frame allows it to change the keybind in the addon savedVariables, then do it
|
||
|
|
local bKeybindJustCreated = true
|
||
|
|
self:SaveKeybindToKeybindData(keybindTable, pressedKeybind, bKeybindJustCreated)
|
||
|
|
end
|
||
|
|
|
||
|
|
self:CallKeybindChangeCallback("modified", keybindTable, pressedKeybind)
|
||
|
|
|
||
|
|
local keybindScroll = self:GetKeybindScroll()
|
||
|
|
keybindScroll:UpdateScroll()
|
||
|
|
|
||
|
|
--start editing this keybindTable
|
||
|
|
self:StartEditingKeybindSettings("LeftButton", actionIdentifier, keybindTable)
|
||
|
|
|
||
|
|
--get the keybind editor frame
|
||
|
|
---@type df_editkeybindframe
|
||
|
|
local keybindEditor = self:GetEditPanel()
|
||
|
|
|
||
|
|
local macroEditBox = keybindEditor.editMacroEditBox
|
||
|
|
macroEditBox:SetText(keybindTable.macro)
|
||
|
|
macroEditBox:SetFocus()
|
||
|
|
end
|
||
|
|
|
||
|
|
local createMacroButton = detailsFramework:CreateButton(self.Header, onClickCreateMacroButton, 100, 20, "Create Macro Keybind", nil, nil, nil, "CreateMacroButton", "$parentCreateMacroButton", 0, DARK_BUTTON_TEMPLATE, detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE"))
|
||
|
|
createMacroButton:SetPoint("left", self.Header, "left", 0, 0)
|
||
|
|
createMacroButton:SetFrameLevel(self.Header:GetFrameLevel()+10)
|
||
|
|
createMacroButton:SetIcon(136377)
|
||
|
|
|
||
|
|
local keybindScroll = detailsFramework:CreateScrollBox(self, "$parentScrollBox", detailsFramework.KeybindMixin.RefreshKeybindScroll, {}, scroll_width, scroll_height, scroll_lines, scroll_line_height)
|
||
|
|
---@cast keybindScroll df_keybindscroll
|
||
|
|
|
||
|
|
detailsFramework:ReskinSlider(keybindScroll)
|
||
|
|
keybindScroll:SetPoint("topleft", self.Header, "bottomleft", 0, -5)
|
||
|
|
self.keybindScroll = keybindScroll
|
||
|
|
|
||
|
|
keybindScroll:SetBackdropColor(0, 0, 0, 0)
|
||
|
|
keybindScroll:SetBackdropBorderColor(0, 0, 0, 0)
|
||
|
|
keybindScroll.__background:SetAlpha(0)
|
||
|
|
|
||
|
|
for i = 1, scroll_lines do
|
||
|
|
keybindScroll:CreateLine(self.CreateKeybindScrollLine)
|
||
|
|
end
|
||
|
|
|
||
|
|
--scroll data constructor
|
||
|
|
function keybindScroll.UpdateScroll() --~update
|
||
|
|
--keybind data from saved variables
|
||
|
|
---@type df_keybind[]
|
||
|
|
local data = self:GetKeybindData()
|
||
|
|
|
||
|
|
--pre build keybind data to be used by the scroll data constructor
|
||
|
|
---@type table<any, df_keybind>
|
||
|
|
local keybindDataParsed = {}
|
||
|
|
|
||
|
|
---@type df_keybind[]
|
||
|
|
local allKeybindMacros = {}
|
||
|
|
|
||
|
|
--iterage amoung keybinds already set by the user
|
||
|
|
--and fill the tables 'keybindDataParsed' where the key is actionId and the value is the keybind data
|
||
|
|
--also fill the table 'allKeybindMacros' with all macros, this is an array with keybind data
|
||
|
|
for i = 1, #data do
|
||
|
|
---@type df_keybind
|
||
|
|
local keybindData = data[i]
|
||
|
|
|
||
|
|
local actionId = keybindData.action --the actionId can be "macro" for macros
|
||
|
|
local keybind = keybindData.keybind --the keybind to active the action
|
||
|
|
local macro = keybindData.macro --macro here is the macro text
|
||
|
|
local name = keybindData.name --for macros it shows the macro name where the spellName is for instance
|
||
|
|
local icon = keybindData.icon --for macros the user can set an icon
|
||
|
|
local conditions = keybindData.conditions --allows the user to set conditions for the keybind to be active
|
||
|
|
|
||
|
|
local bIsSpell = actionId and type(actionId) == "number"
|
||
|
|
if (bIsSpell) then
|
||
|
|
local spellId = actionId
|
||
|
|
keybindDataParsed[spellId] = keybindData
|
||
|
|
|
||
|
|
elseif (defaultMouseKeybindsKV[actionId]) then
|
||
|
|
keybindDataParsed[actionId] = keybindData --"target" "focus" "togglemenu"
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
if (type(actionId) == "string" and self:IsKeybindActionMacro(actionId)) then
|
||
|
|
table.insert(allKeybindMacros, keybindData)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
---@type keybind_scroll_data[]
|
||
|
|
local scrollData = {}
|
||
|
|
|
||
|
|
---@type keybind_scroll_data[] store spells that are not available, they are added after the spells available
|
||
|
|
local spellsNotAvailable = {}
|
||
|
|
|
||
|
|
---@type keybind_scroll_data[] store macros that are not available, they are added after the spells available
|
||
|
|
local macrosNotAvailable = {}
|
||
|
|
|
||
|
|
table.insert(scrollData, {"@separator", "Regualar Actions", "", "", false, -1})
|
||
|
|
|
||
|
|
if (self.options.show_unitcontrols) then
|
||
|
|
for i, mouseActionKeyInfo in ipairs(defaultMouseKeybinds) do
|
||
|
|
local mouseActionId = mouseActionKeyInfo.action
|
||
|
|
local mouseDefaultKeybind = mouseActionKeyInfo.keybind
|
||
|
|
local mouseIcon = mouseActionKeyInfo.icon
|
||
|
|
local mouseActionName = mouseActionKeyInfo.name
|
||
|
|
|
||
|
|
local keybindData = keybindDataParsed[mouseActionId]
|
||
|
|
local actionIdentifier = "system-" .. mouseActionId
|
||
|
|
|
||
|
|
local thisScrollData = {keybindData and keybindData.name or mouseActionName, keybindData and keybindData.icon or mouseIcon, mouseActionId, keybindData or false, true, 0, actionIdentifier}
|
||
|
|
table.insert(scrollData, 1+i, thisScrollData)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
table.insert(scrollData, {"@separator", "Macros", "", "", false, 1})
|
||
|
|
|
||
|
|
if (self.options.show_macros) then
|
||
|
|
--sort the table alphabetically
|
||
|
|
table.sort(allKeybindMacros, function(t1, t2) return t1.name < t2.name end)
|
||
|
|
|
||
|
|
for i, keybindData in ipairs(allKeybindMacros) do
|
||
|
|
local macroName = keybindData.name
|
||
|
|
local macroIcon = keybindData.icon
|
||
|
|
local macroText = keybindData.macro
|
||
|
|
local actionId = keybindData.action
|
||
|
|
local conditions = keybindData.conditions
|
||
|
|
|
||
|
|
local bCanLoad = detailsFramework:PassLoadFilters(conditions)
|
||
|
|
local sortScore = 2
|
||
|
|
|
||
|
|
local actionIdentifier = actionId
|
||
|
|
|
||
|
|
---@type keybind_scroll_data
|
||
|
|
local thisScrollData = {macroName, macroIcon, actionId, keybindData, bCanLoad, sortScore, actionIdentifier}
|
||
|
|
if (bCanLoad) then
|
||
|
|
table.insert(scrollData, thisScrollData)
|
||
|
|
else
|
||
|
|
table.insert(macrosNotAvailable, thisScrollData)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
table.insert(scrollData, {"@separator", "Spells", "", "", false, 3})
|
||
|
|
|
||
|
|
local indexToAddNotAvailableMacros = #scrollData + 1
|
||
|
|
|
||
|
|
if (self.options.show_spells) then
|
||
|
|
--the a list of all spells
|
||
|
|
local allPlayerSpells = detailsFramework:GetAvailableSpells()
|
||
|
|
--bIsAvailable is a boolean that tells if the spell is from the spec the player is currently using (spells grayed out on the spellbook would be false here)
|
||
|
|
for spellId, bIsAvailable in pairs(allPlayerSpells) do
|
||
|
|
local spellName, _, spellIcon = GetSpellInfo(spellId)
|
||
|
|
if (spellName) then
|
||
|
|
---@type df_keybind|nil
|
||
|
|
local keybindData = keybindDataParsed[spellId] --could be nil if doesn't exists
|
||
|
|
|
||
|
|
--show spells with keybinds at the top of the list, then show spells that are available, then show spells that are not available
|
||
|
|
--always sub sorting by the spell name
|
||
|
|
local sortScore = getSpellSortOrder(keybindData, spellName, bIsAvailable)
|
||
|
|
local actionId = spellId
|
||
|
|
|
||
|
|
local actionIdentifier = "spell-" .. actionId
|
||
|
|
|
||
|
|
---@type keybind_scroll_data
|
||
|
|
local thisScrollData = {keybindData and keybindData.name or spellName, keybindData and keybindData.icon or spellIcon, actionId, keybindData or false, bIsAvailable, sortScore, actionIdentifier}
|
||
|
|
|
||
|
|
if (not bIsAvailable) then
|
||
|
|
spellsNotAvailable[#spellsNotAvailable+1] = thisScrollData
|
||
|
|
else
|
||
|
|
scrollData[#scrollData+1] = thisScrollData
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
table.sort(scrollData, function(a, b) return a[6] < b[6] end)
|
||
|
|
table.sort(spellsNotAvailable, function(a, b) return a[6] < b[6] end)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (#macrosNotAvailable > 0) then
|
||
|
|
table.insert(scrollData, {"@separator", "Macros Not Available", "", "", false, 1})
|
||
|
|
|
||
|
|
for i = 1, #macrosNotAvailable do
|
||
|
|
local thisScrollData = macrosNotAvailable[i]
|
||
|
|
table.insert(scrollData, thisScrollData)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if (#spellsNotAvailable > 0) then
|
||
|
|
table.insert(scrollData, {"@separator", "Spells Not Available", "", "", false, 3})
|
||
|
|
|
||
|
|
for i = 1, #spellsNotAvailable do
|
||
|
|
local thisScrollData = spellsNotAvailable[i]
|
||
|
|
table.insert(scrollData, thisScrollData)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
keybindScroll:SetData(scrollData)
|
||
|
|
keybindScroll:Refresh()
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
---return the keybind data
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@return df_keybind[]
|
||
|
|
GetKeybindData = function(self)
|
||
|
|
return self.data
|
||
|
|
end,
|
||
|
|
|
||
|
|
---set the keybind data from a profile
|
||
|
|
---data consists in a table where the actionId (any) is the key and the value is the keybind (string)
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param newData df_keybind[]
|
||
|
|
SetKeybindData = function(self, newData)
|
||
|
|
self.data = newData
|
||
|
|
local keybindScroll = self:GetKeybindScroll()
|
||
|
|
keybindScroll:UpdateScroll()
|
||
|
|
end,
|
||
|
|
|
||
|
|
---set the callback function to be called when the player set or clear a keybind
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param callback function
|
||
|
|
SetKeybindCallback = function(self, callback)
|
||
|
|
self.callback = callback
|
||
|
|
local keybindScroll = self:GetKeybindScroll()
|
||
|
|
keybindScroll:UpdateScroll()
|
||
|
|
end,
|
||
|
|
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@return function
|
||
|
|
GetKeybindCallback = function(self)
|
||
|
|
return self.callback
|
||
|
|
end,
|
||
|
|
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param type string "modified", "removed", "conditions", "name"
|
||
|
|
---@param keybindTable df_keybind?
|
||
|
|
---@param keybindPressed string?
|
||
|
|
---@param removedIndex number?
|
||
|
|
---@param macroText string?
|
||
|
|
CallKeybindChangeCallback = function(self, type, keybindTable, keybindPressed, removedIndex, macroText)
|
||
|
|
local callbackFunc = self:GetKeybindCallback()
|
||
|
|
if (callbackFunc) then
|
||
|
|
detailsFramework:Dispatch(callbackFunc, self, type, keybindTable, keybindPressed, removedIndex, macroText)
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param actionId any
|
||
|
|
IsKeybindActionMacro = function(self, actionId)
|
||
|
|
if (type(actionId) == "string") then
|
||
|
|
return actionId:match("^macro%-")
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
---on press enter on the edit frame name editbox
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param newName string
|
||
|
|
OnKeybindNameChange = function(self, newName)
|
||
|
|
local editFrame = self:GetEditPanel()
|
||
|
|
local keybindTable = editFrame.keybindTable
|
||
|
|
|
||
|
|
local actionId = keybindTable.action
|
||
|
|
---@cast actionId string
|
||
|
|
|
||
|
|
keybindTable.name = newName
|
||
|
|
|
||
|
|
if (self:IsKeybindActionMacro(actionId)) then
|
||
|
|
keybindTable.action = "macro-" .. newName
|
||
|
|
end
|
||
|
|
|
||
|
|
self:CallKeybindChangeCallback("name", keybindTable)
|
||
|
|
|
||
|
|
local keybindScroll = self:GetKeybindScroll()
|
||
|
|
keybindScroll:UpdateScroll()
|
||
|
|
end,
|
||
|
|
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@param macroText string
|
||
|
|
OnKeybindMacroChange = function(self, macroText)
|
||
|
|
---@type df_keybindframe
|
||
|
|
local keyBindFrame = getMainFrame(self)
|
||
|
|
|
||
|
|
local editFrame = keyBindFrame:GetEditPanel()
|
||
|
|
local keybindTable = editFrame.keybindTable
|
||
|
|
|
||
|
|
if (keyBindFrame.options.can_modify_keybind_data) then
|
||
|
|
keybindTable.macro = macroText
|
||
|
|
end
|
||
|
|
|
||
|
|
keyBindFrame:CallKeybindChangeCallback("macro", keybindTable, nil, nil, macroText)
|
||
|
|
end,
|
||
|
|
|
||
|
|
OnKeybindIconChange = function(self, texture)
|
||
|
|
local editFrame = self:GetEditPanel()
|
||
|
|
local keybindTable = editFrame.keybindTable
|
||
|
|
keybindTable.icon = texture
|
||
|
|
self:CallKeybindChangeCallback("icon", keybindTable)
|
||
|
|
end,
|
||
|
|
|
||
|
|
---return true if the user is editing a keybind
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@return boolean bIsEditing
|
||
|
|
---@return string actionIdentifier
|
||
|
|
---@return df_keybind keybindTable
|
||
|
|
IsEditingKeybindSettings = function(self)
|
||
|
|
local editFrame = self:GetEditPanel()
|
||
|
|
return editFrame.bIsEditing, editFrame.actionIdentifier, editFrame.keybindTable
|
||
|
|
end,
|
||
|
|
|
||
|
|
---start editing the keybind settings
|
||
|
|
---@param self frame
|
||
|
|
---@param button string
|
||
|
|
---@param actionIdentifier string
|
||
|
|
---@param keybindTable df_keybind
|
||
|
|
StartEditingKeybindSettings = function(self, button, actionIdentifier, keybindTable)
|
||
|
|
---@type df_keybindframe
|
||
|
|
local keyBindFrame = getMainFrame(self)
|
||
|
|
|
||
|
|
local bIsListening = keyBindFrame:GetListeningState()
|
||
|
|
if (bIsListening) then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local editFrame = keyBindFrame:GetEditPanel()
|
||
|
|
editFrame:Enable()
|
||
|
|
|
||
|
|
editFrame.nameEditBox:SetText(keybindTable.name)
|
||
|
|
editFrame.iconPickerButton:SetIcon(keybindTable.icon)
|
||
|
|
|
||
|
|
local actionId = keybindTable.action
|
||
|
|
---@cast actionId string
|
||
|
|
if (keyBindFrame:IsKeybindActionMacro(actionId)) then
|
||
|
|
editFrame.editMacroEditBox:SetText(keybindTable.macro)
|
||
|
|
editFrame.deleteMacroButton:Enable()
|
||
|
|
else
|
||
|
|
editFrame.editMacroEditBox:Disable()
|
||
|
|
editFrame.deleteMacroButton:Disable()
|
||
|
|
end
|
||
|
|
|
||
|
|
editFrame.actionIdentifier = actionIdentifier
|
||
|
|
editFrame.keybindTable = keybindTable
|
||
|
|
editFrame.bIsEditing = true
|
||
|
|
end,
|
||
|
|
|
||
|
|
---disable and clear all entries in the edit frame
|
||
|
|
---@param self df_keybindframe
|
||
|
|
StopEditingKeybindSettings = function(self)
|
||
|
|
local editFrame = self:GetEditPanel()
|
||
|
|
editFrame.bIsEditing = false
|
||
|
|
editFrame.actionIdentifier = nil
|
||
|
|
editFrame.keybindTable = nil
|
||
|
|
editFrame:Disable()
|
||
|
|
end,
|
||
|
|
|
||
|
|
---return the editing keybind frame
|
||
|
|
---@param self df_keybindframe
|
||
|
|
---@return df_editkeybindframe
|
||
|
|
GetEditPanel = function(self)
|
||
|
|
return self.editKeybindFrame
|
||
|
|
end,
|
||
|
|
|
||
|
|
---@param self df_keybindframe
|
||
|
|
CreateEditPanel = function(self) --~edit
|
||
|
|
local options_text_template = detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
|
||
|
|
local options_dropdown_template = detailsFramework:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
|
||
|
|
local options_switch_template = detailsFramework:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
|
||
|
|
local options_slider_template = detailsFramework:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
|
||
|
|
local options_button_template = detailsFramework:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
|
||
|
|
|
||
|
|
---@type df_editkeybindframe
|
||
|
|
local editFrame = CreateFrame("frame", "$parentEditPanel", self, "BackdropTemplate")
|
||
|
|
editFrame:SetSize(self.options.edit_width, self.options.edit_height)
|
||
|
|
editFrame:SetPoint("topleft", self, "topright", 28, 0) --give space for the scrollbar
|
||
|
|
self.editKeybindFrame = editFrame
|
||
|
|
|
||
|
|
--name
|
||
|
|
local nameText = editFrame:CreateFontString("$parentNameText", "overlay", "GameFontNormal")
|
||
|
|
nameText:SetPoint("topleft", editFrame, "topleft", 10, -10)
|
||
|
|
nameText:SetText("Name:")
|
||
|
|
detailsFramework:SetFontColor(nameText, "BLIZZ_OPTIONS_COLOR")
|
||
|
|
|
||
|
|
local nameEditBoxCallback = function(param1, param2, text)
|
||
|
|
--print("name change", param1, param2, text)
|
||
|
|
--self:OnKeybindNameChange(text)
|
||
|
|
end
|
||
|
|
local nameEditBox = detailsFramework:CreateTextEntry(editFrame, nameEditBoxCallback, 200, 20, "nameEditBox", "$parentNameEditBox", nil, options_dropdown_template)
|
||
|
|
nameEditBox:SetPoint("topleft", nameText, "bottomleft", 0, -5)
|
||
|
|
nameEditBox:SetBackdropColor(.1, .1, .1, .834)
|
||
|
|
nameEditBox:SetJustifyH("left")
|
||
|
|
nameEditBox:SetTextInsets(5, 3, 0, 0)
|
||
|
|
|
||
|
|
--icon
|
||
|
|
local iconText = editFrame:CreateFontString("$parentIconText", "overlay", "GameFontNormal")
|
||
|
|
iconText:SetPoint("topleft", nameEditBox.widget, "bottomleft", 0, -10)
|
||
|
|
iconText:SetText("Icon:")
|
||
|
|
detailsFramework:SetFontColor(iconText, "BLIZZ_OPTIONS_COLOR")
|
||
|
|
|
||
|
|
local iconPickerButtonCallback = function(texture)
|
||
|
|
editFrame.iconPickerButton:SetIcon(texture)
|
||
|
|
--self:OnKeybindIconChange(texture)
|
||
|
|
end
|
||
|
|
|
||
|
|
local iconPickerButton = detailsFramework:CreateButton(editFrame, function() detailsFramework:IconPick(iconPickerButtonCallback, true) end, 20, 20, "", nil, nil, nil, "iconPickerButton", "$parentIconPickerButton", 0, DARK_BUTTON_TEMPLATE, detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE"))
|
||
|
|
iconPickerButton:SetPoint("topleft", iconText, "bottomleft", 0, -5)
|
||
|
|
iconPickerButton:SetIcon([[]], nil, nil, nil, {0.1264, 0.2514, 0.5048, 0.7548}, nil, nil, 4)
|
||
|
|
iconPickerButton.tooltip = "pick an icon"
|
||
|
|
|
||
|
|
--macro
|
||
|
|
local editMacroText = editFrame:CreateFontString("$parentEditMacroText", "overlay", "GameFontNormal")
|
||
|
|
editMacroText:SetPoint("topleft", iconPickerButton.widget, "bottomleft", 0, -10)
|
||
|
|
editMacroText:SetText("Macro:")
|
||
|
|
detailsFramework:SetFontColor(editMacroText, "BLIZZ_OPTIONS_COLOR")
|
||
|
|
|
||
|
|
---@type df_luaeditor
|
||
|
|
local editMacroEditBox = detailsFramework:NewSpecialLuaEditorEntry(editFrame, self.options.edit_width-35, 200, "editMacroEditBox", "$parentEditMacroEditBox", true)
|
||
|
|
editMacroEditBox:SetBackdrop ({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
|
||
|
|
editMacroEditBox:SetBackdropBorderColor(0, 0, 0, 1)
|
||
|
|
editMacroEditBox:SetBackdropColor(.1, .1, .1, .5)
|
||
|
|
detailsFramework:ReskinSlider(editMacroEditBox.scroll)
|
||
|
|
editMacroEditBox:SetPoint("topleft", editMacroText, "bottomleft", 0, -5)
|
||
|
|
|
||
|
|
editMacroEditBox["Center"]:SetColorTexture(.1, .1, .1, .834)
|
||
|
|
|
||
|
|
local saveButtonCallback = function()
|
||
|
|
local bIsEditing, actionIdentifier, keybindTable = self:IsEditingKeybindSettings()
|
||
|
|
if (bIsEditing and keybindTable) then
|
||
|
|
local keybindName = nameEditBox:GetText()
|
||
|
|
local iconTexture = editFrame.iconPickerButton.icon
|
||
|
|
local keybindTexture = iconTexture:GetTexture()
|
||
|
|
local keybindMacroText = editMacroEditBox:GetText()
|
||
|
|
|
||
|
|
--check if the macro has default name and icon
|
||
|
|
if (keybindName:find("@Macro") and iconTexture:GetTexture() == 136377) then
|
||
|
|
for macro in keybindMacroText:gmatch("([^%s]+)") do
|
||
|
|
local spellName, _, spellIcon = GetSpellInfo(macro)
|
||
|
|
if (spellName) then
|
||
|
|
keybindName = spellName
|
||
|
|
keybindTexture = spellIcon
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
self:OnKeybindNameChange(keybindName)
|
||
|
|
self:OnKeybindIconChange(keybindTexture)
|
||
|
|
|
||
|
|
local actionId = keybindTable.action
|
||
|
|
---@cast actionId string
|
||
|
|
|
||
|
|
if (self:IsKeybindActionMacro(actionId)) then
|
||
|
|
self:OnKeybindMacroChange(keybindMacroText)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
self:StopEditingKeybindSettings()
|
||
|
|
|
||
|
|
local keybindScroll = self:GetKeybindScroll()
|
||
|
|
keybindScroll:UpdateScroll()
|
||
|
|
end
|
||
|
|
|
||
|
|
--save button
|
||
|
|
local saveButton = detailsFramework:CreateButton(editFrame, saveButtonCallback, 120, 20, "Save", nil, nil, nil, "saveButton", "$parentSaveButton", 0, DARK_BUTTON_TEMPLATE, detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE"))
|
||
|
|
saveButton:SetPoint("topleft", editMacroEditBox, "bottomleft", 0, -10)
|
||
|
|
saveButton:SetIcon([[Interface\BUTTONS\UI-CheckBox-Check]])
|
||
|
|
|
||
|
|
local cancelButtonCallback = function()
|
||
|
|
self:StopEditingKeybindSettings()
|
||
|
|
end
|
||
|
|
|
||
|
|
--cancel button
|
||
|
|
local cancelButton = detailsFramework:CreateButton(editFrame, cancelButtonCallback, 120, 20, "Cancel", nil, nil, nil, "cancelButton", "$parentCancelButton", 0, DARK_BUTTON_TEMPLATE, detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE"))
|
||
|
|
cancelButton:SetPoint("left", saveButton, "right", 10, 0)
|
||
|
|
cancelButton:SetIcon([[Interface\BUTTONS\UI-GROUPLOOT-PASS-DOWN]])
|
||
|
|
|
||
|
|
--conditions
|
||
|
|
local conditionsText = editFrame:CreateFontString("$parentConditionsText", "overlay", "GameFontNormal")
|
||
|
|
conditionsText:SetPoint("topleft", saveButton.widget, "bottomleft", 0, -40)
|
||
|
|
conditionsText:SetText("Can Load Keybind?")
|
||
|
|
detailsFramework:SetFontColor(conditionsText, "BLIZZ_OPTIONS_COLOR")
|
||
|
|
|
||
|
|
local onLoadConditionsChange = function()
|
||
|
|
--no parameters is passed as the modifications are done directly on the keybindTable.conditions
|
||
|
|
--trigger a callback to inform the addon about the change
|
||
|
|
self:CallKeybindChangeCallback("conditions", editFrame.keybindTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
local openConditionsPanel = function()
|
||
|
|
local conditionsSettings = editFrame.keybindTable.conditions
|
||
|
|
detailsFramework:OpenLoadConditionsPanel(conditionsSettings, onLoadConditionsChange, {title = "Keybind Load Conditions", name = editFrame.keybindTable.name})
|
||
|
|
end
|
||
|
|
|
||
|
|
local conditionsButton = detailsFramework:CreateButton(editFrame, openConditionsPanel, 160, 20, "Edit Load Conditions", nil, nil, [[]], "conditionsButton", "$parentConditionsButton", 0, DARK_BUTTON_TEMPLATE, detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE"))
|
||
|
|
conditionsButton:SetPoint("topleft", conditionsText, "bottomleft", 0, -5)
|
||
|
|
|
||
|
|
local conditionsFailLoadReasonText = editFrame:CreateFontString("$parentConditionsFailLoadText", "overlay", "GameFontNormal")
|
||
|
|
conditionsFailLoadReasonText:SetPoint("topleft", conditionsButton.widget, "bottomleft", 0, -20)
|
||
|
|
conditionsFailLoadReasonText:SetText("")
|
||
|
|
conditionsFailLoadReasonText:SetJustifyH("left")
|
||
|
|
detailsFramework:SetFontColor(conditionsFailLoadReasonText, "firebrick")
|
||
|
|
editFrame.conditionsFailLoadReasonText = conditionsFailLoadReasonText
|
||
|
|
|
||
|
|
--create a button to delete a macro keybind
|
||
|
|
local deleteMacroText = editFrame:CreateFontString("$parentDeleteMacroText", "overlay", "GameFontNormal")
|
||
|
|
deleteMacroText:SetPoint("topleft", saveButton.widget, "bottomleft", 180, -40)
|
||
|
|
deleteMacroText:SetText("Delete Macro")
|
||
|
|
detailsFramework:SetFontColor(deleteMacroText, "BLIZZ_OPTIONS_COLOR")
|
||
|
|
|
||
|
|
local onClickDeleteMacroButton = function()
|
||
|
|
self:DeleteMacro()
|
||
|
|
end
|
||
|
|
|
||
|
|
local deleteMacroButton = detailsFramework:CreateButton(editFrame, onClickDeleteMacroButton, 160, 20, "Delete This Macro", nil, nil, [[]], "deleteMacroButton", "$parentDeleteMacroButton", 0, DARK_BUTTON_TEMPLATE, detailsFramework:GetTemplate("font", "OPTIONS_FONT_TEMPLATE"))
|
||
|
|
deleteMacroButton:SetPoint("topleft", deleteMacroText, "bottomleft", 0, -5)
|
||
|
|
|
||
|
|
--methods
|
||
|
|
function editFrame:Disable()
|
||
|
|
nameEditBox:SetText("")
|
||
|
|
nameEditBox:Disable()
|
||
|
|
editMacroEditBox:SetText("")
|
||
|
|
editMacroEditBox:Disable()
|
||
|
|
iconPickerButton:Disable()
|
||
|
|
conditionsButton:Disable()
|
||
|
|
deleteMacroButton:Disable()
|
||
|
|
saveButton:Disable()
|
||
|
|
cancelButton:Disable()
|
||
|
|
end
|
||
|
|
|
||
|
|
function editFrame:Enable()
|
||
|
|
nameEditBox:Enable()
|
||
|
|
iconPickerButton:Enable()
|
||
|
|
conditionsButton:Enable()
|
||
|
|
deleteMacroButton:Enable()
|
||
|
|
editMacroEditBox:Enable()
|
||
|
|
saveButton:Enable()
|
||
|
|
cancelButton:Enable()
|
||
|
|
end
|
||
|
|
|
||
|
|
editFrame:Disable()
|
||
|
|
end,
|
||
|
|
}
|
||
|
|
|
||
|
|
---@param parent frame
|
||
|
|
---@param name string?
|
||
|
|
---@param options table?
|
||
|
|
---@param setKeybindCallback function?
|
||
|
|
---@param keybindData table?
|
||
|
|
function detailsFramework:CreateKeybindFrame(parent, name, options, setKeybindCallback, keybindData)
|
||
|
|
---@type df_keybindframe
|
||
|
|
local keyBindFrame = CreateFrame("frame", name, parent, "BackdropTemplate")
|
||
|
|
keyBindFrame.bIsKeybindFrame = true
|
||
|
|
|
||
|
|
detailsFramework:Mixin(keyBindFrame, detailsFramework.OptionsFunctions)
|
||
|
|
detailsFramework:Mixin(keyBindFrame, detailsFramework.KeybindMixin)
|
||
|
|
|
||
|
|
options = options or {}
|
||
|
|
keyBindFrame:BuildOptionsTable(default_options, options)
|
||
|
|
|
||
|
|
if (keyBindFrame.options.width ~= default_options.width or keyBindFrame.options.height ~= default_options.height) then
|
||
|
|
local lineHeight = keyBindFrame.options.line_height
|
||
|
|
keyBindFrame.options.amount_lines = math.floor((keyBindFrame.options.height - 20) / lineHeight)
|
||
|
|
keyBindFrame.options.scroll_height = keyBindFrame.options.height - 20
|
||
|
|
keyBindFrame.options.scroll_width = keyBindFrame.options.width - 10
|
||
|
|
end
|
||
|
|
|
||
|
|
if (keyBindFrame.options.edit_height == 0) then
|
||
|
|
keyBindFrame.options.edit_height = keyBindFrame.options.height
|
||
|
|
end
|
||
|
|
|
||
|
|
keyBindFrame:SetSize(keyBindFrame.options.width, keyBindFrame.options.height)
|
||
|
|
|
||
|
|
keyBindFrame:SetScript("OnHide", function()
|
||
|
|
if (keyBindFrame:IsListening()) then
|
||
|
|
keyBindFrame:SetListeningState(false)
|
||
|
|
local keybindListener = keyBindFrame:GetKeybindListener()
|
||
|
|
keybindListener:SetScript("OnKeyDown", nil)
|
||
|
|
end
|
||
|
|
|
||
|
|
local bIsEditingKeybind = keyBindFrame:IsEditingKeybindSettings()
|
||
|
|
if (bIsEditingKeybind) then
|
||
|
|
keyBindFrame:StopEditingKeybindSettings()
|
||
|
|
end
|
||
|
|
|
||
|
|
keyBindFrame:SetClearButtonsEnabled(true)
|
||
|
|
keyBindFrame:SetEditButtonsEnabled(true)
|
||
|
|
end)
|
||
|
|
|
||
|
|
keyBindFrame:SetScript("OnShow", function()
|
||
|
|
local keybindScroll = keyBindFrame:GetKeybindScroll()
|
||
|
|
keybindScroll:UpdateScroll()
|
||
|
|
end)
|
||
|
|
|
||
|
|
keyBindFrame:CreateKeybindScroll()
|
||
|
|
keyBindFrame:CreateKeybindListener()
|
||
|
|
keyBindFrame:CreateEditPanel()
|
||
|
|
|
||
|
|
keyBindFrame:SetKeybindData(keybindData or {})
|
||
|
|
|
||
|
|
if (setKeybindCallback) then
|
||
|
|
keyBindFrame:SetKeybindCallback(setKeybindCallback)
|
||
|
|
end
|
||
|
|
|
||
|
|
return keyBindFrame
|
||
|
|
end
|