ZO_GamepadTooltip = {} local function LayoutFunction(self, tooltipType, ...) local tooltipContainer = self:GetTooltipContainer(tooltipType) if tooltipContainer == nil then return end local tooltipContainerTip = self:GetAndInitializeTooltipContainerTip(tooltipType) local tooltipFunction = tooltipContainerTip.tooltip[self.currentLayoutFunctionName] or nil if tooltipFunction == nil then local newTooltipFunction = ZO_Tooltip[self.currentLayoutFunctionName] or nil if newTooltipFunction ~= nil then --If we got here, that means the layout function was added to ZO_Tooltip after we initialized this tooltip --In that case, update the tooltip to have that function too --This will only update standard gamepad tooltips. Any custom tooltips (such as ones created with ZO_ResizingFloatingScrollTooltip_Gamepad_OnInitialized) --will still only have functions that existed at the time of initialization tooltipContainerTip.tooltip[self.currentLayoutFunctionName] = newTooltipFunction tooltipFunction = newTooltipFunction else -- if this line fired you called a function that does not exist on ZO_GamepadTooltip or ZO_Tooltip return nil end end -- Always default the border to hidden so that tooltips to which it is not relevant don't have to deal with it. self:SetBorderHidden(tooltipType, true) local tooltipInfo = self:GetTooltipInfo(tooltipType) tooltipContainerTip:ClearLines(tooltipInfo.resetScroll) local returnValue = tooltipFunction(tooltipContainerTip.tooltip, ...) local tooltipFragment = self:GetTooltipFragment(tooltipType) if tooltipContainerTip:HasControls() then SCENE_MANAGER:AddFragment(tooltipFragment) if self:DoesAutoShowTooltipBg(tooltipType) then SCENE_MANAGER:AddFragment(self:GetTooltipBgFragment(tooltipType)) end else SCENE_MANAGER:RemoveFragment(tooltipFragment) if self:DoesAutoShowTooltipBg(tooltipType) then SCENE_MANAGER:RemoveFragment(self:GetTooltipBgFragment(tooltipType)) end end return returnValue end ZO_GamepadTooltip.metaTable = { __index = function(t, key) local value = ZO_GamepadTooltip[key] if value == nil then t.currentLayoutFunctionName = key return LayoutFunction end return value end, } --When adding a new one of these, make sure you update the TOOLTIP_NARRATION_ORDER table in this file as well GAMEPAD_LEFT_TOOLTIP = "GAMEPAD_LEFT_TOOLTIP" GAMEPAD_RIGHT_TOOLTIP = "GAMEPAD_RIGHT_TOOLTIP" GAMEPAD_MOVABLE_TOOLTIP = "GAMEPAD_MOVABLE_TOOLTIP" GAMEPAD_LEFT_DIALOG_TOOLTIP = "GAMEPAD_LEFT_DIALOG_TOOLTIP" GAMEPAD_QUAD3_TOOLTIP = "GAMEPAD_QUAD3_TOOLTIP" GAMEPAD_QUAD1_TOOLTIP = "GAMEPAD_QUAD1_TOOLTIP" GAMEPAD_QUAD_2_3_TOOLTIP = "GAMEPAD_QUAD_2_3_TOOLTIP" GAMEPAD_TOOLTIP_NORMAL_BG = 1 GAMEPAD_TOOLTIP_DARK_BG = 2 function ZO_GamepadTooltip:New(...) local gamepadTooltip = {} setmetatable(gamepadTooltip, self.metaTable) gamepadTooltip:Initialize(...) return gamepadTooltip end function ZO_GamepadTooltip:Initialize(control, dialogControl) self.control = control self.dialogControl = dialogControl self.tooltips = {} self.customTooltipNarrations = {} local AUTO_SHOW_BG = true self:InitializeTooltip(GAMEPAD_LEFT_TOOLTIP, self.control, "Left", AUTO_SHOW_BG, RIGHT) self:InitializeTooltip(GAMEPAD_RIGHT_TOOLTIP, self.control, "Right", AUTO_SHOW_BG, LEFT) self:InitializeTooltip(GAMEPAD_MOVABLE_TOOLTIP, self.control, "Movable", AUTO_SHOW_BG, RIGHT) self:InitializeTooltip(GAMEPAD_QUAD3_TOOLTIP, self.control, "Quadrant3", AUTO_SHOW_BG, RIGHT) self:InitializeTooltip(GAMEPAD_QUAD1_TOOLTIP, self.control, "Quadrant1", AUTO_SHOW_BG, RIGHT) self:InitializeTooltip(GAMEPAD_LEFT_DIALOG_TOOLTIP, self.dialogControl, "Left", AUTO_SHOW_BG, RIGHT) self:InitializeTooltip(GAMEPAD_QUAD_2_3_TOOLTIP, self.control, "Quadrant_2_3_", AUTO_SHOW_BG, RIGHT, "quadrant_2_3_Tooltip") end function ZO_GamepadTooltip:InitializeTooltip(tooltipType, baseControl, prefix, autoShowBg, scrollIndicatorSide, style) local control = baseControl:GetNamedChild(prefix.."Tooltip") local bgControl = baseControl:GetNamedChild(prefix.."TooltipBg") local darkBgControl = baseControl:GetNamedChild(prefix.."TooltipDarkBg") local headerContainerControl = baseControl:GetNamedChild(prefix.."HeaderContainer") local container = control:GetNamedChild("Container") container.tip = container:GetNamedChild("Tip") container.tip.initialized = false; container.gamepadTooltipContainerBorderControl = container:GetNamedChild("Border") container.statusLabel = container:GetNamedChild("StatusLabel") container.statusLabelValue = container:GetNamedChild("StatusLabelValue") container.statusLabelValueForVisualLayer = container:GetNamedChild("StatusLabelValueForVisualLayer") container.statusLabelVisualLayer = container:GetNamedChild("StatusLabelVisualLayer") container.bottomRail = container:GetNamedChild("BottomRail") control.container = container local bgFragment = ZO_FadeSceneFragment:New(bgControl, true) bgControl:SetAnchorFill(control) _G[tooltipType.."_BACKGROUND_FRAGMENT"] = bgFragment local darkBgFragment = ZO_FadeSceneFragment:New(darkBgControl, true) _G[tooltipType.."_DARK_BACKGROUND_FRAGMENT"] = darkBgFragment darkBgControl:SetAnchorFill(control) local headerControl = nil if headerContainerControl ~= nil then local headerContainer = headerContainerControl:GetNamedChild("ContentContainer") if headerContainer ~= nil then headerControl = headerContainer:GetNamedChild("Header") ZO_GamepadGenericHeader_Initialize(headerControl, ZO_GAMEPAD_HEADER_TABBAR_DONT_CREATE) end end self.tooltips[tooltipType] = { control = control, bgControl = bgControl, darkBgControl = darkBgControl, headerContainerControl = headerContainerControl, headerControl = headerControl, fragment = ZO_FadeSceneFragment:New(control, true), bgFragment = bgFragment, darkBgFragment = darkBgFragment, autoShowBg = autoShowBg, defaultAutoShowBg = autoShowBg, bgType = GAMEPAD_TOOLTIP_NORMAL_BG, resetScroll = true, scrollIndicatorSide = scrollIndicatorSide, style = style, } self:SetScrollIndicatorSide(tooltipType, scrollIndicatorSide) end --Set retainFragment to true if you intend to re-layout this tooltip immediately after calling ClearTooltip --This saves us the performance cost of removing the fragment just to add it right back in again --Particularly when done in an update loop function ZO_GamepadTooltip:ClearTooltip(tooltipType, retainFragment) local tooltipContainer = self:GetTooltipContainer(tooltipType) if tooltipContainer then local tooltipContainerTip = self:GetAndInitializeTooltipContainerTip(tooltipType) local tooltipInfo = self:GetTooltipInfo(tooltipType) tooltipContainerTip:ClearLines(tooltipInfo.resetScroll) if not retainFragment then SCENE_MANAGER:RemoveFragment(self:GetTooltipFragment(tooltipType)) if self:DoesAutoShowTooltipBg(tooltipType) then SCENE_MANAGER:RemoveFragment(self:GetTooltipBgFragment(tooltipType)) end end self:ClearStatusLabel(tooltipType) end end function ZO_GamepadTooltip:ResetScrollTooltipToTop(tooltipType) local tooltipContainerTip = self:GetAndInitializeTooltipContainerTip(tooltipType) if tooltipContainerTip then tooltipContainerTip:ResetToTop() end end function ZO_GamepadTooltip:SetBorderHidden(tooltipType, isHidden) local container = self:GetTooltipContainer(tooltipType) if container.gamepadTooltipContainerBorderControl then container.gamepadTooltipContainerBorderControl:SetHidden(isHidden) end end function ZO_GamepadTooltip:ClearStatusLabel(tooltipType) self:SetStatusLabelText(tooltipType) end function ZO_GamepadTooltip:SetStatusLabelText(tooltipType, stat, value, visualLayer) if stat == nil then stat = "" end if value == nil then value = "" end if visualLayer == nil then visualLayer = "" end local tooltipContainer = self:GetTooltipContainer(tooltipType) if tooltipContainer then --Set the status label narration text on the specified tooltip local tooltip = self:GetTooltip(tooltipType) if tooltip then tooltip:SetStatusLabelNarrationText(stat, value, visualLayer) end tooltipContainer.statusLabel:SetText(stat) if visualLayer ~= "" then tooltipContainer.statusLabelValueForVisualLayer:SetText(value) else tooltipContainer.statusLabelValue:SetText(value) end tooltipContainer.statusLabelVisualLayer:SetText(visualLayer) local hidden = stat == "" and value == "" and visualLayer == "" tooltipContainer.statusLabel:SetHidden(hidden) tooltipContainer.statusLabelVisualLayer:SetHidden(hidden) tooltipContainer.bottomRail:SetHidden(hidden) tooltipContainer.statusLabelValue:SetHidden(hidden or (visualLayer ~= "")) tooltipContainer.statusLabelValueForVisualLayer:SetHidden(hidden or (visualLayer == "")) end end function ZO_GamepadTooltip:SetMovableTooltipVerticalRules(leftHidden, rightHidden) local bgControl = self:GetTooltipInfo(GAMEPAD_MOVABLE_TOOLTIP).bgControl:GetNamedChild("Bg") bgControl:GetNamedChild("LeftDivider"):SetHidden(leftHidden) bgControl:GetNamedChild("RightDivider"):SetHidden(rightHidden) end function ZO_GamepadTooltip:SetMovableTooltipAnchors(anchorTable) local movableTooltipContainer = self:GetTooltipInfo(GAMEPAD_MOVABLE_TOOLTIP).control movableTooltipContainer:ClearAnchors() for i, anchor in ipairs(anchorTable) do movableTooltipContainer:SetAnchor(anchor:GetMyPoint(), anchor:GetTarget(), anchor:GetRelativePoint(), anchor:GetOffsetX(), anchor:GetOffsetY()) end end function ZO_GamepadTooltip:SetScrollIndicatorSide(tooltipType, side) local tooltipContainer = self:GetTooltipContainer(tooltipType) if tooltipContainer then local tooltipInfo = self:GetTooltipInfo(tooltipType) -- we don't want to initialize the tip at this point, because we don't need it to be yet -- and this is called in the class initialization, which defeats the point of deferring initialization of the tip local tooltipContainerTip = tooltipContainer.tip local scrollIndicator = tooltipContainerTip:GetNamedChild("ScrollIndicator") ZO_Scroll_Gamepad_SetScrollIndicatorSide(scrollIndicator, tooltipInfo.bgControl, side) end end function ZO_GamepadTooltip:SetInputEnabled(tooltipType, enabled) local tooltipContainerTip = self:GetAndInitializeTooltipContainerTip(tooltipType) if tooltipContainerTip then tooltipContainerTip:SetInputEnabled(enabled) end end function ZO_GamepadTooltip:ShowBg(tooltipType) SCENE_MANAGER:AddFragment(self:GetTooltipBgFragment(tooltipType)) end function ZO_GamepadTooltip:HideBg(tooltipType) SCENE_MANAGER:RemoveFragment(self:GetTooltipBgFragment(tooltipType)) end function ZO_GamepadTooltip:SetAutoShowBg(tooltipType, autoShowBg) self:GetTooltipInfo(tooltipType).autoShowBg = autoShowBg end function ZO_GamepadTooltip:SetBgType(tooltipType, bgType) self:GetTooltipInfo(tooltipType).bgType = bgType end function ZO_GamepadTooltip:SetBgAlpha(tooltipType, alpha) local tooltipInfo = self:GetTooltipInfo(tooltipType) tooltipInfo.bgControl:GetNamedChild("Bg"):SetAlpha(alpha) tooltipInfo.darkBgControl:GetNamedChild("Bg"):SetAlpha(alpha) end function ZO_GamepadTooltip:SetTooltipResetScrollOnClear(tooltipType, resetScroll) local tooltipInfo = self:GetTooltipInfo(tooltipType) tooltipInfo.resetScroll = resetScroll end function ZO_GamepadTooltip:ShowGenericHeader(tooltipType, data) local tooltipInfo = self:GetTooltipInfo(tooltipType) tooltipInfo.headerData = data ZO_GamepadGenericHeader_Refresh(tooltipInfo.headerControl, data) tooltipInfo.headerContainerControl:SetHidden(false) end function ZO_GamepadTooltip:Reset(tooltipType) local tooltipInfo = self:GetTooltipInfo(tooltipType) tooltipInfo.autoShowBg = tooltipInfo.defaultAutoShowBg tooltipInfo.bgType = GAMEPAD_TOOLTIP_NORMAL_BG tooltipInfo.bgControl:GetNamedChild("Bg"):SetAlpha(1) tooltipInfo.darkBgControl:GetNamedChild("Bg"):SetAlpha(1) tooltipInfo.resetScroll = true self:SetScrollIndicatorSide(tooltipType, tooltipInfo.scrollIndicatorSide) if tooltipInfo.headerContainerControl ~= nil then tooltipInfo.headerContainerControl:SetHidden(true) end tooltipInfo.headerData = nil if tooltipType == GAMEPAD_MOVABLE_TOOLTIP then local HIDE_LEFT_DIVIDER = false local HIDE_RIGHT_DIVIDER = false self:SetMovableTooltipVerticalRules(HIDE_LEFT_DIVIDER, HIDE_RIGHT_DIVIDER) end self:ClearTooltip(tooltipType) end function ZO_GamepadTooltip:GetTooltip(tooltipType) local tooltipContainerTip = self:GetAndInitializeTooltipContainerTip(tooltipType) if tooltipContainerTip then return tooltipContainerTip.tooltip end end function ZO_GamepadTooltip:GetTooltipContainer(tooltipType) return self:GetTooltipInfo(tooltipType).control.container end function ZO_GamepadTooltip:GetAndInitializeTooltipContainerTip(tooltipType) local tooltipContainer = self:GetTooltipContainer(tooltipType) if tooltipContainer then local tooltipContainerTip = tooltipContainer.tip if tooltipContainerTip.initialized == false then tooltipContainerTip.initialized = true ZO_ScrollTooltip_Gamepad:Initialize(tooltipContainerTip, ZO_TOOLTIP_STYLES, self:GetTooltipInfo(tooltipType).style) tooltipContainerTip.tooltip.gamepadTooltipContainerBorderControl = tooltipContainer.gamepadTooltipContainerBorderControl end return tooltipContainerTip end end function ZO_GamepadTooltip:GetTooltipFragment(tooltipType) return self:GetTooltipInfo(tooltipType).fragment end function ZO_GamepadTooltip:GetTooltipBgFragment(tooltipType) local info = self:GetTooltipInfo(tooltipType) if info.bgType == GAMEPAD_TOOLTIP_NORMAL_BG then return info.bgFragment elseif info.bgType == GAMEPAD_TOOLTIP_DARK_BG then return info.darkBgFragment end end function ZO_GamepadTooltip:AddTooltipInstantScene(tooltipType, scene) local info = self:GetTooltipInfo(tooltipType) info.fragment:AddInstantScene(scene) info.bgFragment:AddInstantScene(scene) info.darkBgFragment:AddInstantScene(scene) end function ZO_GamepadTooltip:DoesAutoShowTooltipBg(tooltipType) return self:GetTooltipInfo(tooltipType).autoShowBg end function ZO_GamepadTooltip:GetTooltipInfo(tooltipType) return self.tooltips[tooltipType] end function ZO_GamepadTooltip:RegisterCustomTooltipNarration(narrationInfo) table.insert(self.customTooltipNarrations, narrationInfo) end do --The order to narrate tooltips in. Should be ordered based on where the tooltip is located visually, from left to right --If the tooltip is not included in this table, it will not be checked when attempting to narrate all visible tooltips local TOOLTIP_NARRATION_ORDER = { GAMEPAD_QUAD1_TOOLTIP, GAMEPAD_LEFT_TOOLTIP, GAMEPAD_LEFT_DIALOG_TOOLTIP, GAMEPAD_QUAD_2_3_TOOLTIP, GAMEPAD_QUAD3_TOOLTIP, GAMEPAD_RIGHT_TOOLTIP, GAMEPAD_MOVABLE_TOOLTIP, } function ZO_GamepadTooltip:GetNarrationText(optionalTooltipType) local narrationText = {} if self.tooltips[optionalTooltipType] then local tooltipInfo = self:GetTooltipInfo(optionalTooltipType) if tooltipInfo then --If the tooltip has a generic header, get the narration for that first if tooltipInfo.headerContainerControl and not tooltipInfo.headerContainerControl:IsHidden() and tooltipInfo.headerControl and tooltipInfo.headerData then table.insert(narrationText, ZO_GamepadGenericHeader_GetNarrationText(tooltipInfo.headerControl, tooltipInfo.headerData)) end --Make sure the tooltip is actually showing if tooltipInfo.fragment and tooltipInfo.fragment:IsShowing() then --If a valid tooltip type was specified, grab the narration text for that one local tooltip = self:GetTooltip(optionalTooltipType) if tooltip then table.insert(narrationText, tooltip:GetNarrationText()) end end end else --If we didn't get a valid tooltip type, just get the narration text for every visible tooltip for _, tooltipType in ipairs(TOOLTIP_NARRATION_ORDER) do local tooltipInfo = self:GetTooltipInfo(tooltipType) if tooltipInfo then --If the tooltip has a generic header, get the narration for that first if tooltipInfo.headerContainerControl and not tooltipInfo.headerContainerControl:IsHidden() and tooltipInfo.headerControl and tooltipInfo.headerData then table.insert(narrationText, ZO_GamepadGenericHeader_GetNarrationText(tooltipInfo.headerControl, tooltipInfo.headerData)) end --Make sure the tooltip is actually showing if tooltipInfo.fragment and tooltipInfo.fragment:IsShowing() then local tooltip = self:GetTooltip(tooltipType) if tooltip then table.insert(narrationText, tooltip:GetNarrationText()) end end end end for _, narrationInfo in ipairs(self.customTooltipNarrations) do if narrationInfo:canNarrate() then table.insert(narrationText, narrationInfo:tooltipNarrationFunction()) end end end return narrationText end end function ZO_GamepadTooltip_OnInitialized(control, dialogControl) GAMEPAD_TOOLTIPS = ZO_GamepadTooltip:New(control, dialogControl) end