ZO_KeybindButtonMixin = {} function ZO_KeybindButtonMixin:GetKeybind() return ZO_Keybindings_ShouldUseGamepadAction(self.alwaysPreferGamepadMode) and self.gamepadPreferredKeybind or self.keybind end function ZO_KeybindButtonMixin:GetKeyboardKeybind() return self.keybind end function ZO_KeybindButtonMixin:GetGamepadKeybind() return self.gamepadPreferredKeybind end function ZO_KeybindButtonMixin:UpdateEnabledState() if self:IsHidden() then self.enableStateDirty = true return false else self.nameLabel:SetEnabled(self.enabled) local keybindEnabled = self.keybindEnabled and self.enabled local keybindColor = keybindEnabled and ZO_SELECTED_TEXT or ZO_DISABLED_TEXT self.keyLabel:SetColor(keybindColor:UnpackRGBA()) self.keyLabel:SetAlpha((self:GetKeybind() or self.customKeyText) and 1 or 0) ZO_KeyMarkupLabel_SetEdgeFileColor(self.keyLabel, keybindColor) return true end end function ZO_KeybindButtonMixin:SetEnabled(enabled) if enabled ~= self.enabled then self.enabled = enabled self:UpdateEnabledState() end end function ZO_KeybindButtonMixin:SetState(buttonState, locked) self:SetEnabled(buttonState ~= BSTATE_DISABLED) end function ZO_KeybindButtonMixin:SetKeybindEnabled(enabled) if enabled ~= self.keybindEnabled then self.keybindEnabled = enabled self:UpdateEnabledState() end end function ZO_KeybindButtonMixin:IsEnabled() return self.enabled end function ZO_KeybindButtonMixin:SetClickSound(clickSound) self.clickSound = clickSound end function ZO_KeybindButtonMixin:SetText(text, narrationText) self.nameText = text self.nameTextNarration = narrationText self.nameLabel:SetText(self.nameText) end function ZO_KeybindButtonMixin:SetCustomKeyText(keyText) self.customKeyText = true self.keyLabel:SetText(ZO_Keybindings_GenerateTextKeyMarkup(keyText)) self:UpdateEnabledState() end function ZO_KeybindButtonMixin:SetCustomKeyIcon(keyIcon) local key = ("|t%f%%:%f%%:%s|t"):format(200, 200, keyIcon) self.customKeyText = true self.keyLabel:SetText(key) self:UpdateEnabledState() end function ZO_KeybindButtonMixin:ShowKeyIcon() self.keyLabel:SetHidden(false) end function ZO_KeybindButtonMixin:HideKeyIcon() self.keyLabel:SetHidden(true) end function ZO_KeybindButtonMixin:SetupStyle(styleInfo) KEYBIND_STRIP:SetupButtonStyle(self, styleInfo or KEYBIND_STRIP:GetStyle()) end function ZO_KeybindButtonMixin:SetKeybindEnabledInEdit(enabled) self.keybindEnabledInEdit = enabled end function ZO_KeybindButtonMixin:SetMouseOverEnabled(enabled) ZO_SelectableLabel_SetMouseOverEnabled(self.nameLabel, enabled) end function ZO_KeybindButtonMixin:SetNormalTextColor(color) ZO_SelectableLabel_SetNormalColor(self.nameLabel, color) end function ZO_KeybindButtonMixin:SetNameFont(font) self.nameLabel:SetFont(font) end function ZO_KeybindButtonMixin:SetKeyFont(font) self.keyLabel:SetFont(font) end function ZO_KeybindButtonMixin:AdjustBindingAnchors(wideSpacing) if not self:GetUsingCustomAnchors() then self.keyLabel:SetAnchor(RIGHT, self.nameLabel, LEFT, wideSpacing and -15 or 0) end end function ZO_KeybindButtonMixin:SetUsingCustomAnchors(useCustom) self.usingCustomAnchors = useCustom end function ZO_KeybindButtonMixin:GetUsingCustomAnchors() return self.usingCustomAnchors end local function OnKeybindLabelChanged(label, bindingText, key, mod1, mod2, mod3, mod4) label.owner:AdjustBindingAnchors(not ZO_Keybindings_ShouldUseIconKeyMarkup(key)) end function ZO_KeybindButtonMixin:SetKeybind(keybind, showUnbound, gamepadPreferredKeybind, alwaysPreferGamepadMode, showAsHold) local hadKeybind = self:GetKeybind() ~= nil self.keybind = keybind self.gamepadPreferredKeybind = gamepadPreferredKeybind self.alwaysPreferGamepadMode = alwaysPreferGamepadMode keybind = self:GetKeybind() if keybind then if hadKeybind then ZO_Keybindings_UnregisterLabelForBindingUpdate(self.keyLabel) end ZO_Keybindings_RegisterLabelForBindingUpdate(self.keyLabel, self.keybind, showUnbound, self.gamepadPreferredKeybind, OnKeybindLabelChanged, alwaysPreferGamepadMode, showAsHold) else ZO_Keybindings_UnregisterLabelForBindingUpdate(self.keyLabel) end self:UpdateEnabledState() end function ZO_KeybindButtonMixin:SetCallback(callback) self.callback = callback end function ZO_KeybindButtonMixin:GetKeybindButtonDescriptorReference() return self.keybindDescriptorReference end function ZO_KeybindButtonMixin:ShouldBeVisible() local visible = self.keybindDescriptorReference and self.keybindDescriptorReference.visible or true if type(visible) == "function" then visible = visible(self) end return visible ~= false -- nil defaults to visible end function ZO_KeybindButtonMixin:UpdateVisibility() local visible = self:ShouldBeVisible() return self:SetHidden(not visible) end --Generate narration data for this keybind button --If the keybind is not visible, nothing will be returned function ZO_KeybindButtonMixin:GetKeybindButtonNarrationData() local visible = self:ShouldBeVisible() if not visible then return nil end local narrationData = { name = self.nameTextNarration or self.nameText, keybindName = ZO_Keybindings_GetHighestPriorityNarrationStringFromAction(self:GetKeybind()) or GetString(SI_ACTION_IS_NOT_BOUND), enabled = self.enabled, } return narrationData end function ZO_KeybindButtonMixin:SetKeybindButtonDescriptor(keybindDescriptor) self.keybindDescriptorReference = keybindDescriptor if keybindDescriptor.name then local name = keybindDescriptor.name if type(keybindDescriptor.name) == "function" then name = keybindDescriptor.name() end self:SetText(name) end if keybindDescriptor.keybind then self:SetKeybind(keybindDescriptor.keybind) end if keybindDescriptor.callback then self:SetCallback(keybindDescriptor.callback) end if keybindDescriptor.sound then self:SetClickSound(keybindDescriptor.sound) end if keybindDescriptor.customKeyText then self:SetCustomKeyText(keybindDescriptor.customKeyText) end if keybindDescriptor.customKeyIcon then self:SetCustomKeyIcon(keybindDescriptor.customKeyIcon) end end function ZO_KeybindButtonMixin:OnClicked() local visible = self:ShouldBeVisible() if not visible then return end if self.enabled then if self.clickSound then if type(self.clickSound) == "function" then PlaySound(self.clickSound()) else PlaySound(self.clickSound) end end if self.callback then self.callback(self) end else PlaySound(SOUNDS.KEYBIND_BUTTON_DISABLED) end end local g_cooldownButtons = {} -- Should only be used for Floating Keybind Buttons -- Otherwise use ZO_KeybindStrip:TriggerCooldown function ZO_KeybindButtonMixin:SetCooldown(durationMs) self.cooldownDurationMs = durationMs self.cooldownStartTimeMs = GetFrameTimeMilliseconds() --Check for duplicates for i, button in ipairs(g_cooldownButtons) do if button == self then return end end self.baseText = self.nameLabel:GetText() table.insert(g_cooldownButtons, self) end local g_areKeybindsEnabled local g_keybindButtons = {} local g_numDisabledReferences = 0 local function OnUpdate() local shouldKeybindsBeEnabled = not HasActiveEditControl() and g_numDisabledReferences == 0 if shouldKeybindsBeEnabled ~= g_areKeybindsEnabled then g_areKeybindsEnabled = shouldKeybindsBeEnabled for i = 1, #g_keybindButtons do local currentKeybindButton = g_keybindButtons[i] if not currentKeybindButton.keybindEnabledInEdit then currentKeybindButton:SetKeybindEnabled(shouldKeybindsBeEnabled) end end end local currentTimeMs = GetFrameTimeMilliseconds() for i = #g_cooldownButtons, 1, -1 do local button = g_cooldownButtons[i] local timeDifferenceMs = currentTimeMs - button.cooldownStartTimeMs local shouldBeEnabled = timeDifferenceMs > button.cooldownDurationMs if shouldBeEnabled then button:SetText(button.baseText) button.cooldownDurationMs = nil button.cooldownStartTimeMs = nil table.remove(g_cooldownButtons, i) else local secondsTillEnabled = zo_ceil((button.cooldownStartTimeMs + button.cooldownDurationMs - currentTimeMs) / 1000) button:SetText(zo_strformat(SI_BINDING_NAME_COOLDOWN_FORMAT, button.baseText, secondsTillEnabled)) end button:SetEnabled(shouldBeEnabled) end end EVENT_MANAGER:RegisterForUpdate("KeybindButtonUpdate", 0, OnUpdate) function ZO_KeybindButtonTemplate_AddGlobalDisableReference() g_numDisabledReferences = g_numDisabledReferences + 1 end function ZO_KeybindButtonTemplate_RemoveGlobalDisableReference() g_numDisabledReferences = g_numDisabledReferences - 1 end function ZO_KeybindButtonTemplate_OnMouseUp(self, button, upInside) if upInside and (button == MOUSE_BUTTON_INDEX_LEFT) and self.enabled then self:OnClicked() end end function ZO_KeybindButtonTemplate_OnInitialized(self) self.nameLabel = self:GetNamedChild("NameLabel") self.keyLabel = self:GetNamedChild("KeyLabel") self.keyLabel.owner = self self.enabled = true self.keybindEnabled = true zo_mixin(self, ZO_KeybindButtonMixin) self:SetHandler("OnEffectivelyShown", function() if self.enableStateDirty then self.enableStateDirty = nil self:UpdateEnabledState() end end) ZO_KeyMarkupLabel_SetCustomOffsets(self.keyLabel, -5, 5, -2, 3) ZO_SelectableLabel_OnInitialized(self.nameLabel) table.insert(g_keybindButtons, self) self:UpdateEnabledState() end function ZO_KeybindButtonTemplate_Setup(self, keybind, callbackFunction, text) ZO_KeybindButtonTemplate_OnInitialized(self) self:SetKeybind(keybind) self:SetText(text) self:SetCallback(callbackFunction) end ZO_ChromaKeybindButtonMixin = {} function ZO_ChromaKeybindButtonMixin:SetChromaEnabled(enabled) if self.chromaEnabled ~= enabled then self.chromaEnabled = enabled self:UpdateChromaEffect() end end function ZO_ChromaKeybindButtonMixin:AddChromaEffect() if ZO_RZCHROMA_EFFECTS and self:AreChromaEffectsEnabled() then local keybindAction = self:GetKeyboardKeybind() if keybindAction then ZO_RZCHROMA_EFFECTS:AddKeybindActionEffect(keybindAction) end end end function ZO_ChromaKeybindButtonMixin:RemoveChromaEffect() if ZO_RZCHROMA_EFFECTS then local keybindAction = self:GetKeyboardKeybind() if keybindAction then ZO_RZCHROMA_EFFECTS:RemoveKeybindActionEffect(keybindAction) end end end function ZO_ChromaKeybindButtonMixin:UpdateChromaEffect() if ZO_RZCHROMA_EFFECTS and not self:IsHidden() then local keybindAction = self:GetKeyboardKeybind() if keybindAction then if self:AreChromaEffectsEnabled() then ZO_RZCHROMA_EFFECTS:AddKeybindActionEffect(keybindAction) else ZO_RZCHROMA_EFFECTS:RemoveKeybindActionEffect(keybindAction) end end end end function ZO_ChromaKeybindButtonMixin:SetKeybind(keybind, showUnbound, gamepadPreferredKeybind, alwaysPreferGamepadMode) local previousKeybind = self:GetKeyboardKeybind() local refreshKeybind = keybind ~= previousKeybind and not self:IsHidden() if refreshKeybind then self:RemoveChromaEffect() end ZO_KeybindButtonMixin.SetKeybind(self, keybind, showUnbound, gamepadPreferredKeybind, alwaysPreferGamepadMode) if refreshKeybind then self:AddChromaEffect() end end function ZO_ChromaKeybindButtonMixin:UpdateEnabledState() if ZO_KeybindButtonMixin.UpdateEnabledState(self) then self:UpdateChromaEffect() end end function ZO_ChromaKeybindButtonMixin:AreChromaEffectsEnabled() return self.chromaEnabled and self:IsEnabled() end function ZO_ChromaKeybindButtonTemplate_OnInitialized(self) ZO_KeybindButtonTemplate_OnInitialized(self) zo_mixin(self, ZO_ChromaKeybindButtonMixin) self:SetChromaEnabled(true) end function ZO_ChromaKeybindButtonTemplate_Setup(self, keybind, callbackFunction, text) ZO_ChromaKeybindButtonTemplate_OnInitialized(self) self:SetKeybind(keybind) self:SetText(text) self:SetCallback(callbackFunction) end function ZO_KeybindButton_ChromaBehavior_OnEffectivelyShown(self) if self.AddChromaEffect then self:AddChromaEffect() end end function ZO_KeybindButton_ChromaBehavior_OnEffectivelyHidden(self) if self.RemoveChromaEffect then self:RemoveChromaEffect() end end