ZO_EMOTE_COLUMN_WIDTH = 400 ZO_EMOTE_ROW_HEIGHT = 70 local GAMEPAD_PLAYER_EMOTE_SCENE_NAME = "gamepad_player_emote" local GAMEPAD_PLAYER_EMOTE_MENU_ENTRY_TEMPLATE = "ZO_GamepadItemSubEntryTemplate" local MODE_CATEGORY_INACTIVE = 0 local MODE_CATEGORY_SELECTION = 1 local MODE_EMOTE_SELECTION = 2 local MODE_EMOTE_ASSIGNMENT = 3 local NUM_EMOTE_ENTRIES_IN_COLUMN = 9 local NUM_EMOTE_ENTRY_COLUMNS = 3 local NUM_EMOTES_ON_PAGE = NUM_EMOTE_ENTRY_COLUMNS * NUM_EMOTE_ENTRIES_IN_COLUMN local EMOTE_GRID_MODE_EMOTES = 0 local EMOTE_GRID_MODE_QUICK_CHAT = 1 -- -- ZO_EmoteGridEntry class. These entries wrap the controls that make up the grid of emotes the user can select from -- local EMOTE_GRID_ENTRY_TYPE_NONE = 0 local EMOTE_GRID_ENTRY_TYPE_EMOTE = 1 local EMOTE_GRID_ENTRY_TYPE_QUICK_CHAT = 2 ZO_EmoteGridEntry = ZO_InitializingObject:Subclass() function ZO_EmoteGridEntry:Initialize(control) self.control = control self.title = control:GetNamedChild("Title") self.highlight = control:GetNamedChild("Highlight") self.entryType = EMOTE_GRID_ENTRY_TYPE_NONE self.id = 0 end function ZO_EmoteGridEntry:SetAnchor(column, row) self.control:ClearAnchors() self.control:SetAnchor(TOPLEFT, nil, TOPLEFT, (column - 1) * ZO_EMOTE_COLUMN_WIDTH, (row - 1) * ZO_EMOTE_ROW_HEIGHT) end function ZO_EmoteGridEntry:SetVisible(visible) self.control:SetHidden(not visible) end function ZO_EmoteGridEntry:SetHighlightVisible(visible) self.highlight:SetHidden(not visible) end function ZO_EmoteGridEntry:Reset() self:SetVisible(false) self:SetHighlightVisible(false) end function ZO_EmoteGridEntry:SetEmoteInfo(emoteId) self.entryType = EMOTE_GRID_ENTRY_TYPE_EMOTE self.id = emoteId local emoteInfo = PLAYER_EMOTE_MANAGER:GetEmoteItemInfo(emoteId) if emoteInfo.isOverriddenByPersonality then self:SetName(ZO_PERSONALITY_EMOTES_COLOR:Colorize(emoteInfo.displayName)) else self:SetName(emoteInfo.displayName) end end function ZO_EmoteGridEntry:SetQuickChatInfo(quickChatId) self.entryType = EMOTE_GRID_ENTRY_TYPE_QUICK_CHAT self.id = quickChatId self:SetName(QUICK_CHAT_MANAGER:GetFormattedQuickChatName(quickChatId)) end function ZO_EmoteGridEntry:SetName(name) self.title:SetText(name) self.name = name end function ZO_EmoteGridEntry:GetName() return self.name end function ZO_EmoteGridEntry:GetId() return self.id end function ZO_EmoteGridEntry:GetEntryType() return self.entryType end -- -- ZO_GamepadEmoteGrid class. This class manages the full grid of emotes including page switching -- ZO_GamepadEmoteGrid = ZO_GamepadPagedGrid:Subclass() function ZO_GamepadEmoteGrid:Initialize(control, footerControl) local COLUMN_MAJOR = false ZO_GamepadPagedGrid.Initialize(self, control, COLUMN_MAJOR, footerControl) self.allowHighlight = true self.emoteEntries = {} self.visibleEmotes = {} self.mode = EMOTE_GRID_MODE_EMOTES self.emoteList = nil self:InitializeEmoteGridEntries() self:SetPageNumberFont("ZoFontGamepadBold54") end function ZO_GamepadEmoteGrid:InitializeEmoteEntryPool() local function CreateEmote(objectPool) local emoteControl = ZO_ObjectPool_CreateControl("ZO_GamepadPlayerEmoteEntryTemplate", objectPool, self.control) return ZO_EmoteGridEntry:New(emoteControl) end self.emoteEntryPool = ZO_ObjectPool:New(CreateEmote, ZO_ObjectPool_DefaultResetObject) end function ZO_GamepadEmoteGrid:InitializeEmoteGridEntries() self:InitializeEmoteEntryPool() for column = 1, NUM_EMOTE_ENTRY_COLUMNS do self.emoteEntries[column] = {} for row = 1, NUM_EMOTE_ENTRIES_IN_COLUMN do local emoteEntry = self.emoteEntryPool:AcquireObject() emoteEntry:SetAnchor(column, row) self.emoteEntries[column][row] = emoteEntry end end end function ZO_GamepadEmoteGrid:ResetGridEntry(column, row, visible) local emoteEntry = self.emoteEntries[column][row] emoteEntry:SetHighlightVisible(false) emoteEntry:SetVisible(visible) end function ZO_GamepadEmoteGrid:ResetPageInfo() local FIRST_PAGE = 1 local numPages = math.ceil(#self.emoteList / NUM_EMOTES_ON_PAGE) self:SetPageInfo(FIRST_PAGE, numPages) end local function ShouldEmoteShowInGamepadUI(emoteData) return emoteData.showInGamepadUI end function ZO_GamepadEmoteGrid:ChangeEmoteListForEmoteType(emoteType) self.mode = EMOTE_GRID_MODE_EMOTES self.emoteList = PLAYER_EMOTE_MANAGER:GetEmoteListForType(emoteType, ShouldEmoteShowInGamepadUI) self:ResetPageInfo() end function ZO_GamepadEmoteGrid:ChangeEmoteListForQuickChat() self.mode = EMOTE_GRID_MODE_QUICK_CHAT self.emoteList = QUICK_CHAT_MANAGER:BuildQuickChatList() self:ResetPageInfo() end function ZO_GamepadEmoteGrid:GetCurrentSelectedEmote() if self.currentHighlight then return self.emoteEntries[self.currentHighlight.column][self.currentHighlight.row] end return nil end function ZO_GamepadEmoteGrid:GetSelectedEmoteName() return self:GetCurrentSelectedEmote():GetName() end function ZO_GamepadEmoteGrid:GetSelectedEmoteId() return self:GetCurrentSelectedEmote():GetId() end function ZO_GamepadEmoteGrid:GetSelectedEmoteType() return self:GetCurrentSelectedEmote():GetEntryType() end function ZO_GamepadEmoteGrid:SetAllowHighlight(allow) self.allowHighlight = allow self:RefreshGridHighlight() end do local SHOW_GRID_ENTRY = true local HIDE_GRID_ENTRY = false function ZO_GamepadEmoteGrid:RefreshGrid() --[[ Refresh the grid by resetting the visibleEmotes boolean array used by ZO_GamepadGrid and then setting controls Visible or Hidden based on how many entries are needed to be shown for the current list size on the current page --]] ZO_ClearNumericallyIndexedTable(self.visibleEmotes) local currentPage = self:GetCurrentPage() local emoteStartIndex = ((currentPage - 1) * NUM_EMOTES_ON_PAGE) local numEmotes = #self.emoteList local numEmotesToShow = numEmotes > 0 and zo_min(numEmotes - emoteStartIndex, NUM_EMOTES_ON_PAGE) or numEmotes local numShown = 0 for column = 1, NUM_EMOTE_ENTRY_COLUMNS do if numShown < numEmotesToShow then self.visibleEmotes[column] = {} end for row = 1, NUM_EMOTE_ENTRIES_IN_COLUMN do if numShown < numEmotesToShow then self:ResetGridEntry(column, row, SHOW_GRID_ENTRY) self.visibleEmotes[column][row] = true numShown = numShown + 1 if self.mode == EMOTE_GRID_MODE_EMOTES then self.emoteEntries[column][row]:SetEmoteInfo(self.emoteList[emoteStartIndex + numShown]) elseif self.mode == EMOTE_GRID_MODE_QUICK_CHAT then self.emoteEntries[column][row]:SetQuickChatInfo(self.emoteList[emoteStartIndex + numShown]) end else self:ResetGridEntry(column, row, HIDE_GRID_ENTRY) end end end self:ResetGridPosition() end end function ZO_GamepadEmoteGrid:GetNumEmoteEntries() return self.emoteList and #self.emoteList or 0 end -- functions overriden from base class function ZO_GamepadEmoteGrid:GetGridItems() return self.visibleEmotes end function ZO_GamepadEmoteGrid:RefreshGridHighlight() if self.currentHighlight then self.emoteEntries[self.currentHighlight.column][self.currentHighlight.row]:SetHighlightVisible(false) end local column, row = self:GetGridPosition() if column > 0 and row > 0 then self.emoteEntries[column][row]:SetHighlightVisible(self.allowHighlight) self.currentHighlight = {row = row, column = column} end end function ZO_GamepadEmoteGrid:Activate() ZO_GamepadPagedGrid.Activate(self) self.footer.control:SetHidden(false) end function ZO_GamepadEmoteGrid:Deactivate() ZO_GamepadPagedGrid.Deactivate(self) self.footer.control:SetHidden(true) end function ZO_GamepadEmoteGrid:GetNarrationText() return SCREEN_NARRATION_MANAGER:CreateNarratableObject(self:GetSelectedEmoteName()) end function ZO_GamepadEmoteGrid:GetHeaderNarration() return { GAMEPAD_PLAYER_EMOTE:GetContentHeaderNarrationText(), self:GetCurrentPageNarration() } end -- -- ZO_GamepadPlayerEmote class. This class creates our gamepad scene and emote category list and contains -- a ZO_GamepadEmoteGrid object and quickslot radial menu ZO_GamepadPlayerEmote = ZO_Gamepad_ParametricList_Screen:Subclass() function ZO_GamepadPlayerEmote:Initialize(control) self.control = control self.emoteListGridControl = control:GetNamedChild("EmoteListGrid") local quickslotControl = control:GetNamedChild("Quickslot") self.wheelControl = quickslotControl:GetNamedChild("EmoteWheel") self.assignLabel = quickslotControl:GetNamedChild("Assign") self.selectedEmoteNameLabel = quickslotControl:GetNamedChild("SelectedEmoteName") GAMEPAD_PLAYER_EMOTE_SCENE = ZO_Scene:New(GAMEPAD_PLAYER_EMOTE_SCENE_NAME, SCENE_MANAGER) local ACTIVATE_ON_SHOW = true ZO_Gamepad_ParametricList_Screen.Initialize(self, control, ZO_GAMEPAD_HEADER_TABBAR_DONT_CREATE, ACTIVATE_ON_SHOW, GAMEPAD_PLAYER_EMOTE_SCENE) end function ZO_GamepadPlayerEmote:OnDeferredInitialize() self:InitializeHeader() self:InitializeEmoteGrid() self:CreateCategoryList() self:InitializeRadialMenu() PLAYER_EMOTE_MANAGER:RegisterCallback("EmoteListUpdated", function() if GAMEPAD_PLAYER_EMOTE_SCENE:IsShowing() then self:CreateCategoryList() else self:MarkDirty() end end) end function ZO_GamepadPlayerEmote:OnSelectionChanged() local targetData = self.categoryList:GetTargetData() if targetData then self.currentData = targetData if targetData.type == ACTION_TYPE_EMOTE then self.emoteListGrid:ChangeEmoteListForEmoteType(targetData.emoteCategory) elseif targetData.type == ACTION_TYPE_QUICK_CHAT then self.emoteListGrid:ChangeEmoteListForQuickChat() end end KEYBIND_STRIP:UpdateCurrentKeybindButtonGroups() end function ZO_GamepadPlayerEmote:SetupList(list) local function IsEntryCategoryEqual(left, right) if left.type == right.type then if left.type == ACTION_TYPE_QUICK_CHAT then return true elseif left.type == ACTION_TYPE_EMOTE then return left.emoteCategory == right.emoteCategory end end return false end list:AddDataTemplate(GAMEPAD_PLAYER_EMOTE_MENU_ENTRY_TEMPLATE, ZO_SharedGamepadEntry_OnSetup, ZO_GamepadMenuEntryTemplateParametricListFunction, IsEntryCategoryEqual) end function ZO_GamepadPlayerEmote:ViewCategory(categoryData) if categoryData then local ANY_TEMPLATE = nil local index = self.categoryList:GetIndexForData(ANY_TEMPLATE, categoryData) if index then self.categoryList:SetSelectedIndexWithoutAnimation(index) else return internalassert(false, "Trying to view an invalid category") end end end function ZO_GamepadPlayerEmote:CreateCategoryList() self.categoryList = self:GetMainList() self.categoryList:Clear() local quickChatIcon = GetSharedQuickChatIcon() local data = ZO_GamepadEntryData:New(GetString(SI_QUICK_CHAT_EMOTE_MENU_ENTRY_NAME), quickChatIcon) data:SetModifyTextType(MODIFY_TEXT_TYPE_UPPERCASE) data:SetIconTintOnSelection(true) data.type = ACTION_TYPE_QUICK_CHAT self.categoryList:AddEntry(GAMEPAD_PLAYER_EMOTE_MENU_ENTRY_TEMPLATE, data) local categories = PLAYER_EMOTE_MANAGER:GetEmoteCategories() for _, category in ipairs(categories) do if category ~= EMOTE_CATEGORY_INVALID then local emoteIcon = PLAYER_EMOTE_MANAGER:GetSharedEmoteIconForCategory(category) local data = ZO_GamepadEntryData:New(GetString("SI_EMOTECATEGORY", category), emoteIcon) data:SetModifyTextType(MODIFY_TEXT_TYPE_UPPERCASE) data:SetIconTintOnSelection(true) data.type = ACTION_TYPE_EMOTE data.emoteCategory = category self.categoryList:AddEntry(GAMEPAD_PLAYER_EMOTE_MENU_ENTRY_TEMPLATE, data) end end self.categoryList:Commit() self.isDirty = false end function ZO_GamepadPlayerEmote:MarkDirty() self.isDirty = true end function ZO_GamepadPlayerEmote:InitializeHeader() self.headerData = { titleText = GetString(SI_GAMEPAD_MAIN_MENU_EMOTES) } local rightPane = self.control:GetNamedChild("RightPane") local contentContainer = rightPane:GetNamedChild("Container"):GetNamedChild("ContentHeader") self.contentHeader = contentContainer:GetNamedChild("Header") ZO_GamepadGenericHeader_Initialize(self.contentHeader, ZO_GAMEPAD_HEADER_TABBAR_DONT_CREATE, ZO_GAMEPAD_HEADER_LAYOUTS.DATA_PAIRS_TOGETHER) local titleControl = self.contentHeader:GetNamedChild("TitleContainerTitle") titleControl:SetFont("ZoFontGamepad54") self.contentHeaderData = { titleText = function() if self.mode == MODE_CATEGORY_SELECTION or self.mode == MODE_EMOTE_SELECTION then local currentData = self.currentData if currentData then if currentData.type == ACTION_TYPE_QUICK_CHAT then return GetString(SI_QUICK_CHAT_EMOTE_MENU_ENTRY_NAME) elseif currentData.type == ACTION_TYPE_EMOTE then return GetString("SI_EMOTECATEGORY", currentData.emoteCategory) end end end end, } end function ZO_GamepadPlayerEmote:InitializeEmoteGrid() self.emoteListGrid = ZO_GamepadEmoteGrid:New(self.emoteListGridControl, self.control:GetNamedChild("RightPaneContainerFooter")) self.emoteListGrid:SetPageChangedCallback(function() self:RefreshHeader() end) end function ZO_GamepadPlayerEmote:InitializeRadialMenu() local wheelData = { hotbarCategories = { HOTBAR_CATEGORY_EMOTE_WHEEL, HOTBAR_CATEGORY_QUICKSLOT_WHEEL }, numSlots = ACTION_BAR_UTILITY_BAR_SIZE, showCategoryLabel = true, onSelectionChangedCallback = function() KEYBIND_STRIP:UpdateKeybindButtonGroup(self.emoteAssignmentKeybindStripDescriptor) end, customNarrationObjectName = "EmoteAssignableUtilityWheel", headerNarrationFunction = function() local narrations = {} ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(GetString(SI_GAMEPAD_EMOTE_ASSIGN_INSTRUCTIONS))) ZO_AppendNarration(narrations, SCREEN_NARRATION_MANAGER:CreateNarratableObject(self.emoteListGrid:GetSelectedEmoteName())) return narrations end, } self.wheel = ZO_AssignableUtilityWheel_Gamepad:New(self.wheelControl, wheelData) end function ZO_GamepadPlayerEmote:PerformUpdate() self:RefreshHeader() end function ZO_GamepadPlayerEmote:RefreshHeader() local personalityId = GetActiveCollectibleByType(COLLECTIBLE_CATEGORY_TYPE_PERSONALITY, GAMEPLAY_ACTOR_CATEGORY_PLAYER) local collectibleData = ZO_COLLECTIBLE_DATA_MANAGER:GetCollectibleDataById(personalityId) if collectibleData then self.headerData.data1HeaderText = GetString(SI_GAMEPAD_EMOTE_PERSONALITY_OVERRIDE_HEADER) self.headerData.data1Text = ZO_PERSONALITY_EMOTES_COLOR:Colorize(zo_strformat(SI_GAMEPAD_SOCIAL_PERSONALITY, collectibleData:GetName())) else self.headerData.data1HeaderText = nil self.headerData.data1Text = nil end ZO_GamepadGenericHeader_Refresh(self.header, self.headerData) ZO_GamepadGenericHeader_Refresh(self.contentHeader, self.contentHeaderData) end function ZO_GamepadPlayerEmote:GetContentHeaderNarrationText() return ZO_GamepadGenericHeader_GetNarrationText(self.contentHeader, self.contentHeaderData) end function ZO_GamepadPlayerEmote:InitializeKeybindStripDescriptors() -- keybinds when a category is selected self.categoryKeybindStripDescriptor = { { name = GetString(SI_PLAYER_EMOTE_USE_EMOTE), keybind = "UI_SHORTCUT_PRIMARY", alignment = KEYBIND_STRIP_ALIGN_LEFT, visible = function() return self.emoteListGrid:GetCurrentSelectedEmote() ~= nil end, callback = function() SCENE_MANAGER:ShowBaseScene() local emoteId = self.emoteListGrid:GetSelectedEmoteId() if self.currentData.type == ACTION_TYPE_QUICK_CHAT then QUICK_CHAT_MANAGER:PlayQuickChat(emoteId) elseif self.currentData.type == ACTION_TYPE_EMOTE then local emoteIndex = PLAYER_EMOTE_MANAGER:GetEmoteItemInfo(emoteId).emoteIndex PlayEmoteByIndex(emoteIndex) end end, }, { name = GetString(SI_PLAYER_EMOTE_ASSIGN_EMOTE), keybind = "UI_SHORTCUT_SECONDARY", alignment = KEYBIND_STRIP_ALIGN_LEFT, visible = function() return self.emoteListGrid:GetCurrentSelectedEmote() ~= nil end, callback = function() self:ChangeCurrentMode(MODE_EMOTE_ASSIGNMENT) end, }, } ZO_Gamepad_AddBackNavigationKeybindDescriptorsWithSound(self.categoryKeybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, function() self:ChangeCurrentMode(MODE_CATEGORY_SELECTION) end) -- keybinds when assigning emotes self.emoteAssignmentKeybindStripDescriptor = {} local function OnAssignPendingData() self.wheel:TryAssignPendingToSelectedEntry() end local function ShouldShowAssignKeybind() return self.wheel:GetSelectedRadialEntry() ~= nil end ZO_Gamepad_AddForwardNavigationKeybindDescriptors(self.emoteAssignmentKeybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, OnAssignPendingData, GetString(SI_GAMEPAD_ITEM_ACTION_QUICKSLOT_ASSIGN), ShouldShowAssignKeybind) ZO_Gamepad_AddBackNavigationKeybindDescriptors(self.emoteAssignmentKeybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, function() self:ChangeCurrentMode(MODE_EMOTE_SELECTION) end) -- keybinds when selecting a category self.keybindStripDescriptor = {} ZO_Gamepad_AddForwardNavigationKeybindDescriptorsWithSound(self.keybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, function() self:ChangeCurrentMode(MODE_EMOTE_SELECTION) end, GetString(SI_GAMEPAD_SELECT_OPTION), function() return self.emoteListGrid:GetNumEmoteEntries() > 0 end) ZO_Gamepad_AddBackNavigationKeybindDescriptors(self.keybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON) self:SetListsUseTriggerKeybinds(true) end function ZO_GamepadPlayerEmote:DeselectCurrentMode() if self.mode == MODE_CATEGORY_SELECTION then KEYBIND_STRIP:RemoveKeybindButtonGroup(self.keybindStripDescriptor) self:DeactivateCurrentList() elseif self.mode == MODE_EMOTE_SELECTION then KEYBIND_STRIP:RemoveKeybindButtonGroup(self.categoryKeybindStripDescriptor) self.emoteListGrid:Deactivate() self.emoteListGrid:SetAllowHighlight(false) elseif self.mode == MODE_EMOTE_ASSIGNMENT then self:HideAssignableUtilityWheel() self.emoteListGridControl:SetHidden(false) KEYBIND_STRIP:RemoveKeybindButtonGroup(self.emoteAssignmentKeybindStripDescriptor) end self.mode = MODE_CATEGORY_INACTIVE end function ZO_GamepadPlayerEmote:SelectMode(mode) self.mode = mode if self.mode == MODE_CATEGORY_SELECTION then KEYBIND_STRIP:AddKeybindButtonGroup(self.keybindStripDescriptor) self:ActivateCurrentList() self.emoteListGrid:SetAllowHighlight(false) elseif self.mode == MODE_EMOTE_SELECTION then KEYBIND_STRIP:AddKeybindButtonGroup(self.categoryKeybindStripDescriptor) self.emoteListGrid:SetAllowHighlight(true) self.emoteListGrid:Activate() elseif self.mode == MODE_EMOTE_ASSIGNMENT then self:ShowAssignableUtilityWheel() end end function ZO_GamepadPlayerEmote:ChangeCurrentMode(mode) if self.mode ~= mode then self:DeselectCurrentMode() self:SelectMode(mode) self:RefreshHeader() end end function ZO_GamepadPlayerEmote:ShowAssignableUtilityWheel() local useAccessibleWheel = GetSetting_Bool(SETTING_TYPE_ACCESSIBILITY, ACCESSIBILITY_SETTING_ACCESSIBLE_QUICKWHEELS) local actionId = self.emoteListGrid:GetSelectedEmoteId() local slotType = nil local activeEntryType = self.emoteListGrid:GetSelectedEmoteType() if activeEntryType == EMOTE_GRID_ENTRY_TYPE_EMOTE then slotType = ACTION_TYPE_EMOTE elseif activeEntryType == EMOTE_GRID_ENTRY_TYPE_QUICK_CHAT then slotType = ACTION_TYPE_QUICK_CHAT end if useAccessibleWheel then ACCESSIBLE_ASSIGNABLE_UTILITY_WHEEL_GAMEPAD:SetPendingSimpleAction(slotType, actionId) ACCESSIBLE_ASSIGNABLE_UTILITY_WHEEL_GAMEPAD:Show({ HOTBAR_CATEGORY_EMOTE_WHEEL, HOTBAR_CATEGORY_QUICKSLOT_WHEEL }) else self.emoteListGridControl:SetHidden(true) KEYBIND_STRIP:AddKeybindButtonGroup(self.emoteAssignmentKeybindStripDescriptor) self.wheel:SetPendingSimpleAction(slotType, actionId) self.assignLabel:SetHidden(false) self.selectedEmoteNameLabel:SetHidden(false) self.selectedEmoteNameLabel:SetText(self.emoteListGrid:GetSelectedEmoteName()) -- This will Activate the menu and show it self.wheel:Show() end end function ZO_GamepadPlayerEmote:HideAssignableUtilityWheel() self.assignLabel:SetHidden(true) self.selectedEmoteNameLabel:SetHidden(true) -- This will deactivate the menu and hide it self.wheel:Hide() end function ZO_GamepadPlayerEmote:OnShowing() if self.isDirty then self:CreateCategoryList() end if self.queuedBrowseToCategoryData then self:ViewCategory(self.queuedBrowseToCategoryData) self.queuedBrowseToCategoryData = nil end self:ChangeCurrentMode(MODE_CATEGORY_SELECTION) TriggerTutorial(TUTORIAL_TRIGGER_EMOTES_MENU_OPENED) end function ZO_GamepadPlayerEmote:OnHiding() self:ChangeCurrentMode(MODE_CATEGORY_INACTIVE) end function ZO_GamepadPlayerEmote:QueueBrowseToCategoryData(categoryData) self.queuedBrowseToCategoryData = categoryData end --Global XML Handlers ----------------------- function ZO_GamepadPlayerEmote_OnInitialized(control) GAMEPAD_PLAYER_EMOTE = ZO_GamepadPlayerEmote:New(control) end