diff --git a/Titan/Titan.lua b/Titan/Titan.lua index 763b8d3..00df403 100644 --- a/Titan/Titan.lua +++ b/Titan/Titan.lua @@ -222,8 +222,11 @@ local function RegisterForEvents() _G[TITAN_PANEL_CONTROL]:RegisterEvent("ZONE_CHANGED_NEW_AREA"); -- 2026 Apr Add more info for Alts - _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_MONEY"); - _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_EQUIPMENT_CHANGED"); + _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_MONEY") + _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") + _G[TITAN_PANEL_CONTROL]:RegisterEvent("TIME_PLAYED_MSG") + _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_LEVEL_UP") + _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_XP_UPDATE") end -------------------------------------------------------------- @@ -262,6 +265,81 @@ local function RegisterAddonCompartment() end end +--****** overload the 'time played' text to Chat - if XP requested the API call +local requesting +---@diagnostic disable: duplicate-set-field + +-- Save orignal output to Chat +-- somewhere in 11.* (The World Within) this changed +local orig_ChatFrame_DisplayTimePlayed = function(...) end + +-- Do not output Chat messages when using RequestTimePlayed +function TitanPanelBarButton:RequestTimePlayed() + requesting = true + RequestTimePlayed() +end + +if Titan_Global.switch.chat_class then + orig_ChatFrame_DisplayTimePlayed = ChatFrameUtil.DisplayTimePlayed + + ChatFrameUtil.DisplayTimePlayed = function(...) --TimePlayed(...) + if requesting then + -- XP requested time played, do not spam Chat + requesting = false + else + -- XP did not request time played so output + ---@diagnostic disable-next-line: need-check-nil + orig_ChatFrame_DisplayTimePlayed(...) + end + end +else + orig_ChatFrame_DisplayTimePlayed = ChatFrame_DisplayTimePlayed + + ChatFrameUtil.DisplayTimePlayed = function(...) --TimePlayed(...) + if requesting then + -- XP requested time played, do not spam Chat + requesting = false + else + -- XP did not request time played so output + ---@diagnostic disable-next-line: need-check-nil + orig_ChatFrame_DisplayTimePlayed(...) + end + end +end +--****** overload end + +local function SetToonZoneInfo() + local toon_info = TitanSettings.Players[TitanSettings.Player].Info ---@class CharInfo + toon_info.zoneText = GetZoneText() + toon_info.subZoneText = GetSubZoneText() or "" +end + +local function GetElapsed(time_ago) + return (_G.time() - time_ago) +end + +--local Collect info for time played +local function SetToonPlayedInfo(action, total, level) + local toon_info = TitanSettings.Players[TitanSettings.Player].Info ---@class CharInfo + + if action == 'init' then + TitanPanelBarButton:RequestTimePlayed() -- TIME_PLAYED_MSG + toon_info.played_start = _G.time() + elseif action == 'update' then -- via event TIME_PLAYED_MSG + toon_info.played_total = total + GetElapsed(toon_info.played_start) + toon_info.played_this_level = level + GetElapsed(toon_info.played_start) + elseif action == 'logout' then -- + toon_info.played_total = toon_info.played_total + GetElapsed(toon_info.played_start) + toon_info.played_this_level = toon_info.played_this_level + GetElapsed(toon_info.played_start) + elseif action == 'level' then + toon_info.played_start = _G.time() + toon_info.played_total = toon_info.played_total + GetElapsed(toon_info.played_start) + toon_info.played_this_level = GetElapsed(toon_info.played_start) + else + -- !? + end +end + local function SetToonInfo(toon) -- New Dec 2025 Collect some toon info for profile display -- Unlikely to change on reload but... @@ -302,23 +380,30 @@ local function SetToonInfo(toon) toon_info.gold_toon = GetMoney() -- NO Warband local avgItemLevel, avgItemLevelEquipped, avgItemLevelPvp = GetAverageItemLevel() - toon_info.itemLevelAve = avgItemLevel -- using ony equp change event, this may not be accurate... + toon_info.itemLevelAve = avgItemLevel -- using only equp change event, this may not be accurate... toon_info.itemLevelEquipped = avgItemLevelEquipped -- this is the one we are tracking toon_info.itemLevelPvp = avgItemLevelPvp + + SetToonPlayedInfo('init') + + toon_info.unit_xp = UnitXP("player") + toon_info.unit_xp_max = UnitXPMax("player") end local function SetToonLogout(toon) -- New Dec 2025 Collect some toon info for profile display -- Unlikely to change on reload but... local toon_info = TitanSettings.Players[toon].Info - local unit = "player" - toon_info.zoneText = GetZoneText() - toon_info.subZoneText = GetSubZoneText() or "" + toon_info.gold_toon = GetMoney() local now = _G.time() toon_info.logout = now toon_info.logoutStr = TitanUtils_GetDateText(now, true) + + -- Zone and subzone set via events + + SetToonPlayedInfo('logout') end local function SetPluginsAndConfig() @@ -548,6 +633,7 @@ function TitanPanelBarButton:PLAYER_ENTERING_WORLD(arg1, arg2, arg3, arg4) Titan_Debug.Out('titan', 'p_e_w', "Titan init processing done") end + ---Titan Handle CVAR_UPDATE React to user changed WoW options. function TitanPanelBarButton:CVAR_UPDATE(cvarname, cvarvalue) if cvarname == "USE_UISCALE" @@ -587,16 +673,19 @@ end ---Titan Handle ZONE_CHANGED_INDOORS Hide Titan top bars if user requested to hide Top bar(s) in BG or arena function TitanPanelBarButton:ZONE_CHANGED() TitanPanelBarButton_DisplayBarsWanted("ZONE_CHANGED") + SetToonZoneInfo() end ---Titan Handle ZONE_CHANGED_INDOORS Hide Titan top bars if user requested to hide Top bar(s) in BG or arena function TitanPanelBarButton:ZONE_CHANGED_INDOORS() TitanPanelBarButton_DisplayBarsWanted("ZONE_CHANGED_INDOORS") + SetToonZoneInfo() end ---Titan Handle ZONE_CHANGED_INDOORS Hide Titan top bars if user requested to hide Top bar(s) in BG or arena function TitanPanelBarButton:ZONE_CHANGED_NEW_AREA() TitanPanelBarButton_DisplayBarsWanted("ZONE_CHANGED_NEW_AREA") + SetToonZoneInfo() end ---Titan Handle PET_BATTLE_CLOSE Hide Titan bars during pet battle. @@ -632,14 +721,14 @@ function TitanPanelBarButton:PLAYER_REGEN_DISABLED() TitanPanelBarButton_DisplayBarsWanted("PLAYER_REGEN_DISABLED") end ----Titan Handle ZONE_CHANGED_INDOORS Hide Titan top bars if user requested to hide Top bar(s) in BG or arena +---Titan Store in profile function TitanPanelBarButton:PLAYER_MONEY() local toon_info = TitanSettings.Players[TitanSettings.Player].Info -- 2026 Mar Add more info for Alts toon_info.gold_toon = GetMoney() -- NO Warband end ----Titan Handle ZONE_CHANGED_INDOORS Hide Titan top bars if user requested to hide Top bar(s) in BG or arena +---Titan Store in profile function TitanPanelBarButton:PLAYER_EQUIPMENT_CHANGED() local toon_info = TitanSettings.Players[TitanSettings.Player].Info -- 2026 Mar Add more info for Alts @@ -653,6 +742,26 @@ function TitanPanelBarButton:PLAYER_EQUIPMENT_CHANGED() end +---Titan Handle TIME_PLAYED_MSG Total and this level for /played +function TitanPanelBarButton:TIME_PLAYED_MSG(a1, a2, ...) + local toon_info = TitanSettings.Players[TitanSettings.Player].Info ---@class CharInfo + SetToonPlayedInfo('update', a1, a2) +end + +---Titan Handle TIME_PLAYED_MSG Total and this level for /played +function TitanPanelBarButton:PLAYER_LEVEL_UP(...) + local toon_info = TitanSettings.Players[TitanSettings.Player].Info ---@class CharInfo + SetToonPlayedInfo('level') +end + +---Titan Store XP and Max in profile +function TitanPanelBarButton:PLAYER_XP_UPDATE(...) + local toon_info = TitanSettings.Players[TitanSettings.Player].Info ---@class CharInfo + toon_info.unit_xp = UnitXP("player") + toon_info.unit_xp_max = UnitXPMax("player") +end + + if Titan_Global.switch.can_edit_ui then -- Do not need to adjust frames else diff --git a/Titan/TitanUtils.lua b/Titan/TitanUtils.lua index 2544029..f5f70c5 100644 --- a/Titan/TitanUtils.lua +++ b/Titan/TitanUtils.lua @@ -1678,7 +1678,7 @@ end ---@param profile string A player name to look up ---@param attrib string Specific data to look up ---@param create boolean If true and no data table, create an empty table ----@return string result is_custom | found | not_found | created +---@return string result is_custom | found | not_found or created ---@return table? data nil or table of data found/created function TitanUtils_GetProfileInfo(profile, attrib, create) local _, server, is_custom = TitanUtils_ParseName(profile) diff --git a/Titan/_ATitanDoc.lua b/Titan/_ATitanDoc.lua index 7220510..45a5866 100644 --- a/Titan/_ATitanDoc.lua +++ b/Titan/_ATitanDoc.lua @@ -51,6 +51,13 @@ Contains ... --]===] Each file has a terse description of its contents. +--[===[ Var +... +--]===] +These are critical tables and info used within Titan. +Unless specifically marked otherwise, treat these as "---Titan". + + ---API These are routines Titan will keep stable. Changes to these varibles and routines will be broadcast to developers via Discord at a minimum. @@ -58,12 +65,6 @@ Changes to these varibles and routines will be broadcast to developers via Disco ---Titan These are global routines Titan uses. These may change at any time per Titan needs and design. ---[===[ Var -... ---]===] -These are critical tables and info used within Titan. -Unless specifically marked otherwise, treat these as "---Titan". - ---local These are local routines that may change at any time. --]======] @@ -146,6 +147,43 @@ We don’t recommend using an online source to convert one image format to anoth They have a tendency to add additional code or info to the image. --]======] +--[======[ Titan Panel Profiles +Titan has always run on profiles. In release 9.* this became more explicit to the user with Sync. +Custom profiles have been available for some time before 9.* but are more usable with Sync and Sync All. + +On PEW, Titan determines the profile to use - See code flow below. +This sets Titan the way the user wants; showing the selected bars and plugins. + +Also in 9.* character data such as gold and mail (Post) were moved into the profile. +This reduced the data built-in plugins needed to store on each character. +The moving of data changed Titan saved vars and processing. + +Every character has had a section in saved variables since release 1.0: +TitanSettings.Players.<name>@<server> + +Under this .Info table was added in 9.* to hold character information. +Some built-in plugins added a .<plugin> at the same level as .Info; such as .Gold for Gold +The table holds data needed for the plugin such as a show / hide character option. + +The Saved Variables section below shows a sample saved variable structure. + +Consequences of this change are: +1) Titan must ensure a .Info exists for each character profile. +This is done in TitanVariables before Titan decides the profile. +.Info can be an empty table for a character not logged into yet but it must exist. +Dealing with non existent values before using is easier than seeing if a table exists before every reference. + +2) Plugins with their own section must ensure the entry exists for each character profile. +This should be done as part of the OnShow to ensure Titan tables are whole. + +3) Titan and Plugins that need .Info must NOT assume values exist. +This allows information to be built over time as the user logs into characters. +Plugins should set default values as the table entry is created. + +Note that character profiles do not include custom profiles. One can not log into custom profiles. + +--]======] + --[======[ Titan Addon code flow First step: ======= Starting WoW @@ -353,59 +391,75 @@ TitanSettings = { ["Players"] = { ["Embic@Staghelm"] = { ["Panel"] = { - -- Holds all the Titan settings for this character + -- Holds all the Titan level settings for this character + } + ["Info"] = { + -- Holds various information for this character, used by Titan and some built-in plugins + -- example : + ["levelText"] = "80", + ["itemLevelPvp"] = 137.75, + ["class"] = "Demon Hunter", + ["raceName"] = "NightElf", + ["race"] = "Night Elf", + ["played_start"] = 1775660178, + ["factionName"] = "Alliance", + ["level"] = 80, + ["server"] = "Staghelm", + ["played_total"] = 805746, + ["gold_toon"] = 1086716295, + ["itemLevelEquipped"] = 137.75, + ["logout"] = 1775660193, + ["itemLevelAve"] = 137.75, + ["raceId"] = 4, + ["faction"] = "Alliance", + ["logoutStr"] = "2026-04-08 10:56", + ["name"] = "Stormblade", + ["className"] = "DEMONHUNTER", + ["subZoneText"] = "The Bazaar", + ["played_this_level"] = 128790, + ["classId"] = 12, + ["zoneText"] = "Silvermoon City", + } + [<plugin>] = { + -- Holds various information for this character, specific to THIS plugin } ["BarVars"] = { -- Holds all the Titan bar settings for this character } ["Plugins"] = { - -- Each registered plugin will be here - ["Starter"] = { - ["notes"] = "Adds bag and free slot information to Titan Panel.\n", - ["menuTextFunction"] = nil, - ["id"] = "Starter", - ["menuText"] = "Bag", - ["iconWidth"] = 16, - ["savedVariables"] = { - ["ShowColoredText"] = 1, - ["CustomLabel3Text"] = "", - ["ShowIcon"] = 1, - ["OpenBags"] = false, - ["CustomLabel3TextShow"] = false, - ["CustomLabelTextShow"] = false, - ["CustomLabel4Text"] = "", - ["CustomLabel2Text"] = "", - ["OpenBagsClassic"] = "new_install", - ["ShowLabelText"] = 1, - ["CustomLabel4TextShow"] = false, - ["CountProfBagSlots"] = false, - ["ShowUsedSlots"] = 1, - ["DisplayOnRightSide"] = false, - ["ShowDetailedInfo"] = false, - ["CustomLabel2TextShow"] = false, - ["CustomLabelText"] = "", - }, - ["controlVariables"] = { - ["DisplayOnRightSide"] = true, - ["ShowColoredText"] = true, - ["ShowIcon"] = true, - ["ShowLabelText"] = true, - }, - ["version"] = "1.0.0", - ["category"] = "Information", - ["buttonTextFunction"] = nil , - ["tooltipTextFunction"] = nil , - ["icon"] = "Interface\\AddOns\\TitanPlugin\\Artwork\\TitanStarter", - ["tooltipTitle"] = "Bags Info", - }, - } + -- Each registered plugin saved vars will be here + -- Below is Location as an example + ["Location"] = { + ["CoordsLoc"] = "Bottom", + ["ShowZoneText"] = 1, + ["NumLabelsSeen"] = 2, + ["ShowRealmText"] = false, + ["ShowIcon"] = 1, + ["ShowCoordsText"] = true, + ["ShowSubZoneText"] = false, + ["CustomLabelText"] = "", + ["CustomLabel3TextShow"] = false, + ["CustomLabelTextShow"] = false, + ["ShowCoordsOnMap"] = true, + ["CustomLabel4Text"] = "", + ["ShowCursorOnMap"] = true, + ["CoordsFormat"] = "(%.d, %.d)", + ["ShowLabelText"] = 1, + ["DisplayOnRightSide"] = false, + ["ShowColoredText"] = 1, + ["UpdateWorldmap"] = false, + ["CustomLabel2Text"] = "", + ["CustomLabel2TextShow"] = false, + ["CoordsLabel"] = true, + ["CustomLabel3Text"] = "", + ["CustomLabel4TextShow"] = false, + }, ["Adjust"] = { -- Holds offsets for frames the user may adjust - Retail and Classic have different list of frames } ["Register"] = { - -- Holds data as each plugin and LDB is attempted to be registered. - -- There may be helpful debug data here under your plugin name if the plugin is not shown as expected. - -- Titan > Configuration > Attempts shows some of this data, including errors. + -- Exists but empty - used to holds data as each plugin and LDB is attempted to be registered. + -- Titan > Configuration > Attempts shows some data, including errors. } ... TitanAll = { diff --git a/Titan/_TitanIDE.lua b/Titan/_TitanIDE.lua index 2aaa335..ec4149a 100644 --- a/Titan/_TitanIDE.lua +++ b/Titan/_TitanIDE.lua @@ -198,7 +198,7 @@ C_Bank = {} -- 11.0.0 New Warbank - Hopefully WoW API extension will catch up so ---@field AddContextMenu function Titan ONLY to create root menu --====== New Dec 2025 Collect info on each toon for Profile Config --- Also used by plugins Gold and Post +-- Also used by plugins such as Gold and Post ---@class CharInfo ---@field name string ---@field server string @@ -216,6 +216,11 @@ C_Bank = {} -- 11.0.0 New Warbank - Hopefully WoW API extension will catch up so ---@field itemLevelAve number ---@field itemLevelEquipped number ---@field itemLevelPvp number +---@field played_start number +---@field played_total number +---@field played_this_level number +---@field unit_xp number +---@field unit_xp_max number --====== Profile output from Utils ---@class Get_Profile_Result diff --git a/TitanAlts/Artwork/Alliance.blp b/TitanAlts/Artwork/Alliance.blp new file mode 100755 index 0000000..b5508fc Binary files /dev/null and b/TitanAlts/Artwork/Alliance.blp differ diff --git a/TitanAlts/Artwork/Alts.blp b/TitanAlts/Artwork/Alts.blp new file mode 100755 index 0000000..ceb493d Binary files /dev/null and b/TitanAlts/Artwork/Alts.blp differ diff --git a/TitanAlts/Artwork/Horde.blp b/TitanAlts/Artwork/Horde.blp new file mode 100755 index 0000000..570ca67 Binary files /dev/null and b/TitanAlts/Artwork/Horde.blp differ diff --git a/TitanAlts/Artwork/Neutral.blp b/TitanAlts/Artwork/Neutral.blp new file mode 100755 index 0000000..8ccbffd Binary files /dev/null and b/TitanAlts/Artwork/Neutral.blp differ diff --git a/TitanAlts/Artwork/TitanPanelPushpinIn.tga b/TitanAlts/Artwork/TitanPanelPushpinIn.tga new file mode 100755 index 0000000..406ee98 Binary files /dev/null and b/TitanAlts/Artwork/TitanPanelPushpinIn.tga differ diff --git a/TitanAlts/Artwork/TitanPanelPushpinOut.tga b/TitanAlts/Artwork/TitanPanelPushpinOut.tga new file mode 100755 index 0000000..d3c892b Binary files /dev/null and b/TitanAlts/Artwork/TitanPanelPushpinOut.tga differ diff --git a/TitanAlts/TitanAlts.lua b/TitanAlts/TitanAlts.lua new file mode 100755 index 0000000..12fc2be --- /dev/null +++ b/TitanAlts/TitanAlts.lua @@ -0,0 +1,1219 @@ +---@diagnostic disable: duplicate-set-field +--[[ +-- ************************************************************************** +-- * TitanUI.lua +-- * +-- * By: The Titan Panel Development Team +-- ************************************************************************** +--]] +-- ******************************** Constants ******************************* +local add_on = ... +local _G = _G --getfenv(0); +local L = LibStub("AceLocale-3.0"):GetLocale(TITAN_ID, true) + +local QTip = LibStub("LibQTip-1.0") +local iconProvider, cellPrototype, baseCellPrototype = QTip:CreateCellProvider(QTip.LabelProvider) +-- Required for Create - just call the base init +function cellPrototype:InitializeCell() + baseCellPrototype.InitializeCell(self); +end + +-- Required for Create - override the base Setup to use an icon +function cellPrototype:SetupCell(tooltip, value, justification, font) + local _, height = baseCellPrototype.SetupCell(self, tooltip, format("|T%s:0|t", tostring(value)), "CENTER"); + return baseCellPrototype.SetupCell(self, tooltip, + format("|T%s:%2$d:%2$d:0:0:64:64:4:60:4:60|t", tostring(value), height), "CENTER"); +end + +local UNK = TitanUtils_GetGrayText("-") +--]] + +local AceConfigDialog = LibStub("AceConfigDialog-3.0") + +local artwork_path = "Interface\\AddOns\\TitanAlts\\Artwork\\" +local TITAN_PLUGIN = "Alts" +local TITLE = "Alts" +local TITAN_BUTTON = "TitanPanel" .. TITAN_PLUGIN .. "Button" +local VERSION = C_AddOns.GetAddOnMetadata(add_on, "Version") +local MAX_COLS = 10 + +local Alts = {} -- namespace for Alts routines as needed + +-- ******************************** IDE ******************************* +---@class AltInfo -- To store desired info for display +---@field name_titan string +---@field server string +---@field class string +---@field className string +---@field classId number +---@field faction string +---@field factionName string +---@field level number +---@field levelText string +---@field race string +---@field raceName string +---@field raceId number +---@field gold_toon string +---@field itemLevelAve number +---@field itemLevelEquipped number +---@field itemLevelPvp number +---@field zoneText string +---@field subZoneText string +---@field logout string +---@field xp_now number -- UnitXP("player") and UnitXPMax("player"); GetXPExhaustion() +---@field xp_max number +---@field xp_per string +---@field xp_rest number -- ?? GetRestState() for XP multiplier +---@field prof_1 string -- GetProfessions() then GetProfessionInfo(index) +---@field prof_2 string +---@field played_total number -- RequestTimePlayed() >> TIME_PLAYED_MSG +---@field sync_titan string -- may implement +---@field sync_global boolean -- may implement + +-- ******************************** Variables ******************************* +local trace = false -- true / false Make true when debug output is needed. +local alts_tt = {} -- Holds alt data for tooltip display; gen once except for logged in toon +local alts_tt_sort_col = "" -- one sort to rule them all... +local alts_tt_sort_ascend = true -- default on click; click again to flip +local tt_frame = {} -- tooltip on the QTip :) + +Titan_Debug.alts = {} +Titan_Debug.alts.tool_tips = false + +-- ******************************** Routines ******************************* + +--Helper routines + +local function CloseQTooltip(self, force) + if self.qtip:Acquire("TitanAlts_Tooltip", MAX_COLS) then --(not self.qtooltip) then + if (force) then + self.qtooltip.locked = false; + end + if (self.qtooltip.locked) then + -- leave tooltip alone + else + self.qtooltip:SetScale(1); + self.qtip:Release(self.qtooltip); + -- table.wipe(alts_tooltip); + end + else + return; + end +end + +local function GetTimeParts(seconds_value) + local s = seconds_value + local years = 0 + local days = 0 + local hours = 0 + local minutes = 0 + local seconds = 0 + if not s or (s < 0) then + seconds = -1 + else + years = floor(s / 365 / 24 / 60 / 60); s = mod(s, 365 * 24 * 60 * 60); + days = floor(s / 24 / 60 / 60); s = mod(s, 24 * 60 * 60); + hours = floor(s / 60 / 60); s = mod(s, 60 * 60); + minutes = floor(s / 60); s = mod(s, 60); + seconds = s; + end + + return years, days, hours, minutes, seconds +end + +local function GetAbbrTimeText(seconds_value) + local timeText = ""; + local years, days, hours, minutes, seconds = GetTimeParts(seconds_value) + if seconds == nil + or seconds == 0 + then + timeText = UNK + else + if (years > 0) then + timeText = timeText .. format("%d" .. "y" .. " ", years); + end + if (days > 0) then + timeText = timeText .. format("%d" .. L["TITAN_PANEL_DAYS_ABBR"] .. " ", days); + end + if (hours > 0) then + timeText = timeText .. format("%d" .. L["TITAN_PANEL_HOURS_ABBR"] .. " ", hours); + elseif (hours == 0 and minutes > 0) then + timeText = timeText .. format("%d" .. L["TITAN_PANEL_HOURS_ABBR"] .. " ", hours); + end +--[[ + if (days ~= 0 or hours ~= 0 or minutes ~= 0) then + timeText = timeText .. format("%d" .. L["TITAN_PANEL_MINUTES_ABBR"] .. " ", minutes); + end +-- timeText = timeText .. format("%d" .. L["TITAN_PANEL_SECONDS_ABBR"], seconds) +--]] + end + return timeText; +end + +---local Helper to set both the parent and the position of Tooltip for the plugin tooltip. +---@param parent table Reference to the frame to attach the tooltip to +---@param anchorPoint string Tooltip anchor location (side or corner) to use +---@param relativeToFrame string name name of the frame, usually the plugin), to attach the tooltip to +---@param relativePoint string Parent anchor location (side or corner) to use +---@param xOffset number X offset +---@param yOffset number Y offset +---@param frame table Tooltip frame +---@param custom boolean If custom / not tooltip frame +local function SetOwnerPosition(parent, anchorPoint, relativeToFrame, relativePoint, xOffset, yOffset, frame, custom) + -- Changes for 9.1.5 Removed the background template from the Tooltip + -- Making changes to it difficult and possibly changing the tooltip globally. + + if custom then + -- do NOT set owner - it clears the contents! + else + frame:SetOwner(parent, "ANCHOR_NONE") + end + + frame:SetPoint(anchorPoint, relativeToFrame, relativePoint, xOffset, yOffset); + + -- set font size for the Game Tooltip + if TitanPanelGetVar("DisableTooltipFont") then + -- use UI scale + else + if TitanTooltipScaleSet < 1 then + TitanTooltipOrigScale = frame:GetScale(); + TitanTooltipScaleSet = TitanTooltipScaleSet + 1; + end + frame:SetScale(TitanPanelGetVar("TooltipFont")); + end + + local dbg_msg = "_SetOwner _pos" + .. " '" .. tostring(frame:GetName()) .. "'" + .. " " .. tostring(frame:IsShown()) .. "" + .. " @ '" .. tostring(relativeToFrame) .. "'" + .. " " .. tostring(_G[relativeToFrame]:IsShown()) .. "" + Titan_Debug.Out('alts', 'tool_tips', dbg_msg) + dbg_msg = ">>_pos" + .. " " .. tostring(anchorPoint) .. "" + .. " " .. tostring(relativePoint) .. "" + .. " w" .. tostring(format("%0.1f", frame:GetWidth())) .. "" + .. " h" .. tostring(format("%0.1f", frame:GetHeight())) .. "" + Titan_Debug.Out('alts', 'tool_tips', dbg_msg) +end + +---local Helper to set the screen position of the tooltip frame +---@param self table Plugin frame +---@param id string Plugin id name +---@param frame table Tooltip frame to use +---@param custom? boolean If custom / not tooltip frame +local function SetPanelTooltip(self, id, frame, custom) + local is_custom = custom or false + local button = _G[id] + + if button then + -- Adjust the Y offset as needed + local top = self:GetTop() + local hgt = frame:GetHeight() + local lft = self:GetLeft() + + local rel_y = top - hgt + local pt = "" + local rel_pt = "" + if rel_y > 0 then + pt = "TOP"; + rel_pt = "BOTTOM"; + else + -- too close to bottom of screen + pt = "BOTTOM"; + rel_pt = "TOP"; + end + local rel_x = lft + hgt + if (rel_x < GetScreenWidth()) then + -- menu will fit + pt = pt .. "LEFT"; + rel_pt = rel_pt .. "LEFT"; + else + pt = pt .. "RIGHT"; + rel_pt = rel_pt .. "RIGHT"; + end + + SetOwnerPosition(button, pt, button:GetName(), rel_pt, 0, 0, frame, is_custom) + end +end + +local function ClassColors(class, str) + local res = str + local use = TitanGetVar(TITAN_PLUGIN, "use_class_colors") + if use then + -- local colors = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[class] + local colors = RAID_CLASS_COLORS[class] + if colors then + local r = string.format("%02x", colors.r * 255) + local g = string.format("%02x", colors.g * 255) + local b = string.format("%02x", colors.b * 255) + local coloredText = "|cff" .. r .. g .. b .. str .. "|r" + res = coloredText + end + else + -- untouched + end + return res +end + +local function SetVal(value) + local res = "" + if value then + res = value + else + res = UNK + end + return res +end + +local function Get_gold(money) + local res = "" + if money == nil + or money == 0 then + res = UNK + else + res = TitanUtils_CashToString(money, ",", ".", true, false, true, true) + end + + return res +end + +local function Get_ilvl(level) + local res = "" + if level == nil + or level == 0 then + res = UNK + else + res = string.format("%.0f", level) + end + + return res +end + +local function Get_lvl(level) + local res = "" + if level == nil + or level == 0 then + res = UNK + else + res = string.format("%.0f", level) + end + + return res +end + +local function GetSync(toon) + local profile = TitanVariables_GetProfile(toon) + local res = "" + local global = false + + -- Create string after Profile name in header + if profile.ptype == Titan_Global.profile.GLOBAL then + res = profile.cname + global = true + elseif profile.ptype == Titan_Global.profile.SYNC then + res = profile.cname + elseif profile.ptype == Titan_Global.profile.TOON then + res = Titan_Global.profile.NONE + else + res = UNK + end + + return res, global +end + +local function Cell_tt_show(self, text) + -- HideDetail(); + local tt = tt_frame + tt:SetClampedToScreen(true) + tt:SetOwner(self, "ANCHOR_RIGHT", 10, -10) + SetPanelTooltip(self, self, tt, false) + tt:SetFrameLevel(self:GetFrameLevel() + 1) + tt:SetText(text) + + -- for keeping tooltip up if cursor never goes over tooltip + -- via OnUpdate script + tt.parent_frame = self + tt:Show() +end + +local function Cell_tt_hide(self, text, parent) + local tt = tt_frame + tt:Hide() +end + +local function SortDB(self, tt_key) + + if alts_tt_sort_col == tt_key then + alts_tt_sort_ascend = not alts_tt_sort_ascend -- flip the sort + else + alts_tt_sort_ascend = true + end + alts_tt_sort_col = tt_key + + local sorter = nil + if alts_tt_sort_ascend then + sorter = function(a, b) + return a[tt_key] < b[tt_key] + end; + else + sorter = function (a, b) + return a[tt_key] > b[tt_key] + end; + end + + for idx = 1, #alts_tt do + table.sort(alts_tt, sorter) + end + + Alts.GenTooltip(_G[TITAN_BUTTON]) +end + +-- PLAYER_EQUIPMENT_CHANGED +-- Grab the button text to display +local function GetButtonText(id) + local avgItemLevel, avgItemLevelEquipped, avgItemLevelPvp = GetAverageItemLevel() + local strA, strB = TITLE, "" + local ave = format("%.2f", avgItemLevel) + local eq = format("%.0f", avgItemLevelEquipped) + local pvp = format("%.2f", avgItemLevelPvp) + return strA, strB, "ilvl : ", eq +end + +-- Create the tooltip string +local function GetTooltipText() + local res = "" + local rtn = "\n" + local tab = "\t" + + local header = "Name" .. tab + .. "Realm" .. tab + .. "Class" .. tab + .. "Zone" .. tab + .. "XP" --.. tab + .. rtn + -- .. TitanUtils_GetHighlightText(GetRealmName()) .. rtn + print("alts" + .. " " .. tostring(header) .. "" + ) + local now = _G.time() + + local resets = "Resets in Server Time" .. rtn + local week_reset = C_DateAndTime.GetSecondsUntilWeeklyReset() + local weekly = TitanUtils_GetNormalText("Weekly :") .. tab + .. TitanUtils_GetHighlightText(TitanUtils_GetDateText(week_reset + now, true)) .. rtn + + local day_reset = C_DateAndTime.GetSecondsUntilDailyReset() + local daily = TitanUtils_GetNormalText("Daily :") .. tab + .. TitanUtils_GetHighlightText(TitanUtils_GetDateText(day_reset + now, true)) .. rtn + + local hints = "" + -- .. TitanUtils_GetGreenText("Left Click: Reloads the User Interface") .. rtn + -- .. TitanUtils_GetGreenText("Right Click: For Shortcuts and Debug Tools") .. rtn + + res = res + .. header + .. rtn + .. resets .. daily .. weekly + .. rtn + .. hints + + return res +end + +-- Routine per column... +local headerFont = {} +local header_justify = "CENTER" + +local function GenFaction(self, row, col, action, tt_info, toon_info) + local next = nil + if action == 'header' then + row, next = self.qtooltip:SetCell(row, + col, + artwork_path .. "TitanPanelPushpin" .. (self.qtooltip.locked and "In" or "Out"), -- value + iconProvider --, + ) + self.qtooltip:SetCellScript(row, col, "OnEnter", Cell_tt_show, (self.qtooltip.locked and UNLOCK or LOCK) ); + self.qtooltip:SetCellScript(row, col, "OnLeave", Cell_tt_hide); + -- self.qtooltip:SetCellScript(row, col, "OnMouseDown", OnLockClick); + elseif action == 'row' then + if toon_info.faction == "Alliance" then + row, next = self.qtooltip:SetCell(row, col, artwork_path .. "Alliance", iconProvider) + elseif toon_info.faction == "Horde" then + row, next = self.qtooltip:SetCell(row, col, artwork_path .. "Horde", iconProvider) + else + -- just in case. Technically a faction must be chosen now but there could be OLD toons out there. + row, next = self.qtooltip:SetCell(row, col, "") + end + elseif action == 'total' then + row, next = self.qtooltip:SetCell(row, col, "") + else + -- !? + end + + return row, next +end + +local total_toons = 0 +local total_shown = 0 +local function GenToonName(self, row, col, action, tt_info, toon_info) + local next = nil + if action == 'header' then + row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify) + self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key) + total_shown = 0 + elseif action == 'row' then + row, next = self.qtooltip:SetCell(row, col, ClassColors(toon_info.className, toon_info.name_titan)) + total_shown = total_shown + 1 + elseif action == 'total' then + row, next = self.qtooltip:SetCell(row, col, tostring(total_shown).." / "..tostring(total_toons)) + else + -- !? + end + + return row, next +end + +local function GenLevel(self, row, col, action, tt_info, toon_info) + local next = nil + if action == 'header' then + row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify); + self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key) + elseif action == 'row' then + row, next = self.qtooltip:SetCell(row, col, SetVal(toon_info.levelText), "RIGHT") + elseif action == 'total' then + row, next = self.qtooltip:SetCell(row, col, "") + else + -- !? + end + + return row, next +end + +local function GenILevel(self, row, col, action, tt_info, toon_info) + local next = nil + if action == 'header' then + row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify); + self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key) + elseif action == 'row' then + local str = "" + local tt_str = "" + if toon_info.itemLevelEquipped == nil + or toon_info.itemLevelEquipped == 0 then + str = UNK + else + str = string.format("%.0f", toon_info.itemLevelEquipped) + tt_str = "Equipped : "..PVP.." "..string.format("%.0f", toon_info.itemLevelPvp) + end + row, next = self.qtooltip:SetCell(row, col, str, "RIGHT") + if tt_str == "" then + -- nothing to show + else + self.qtooltip:SetCellScript(row, col, "OnEnter", Cell_tt_show, tt_str); + self.qtooltip:SetCellScript(row, col, "OnLeave", Cell_tt_hide); + end + elseif action == 'total' then + row, next = self.qtooltip:SetCell(row, col, "") + else + -- !? + end + + return row, next +end + +local function GenZone(self, row, col, action, tt_info, toon_info) + local next = nil + if action == 'header' then + row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify); + elseif action == 'row' then + row, next = self.qtooltip:SetCell(row, col, SetVal(toon_info.zoneText)) + self.qtooltip:SetCellScript(row, col, "OnEnter", Cell_tt_show, (toon_info.subZoneText or "") ); + self.qtooltip:SetCellScript(row, col, "OnLeave", Cell_tt_hide); + elseif action == 'total' then + row, next = self.qtooltip:SetCell(row, col, "") + else + -- !? + end + + return row, next +end + +local function GenLogout(self, row, col, action, tt_info, toon_info) + local next = nil + if action == 'header' then + row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify); + elseif action == 'row' then + local str = toon_info.logout + row, next = self.qtooltip:SetCell(row, col, str) + elseif action == 'total' then + row, next = self.qtooltip:SetCell(row, col, "") + else + -- !? + end + + return row, next +end + +local total_gold = 0 +local function GenMoney(self, row, col, action, tt_info, toon_info) + local next = nil + local str = "" + if action == 'header' then + row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify) + self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key) + total_gold = 0 + elseif action == 'row' then + str = "" + if toon_info.gold_toon == nil + or toon_info.gold_toon == 0 then + str = UNK + else + str = TitanUtils_CashToString(toon_info.gold_toon, ",", ".", true, false, true, true) + total_gold = total_gold + toon_info.gold_toon + end + row, next = self.qtooltip:SetCell(row, col, str, "RIGHT") + elseif action == 'total' then + str = TitanUtils_CashToString(total_gold, ",", ".", true, false, true, true) + row, next = self.qtooltip:SetCell(row, col, str) + else + -- !? + end + + return row, next +end + +local total_played = 0 +local function GenPlayed(self, row, col, action, tt_info, toon_info) + local next = nil + local str = "" + if action == 'header' then + row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify) + self.qtooltip:SetCellScript(row, col, "OnMouseDown", SortDB, tt_info.tt_key) + total_played = 0 + elseif action == 'row' then + total_played = total_played + (toon_info.played_total or 0) + -- total time played + str = "" + if toon_info.played_total == nil + or toon_info.played_total == 0 then + str = UNK + else + str = GetAbbrTimeText(toon_info.played_total) + end + row, next = self.qtooltip:SetCell(row, col, str, "RIGHT") + elseif action == 'total' then + str = GetAbbrTimeText(total_played) + row, next = self.qtooltip:SetCell(row, col, str) + else + -- !? + end + + return row, next +end + +local function GenSync(self, row, col, action, tt_info, toon_info) + local next = nil + local str = "" + if action == 'header' then + row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify) + elseif action == 'row' then + -- total time played + str = "" + if toon_info.sync_titan == nil + or toon_info.sync_titan == 0 then + str = UNK + else + str = toon_info.sync_titan + end + row, next = self.qtooltip:SetCell(row, col, str) + elseif action == 'total' then + row, next = self.qtooltip:SetCell(row, col, "") + else + -- !? + end + + return row, next +end + +local max_level = 0 +local function GenXP(self, row, col, action, tt_info, toon_info) + local next = nil + local str = "" + if action == 'header' then + row, next = self.qtooltip:SetCell(row, col, tt_info.title, headerFont, header_justify) + elseif action == 'row' then + str = "" + local tt_str = "" + if toon_info.xp_now == nil + or toon_info.xp_max == nil + or toon_info.xp_now == 0 + or toon_info.xp_max == 0 then + str = UNK + tt_str = "Log in" + elseif toon_info.level_toon == max_level then + str = UNK + tt_str = "Max level" + else + local per = (toon_info.xp_now / toon_info.xp_max) * 100 + str = string.format("%d%%", per) + tt_str = toon_info.xp_now.. " / ".. toon_info.xp_max + end + row, next = self.qtooltip:SetCell(row, col, str) + self.qtooltip:SetCellScript(row, col, "OnEnter", Cell_tt_show, tt_str); + self.qtooltip:SetCellScript(row, col, "OnLeave", Cell_tt_hide); + elseif action == 'total' then + row, next = self.qtooltip:SetCell(row, col, "") + else + -- !? + end + + return row, next +end + +--[[ +This scheme may be overkill but is a data driven approach when columns are +across header, rows, and total of the tooltip. + +tt_cols : holds the col name in the order they will be displayed +tt_data : index are names in tt_col; holds info to fill a cell +- config : if true place in config for Show / Hide +- title : column title +- tt_key : column field; used in sort if enabled; also saved var name for show / hide if config is true +Used to allow loops and min 'hard coding' - only need to change in two places tt_data and OnLoad +- cell_func expects (plugin(Alts), row, col, action, toon name, toon table/info) for SetCell +returning row, next_col/nil +A routine is needed for each col because each col has unique processing needs. + +In the GenTooltip there will be 3 loops : header, row, and total +- cell_func must handle each action to ensure data aligns +- Qtip will handle the size and spacing + +--]] + +local tt_cols = { -- set order of the cols, user can show / hide most + "faction", + "toon_name", + "level", + "item_level", + "zone", + "logout", + "money", + "played", + "profile", + "unit_xp", +} +local tt_data = { -- index MUST include all tt_cols values !!! + ["faction"] = { + config = false, + tt_key = "faction", + sortable = false, + title = "", + cell_func = GenFaction, + }, + ["toon_name"] = { + config = false, + tt_key = "name_titan", + title = NAME, + cell_func = GenToonName, + }, + ["level"] = { + config = true, + tt_key = "level_toon", + title = LEVEL_ABBR, + cell_func = GenLevel, + }, + ["item_level"] = { + config = true, + tt_key = "itemLevelEquipped", + title = ITEM_LEVEL_ABBR, + cell_func = GenILevel, + }, + ["zone"] = { + config = true, + tt_key = "zone", + title = ZONE, + cell_func = GenZone, + }, + ["logout"] = { + config = true, + tt_key = "logout", + title = L["TITAN_PANEL_MENU_PROFILE_LOGOUT"], + cell_func = GenLogout, + }, + ["money"] = { + config = true, + tt_key = "gold_toon", + title = L["TITAN_GOLD_MENU_TEXT"], + cell_func = GenMoney, + }, + ["played"] = { + config = true, + tt_key = "played_total", + title = PLAYED, + cell_func = GenPlayed, + }, + ["profile"] = { + config = true, + tt_key = "sync_titan", + title = L["TITAN_PANEL_MENU_PROFILE_SYNC"], + cell_func = GenSync, + }, + ["unit_xp"] = { + config = true, + tt_key = "xp_now", + title = L["TITAN_XP_MENU_TEXT"], + cell_func = GenXP, + }, +} + +---Generate or wipe the tooltip DB +---@param action string create | wipe +local function GenDB(self, action) + self.qtooltip.locked = false; + + wipe(alts_tt) + if action == 'wipe' then + -- already cleared, get out + else + for idx, pdata in TitanUtils_PlayerIter() do + local result = "" + local str = "" + local toon_info ---@class CharInfo + local alt_info = {} ---@class AltInfo + + result, toon_info = TitanUtils_GetProfileInfo(idx, "Info", false) + if result == "is_custom" then + -- skip, can not log in + elseif toon_info then -- found BUT could be empty... + -- Need to copy so Titan Settings are not changed + alt_info[tt_data["faction"].tt_key] = toon_info.faction + alt_info[tt_data["toon_name"].tt_key] = idx + alt_info.className = toon_info.className --ClassColors(toon_info.className, toon_info.class) + alt_info[tt_data["level"].tt_key] = toon_info.level + alt_info.levelText = Get_lvl(toon_info.level) + alt_info[tt_data["zone"].tt_key] = toon_info.zoneText + alt_info.subZoneText = toon_info.subZoneText + alt_info[tt_data["logout"].tt_key] = TitanUtils_GetDateText(toon_info.logout, false) + alt_info[tt_data["money"].tt_key] = toon_info.gold_toon + alt_info[tt_data["item_level"].tt_key] = toon_info.itemLevelEquipped + alt_info.itemLevelPvp = toon_info.itemLevelPvp + + alt_info[tt_data["played"].tt_key] = toon_info.played_total + + alt_info[tt_data["profile"].tt_key], alt_info.sync_global = GetSync(idx) + + alt_info[tt_data["unit_xp"].tt_key] = toon_info.unit_xp + alt_info.xp_max = toon_info.unit_xp_max + alt_info.xp_per = "" + + -- Get Alts plugin info; + -- this will create .Alts table on a character profile, if it does not exist + local res, plugin_info = TitanUtils_GetProfileInfo(idx, "Alts", true) + if res == 'created' then + plugin_info.show = true -- default + else + -- use the value + end + local show_me = false + if plugin_info then -- sometimes IDE is a pain... :) + show_me = plugin_info.show + else + -- should never get here + end + alt_info.show = show_me + + + table.insert(alts_tt, alt_info) + end + end + + -- Sort by name initially + -- cobbled from SortDB :) + local tt_key = "name_titan" + alts_tt_sort_col = tt_key + local sorter = function(a, b) + return a[tt_key] < b[tt_key] + end; + + for idx = 1, #alts_tt do + table.sort(alts_tt, sorter) + end + end +end + +function Alts.GenTooltip(self) + self.qtooltip:Clear() + self.qtooltip:SetScale(TitanPanelGetVar("Scale")); + self.qtooltip:SmartAnchorTo(self); + self.qtooltip.parent = self; + + headerFont = self.qtooltip:GetHeaderFont() + headerFont:SetTextColor(NORMAL_FONT_COLOR:GetRGB()) + + -- This may not be ideal but it does collect the current toon... + GenDB(self, 'create') + local column + local row + + -- To allow configurable cols, we need to check at each point we build a line + -- to keep data in the right cols. + -- Declare here to use local vars + local function CheckCol(col_name, action, toon_info) + local ok = false + if tt_data[col_name].config then + if TitanGetVar(TITAN_PLUGIN, tt_data[col_name].tt_key) then + ok = true + else + -- user does not want to show + end + else + ok = true -- required + end + if ok then + row, column = tt_data[col_name].cell_func(self, row, column, action, tt_data[col_name], toon_info) + else + -- skip this col + end + end + + -- NOTE: The various QTip cell functions advance 'column' on success + -- NOTE: The various QTip row functions advance 'row' on success + + -- Create header + row, column = self.qtooltip:AddHeader() + for idx = 1, #tt_cols do + CheckCol(tt_cols[idx], 'header', nil) + end + + row, column = self.qtooltip:AddSeparator(); + + total_toons = 0 + for idx = 1, #alts_tt do + local toon_info ---@class AltInfo + toon_info = alts_tt[idx] + local result, this_toon = TitanUtils_GetProfileInfo(toon_info.name_titan, "Alts", false) + + if toon_info == nil then + -- IDE sanity check, should be filled by GenDB + elseif this_toon then + if this_toon.show == true then + row, column = self.qtooltip:AddLine() + + for col_idx = 1, #tt_cols do + CheckCol(tt_cols[col_idx], 'row', toon_info) + end + else + -- user deselected + end + total_toons = total_toons + 1 -- count toward total + else + -- !? + end + end + + row, column = self.qtooltip:AddSeparator() + row, column = self.qtooltip:AddLine() + + local str = " " + for idx = 1, #tt_cols do + CheckCol(tt_cols[idx], 'total', nil) + end + + self.qtooltip:UpdateScrolling(512); + self.qtooltip:Show(); + + if (self.qtooltip.locked) then + self.qtooltip:SetAutoHideDelay(nil); + else + self.qtooltip:SetAutoHideDelay(0.5, self) + end +end + +local scroll_hgt = math.floor(GetScreenHeight() * .6) -- virtual height in pixels +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_PLUGIN + local root = rootDescription -- menu widget to start with + + CloseQTooltip(_G[TITAN_BUTTON], true) + + local opts_show = Titan_Menu.AddButton(root, SHOW) + do -- next level options + for idx = 1, #tt_cols do + local col_name = tt_cols[idx] + + if tt_data[col_name].config then + Titan_Menu.AddSelector(opts_show, id, tt_data[col_name].title, tt_data[col_name].tt_key) + else + -- not user selectable to hide + end + end + Titan_Menu.AddDivider(opts_show) + Titan_Menu.AddSelector(opts_show, id, "Use Class Colors", "use_class_colors") + end + + -- for idx, pdata in TitanUtils_PlayerIter() do + local opts_show_toons = Titan_Menu.AddButton(root, L["TITAN_PANEL_MENU_PROFILE_CHARS"]) + do -- next level options + for idx, pdata in TitanUtils_PlayerIter() do + local result, toon_info = TitanUtils_GetProfileInfo(idx, "Alts", false) + if result == "is_custom" then + -- skip, can not log in + elseif toon_info then + Titan_Menu.AddSelectorGeneric(opts_show_toons, idx, + function(data) + return data.toon.show + end, + function(data) + data.toon.show = not data.toon.show + end, + { toon = toon_info } + ) + else + -- not user selectable to hide + end + end + end + Titan_Menu.SetScroll(opts_show_toons, scroll_hgt) -- in case menu height is larger than screen / window + +end + +local function OnEnter(self) + if self.qtip:IsAcquired("TitanAlts_Tooltip") then + -- tooltip is active + else + self.qtooltip = self.qtip:Acquire("TitanAlts_Tooltip", MAX_COLS); + Alts.GenTooltip(self) + end +end + +local function OnLeave(self, force) + CloseQTooltip(self, force) +end + +-- Create the .registry for Titan so it can register and place the plugin + +local function OnLoad(self) + local notes = "" + .. "Relevant info on toon and alts.\n" + -- .."- xxx.\n" + self.registry = { + id = TITAN_PLUGIN, + category = "Built-ins", + version = VERSION, + menuText = TITLE, + -- menuTextFunction = CreateMenu, + menuContextFunction = GeneratorFunction, -- NEW scheme + buttonTextFunction = GetButtonText, + tooltipTitle = TITLE, + -- tooltipTextFunction = GetTooltipText, + icon = artwork_path .. "Alts", + iconWidth = 16, + notes = notes, + controlVariables = { + ShowIcon = true, + ShowLabelText = true, + -- ShowColoredText = true, + DisplayOnRightSide = true, + }, + savedVariables = { + ShowIcon = 1, + ShowLabelText = 1, + -- ShowColoredText = 1, + DisplayOnRightSide = false, + -- show / hide cols + --tt_key doubles as saved var + level_toon = true, + itemLevelEquipped = true, + zone = false, + logout = false, + gold_toon = true, + played_total = false, + profile = false, + xp_now = true, + -- end show / hide cols + use_class_colors = true, + } + } + + self.qtip = QTip + self.qtipIconProvider = iconProvider + self.qtooltip = {} + self.qtooltip.locked = false + +end + +-- Parse and react to registered events +local function OnEvent(self, event, a1, a2, ...) + if (event == "PLAYER_EQUIPMENT_CHANGED") then + TitanPanelButton_UpdateButton(TITAN_PLUGIN) + end + + Titan_Debug.Out('gold', 'events', event) +end + +-- Handle mouse clicks +local function OnClick(self, button) + if trace then + TitanPluginDebug(TITAN_PLUGIN, "Titan Alts click" + .. " " .. tostring(button) .. "" + ) + end + if (button == "LeftButton") then + -- C_UI.Reload() --ReloadUI() + end +end + +local function OnShow(self) + self:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") +-- GenDB(self, 'create') + TitanPanelButton_UpdateButton(TITAN_PLUGIN) + + max_level = GetMaxLevelForPlayerExpansion() +end + +local function OnHide(self) + self:UnregisterEvent("PLAYER_EQUIPMENT_CHANGED") + GenDB(self, 'wipe') +end + +-- ====== Create needed frames +local function Create_Frames() + if _G[TITAN_BUTTON] then + return -- if already created + end + + if trace then + TitanPluginDebug(TITAN_PLUGIN, "TS frames" + .. " '" .. tostring(TITAN_BUTTON) .. "'" + ) + end + + -- general container frame + local f = CreateFrame("Frame", nil, UIParent) + local window = CreateFrame("Button", TITAN_BUTTON, f, "TitanPanelComboTemplate") + window:SetFrameStrata("FULLSCREEN") + -- Using SetScript to set "OnLoad" does not work + -- + -- This routine sets the guts of the plugin - the .registry + OnLoad(window); + + window:SetScript("OnShow", function(self) + OnShow(self) + -- This routine ensures the plugin is put where the user requested it. + -- Titan saves the bar the plugin was on. It does not save the relative order. + TitanPanelButton_OnShow(self); + end) + window:SetScript("OnHide", function(self) + OnHide(self) + end) + window:SetScript("OnEvent", function(self, event, ...) + OnEvent(self, event, ...) + end) + window:SetScript("OnClick", function(self, button) + -- Typically this routine handles actions on left click + OnClick(self, button); + -- Typically this routine handles the menu creation on right click + TitanPanelButton_OnClick(self, button); + end) + + window:SetScript("OnEnter", function(self) + OnEnter(self) + end) + window:SetScript("OnLeave", function(self) + --OnLeave(self) + end) + + -- Create tooltip frame for this plugin + -- OnUpdate starts as soon as OnShow is done... + tt_frame = CreateFrame("GameTooltip", "TitanRepairTooltip", UIParent, "GameTooltipTemplate") + local tt_init_timeout = .5 + + tt_frame:SetScript("OnShow", function(self) + local time_out = TitanPanelGetVar("TooltipTimeout") + local dbg_msg = "OnShow" + .. " timeout: " .. tostring(time_out) .. "" + .. " USING: " .. tostring(tt_init_timeout) .. "" + .. " isCounting: " .. tostring(self.isCounting) .. "" + .. " timer: " .. tostring(self.frameTimer) .. "" + .. " plugin: " .. tostring(self.registry_id) .. "" + .. " plugin_frame: " .. tostring(self.plugin_frame_str) .. "" + Titan_Debug.Out('alts', 'tool_tips', dbg_msg) + + -- OnShow will start the OnUpdate. + -- If user enters plugin, the tooltip will show + -- BUT if the user never enters the tooltip, it will keep showing because + -- the OnLeave did not kick the timer. + TitanUtils_StartFrameCounting(self, tt_init_timeout) + end) + tt_frame:SetScript("OnEnter", function(self) + local time_out = TitanPanelGetVar("TooltipTimeout") + + local dbg_msg = "OnEnter" + .. " timeout: " .. tostring(time_out) .. "" + .. " isCounting: " .. tostring(self.isCounting) .. "" + .. " timer: " .. tostring(self.frameTimer) .. "" + Titan_Debug.Out('alts', 'tool_tips', dbg_msg) + + TitanUtils_StopFrameCounting(self) + end) + tt_frame:SetScript("OnLeave", function(self) + local time_out = TitanPanelGetVar("TooltipTimeout") + + local dbg_msg = "OnLeave" + .. " timeout: " .. tostring(time_out) .. "" + .. " isCounting: " .. tostring(self.isCounting) .. "" + .. " timer: " .. tostring(self.frameTimer) .. "" + Titan_Debug.Out('alts', 'tool_tips', dbg_msg) + + if time_out < 0.1 then + tt_frame:Hide() -- hide right away + else + TitanUtils_StartFrameCounting(self, time_out) + end + end) + + local debug_over = false + local debug_over_new = false + tt_frame:SetScript("OnUpdate", function(self, elapsed) + local time_out = TitanPanelGetVar("TooltipTimeout") + + --[[ -- Be VERY careful enabling this debug :) + local dbg_msg = "TT OnUpdate" + .. " timeout: " .. tostring(time_out) .. "" + .. " isCounting: " .. tostring(self.isCounting) .. "" + .. " timer: " .. tostring(self.frameTimer) .. "" + --Titan_Debug.Out('alts', 'tool_tips', dbg_msg) + if self.isCounting == nil then + Titan_Debug.Out('alts', 'tool_tips', dbg_msg) + elseif self.frameTimer <= 0.01 then + Titan_Debug.Out('alts', 'tool_tips', dbg_msg) + else + end + --]] + + -- Compromise to keep tooltip open if the user stays over plugin + -- and does not mouse over tooltip frame (OnEnter) + local is_over = self.parent_frame:IsMouseOver() + if is_over then + TitanUtils_StopFrameCounting(self) + debug_over_new = true + else + TitanUtils_CheckFrameCounting(self, elapsed); + debug_over = false + end + + --[[ + if debug_over ~= debug_over_new then + debug_over = debug_over_new + local dbg_msg = "OnUpdate" + .. " over: " .. tostring(is_over) .. "" + .. " timeout: " .. tostring(time_out) .. "" + .. " isCounting: " .. tostring(self.isCounting) .. "" + .. " timer: " .. tostring(self.frameTimer) .. "" + Titan_Debug.Out('alts', 'tool_tips', dbg_msg) + else + end + --]] + end) +end + +Create_Frames() -- do the work diff --git a/TitanAlts/TitanAlts.toc b/TitanAlts/TitanAlts.toc new file mode 100644 index 0000000..a9538dc --- /dev/null +++ b/TitanAlts/TitanAlts.toc @@ -0,0 +1,12 @@ +## Interface: 120001, 110205, 50502, 20505, 11508 +## Title: Titan Panel [|cffeda55fAlts|r] |cff00aa009.1.5|r +## Author: Titan Panel Dev Team +## Version: 9.1.5 +## Notes: Adds Reload and select functions in a plugin +## Author: Titan Panel Development Team +## IconTexture: Interface\AddOns\TitanAlts\Artwork\Alts +## SavedVariables: +## Dependencies: Titan +## DefaultState: Enabled + +TitanAlts.lua