diff --git a/Titan/Artwork/Titan.blp b/Titan/Artwork/Titan.blp new file mode 100755 index 0000000..00c677f Binary files /dev/null and b/Titan/Artwork/Titan.blp differ diff --git a/Titan/Titan.lua b/Titan/Titan.lua index c87ae87..a0aea93 100644 --- a/Titan/Titan.lua +++ b/Titan/Titan.lua @@ -18,18 +18,6 @@ local AceTimer = LibStub("AceTimer-3.0") local media = LibStub("LibSharedMedia-3.0") local AceConfigDialog = LibStub("AceConfigDialog-3.0") ----Open the WoW config to the requested place. ---- Use AceConfigDialog:Open to open a specific part of the Titan config as a distinct frame ----@param ... unknown -local function OpenConfig(...) - -- WoW 12.0 (Midnight) changed the API to open their Config. - if C_SettingsUtil and C_SettingsUtil.OpenSettingsPanel then - C_SettingsUtil.OpenSettingsPanel(...) - else - Settings.OpenToCategory(...) - end -end - -- TitanDebug (cmd.." : "..p1.." "..p2.." "..p3.." "..#cmd_list) -------------------------------------------------------------- @@ -100,7 +88,7 @@ function TitanPanel_SaveCustomProfile(profile_name) -- helper to actually write the profile to the Titan saved vars local function Write_profile(name) --- local currentprofilevalue, _, _ = TitanUtils_GetPlayer() + -- local currentprofilevalue, _, _ = TitanUtils_GetPlayer() local currentprofilevalue = profile_name local profileName = TitanUtils_CreateName(name, TITAN_CUSTOM_PROFILE_POSTFIX) TitanSettings.Players[profileName] = @@ -112,7 +100,7 @@ function TitanPanel_SaveCustomProfile(profile_name) TitanPrint(L["TITAN_PANEL_MENU_PROFILE_SAVE_PENDING"] .. "'" .. profile_name .. "'" .. " > '" .. profileName .. "'" --- .. " > '" .. name .. "'" + -- .. " > '" .. name .. "'" , "info") end -- helper to ask the user to overwrite a profile @@ -295,17 +283,28 @@ end local function SetToonInfo(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 toon_info = TitanSettings.Players[toon].Info ---@class CharInfo local unit = "player" - local classFilename, classId = UnitClassBase(unit) - local localizedClassName, classFile, classID = GetClassInfo(classId) - toon_info.class = localizedClassName - toon_info.classId = classID + local p, s, is_custom = TitanUtils_ParseName(toon) + toon_info.name = p + toon_info.server = s + + local classFilename, classID = UnitClassBase(unit) -- regardless of comsetic changes + local classInfo = C_CreatureInfo.GetClassInfo(classID) + if classInfo == nil then + toon_info.class = "??" + toon_info.className = "??" + toon_info.classId = 0 + else + toon_info.class = classInfo.className + toon_info.className = classInfo.classFile + toon_info.classId = classInfo.classID + end local englishFaction, localizedFaction = UnitFactionGroup(unit) toon_info.faction = localizedFaction - toon_info.factionId = englishFaction + toon_info.factionName = englishFaction local level = UnitLevel(unit) toon_info.level = level @@ -313,7 +312,11 @@ local function SetToonInfo(toon) local localizedRaceName, englishRaceName, raceID = UnitRace(unit) toon_info.race = localizedRaceName + toon_info.raceName = englishRaceName toon_info.raceId = raceID + + toon_info.zoneText = GetZoneText() + toon_info.subZoneText = GetSubZoneText() or "" end local function SetToonLogout(toon) @@ -352,13 +355,6 @@ function TitanPanel_PlayerEnteringWorld(reload) TitanPrint("", "header") end - if not ServerTimeOffsets then - ServerTimeOffsets = {}; - end - if not ServerHourFormat then - ServerHourFormat = {}; - end - -- Set the two anchors in their default positions -- until the Titan bars are drawn Titan_Debug.Out('titan', 'p_e_w', "Create anchors for other addons") @@ -372,29 +368,13 @@ function TitanPanel_PlayerEnteringWorld(reload) for idx, v in pairs(TitanBarData) do Titan_Debug.Out('titan', 'bars_setup', "... " .. tostring(v.name)) - TitanPanelButton_CreateBar(idx) + TitanPanelButton_CreateBar(idx, v.locale_name) end -- Titan_AutoHide_Create_Frames() -- Add to Addon Compartment, if feature is present RegisterAddonCompartment() - -- Set clock vars based on user setting - if TitanPlugins["Clock"] then - local realmName = GetRealmName() - if ServerTimeOffsets[realmName] then - TitanSetVar("Clock", "OffsetHour", ServerTimeOffsets[realmName]) - elseif TitanGetVar("Clock", "OffsetHour") then - ServerTimeOffsets[realmName] = TitanGetVar("Clock", "OffsetHour") - end - - if ServerHourFormat[realmName] then - TitanSetVar("Clock", "Format", ServerHourFormat[realmName]) - elseif TitanGetVar("Clock", "Format") then - ServerHourFormat[realmName] = TitanGetVar("Clock", "Format") - end - end - -- Should be safe to register for events that could show / hide Bars Titan_Debug.Out('titan', 'p_e_w', "Register for events Titan needs") RegisterForEvents() @@ -404,7 +384,6 @@ function TitanPanel_PlayerEnteringWorld(reload) local _ = nil TitanSettings.Player, _, _ = TitanUtils_GetPlayer() - SetToonInfo(TitanSettings.Player) -- Some addons wait to create their LDB component or a Titan addon could @@ -478,19 +457,6 @@ end --]===] ----Titan Handle ADDON_LOADED Minimal setup in prep for player login. -function TitanPanelBarButton:ADDON_LOADED(addon) - if addon == TITAN_ID then - _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_ENTERING_WORLD") - - Titan_Debug.Out('titan', 'events', "ADDON_LOADED") - - -- Unregister event - saves a few event calls. - self:UnregisterEvent("ADDON_LOADED"); - self.ADDON_LOADED = nil - end -end - ---Titan Handle PLAYER_ENTERING_WORLD Initialize Titan, set and display Titan bars and plugins. function TitanPanelBarButton:PLAYER_ENTERING_WORLD(arg1, arg2) local call_success = nil @@ -960,7 +926,7 @@ print("_Set bar color" TOOLTIP_DEFAULT_COLOR.b, color.alpha); -- 2024 Aug : Border will use the color alpha - _G[frame]:SetBackdropColor( + _G[frame]:SetBackdropColor( color.r, color.g, color.b, @@ -1050,13 +1016,13 @@ print("_Tex" ) --]] -- Use the texture / skin per user selectable options ---[[ + --[[ if TitanBarDataVars["Global"].texure == Titan_Global.SKIN then Set_Skin(frame, titanTexture, TitanBarDataVars["Global"].skin) -- tex_path = TitanPanelGetVar("TexturePath") elseif TitanBarDataVars["Global"].texure == Titan_Global.COLOR then Set_Color(frame, titanTexture, TitanBarDataVars["Global"].color) else ---]] +--]] if TitanBarDataVars[frame].texure == Titan_Global.SKIN then Set_Skin(frame, titanTexture, TitanBarDataVars[frame].skin) elseif TitanBarDataVars[frame].texure == Titan_Global.COLOR then @@ -1548,8 +1514,8 @@ local function showBar(frame_str) -- ===== Battleground or Arena : User selected -- if (TitanPanelGetVar("HideBarsInPVP")) if TitanBarDataVars[frame_str].hide_in_pvp - and (C_PvP.IsBattleground() - or C_PvP.IsArena() + and (C_PvP and C_PvP.IsBattleground() + or C_PvP and C_PvP.C_PvP.IsArena() -- or GetZoneText() == "Stormwind City" -- or GetZoneText() == "Tempest Keep" ) @@ -1909,7 +1875,12 @@ function TitanPanelButton_Justify() -- Look at each bar for plugins. for idx, v in pairs(TitanBarData) do bar = TitanBarData[idx].name - y_offset = TitanBarData[idx].plugin_y_offset +--print("Bar Y" +-- .. " " .. tostring(idx) .. "" +-- .. " " .. tostring(TitanBarData[idx].plugin_y_offset) .. "" +-- .. " " .. tostring(TitanBarDataVars[idx].plugin_off_y) .. "" +--) + y_offset = TitanBarData[idx].plugin_y_offset -- + TitanBarDataVars[idx].plugin_off_y -- user may offset x_offset = TitanBarData[idx].plugin_x_offset firstLeftButton = TitanUtils_GetButton(TitanPanelSettings.Buttons [TitanUtils_GetFirstButtonOnBar(bar, TITAN_LEFT)]) @@ -1961,236 +1932,67 @@ end -------------------------------------------------------------- -- -- Local routines for Titan menu creation -local R_ADDONS = "Addons_" -local R_PLUGIN = "Plugin_" -local R_SETTINGS = "Settings" -local R_PROFILE = "Profile_" -local R_BARS_SETTING = "Bar_Show_Hide" - ----local Show main Titan (right click) menu. ----@param frame string Frame to add to -local function BuildMainMenu(frame) - local locale_bar = TitanBarData[frame].locale_name - local info = {}; - ----------------- - -- Menu title - TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_MENU_TITLE"] .. " - " .. locale_bar); - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_MENU_PLUGINS"]); - - ----------------- - -- Plugin Categories - -- Both arrays are in TitanGlobal - ---@diagnostic disable-next-line: param-type-mismatch - for index, id in pairs(L["TITAN_PANEL_MENU_CATEGORIES"]) do - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_MENU_CATEGORIES"][index]; - info.value = R_ADDONS .. TITAN_PANEL_BUTTONS_PLUGIN_CATEGORY[index]; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info); - end - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - - ----------------- - -- Bars - Show / Hide - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_MENU_OPTIONS_BARS"]; - info.value = R_BARS_SETTING - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - - if Titan_Global.switch.midnight then - -- disable until we figure this out +---Titan Determine if the given plugin is on any Titan bar. +---@param id string Unique ID of the plugin +---@return boolean shown True on a Titan bar even if hidden or on auto hide +function TitanPanel_IsPluginShown(id) + if (id and TitanPanelSettings) then + return TitanUtils_TableContainsValue(TitanPanelSettings.Buttons, id) else - ----------------- - -- Config - just one button to open the first Titan option screen - do - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_MENU_CONFIGURATION"]; - info.value = "Config"; - info.func = function() - TitanUpdateConfig("init") - OpenConfig(TITAN_PANEL_CONFIG.topic.About) - end - TitanPanelRightClickMenu_AddButton(info); - end - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - end - - ----------------- - -- Profiles - -- TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_MENU_PROFILES"]); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_MENU_PROFILES"] .. " " .. L["TITAN_PANEL_MENU_CONFIGURATION"] - info.value = "ConfigProfile"; - info.func = function() - TitanUpdateConfig("init") - AceConfigDialog:Open("Titan Panel Addon Chars") + return false end - TitanPanelRightClickMenu_AddButton(info); - - local res = TitanVariables_GetProfile(TitanUtils_GetPlayer()) - info = {}; - info.notCheckable = true - info.text = res.cname - info.value = "Global_value" - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); +end - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_MENU_HELP"] - info.value = "ConfigProfile"; - info.func = function() - TitanUpdateConfig("init") - AceConfigDialog:Open("Titan Panel Help List") +---Titan Determine if the given plugin is / would be on right or left of a Titan bar. +---@param id string Unique ID of the plugin +---@return string R_L TITAN_RIGHT("Right") or TITAN_Left("Left") +function TitanPanel_GetPluginSide(id) + if (TitanGetVar(id, "DisplayOnRightSide")) then + return TITAN_RIGHT; + else + return TITAN_LEFT; end - TitanPanelRightClickMenu_AddButton(info); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - - ----------------- - -- Hide this bar - info = {}; - info.text = (HIDE or "Hide") - info.value = "HideMe" - info.notCheckable = true - info.disabled = (TitanUtils_NumActiveBars() == 1) - info.arg1 = frame; - info.func = function(self, frame_str) - TitanBarDataVars[frame_str].show = not TitanBarDataVars[frame_str].show - TitanPanelBarButton_DisplayBarsWanted(frame_str .. " user clicked Hide") - end - info.keepShownOnClick = nil - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); -end - ----local Show list of plugin defined options from the Titan right click menu. -local function BuildPluginMenu() - -- - local info = {}; - - -- Handle the plugins +end - for index, id in pairs(TitanPluginsIndex) do - local plugin = TitanUtils_GetPlugin(id) - local par_val = TitanPanelRightClickMenu_GetDropdMenuValue() - local menu_plugin = string.gsub(par_val, R_PLUGIN, "") - if plugin and plugin.id and plugin.id == menu_plugin then - --title - info = {}; - info.text = TitanPlugins[plugin.id].menuText; - info.notCheckable = true - info.notClickable = 1; - info.isTitle = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - --ShowIcon - if plugin.controlVariables.ShowIcon then - info = {}; - info.text = L["TITAN_PANEL_MENU_SHOW_ICON"]; - info.value = plugin.id - info.arg1 = plugin.id - info.func = function(self, p_id) -- (self, info.arg1, info.arg2) - TitanPanelRightClickMenu_ToggleVar({ p_id, "ShowIcon", nil }) - end - info.keepShownOnClick = 1; - info.checked = TitanGetVar(plugin.id, "ShowIcon"); - info.disabled = nil; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end +---Titan Set the scale, texture (graphic), and transparancy of all the Titan bars based on the user selection. +---@param reason string Debug note on where the call initiated +function TitanPanel_InitPanelBarButton(reason) + -- Set initial Panel Scale + TitanPanel_SetScale(); - --ShowLabel - if plugin.controlVariables.ShowLabelText then - info = {}; - info.text = L["TITAN_PANEL_MENU_SHOW_LABEL_TEXT"]; - info.value = plugin.id - info.arg1 = plugin.id - info.func = function(self, p_id) -- (self, info.arg1, info.arg2) - TitanPanelRightClickMenu_ToggleVar({ p_id, "ShowLabelText", nil }) - end - info.keepShownOnClick = 1; - info.checked = TitanGetVar(plugin.id, "ShowLabelText"); - info.disabled = nil; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end + -- build debug output + local str = "_InitPanelBarButton" + .. " " .. tostring(reason) .. "" + Titan_Debug.Out('titan', 'bars_setup', str) + TitanPanelBarButton_DisplayBarsWanted("InitPanelBarButton") +end - --ShowRegularText (LDB data sources only atm) - if plugin.controlVariables.ShowRegularText then - info = {}; - info.text = L["TITAN_PANEL_MENU_SHOW_PLUGIN_TEXT"] - info.value = plugin.id - info.arg1 = plugin.id - info.func = function(self, p_id) -- (self, info.arg1, info.arg2) - TitanPanelRightClickMenu_ToggleVar({ p_id, "ShowRegularText", nil }) - end - info.keepShownOnClick = 1; - info.checked = TitanGetVar(plugin.id, "ShowRegularText"); - info.disabled = nil; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end +---Titan Handle ADDON_LOADED Minimal setup in prep for player login. +function TitanPanelBarButton:ADDON_LOADED(addon) + if addon == TITAN_ID then + _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_ENTERING_WORLD") - --ShowColoredText - if plugin.controlVariables.ShowColoredText then - info = {}; - info.text = L["TITAN_PANEL_MENU_SHOW_COLORED_TEXT"]; - info.value = plugin.id - info.arg1 = plugin.id - info.func = function(self, p_id) -- (self, info.arg1, info.arg2) - TitanPanelRightClickMenu_ToggleVar({ p_id, "ShowColoredText", nil }) - end - info.keepShownOnClick = 1; - info.checked = TitanGetVar(plugin.id, "ShowColoredText"); - info.disabled = nil; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end + Titan_Debug.Out('titan', 'events', "ADDON_LOADED") - -- Right-side plugin - if plugin.controlVariables.DisplayOnRightSide then - info = {}; - info.text = L["TITAN_PANEL_MENU_LDB_SIDE"]; - info.value = plugin.id - info.arg1 = plugin.id - info.func = function(self, p_id) -- (self, info.arg1, info.arg2) - TitanToggleVar(p_id, "DisplayOnRightSide") - local bar = TitanUtils_GetWhichBar(p_id) - TitanPanel_RemoveButton(p_id); - TitanUtils_AddButtonOnBar(bar, p_id); - end - info.checked = TitanGetVar(plugin.id, "DisplayOnRightSide"); - info.disabled = nil; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end - end + -- Unregister event - saves a few event calls. + self:UnregisterEvent("ADDON_LOADED"); + self.ADDON_LOADED = nil end end ----local Build the list of plugins for the category the mouse is over - Titan (right click) menu. ----@param frame string Frame to add to -local function BuildPluginCategoryMenu(frame) - local info = {}; +local function AddPlugin(owner, bar, category) local plugin; for index, id in pairs(TitanPluginsIndex) do plugin = TitanUtils_GetPlugin(id) if plugin then -- add the plugin to the menu plugin.category = plugin and plugin.category or "General"; - if (TitanPanelRightClickMenu_GetDropdMenuValue() == R_ADDONS .. plugin.category) then + if (plugin.category == category) then + local internal_bar, which_bar, which_frame_str = TitanUtils_GetWhichBar(id) if not TitanGetVar(id, "ForceBar") - or (TitanGetVar(id, "ForceBar") == TitanBarData[frame].name) then - info = {}; + or (TitanGetVar(id, "ForceBar") == TitanBarData[bar:GetName()].name) then + local info = {}; local ver = plugin and plugin.version or "" if TitanPanelGetVar("VersionShown") then if ver == nil or ver == "" then @@ -2204,36 +2006,29 @@ local function BuildPluginCategoryMenu(frame) info.text = plugin and plugin.menuText .. ver or "" -- Add Bar - local internal_bar, which_bar = TitanUtils_GetWhichBar(id) if which_bar == nil then -- Plugin not shown else - -- if internal_bar == TitanBarData[frame].name then - -- info.text = info.text .. TitanUtils_GetGreenText(" (" .. which_bar .. ")") - -- else info.text = info.text .. TitanUtils_GetGoldText(" (" .. which_bar .. ")") - -- end end - if plugin.controlVariables then - info.hasArrow = 1; - end - info.value = R_PLUGIN .. id; -- for next level dropdown - info.arg1 = frame; - info.arg2 = id; - info.func = function(self, frame_str, plugin_id) -- (self, info.arg1, info.arg2) - -- frame_str is the bar the user clicked to get the menu... - local bar = TitanBarData[frame_str].name - - if TitanPanel_IsPluginShown(plugin_id) then - TitanPanel_RemoveButton(plugin_id); - else - TitanUtils_AddButtonOnBar(bar, plugin_id) - end - end - info.checked = TitanPanel_IsPluginShown(id) or nil - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); + local opts_plugin = Titan_Menu.AddSelectorGeneric(owner, info.text, + function(data) + return (TitanPanel_IsPluginShown(data.p_id) or false) + end, + function(data) + -- frame_str is the bar the user clicked to get the menu... + local p_bar = TitanBarData[data.f_str].name + + if TitanPanel_IsPluginShown(data.p_id) then + TitanPanel_RemoveButton(data.p_id); + else + TitanUtils_AddButtonOnBar(p_bar, data.p_id) + end + end, + { f_str = bar:GetName(), p_id = id } + ) + Titan_Menu.AddControlVars(opts_plugin, id) end end else @@ -2241,148 +2036,117 @@ local function BuildPluginCategoryMenu(frame) end end -local function BuildBarList() - local info = {}; +---Generate and display right click menu options for user. +---@param owner table Plugin frame +---@param rootDescription table Menu context root +local function GeneratorFunction(owner, rootDescription) + local bar = owner + local id = owner.registry.id + local root = rootDescription -- menu widget to start with - -- sort the bar data by their intended order - local bar_list = {} - for _, v in pairs(TitanBarData) do - bar_list[v.order] = v + Titan_Menu.AddText(root, L["TITAN_PANEL_MENU_PLUGINS"]) + do + ---@diagnostic disable-next-line: assign-type-mismatch, param-type-mismatch + for index, id in pairs(L["TITAN_PANEL_MENU_CATEGORIES"]) do + local cat = L["TITAN_PANEL_MENU_CATEGORIES"][index] + local opts_plugins = Titan_Menu.AddButton(root, cat) + AddPlugin(opts_plugins, bar, cat) -- if same category + end end - table.sort(bar_list, function(a, b) - return a.order < b.order - end) - for idx = 1, #bar_list do - local v = bar_list[idx] -- process this bar - local name = v.locale_name - local bar_data = TitanBarDataVars[v.frame_name] + Titan_Menu.AddDivider(root) - info = {}; - info.text = name - info.value = v.frame_name - info.arg1 = v.frame_name - info.func = function(self, arg1) -- (self, info.arg1, info.arg2) - TitanBarDataVars[arg1].show = not TitanBarDataVars[arg1].show - TitanPanelBarButton_DisplayBarsWanted(arg1 .. " right click menu " .. tostring(TitanBarDataVars[arg1].show)) + ----------------- + -- Bars - Show / Hide + local opts_bars = Titan_Menu.AddButton(root, L["TITAN_PANEL_MENU_OPTIONS_BARS"]) + do + -- sort the bar data by their intended order + local bar_list = {} + for _, v in pairs(TitanBarData) do + bar_list[v.order] = v end - --info.keepShownOnClick = 1; - info.checked = bar_data.show - info.disabled = nil; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end -end + table.sort(bar_list, function(a, b) + return a.order < b.order + end) ----Titan This is the controller for the Titan (right click) menu. ----@param self table Titan bar frame that was right clicked ---- Frame name used is <Titan bar name>RightClickMenu -function TitanPanelRightClickMenu_PrepareBarMenu(self) - -- Determine which bar was clicked on - -- local s, e, frame = string.find(self:GetName(), "(.*)RightClickMenu"); - local s, e, frame = string.find(self:GetName(), "(.*)" .. TITAN_PANEL_CLICK_MENU_SUFFIX); - local lev = (TitanPanelRightClickMenu_GetDropdownLevel() or 1) - --[[ -print("_prep R click" -.." "..tostring(frame).."" -.." "..tostring(lev).."" -) ---]] + for idx = 1, #bar_list do + local v = bar_list[idx] -- process this bar + local name = v.locale_name - -- Level 1 - --[===[ - Title - <Bar name> - ---- - Plugins - <list of Categories> - ---- - Configuration => Opens Titan Options - ----- - Profiles - Manage > <Level 2> - Save => Save current profile (used for Global) - ----- - Use Global Profile - <Profile name used or <>> - ---- - Hide => Hide this Bar - --]===] - if lev == 1 then - BuildMainMenu(frame) - end - - -- Level 2 - -- Plugin Categories => Plugins in that category - -- OR - -- Profiles => Server / Realm list - -- OR - -- Bars =? Show checkbox - if (lev == 2) then - if string.find(TitanPanelRightClickMenu_GetDropdMenuValue(), R_ADDONS) then - BuildPluginCategoryMenu(frame) + Titan_Menu.AddSelectorGeneric(opts_bars, name, + function(data) + return TitanBarDataVars[data.f_str].show + end, + function(data) + TitanBarDataVars[data.f_str].show = not TitanBarDataVars[data.f_str].show + TitanPanelBarButton_DisplayBarsWanted(data.f_str .. + " right click menu " .. tostring(TitanBarDataVars[data.f_str].show)) + end, + { f_str = v.frame_name } + ) end + end + Titan_Menu.AddDivider(root) - if (TitanPanelRightClickMenu_GetDropdMenuValue() == R_BARS_SETTING) then - BuildBarList() +-- Hold off for a rewrite using Blizz API over Ace + if Titan_Global.switch.midnight then + -- disable until we figure this out + else + ----------------- + -- Config - just one button to open the first Titan option screen + Titan_Menu.AddCommand(root, id, L["TITAN_PANEL_MENU_CONFIGURATION"], + function() + TitanUpdateConfig("init") + AceConfigDialog:Open("Titan") end - - return; + ) end - -- Level 3 - -- Plugin Categories => Plugins in that category => Plugin defined options - -- OR - -- Profiles > Server / Realm list > Character on realm list - if (lev == 3) then - if string.find(TitanPanelRightClickMenu_GetDropdMenuValue(), R_PLUGIN) then - BuildPluginMenu() + Titan_Menu.AddDivider(root) + + ----------------- + -- Profiles + Titan_Menu.AddCommand(root, id, L["TITAN_PANEL_MENU_PROFILES"] .. " " .. L["TITAN_PANEL_MENU_CONFIGURATION"], + function() + TitanUpdateConfig("init") + AceConfigDialog:Open("Titan Panel Addon Chars") end - return; - end -end + ) ----Titan Determine if the given plugin is on any Titan bar. ----@param id string Unique ID of the plugin ----@return boolean shown True on a Titan bar even if hidden or on auto hide -function TitanPanel_IsPluginShown(id) - if (id and TitanPanelSettings) then - return TitanUtils_TableContainsValue(TitanPanelSettings.Buttons, id) - else - return false - end -end + local res = TitanVariables_GetProfile(TitanUtils_GetPlayer()) + Titan_Menu.AddText(root, res.cname) ----Titan Determine if the given plugin is / would be on right or left of a Titan bar. ----@param id string Unique ID of the plugin ----@return string R_L TITAN_RIGHT("Right") or TITAN_Left("Left") -function TitanPanel_GetPluginSide(id) - if (TitanGetVar(id, "DisplayOnRightSide")) then - return TITAN_RIGHT; - else - return TITAN_LEFT; - end -end + Titan_Menu.AddDivider(root) ----Titan Set the scale, texture (graphic), and transparancy of all the Titan bars based on the user selection. ----@param reason string Debug note on where the call initiated -function TitanPanel_InitPanelBarButton(reason) - -- Set initial Panel Scale - TitanPanel_SetScale(); + Titan_Menu.AddCommand(root, id, L["TITAN_PANEL_MENU_HELP"], + function() + TitanUpdateConfig("init") + AceConfigDialog:Open("Titan Panel Help List") + end + ) - -- build debug output - local str = "_InitPanelBarButton" - .. " " .. tostring(reason) .. "" - Titan_Debug.Out('titan', 'bars_setup', str) - TitanPanelBarButton_DisplayBarsWanted("InitPanelBarButton") -end + Titan_Menu.AddDivider(root) + ----------------- + -- Hide this bar + local frame_str = owner:GetName() + Titan_Menu.AddCommand(root, id, (HIDE or "Hide"), + function(frame_bar) + TitanBarDataVars[frame_bar].show = not TitanBarDataVars[frame_bar].show + TitanPanelBarButton_DisplayBarsWanted(frame_bar .. " user clicked Hide") + end, + frame_str + ) +end -- --========================== -- Routines to handle creation of Titan bars -- ---Titan Create a Titan bar that can show plugins. ----@param frame_str string Unique ID of the plugin -function TitanPanelButton_CreateBar(frame_str) +---@param frame_str string Name of frame to create +---@param short_name string Short localized name of bar +function TitanPanelButton_CreateBar(frame_str, short_name) local this_bar = frame_str local a_bar = CreateFrame("Button", this_bar, UIParent, "Titan_Bar__Display_Template") @@ -2406,6 +2170,39 @@ function TitanPanelButton_CreateBar(frame_str) -- Static full width bar end + -- Jan 2026 Put .registry on each bar for the new menu scheme + -- A bit funky but the right click looks into .registry.menuContextFunction + -- off the frame for the menu function in the new scheme + local notes = "" + .. "Titan ONLY for menu, possibly more.\n" + a_bar.registry = { + id = short_name, + category = Titan_Global.categories.TitanBar, + version = TITAN_VERSION, + menuText = bar_data.locale_name, + --menuTextFunction = CreateMenu, -- OLD + menuContextFunction = GeneratorFunction, -- NEW scheme + --tooltipTitle = "", + --tooltipTextFunction = GetTooltipText, + --buttonTextFunction = FindGold, + icon = "Interface\\AddOns\\Titan\\Artwork\\Titan", + iconWidth = 16, + notes = notes, + controlVariables = { + ShowIcon = false, + ShowLabelText = false, + ShowRegularText = false, + ShowColoredText = false, + DisplayOnRightSide = false, + }, + savedVariables = { + ShowIcon = true, + ShowLabelText = false, + ShowColoredText = true, + DisplayOnRightSide = false, + } + }; + -- ====== -- Bounds only effective on Short bars for now -- Min : No smaller than the padding & one icon @@ -2446,54 +2243,5 @@ end --====== deprecated / Unused --[====[ ---[[ local -NAME: TitanPanel_CreateABar -DESC: Helper to add scripts to the Titan bar passed in. -VAR: frame - The frame name (string) of the Titan bar to create -OUT: None -NOTE: -- This also creates the hider bar in case the user want to use auto hide. -:NOTE ---]] -local function TitanPanel_CreateABar(frame) - if frame then - local bar_name = TitanBarData[frame].name - local bar_width = TitanBarData[frame].width - - if bar_name then - -- Set script handlers for display - _G[frame]:RegisterForClicks("LeftButtonUp", "RightButtonUp"); - _G[frame]:SetScript("OnEnter", function(self) TitanPanelBarButton_OnEnter(self) end) - _G[frame]:SetScript("OnLeave", function(self) TitanPanelBarButton_OnLeave(self) end) - _G[frame]:SetScript("OnClick", function(self, button) TitanPanelBarButton_OnClick(self, button) end) - _G[frame]:SetWidth(bar_width) - - local hide_name = TitanBarData[frame].hider - if hide_name then - -- Set script handlers for display - _G[hide_name]:RegisterForClicks("LeftButtonUp", "RightButtonUp"); - _G[hide_name]:SetScript("OnEnter", function(self) TitanPanelBarButtonHider_OnEnter(self) end) - _G[hide_name]:SetScript("OnLeave", function(self) TitanPanelBarButtonHider_OnLeave(self) end) - _G[hide_name]:SetScript("OnClick", function(self, button) TitanPanelBarButton_OnClick(self, button) end) - - _G[hide_name]:SetFrameStrata("BACKGROUND") - _G[hide_name]:SetWidth(bar_width) - _G[hide_name]:SetHeight(TITAN_PANEL_BAR_HEIGHT/2); - end - - -- Set the display bar - local container = _G[frame] - container:SetHeight(TITAN_PANEL_BAR_HEIGHT); - -- Set local identifier - local container_text = _G[frame.."_Text"] - if container_text then -- was used for debug/creating of the independent bars - container_text:SetText(tostring(bar_name)) - -- for now show it - container:Show() - end - end - else - end -end --]====] diff --git a/Titan/Titan.toc b/Titan/Titan.toc index 1939754..099278e 100644 --- a/Titan/Titan.toc +++ b/Titan/Titan.toc @@ -1,9 +1,9 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55f_Core_|r] |cff00aa009.0.2|r +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55f_Core_|r] |cff00aa009.1.0-pre|r ## Author: Titan Panel Dev Team -## Version: 9.0.2 -## IconTexture: Interface\Icons\Achievement_Dungeon_UlduarRaid_Titan_01 -## SavedVariables: TitanAll, TitanSettings, TitanSkins, ServerTimeOffsets, ServerHourFormat +## Version: 9.1.0-pre +## IconTexture: Interface\AddOns\Titan\Artwork\Titan +## SavedVariables: TitanAll, TitanSettings, TitanSkins ## Notes: Adds display bars to show and control information/launcher plugins. ## Category-enUS: User Interface ## Category-deDE: Benutzerinterface @@ -56,6 +56,7 @@ locale\Localization.TW.lua TitanDebug.lua TitanGlobal.lua TitanUtils.lua +TitanMenu.lua TitanHistory.lua TitanVariables.lua TitanTemplate.xml diff --git a/Titan/TitanConfig.lua b/Titan/TitanConfig.lua index 904b13c..2fa95d0 100644 --- a/Titan/TitanConfig.lua +++ b/Titan/TitanConfig.lua @@ -33,7 +33,6 @@ TITAN_PANEL_CONFIG = { advanced = L["TITAN_PANEL_MENU_ADV"], changes = L["TITAN_PANEL_MENU_CHANGE_HISTORY"], slash = L["TITAN_PANEL_MENU_SLASH_COMMAND"], - -- help = L["TITAN_PANEL_MENU_HELP"], help_list = "Help List", --L["TITAN_PANEL_MENU_HELP"], im_ex_port = "Import / Export", --L["TITAN_PANEL_MENU_HELP"], adjust = "Frame Adjustment", @@ -299,11 +298,11 @@ local function TitanUpdateAdj(t, pos) name = Titan_Global.literals.use, order = position, get = function(info) - local frame_str = info[1] + local frame_str = f_name return TitanAdjustSettings[frame_str].adjust end, set = function(info, val) - local frame_str = info[1] + local frame_str = f_name TitanAdjustSettings[frame_str].adjust = not TitanAdjustSettings[frame_str].adjust TitanPanel_AdjustFrame(frame_str, "Adjust show changed : " .. tostring(TitanAdjustSettings[frame_str].adjust)) @@ -321,18 +320,12 @@ local function TitanUpdateAdj(t, pos) max = 600, step = 1, get = function(info) - local frame_str = info[1] + local frame_str = f_name return TitanAdjustSettings[frame_str].offset end, set = function(info, a) - local frame_str = info[1] + local frame_str = f_name TitanAdjustSettings[frame_str].offset = a - --[[ -print("Cfg Adj" -.." '"..tostring(frame_str).."'" -.." "..tostring(a).."" -) ---]] TitanPanel_AdjustFrame(frame_str, "Adjust offset changed : " .. tostring(a)) end, } @@ -347,14 +340,6 @@ print("Cfg Adj" -- Config Tables changed! AceConfigRegistry:NotifyChange("Titan Panel Bars") - --[===[ -print("Color new:" -.." "..tostring(format("%0.1f", r)).."" -.." "..tostring(format("%0.1f", g)).."" -.." "..tostring(format("%0.1f", b)).."" -.." "..tostring(format("%0.1f", a)).."" -) ---]===] end local function BuildAdj() @@ -411,8 +396,8 @@ VAR: None OUT: None --]] local function TitanUpdateConfigBars(t, pos) - local function IfColor(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local function IfColor(info, bar_short) + local frame_str = TitanVariables_GetFrameName(bar_short) return (TitanBarDataVars[frame_str].texure == Titan_Global.COLOR) end @@ -460,13 +445,13 @@ local function TitanUpdateConfigBars(t, pos) name = L["TITAN_PANEL_MENU_DISPLAY_BAR"], order = position, get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) return TitanBarDataVars[frame_str].show end, set = function(info, val) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) TitanBarDataVars[frame_str].show = not TitanBarDataVars[frame_str].show - TitanPanelBarButton_DisplayBarsWanted(info[1] .. "Show " .. tostring(val)) + TitanPanelBarButton_DisplayBarsWanted(v.name .. "Show " .. tostring(val)) TitanUpdateConfigBars(optionsBars.args, 1000) end, } @@ -478,11 +463,11 @@ local function TitanUpdateConfigBars(t, pos) order = position, disabled = (v.hider == nil), get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) return TitanBarDataVars[frame_str].auto_hide end, set = function(info, val) - Titan_AutoHide_ToggleAutoHide(info[1]) -- short bar name + Titan_AutoHide_ToggleAutoHide(v.name) -- short bar name end, } position = position + 1 -- Center toggle @@ -492,11 +477,11 @@ local function TitanUpdateConfigBars(t, pos) name = L["TITAN_PANEL_MENU_CENTER_TEXT"], order = position, get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) return (TitanBarDataVars[frame_str].align == TITAN_PANEL_BUTTONS_ALIGN_CENTER) end, set = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) if (TitanBarDataVars[frame_str].align == TITAN_PANEL_BUTTONS_ALIGN_CENTER) then TitanBarDataVars[frame_str].align = TITAN_PANEL_BUTTONS_ALIGN_LEFT else @@ -515,11 +500,11 @@ local function TitanUpdateConfigBars(t, pos) desc = L["TITAN_PANEL_MENU_HIDE_IN_COMBAT_DESC"], order = position, get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) return TitanBarDataVars[frame_str].hide_in_combat end, set = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) TitanBarDataVars[frame_str].hide_in_combat = not TitanBarDataVars[frame_str].hide_in_combat end, @@ -532,23 +517,16 @@ local function TitanUpdateConfigBars(t, pos) desc = L["TITAN_PANEL_MENU_HIDE_IN_COMBAT_DESC"] .. " " .. Titan_Global.literals.pvp, order = position, get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) return TitanBarDataVars[frame_str].hide_in_pvp end, set = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) TitanBarDataVars[frame_str].hide_in_pvp = not TitanBarDataVars[frame_str].hide_in_pvp end, } position = position + 1 -- spacer - args[v.name].args.transpacer1 = { - order = position, - type = "description", - width = "full", - name = " ", - } - position = position + 1 -- spacer args[v.name].args.resetposspacer = { order = position, type = "description", @@ -563,39 +541,46 @@ local function TitanUpdateConfigBars(t, pos) order = position, disabled = (v.vert == TITAN_TOP or v.vert == TITAN_BOTTOM), func = function(info, arg1) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) TitanVariables_SetBarPos(_G[frame_str], true) - TitanPanelBarButton_DisplayBarsWanted("Bar reset to default position - " .. tostring(info[1])) + TitanPanelBarButton_DisplayBarsWanted("Bar reset to default position - " .. tostring(v.name)) end, } --[[ - -- ====== - -- Background group - position = position + 1 -- global background - args[v.name].args.globalbackground = { - name = BACKGROUND, - type = "group", - inline = true, + position = position + 1 -- spacer + args[v.name].args.offsetyspacer1 = { + type = "header", + name = "-", order = position, - hidden = function(info) - local hide = false - if TitanBarDataVars["Global"].texure == Titan_Global.NONE then - hide = true - else - hide = false -- skin or color is set global - end - return hide + width = "full", + } + position = position + 1 -- spacer + args[v.name].args.yoffset = { + type = "range", + width = "full", + name = "Plugin Y Offset", + order = position, + min = -12, + max = 12, + step = .5, + get = function(info) + local frame_str = TitanVariables_GetFrameName(v.name) + return TitanBarDataVars[frame_str].plugin_off_y + end, + set = function(info, a) + local frame_str = TitanVariables_GetFrameName(v.name) + +print("Config Y" +.." "..tostring(v.name).."" +.." "..tostring(frame_str).."" +.." "..tostring(a).."" +) TitanBarDataVars[frame_str].plugin_off_y = a + -- Justify button position + TitanPanelButton_Justify(); end, - args = { - globalskins = { - type = "header", - name = L["TITAN_PANEL_MENU_GLOBAL_SKIN_TITLE"], - order = 100, - width = "full", - }, - }, } --]] + position = position + 1 -- background args[v.name].args.background = { name = BACKGROUND, @@ -622,11 +607,11 @@ local function TitanUpdateConfigBars(t, pos) width = "full", style = "radio", get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) return TitanBarDataVars[frame_str].texure end, set = function(info, val) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) TitanBarDataVars[frame_str].texure = val TitanPanel_SetBarTexture(frame_str) end, @@ -640,7 +625,7 @@ local function TitanUpdateConfigBars(t, pos) type = "group", inline = true, hidden = function(info) - return not IfColor(info) + return not IfColor(info, v.name) end, order = 110, args = { @@ -658,7 +643,7 @@ local function TitanUpdateConfigBars(t, pos) -- disabled = (v.vert == TITAN_TOP or v.vert == TITAN_BOTTOM), hasAlpha = true, get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) local color = TitanBarDataVars[frame_str].color return color.r, color.g, @@ -666,7 +651,7 @@ local function TitanUpdateConfigBars(t, pos) color.alpha end, set = function(info, r, g, b, a) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) TitanBarDataVars[frame_str].color.r = r TitanBarDataVars[frame_str].color.g = g @@ -681,14 +666,14 @@ local function TitanUpdateConfigBars(t, pos) name = "Show Border", --L["TITAN_PANEL_MENU_DISPLAY_BAR"], order = 350, get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) return TitanBarDataVars[frame_str].color_border end, set = function(info, val) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) TitanBarDataVars[frame_str].color_border = not TitanBarDataVars[frame_str].color_border TitanPanel_SetBarTexture(frame_str) --- TitanUpdateConfigBars(optionsBars.args, 1000) + -- TitanUpdateConfigBars(optionsBars.args, 1000) end, } }, @@ -698,7 +683,7 @@ local function TitanUpdateConfigBars(t, pos) type = "group", inline = true, hidden = function(info) - return IfColor(info) + return IfColor(info, v.name) end, order = 111, args = { @@ -714,20 +699,20 @@ local function TitanUpdateConfigBars(t, pos) name = "", order = 130, get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) return TitanBarDataVars[frame_str].skin.path end, set = function(info, val) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) TitanBarDataVars[frame_str].skin.path = val TitanPanel_SetBarTexture(frame_str) - if TitanSkinToRemove == TitanPanelGetVar("Texture" .. info[1]) then + if TitanSkinToRemove == TitanPanelGetVar("Texture" .. v.name) then TitanSkinToRemove = "None" end end, values = function(info) local Skinlist = {} - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) for _, val in pairs(TitanSkins) do if val.path ~= TitanBarDataVars[frame_str].skin.path then -- if val.path ~= TitanPanelGetVar("Texture"..v.name) then @@ -752,7 +737,7 @@ local function TitanUpdateConfigBars(t, pos) skinselected = { name = "", image = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) local vert = TitanBarData[frame_str].vert if vert == TITAN_SHORT then vert = TITAN_TOP @@ -775,11 +760,11 @@ local function TitanUpdateConfigBars(t, pos) max = 1, step = 0.01, get = function(info) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) return TitanBarDataVars[frame_str].skin.alpha end, set = function(info, a) - local frame_str = TitanVariables_GetFrameName(info[1]) + local frame_str = TitanVariables_GetFrameName(v.name) _G[frame_str]:SetAlpha(a) TitanBarDataVars[frame_str].skin.alpha = a end, @@ -789,17 +774,6 @@ local function TitanUpdateConfigBars(t, pos) }, } end - - -- Config Tables changed! - -- AceConfigRegistry:NotifyChange("Titan Panel Bars") - --[===[ -print("Color new:" -.." "..tostring(format("%0.1f", r)).."" -.." "..tostring(format("%0.1f", g)).."" -.." "..tostring(format("%0.1f", b)).."" -.." "..tostring(format("%0.1f", a)).."" -) ---]===] end local function BuildBars() @@ -939,7 +913,7 @@ local function UpdateConfigAddons() local header = (plug_in.menuText or "") args[plug_in.id] = { type = "group", - name = ColorVisible(plug_in.id, plug_in.menuText or ""), + name = ColorVisible(plug_in.id, plug_in.menuText_NC or ""), order = idx, args = { name = { @@ -951,9 +925,17 @@ local function UpdateConfigAddons() type = "toggle", name = L["TITAN_PANEL_MENU_SHOW"], order = 3, - get = function(info) return (TitanPanel_IsPluginShown(info[1])) end, + get = function(info) +print("TConfig Show get" +.." "..tostring(info[1]).."" +) + return (TitanPanel_IsPluginShown(info[1])) end, set = function(info, v) local name = info[1] +print("TConfig Show get" +.." "..tostring(info[1]).."" +.." "..tostring(v).."" +) if v then -- Show / add local bar = (TitanGetVar(name, "ForceBar") or TitanUtils_PickBar()) if type(bar) == 'string' then -- sanity and IDE @@ -1320,20 +1302,19 @@ end ---Allow the user to load / delete / reset / sync profile data local function TitanUpdateChars() - local p_info = {} -- used to hold info about each toon in players - local p_sync = {} -- profiles used as Sync + local p_info = {} -- used to hold info about each toon in players + local p_sync = {} -- profiles used as Sync -- Rip through the players (with server name) to sort them for index, id in pairs(TitanSettings.Players) do - -- collect some info on THIS toon for the config local this_toon = {} - local _, server = TitanUtils_ParseName(index) + local _, server, is_custom = TitanUtils_ParseName(index) -- color code the name -- - gold for normal profiles -- - green for custom profiles - if server == TITAN_CUSTOM_PROFILE_POSTFIX then + if is_custom then this_toon.fancy_name = TitanUtils_GetGreenText((index or "?")) this_toon.is_custom = true else @@ -1402,23 +1383,39 @@ local function TitanUpdateChars() order = position, } - do -- toon info - local toon = this_toon.name - if TitanSettings.Players[toon].Info then -- display - local itoon = TitanSettings.Players[toon].Info + do -- profile toon info + local custom_toon, toon_info = TitanUtils_GetPlayerInfo(this_toon.name) + if custom_toon then + -- Cannot login; There is no info to show. + elseif toon_info == nil then + -- For now show nothing + else -- display + local itoon = toon_info local logout = (itoon.logoutStr == nil) and L["TITAN_PANEL_NA"] or itoon.logoutStr position = position + 1 p_args[tostring(position)] = { type = "description", - name = "Last Logout : "..logout, + name = "Last Logout : " .. logout, --width = "0.5", cmdHidden = true, order = position, } + if itoon.zoneText == nil or itoon.subZoneText == nil then + -- not filled in + else + position = position + 1 + p_args[tostring(position)] = { + type = "description", + name = "@ : " .. itoon.zoneText .. " " .. itoon.subZoneText, + --width = "0.5", + cmdHidden = true, + order = position, + } + end position = position + 1 p_args[tostring(position)] = { type = "description", - name = "Level : "..itoon.levelText, + name = "Level : " .. itoon.levelText, width = "0.5", cmdHidden = true, order = position, @@ -1426,7 +1423,7 @@ local function TitanUpdateChars() position = position + 1 p_args[tostring(position)] = { type = "description", - name = "Faction : "..itoon.faction, + name = "Faction : " .. itoon.faction, width = "0.5", cmdHidden = true, order = position, @@ -1434,7 +1431,7 @@ local function TitanUpdateChars() position = position + 1 p_args[tostring(position)] = { type = "description", - name = "Class : "..itoon.class, + name = "Class : " .. itoon.class, width = "0.5", cmdHidden = true, order = position, @@ -1442,64 +1439,33 @@ local function TitanUpdateChars() position = position + 1 p_args[tostring(position)] = { type = "description", - name = "Race : "..itoon.race, + name = "Race : " .. itoon.race, width = "0.5", cmdHidden = true, order = position, } - else -- NA - position = position + 1 - p_args[tostring(position)] = { - type = "description", - name = "Last Logout : "..L["TITAN_PANEL_NA"], - cmdHidden = true, - order = position, - } end + end - --=== Gold on toon, not guild or warbank - position = position + 1 - p_args[tostring(position)] = { - type = "description", - name = "", - cmdHidden = true, - order = position, - } - - local gold_str = "" - local gold_button = TitanUtils_GetButton("Gold") - if gold_button and gold_button:IsShown() then - -- It is enabled + do -- profile Gold + if TitanGold then -- at least loaded if this_toon.is_custom then - -- can not log in to custom so NA - gold_str = "Gold : "..L["TITAN_PANEL_NA"] + -- Cannot login; There is no info to show. else - local name, server = TitanUtils_ParseName(this_toon.name) - local faction = UnitFactionGroup("Player") - gold_str = tostring(TitanPanel_GoldGetGold(name, server, faction)) + if TitanGold.GetInfo then -- it is at least loaded + position = position + 1 + p_args[tostring(position)] = { + name = TitanGold.GetInfo(this_toon.name, true), -- Let Gold decide what to display + order = position, + type = "description", + } + end end - else - -- not enabled - gold_str = "Gold : "..L["TITAN_PANEL_MENU_DISABLED"] end - - position = position + 1 - p_args[tostring(position)] = { - name = gold_str, - order = position, - type = "description", - } end do -- profile Mail - position = position + 1 - p_args[tostring(position)] = { - type = "description", - name = "", - cmdHidden = true, - order = position, - } - + --[[ position = position + 1 p_args[tostring(position)] = { type = "header", @@ -1507,53 +1473,56 @@ local function TitanUpdateChars() cmdHidden = true, order = position, } + --]] - local post_str = "" - local post_button = TitanUtils_GetButton("Post") - if post_button and post_button:IsShown() then - -- Is enabled + if TitanPost then -- it is at least loaded if this_toon.is_custom then -- can not log in to custom so NA - post_str = L["TITAN_PANEL_NA"] else - post_str = TitanPost.GetMailInfo(this_toon.name) - end - else - -- not enabled - post_str = L["TITAN_PANEL_MENU_DISABLED"] - end + local post_str = "" + local post_button = TitanUtils_GetButton("Post") + post_str = L["TITAN_PANEL_NA"] + if post_button and post_button:IsShown() then + post_str = TitanPost.GetInfo(this_toon.name, true) - position = position + 1 - p_args.mailClear = { - name = "Clear", --L["TITAN_PANEL_MENU_LOAD_SETTINGS"], - desc = "Clear Mail info for this toon", - order = position, - type = "execute", - func = function(info, v) - TitanPost.ClearMailInfo(info[1]) - TitanPrint( - "Clear Mail info" - .. " > " .. info[1] .. "" - , "info") - AceConfigRegistry:NotifyChange("Titan Panel Addon Chars") - end, - -- Should be able to clear any specific toon info - --disabled = (this_toon.is_player or g_sync), - } + position = position + 1 + p_args[tostring(position)] = { + name = post_str, + order = position, + type = "description", + } - position = position + 1 - p_args[tostring(position)] = { - name = post_str, - order = position, - type = "description", - } - position = position + 1 - p_args[tostring(position)] = { - type = "description", - name = "", - cmdHidden = true, - order = position, - } + position = position + 1 + p_args.mailClear = { + name = "Clear", --L["TITAN_PANEL_MENU_LOAD_SETTINGS"], + desc = "Clear Mail info for this toon", + order = position, + type = "execute", + func = function(info, v) + TitanPost.ClearMailInfo(this_toon.name) + TitanPrint( + "Clear Mail info" + .. " > " .. this_toon.name .. "" + , "info") + AceConfigRegistry:NotifyChange("Titan Panel Addon Chars") + end, + -- Should be able to clear any specific toon info + --disabled = (this_toon.is_player or g_sync), + } + + position = position + 1 + p_args[tostring(position)] = { + type = "description", + name = "", + cmdHidden = true, + order = position, + } + else + -- not enabled + post_str = L["TITAN_PANEL_MENU_DISABLED"] + end + end + end end do -- profile load / delete @@ -1587,10 +1556,10 @@ local function TitanUpdateChars() type = "execute", -- width = "0.4", func = function(info, v) - TitanVariables_UseSettings(info[1], TitanUtils_GetPlayer(), TITAN_PROFILE_USE) + TitanVariables_UseSettings(this_toon.name, TitanUtils_GetPlayer(), TITAN_PROFILE_USE) TitanPrint( L["TITAN_PANEL_MENU_LOAD_SETTINGS"] - .. " > " .. info[1] .. "" + .. " > " .. this_toon.name .. "" , "info") end, -- does not make sense to load current character profile @@ -1616,10 +1585,10 @@ local function TitanUpdateChars() type = "execute", -- width = "0.4", func = function(info, v) - TitanSettings.Players[info[1]] = nil -- delete the entry + TitanSettings.Players[this_toon.name] = nil -- delete the entry TitanPrint( L["TITAN_PANEL_MENU_PROFILE"] - .. " " .. info[1] .. " " + .. " " .. this_toon.name .. " " .. L["TITAN_PANEL_MENU_PROFILE_DELETED"] , "info") TitanUpdateChars() -- rebuild the toons @@ -1663,7 +1632,7 @@ local function TitanUpdateChars() type = "execute", --width = "1.0", func = function(info, v) - local selected = info[1] + local selected = this_toon.name local str = "" str = str .. " " .. tostring(selected) .. "" @@ -1702,8 +1671,8 @@ local function TitanUpdateChars() name = L["TITAN_PANEL_MENU_PROFILE_SAVE"] .. " " .. L["TITAN_PANEL_MENU_PROFILE_CUSTOM"], desc = L["TITAN_PANEL_MENU_PROFILE_SAVE_DESC"], func = function(info, v) - TitanPanel_SaveCustomProfile(info[1]) -- will output message on write - TitanUpdateChars() -- rebuild the toons + TitanPanel_SaveCustomProfile(this_toon.name) -- will output message on write + TitanUpdateChars() -- rebuild the toons end, } position = position + 1 @@ -1742,21 +1711,21 @@ local function TitanUpdateChars() --width = "full", func = function(info, v) local str = "" - TitanVariables_SetProfile(TitanUtils_GetPlayer(), Titan_Global.profile.SYNC, info[1]) + TitanVariables_SetProfile(TitanUtils_GetPlayer(), Titan_Global.profile.SYNC, this_toon.name) str = str .. " " .. tostring(Titan_Global.profile.SYNC) .. "" - .. " > '" .. tostring(info[1]) .. "'" + .. " > '" .. tostring(this_toon.name) .. "'" .. " : '" .. tostring(TITAN_PROFILE_USE) .. "'" Titan_Debug.Out('titan', 'profile', str) TitanPrint("" .. "" .. L["TITAN_PANEL_MENU_PROFILE_SYNC"] .. "" .. " '" .. TitanUtils_GetPlayer() .. "'" - .. " > '" .. tostring(info[1]) .. "'" + .. " > '" .. tostring(this_toon.name) .. "'" , "info") -- Change over to new profile - -- TitanVariables_UseSettings(nil, info[1], TITAN_PROFILE_USE) + -- TitanVariables_UseSettings(nil, this_toon.name, TITAN_PROFILE_USE) TitanVariables_UseSettings(nil, TitanUtils_GetPlayer(), TITAN_PROFILE_USE) TitanUpdateChars() AceConfigRegistry:NotifyChange("Titan Panel Addon Chars") @@ -1773,16 +1742,16 @@ local function TitanUpdateChars() type = "execute", func = function(info, v) local str = "" - TitanVariables_SetProfile(info[1], Titan_Global.profile.SYNC, Titan_Global.profile.NONE) + TitanVariables_SetProfile(this_toon.name, Titan_Global.profile.SYNC, Titan_Global.profile.NONE) str = str .. " " .. tostring(Titan_Global.profile.SYNC) .. "" - .. " > '" .. tostring(info[1]) .. "'" + .. " > '" .. tostring(this_toon.name) .. "'" .. " : '" .. tostring(Titan_Global.profile.NONE) .. "'" - .. " | '" .. tostring(info[1] == TitanUtils_GetPlayer()) .. "'" + .. " | '" .. tostring(this_toon.name == TitanUtils_GetPlayer()) .. "'" Titan_Debug.Out('titan', 'profile', str) - if info[1] == TitanUtils_GetPlayer() then + if this_toon.name == TitanUtils_GetPlayer() then -- Change over to new profile TitanVariables_UseSettings(nil, TitanUtils_GetPlayer(), TITAN_PROFILE_USE) else @@ -1791,7 +1760,7 @@ local function TitanUpdateChars() TitanPrint("" .. "" .. L["TITAN_PANEL_MENU_PROFILE_CLEAR_SYNC"] .. "" - .. " '" .. tostring(info[1]) .. "'" + .. " '" .. tostring(this_toon.name) .. "'" , "info") TitanUpdateChars() @@ -1832,17 +1801,17 @@ local function TitanUpdateChars() --width = "full", func = function(info, v) local str = "" - TitanVariables_SetProfile(TitanUtils_GetPlayer(), Titan_Global.profile.GLOBAL, info[1]) + TitanVariables_SetProfile(TitanUtils_GetPlayer(), Titan_Global.profile.GLOBAL, this_toon.name) str = str .. " " .. tostring(Titan_Global.profile.GLOBAL) .. "" - .. " > '" .. tostring(info[1]) .. "'" + .. " > '" .. tostring(this_toon.name) .. "'" .. " : '" .. tostring(TITAN_PROFILE_USE) .. "'" Titan_Debug.Out('titan', 'profile', str) TitanPrint("" .. "" .. "Sync All" .. "" - .. " > '" .. tostring(info[1]) .. "'" + .. " > '" .. tostring(this_toon.name) .. "'" , "info") -- Change over to new profile @@ -1870,7 +1839,7 @@ local function TitanUpdateChars() TitanPrint("" .. "" .. "Clear Sync All" .. "" - .. " > '" .. tostring(info[1]) .. "'" + .. " > '" .. tostring(this_toon.name) .. "'" , "info") -- Change over to new profile @@ -1883,6 +1852,54 @@ local function TitanUpdateChars() } end + do + position = position + 1 + p_args.sync_all_title = { + type = "header", + name = TitanUtils_GetGoldText("Uses as Sync"), + cmdHidden = true, + order = position, + } + if g_sync and (TitanAllGetVar("GlobalProfileName") == this_toon.name) then + position = position + 1 + p_args[tostring(position)] = { + type = "description", + name = ALL or "ALL", + cmdHidden = true, + order = position, + } + else + local has_sync = false + for index, id in pairs(TitanSettings.Players) do + if id.Panel["SyncWithProfile"] == this_toon.name then + -- This profile uses this toon as a Sync + position = position + 1 + p_args[tostring(position)] = { + type = "description", + name = tostring(index), + cmdHidden = true, + order = position, + } + has_sync = true + else + -- Any output would be confusing... + end + end + + if has_sync then + -- already listed + else + position = position + 1 + p_args[tostring(position)] = { + type = "description", + name = NONE or "None", + cmdHidden = true, + order = position, + } + end + end + end + -- tell the options screen there is a new list AceConfigRegistry:NotifyChange("Titan Panel Addon Chars") end @@ -1915,11 +1932,11 @@ local function TitanToonList() -- collect some info on THIS toon for the config local this_toon = {} - local _, server = TitanUtils_ParseName(index) + local _, server, is_custom = TitanUtils_ParseName(index) -- color code the name -- - gold for normal profiles -- - green for custom profiles - if server == TITAN_CUSTOM_PROFILE_POSTFIX then + if is_custom then this_toon.fancy_name = TitanUtils_GetGreenText((index or "?")) else this_toon.fancy_name = TitanUtils_GetGoldText((index or "?")) @@ -2143,10 +2160,24 @@ local optionsFrames = { type = "header", name = L["TITAN_PANEL_MENU_OPTIONS_TOOLTIPS"], }, + optiontooltiptimer = { + name = "Tooltip Timeout", --L["TITAN_PANEL_UISCALE_CONTROL_TITLE_UI"], + desc = "Time Tooltip stays after cursor leaves.", --L["TITAN_PANEL_UISCALE_SLIDER_DESC"], + order = 203, + type = "range", + width = "full", + min = 0.5, + max = 10, + step = 0.25, + get = function() return TitanPanelGetVar("TooltipTimeout") end, + set = function(_, a) + TitanPanelSetVar("TooltipTimeout", a); + end, + }, optiontooltip = { name = L["TITAN_PANEL_MENU_TOOLTIPS_SHOWN"], -- desc = L["TITAN_PANEL_MENU_TOOLTIPS_SHOWN"], - order = 201, + order = 205, type = "toggle", width = "full", get = function() return TitanPanelGetVar("ToolTipsShown") end, @@ -2471,12 +2502,6 @@ local optionsSkins = { ---Show the default Titan skins and any custom skins the user has added. local function Show_Skins(t, position) - --[[ - table.sort(TitanSkins, function(a, b) - return string.lower(TitanSkins[a].name) - < string.lower(TitanSkins[b].name) - end) ---]] local skin = "Skin" t[skin .. position] = { type = "description", @@ -2831,9 +2856,9 @@ local function TitanUpdateExtras() type = "execute", width = "full", func = function(info, v) - TitanPluginSettings[info[1]] = nil -- delete the config entry + TitanPluginSettings[name] = nil -- delete the config entry TitanPrint( - " '" .. info[1] .. "' " .. L["TITAN_PANEL_EXTRAS_DELETE_MSG"] + " '" .. name .. "' " .. L["TITAN_PANEL_EXTRAS_DELETE_MSG"] , "info") -- TitanVariables_ExtraPluginSettings() -- rebuild the list TitanUpdateExtras() -- rebuild the options config @@ -3595,8 +3620,117 @@ local function BuildHelpList() end end ---============= Build ther config +local titan_options = { + name = "Titan structure", + type = "group", + childGroups = "tab", + args = {} +} +local function BuiltTitanStructure() + do -- create for config frame; using most of the Blizz config structure + -- This is called from Titan menu and the slash command + titan_options.args = { + titan_entry = { + name = titan_entry.name, + order = 10, + type = "group", + args = titan_entry.args + }, + optionsBars = { + name = optionsBars.name, + order = 20, + type = "group", + args = optionsBars.args + }, + optionsGlobals = { + name = optionsGlobals.name, + order = 30, + type = "group", + args = optionsGlobals.args + }, + optionsAdjust = { + name = optionsAdjust.name, + order = 40, + type = "group", + args = optionsAdjust.args + }, + optionsFrames = { + name = optionsFrames.name, + order = 50, + type = "group", + args = optionsFrames.args + }, + optionsUIScale = { + name = optionsUIScale.name, + order = 60, + type = "group", + args = optionsUIScale.args + }, + optionsSkins = { + name = optionsSkins.name, + order = 70, + type = "group", + args = optionsSkins.args + }, + optionsSkinsCustom = { + name = optionsSkinsCustom.name, + order = 80, + type = "group", + args = optionsSkinsCustom.args + }, + optionsAddons = { + name = optionsAddons.name, + order = 90, + type = "group", + args = optionsAddons.args + }, + optionsAddonAttempts = { + name = optionsAddonAttempts.name, + order = 100, + type = "group", + args = optionsAddonAttempts.args + }, + optionsExtras = { + name = optionsExtras.name, + order = 110, + type = "group", + args = optionsExtras.args + }, + optionsChars = { + name = optionsChars.name, + order = 120, + type = "group", + args = optionsChars.args + }, + optionsImportExport = { + name = optionsImportExport.name, + order = 130, + type = "group", + args = optionsImportExport.args + }, + optionsAdvanced = { + name = optionsAdvanced.name, + order = 140, + type = "group", + args = optionsAdvanced.args + }, + changeHistory = { + name = changeHistory.name, + order = 150, + type = "group", + args = changeHistory.args + }, + helplist = { + name = helplist.name, + order = 160, + type = "group", + args = helplist.args + }, + } + end +end +--============= Build the config ---Build the entire Config table Ace will display local function BuildAll() -- Update the tables for the latest lists @@ -3611,6 +3745,7 @@ local function BuildAll() BuildAdj() BuildAdv() BuildHelpList() + BuiltTitanStructure() end ---Titan This routine will handle the requests to build or clear the Titan Config screens. @@ -3655,7 +3790,7 @@ do -- Register Titan main options list -- The first param needs to used for the 'add to options' -- The second param must be the table Ace will use to create the user options -- - AceConfig:RegisterOptionsTable("Titan Panel Main", titan_entry) + AceConfig:RegisterOptionsTable("Titan Panel About", titan_entry) AceConfig:RegisterOptionsTable("Titan Panel Bars", optionsBars) AceConfig:RegisterOptionsTable("Titan Panel Globals", optionsGlobals) AceConfig:RegisterOptionsTable("Titan Panel Adjust", optionsAdjust) @@ -3672,6 +3807,8 @@ do -- Register Titan main options list AceConfig:RegisterOptionsTable("Titan Panel Addon Changes", changeHistory) -- AceConfig:RegisterOptionsTable("Titan Panel Addon Slash", slashHelp) AceConfig:RegisterOptionsTable("Titan Panel Help List", helplist) + + AceConfigRegistry:RegisterOptionsTable("Titan", titan_options) end do -- Register the options for each entry in Titan option list @@ -3680,7 +3817,8 @@ do -- Register the options for each entry in Titan option list -- The second param should be the same as the .name of the cooresponding table that was registered, -- if not, any 'open' may fail. -- - AceConfigDialog:AddToBlizOptions("Titan Panel Main", titan_entry.name) + + AceConfigDialog:AddToBlizOptions("Titan Panel About", titan_entry.name) AceConfigDialog:AddToBlizOptions("Titan Panel Bars", optionsBars.name, titan_entry.name) AceConfigDialog:AddToBlizOptions("Titan Panel Globals", optionsGlobals.name, titan_entry.name) AceConfigDialog:AddToBlizOptions("Titan Panel Adjust", optionsAdjust.name, titan_entry.name) @@ -3697,4 +3835,6 @@ do -- Register the options for each entry in Titan option list AceConfigDialog:AddToBlizOptions("Titan Panel Addon Changes", changeHistory.name, titan_entry.name) -- AceConfigDialog:AddToBlizOptions("Titan Panel Addon Slash", slashHelp.name, titan_entry.name) AceConfigDialog:AddToBlizOptions("Titan Panel Help List", helplist.name, titan_entry.name) + +-- AceConfigDialog:AddToBlizOptions("Titan_Panel", "Titan") end diff --git a/Titan/TitanDebug.lua b/Titan/TitanDebug.lua index ae5b287..66be0a8 100644 --- a/Titan/TitanDebug.lua +++ b/Titan/TitanDebug.lua @@ -30,7 +30,7 @@ Titan_Debug.titan.events = false Then place calls in code : Titan_Debug.Out("titan", "events", debug_str) -Then set to display them. +Then set to turn display them. Titan_Debug.titan.events = true diff --git a/Titan/TitanGlobal.lua b/Titan/TitanGlobal.lua index 8d13ba2..acf611c 100644 --- a/Titan/TitanGlobal.lua +++ b/Titan/TitanGlobal.lua @@ -10,7 +10,8 @@ local L = LibStub("AceLocale-3.0"):GetLocale(TITAN_ID, true) -- Global variables -Titan_Global = {} -- begin the slow journey to a smaller _G footprint +Titan_Global = {} -- begin the slow journey to a smaller _G footprint +Titan_Menu = {} -- Hold API routines for new menu scheme Titan_Global.recent_changes = "" -- Titan_History.lua @@ -176,6 +177,10 @@ L["TITAN_PANEL_MENU_CATEGORIES"] = { L["TITAN_PANEL_MENU_CATEGORIES_06"], } +-- Intended for Titan only for internal 'plugins' such as Bars +Titan_Global.categories = {} +Titan_Global.categories.TitanBar = "Titan-bar" + -- Bar background types Titan_Global.SKIN = "skin" Titan_Global.COLOR = "color" @@ -231,7 +236,8 @@ Titan_Global.colors = { ---@field category? string The Titan menu category where this plugin will be placed ---@field version? string Plugin version ---@field menuText? string Localized string for the menu (right click) ----@field menuTextFunction? string | function Plugin function to call on right click +---@field menuTextFunction? string | function Plugin function to call on right click NEW Jan 2026 +---@field menuContextFunction? string | function Plugin function to call on right click ---@field buttonTextFunction? string | function Function to call when updating button display ---@field tooltipTitle? string Localized string for the menu ---@field tooltipTextFunction? string | function Function to call for a simple tooltip (OnEnter) diff --git a/Titan/TitanHistory.lua b/Titan/TitanHistory.lua index 004ccfc..a4f75c3 100644 --- a/Titan/TitanHistory.lua +++ b/Titan/TitanHistory.lua @@ -10,6 +10,68 @@ These are in a seperate file to --- Release notes. Keep structure; most recent on 'top' local recent_changes = { { + version = "9.1.0-pre", + when = "2026/02/02", + topics = { + { + topic = "Titan Menus", + lines = { + "!! Menus have been rewritten !! The new menus will look a little different.", + "-- Some menus were reordered or changed to fit the new scheme.", + "Devs : The older scheme and the new scheme work side by side.", + "-- .menuTextFunction will fail when Blizz removes deprecated code in the future - no idea when.", + "-- If you wish to update, please see Bags for old and new menu schemes explained.", + "Devs : Titan now honors color coding in registry.menuText.", + }, + }, + { + topic = "Titan Tooltips", + lines = { + "Internals changed due to Midnight 'secret' value errors, mostly in instances.", + "!! New option in Tooltips and Frames to adjust tooltip timer - .5 - 10 sec.", + "Devs : The registry.tooltipTitle is now optional allowing the title to be custom set.", + "Devs : If your tooltip is not right, please use Titan Discord to message us for assistance.", + "-- Especially if you use registry.tooltipCustomFunction ", + }, + }, + { + topic = "Titan Config", + lines = { + "Opening Config from Titan menu remains unavailable. Use Esc > Options as before.", + "Profile Config now shows some toon info, as well as Gold and Post info if they are enabled.", + }, + }, + { + topic = "Titan Gold", + lines = { + "!! On first login the tracked list will only show that toon !!", + "!! Gold data moved into Titan profiles, causing the need to login to toons again.", + "Menus are changed:", + "- Show and Delete are not available; the data is now part of the profile.", + "- Delete is now delete toon profile", + "Fix : Added back 'show color' option for those that want white text.", + }, + }, + { + topic = "TitanPost", + lines = { + "New built-in! ", + "Button info: ", + ": ?? read/total from last open; ?? = not opened this session.", + ": !! number of toons with expiring mail.", + }, + }, + { + topic = "Titan Fixes", + lines = { + "- Loot : Should not error on mouse over of new gear.", + "- Titan : Should not get IsBattleground error on any WoW version.", + "- Performance : Should now honor selected number of addons.", + }, + }, + }, + }, + { version = "9.0.2", when = "2026/01/12", topics = { @@ -111,18 +173,6 @@ local recent_changes = { }, }, }, - { - version = "8.4.2", - when = "2025/11/01", - topics = { - { - topic = "Titan", - lines = { - "TOC update only.", - }, - }, - }, - }, } ---Format the release notes diff --git a/Titan/TitanMenu.lua b/Titan/TitanMenu.lua new file mode 100644 index 0000000..001fb30 --- /dev/null +++ b/Titan/TitanMenu.lua @@ -0,0 +1,1399 @@ +--[===[ File +Contains various utility routines used by +- Titan and Plugins for thehier menus (right click) 'drop down' +--]===] + +--[===[ +This large file contains various utility routines used by +The Drop Down Menu routines for the Right Click menu are in this file. + +The Titan routines abstract the menu creation built into WoW. + +Whenever there is a change to the menu routines, the abstractions : +: Insulate 3rd party Titan plugin authors from Blizz or lib changes. +: Allow better maintainance by updating Utils rather than updating Titan using search & replace. + +Late 2023 during DragonFlight, WoW expanded the retail version of drop down menu to more Classic versions. +Currently (May 2025) Classic Era is the only one using an explicit timer, and a distinct file version, to close menus. +So, Titan uses a routine only in CE (UIDropDownMenu_StartCounting) to determine which version to use. + +Code notes: +The expected frame name for the Right Click menu of the plugin is: +"TitanPanelRightClickMenu_Prepare"..<registry.id>.."Menu" + +local drop_down_1 = "" -- changes drop down menu version. Blizzard hard-codes the value... + +The L_* routines wrap the drop down menu API for Titan Classic plugins. + + +Jan 2026 : New file moving menu routines from TitanUtils +--]===] + +local _G = getfenv(0); +local L = LibStub("AceLocale-3.0"):GetLocale(TITAN_ID, true) + +local drop_down_1 = "" -- changes if using Blizz drop down (retail) or lib (Classic) + +--====== Set the default drop down menu routines per retail or Classic +drop_down_1 = "DropDownList1" -- Boo!! Per hard-coded Blizz UIDropDownMenu.lua + +--[===[ Var API Dropdown Menu wrappers +Right click menu routines for 3rd party plugins (mainly Classic WoW versions) + +--]===] + +--[[ UI dropdown lib wrappers - Classic plugins mainly +Local helper(s) from the Ace lib. +--]] +-- L_UIDropDownMenuTemplate + +---Ensure the menu is created properly including back drop +---@param name table | string +---@param parent Frame +---@return any +local function create_DropDownMenu(name, parent) + local f + if type(name) == "table" then + f = name + name = f:GetName() + else + f = CreateFrame("Frame", name, parent or nil) + end + + --if not name then name = "" end + + f:SetSize(40, 32) + + f.Left = f:CreateTexture(name and (name .. "Left") or nil, "ARTWORK") + f.Left:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") + f.Left:SetSize(25, 64) + f.Left:SetPoint("TOPLEFT", f, 0, 17) + f.Left:SetTexCoord(0, 0.1953125, 0, 1) + + f.Middle = f:CreateTexture(name and (name .. "Middle") or nil, "ARTWORK") + f.Middle:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") + f.Middle:SetSize(115, 64) + f.Middle:SetPoint("LEFT", f.Left, "RIGHT") + f.Middle:SetTexCoord(0.1953125, 0.8046875, 0, 1) + + f.Right = f:CreateTexture(name and (name .. "Right") or nil, "ARTWORK") + f.Right:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") + f.Right:SetSize(25, 64) + f.Right:SetPoint("LEFT", f.Middle, "RIGHT") + f.Right:SetTexCoord(0.8046875, 1, 0, 1) + + f.Text = f:CreateFontString(name and (name .. "Text") or nil, "ARTWORK", "GameFontHighlightSmall") + f.Text:SetWordWrap(false) + f.Text:SetJustifyH("RIGHT") + f.Text:SetSize(0, 10) + f.Text:SetPoint("RIGHT", f.Right, -43, 2) + + f.Icon = f:CreateTexture(name and (name .. "Icon") or nil, "OVERLAY") + f.Icon:Hide() + f.Icon:SetSize(16, 16) + f.Icon:SetPoint("LEFT", 30, 2) + + -- // UIDropDownMenuButtonScriptTemplate + f.Button = CreateFrame("Button", name and (name .. "Button") or nil, f) + f.Button:SetMotionScriptsWhileDisabled(true) + f.Button:SetSize(24, 24) + f.Button:SetPoint("TOPRIGHT", f.Right, -16, -18) + + f.Button.NormalTexture = f.Button:CreateTexture(name and (name .. "NormalTexture") or nil) + f.Button.NormalTexture:SetTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up") + f.Button.NormalTexture:SetSize(24, 24) + f.Button.NormalTexture:SetPoint("RIGHT", f.Button, 0, 0) + f.Button:SetNormalTexture(f.Button.NormalTexture) + + f.Button.PushedTexture = f.Button:CreateTexture(name and (name .. "PushedTexture") or nil) + f.Button.PushedTexture:SetTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down") + f.Button.PushedTexture:SetSize(24, 24) + f.Button.PushedTexture:SetPoint("RIGHT", f.Button, 0, 0) + f.Button:SetPushedTexture(f.Button.PushedTexture) + + f.Button.DisabledTexture = f.Button:CreateTexture(name and (name .. "DisabledTexture") or nil) + f.Button.DisabledTexture:SetTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled") + f.Button.DisabledTexture:SetSize(24, 24) + f.Button.DisabledTexture:SetPoint("RIGHT", f.Button, 0, 0) + f.Button:SetDisabledTexture(f.Button.DisabledTexture) + + f.Button.HighlightTexture = f.Button:CreateTexture(name and (name .. "HighlightTexture") or nil) + f.Button.HighlightTexture:SetTexture("Interface\\Buttons\\UI-Common-MouseHilight") + f.Button.HighlightTexture:SetSize(24, 24) + f.Button.HighlightTexture:SetPoint("RIGHT", f.Button, 0, 0) + f.Button.HighlightTexture:SetBlendMode("ADD") + f.Button:SetHighlightTexture(f.Button.HighlightTexture) + + -- Button Script + f.Button:SetScript("OnEnter", function(self, motion) + local parent = self:GetParent() + local myscript = parent:GetScript("OnEnter") + if (myscript ~= nil) then + myscript(parent) + end + end) + f.Button:SetScript("OnLeave", function(self, motion) + local parent = self:GetParent() + local myscript = parent:GetScript("OnLeave") + if (myscript ~= nil) then + myscript(parent) + end + end) + f.Button:SetScript("OnMouseDown", function(self, button) + if self:IsEnabled() then + local parent = self:GetParent() + ToggleDropDownMenu(nil, nil, parent) + PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON) + end + end) + + -- UIDropDownMenu Script + f:SetScript("OnHide", function(self) + CloseDropDownMenus() + end) + + return f +end +-- +-- Wrap the drop down lib as if it were Ace lib 4.0 so Classic Titan plugins look the same +-- These need to be global to act like the older version +-- +-- L_UIDropDownMenuDelegate_OnAttributeChanged -- Different in 4.0 +function L_UIDropDownMenu_InitializeHelper(frame) + UIDropDownMenu_InitializeHelper(frame) +end + +function L_Create_UIDropDownMenu(name, parent) + local f = create_DropDownMenu(name, parent) + return f +end + +function L_UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList) + UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList) +end + +function L_UIDropDownMenu_SetInitializeFunction(frame, initFunction) + UIDropDownMenu_SetInitializeFunction(frame, initFunction) +end + +function L_UIDropDownMenu_SetDisplayMode(frame, displayMode) + UIDropDownMenu_SetDisplayMode(frame, displayMode) +end + +function L_UIDropDownMenu_RefreshDropDownSize(self) + UIDropDownMenu_RefreshDropDownSize(self) +end + +--function L_UIDropDownMenu_OnUpdate(self, elapsed) -- Different in 4.0 +function L_UIDropDownMenu_StartCounting(frame) + ---@diagnostic disable-next-line: undefined-global + UIDropDownMenu_StartCounting(frame) -- CE file only +end + +function L_UIDropDownMenu_StopCounting(frame) + ---@diagnostic disable-next-line: undefined-global + UIDropDownMenu_StopCounting(frame) -- CE file only +end + +--function L_UIDropDownMenuButtonInvisibleButton_OnEnter(self)) -- Different in 4.0 +--function L_UIDropDownMenuButtonInvisibleButton_OnLeave(self)) -- Different in 4.0 +--function L_UIDropDownMenuButton_OnEnter(self) -- Different in 4.0 +--function L_UIDropDownMenuButton_OnLeave(self) -- Different in 4.0 +function L_UIDropDownMenu_CreateInfo() + return UIDropDownMenu_CreateInfo() +end + +function L_UIDropDownMenu_CreateFrames(level, index) + UIDropDownMenu_CreateFrames(level, index) +end + +function L_UIDropDownMenu_AddSeparator(level) + UIDropDownMenu_AddSeparator(level) +end + +function L_UIDropDownMenu_AddSpace(level) -- new in 4.0 + UIDropDownMenu_AddSpace(level) +end + +function L_UIDropDownMenu_AddButton(info, level) + UIDropDownMenu_AddButton(info, level) +end + +function L_UIDropDownMenu_CheckAddCustomFrame(self, button, info) + UIDropDownMenu_CheckAddCustomFrame(self, button, info) +end + +function L_UIDropDownMenu_RegisterCustomFrame(self, customFrame) + UIDropDownMenu_RegisterCustomFrame(self, customFrame) +end + +function L_UIDropDownMenu_GetMaxButtonWidth(self) + return UIDropDownMenu_GetMaxButtonWidth(self) +end + +function L_UIDropDownMenu_GetButtonWidth(button) + return UIDropDownMenu_GetButtonWidth(button) +end + +function L_UIDropDownMenu_Refresh(frame, useValue, dropdownLevel) + UIDropDownMenu_Refresh(frame, useValue, dropdownLevel) +end + +function L_UIDropDownMenu_RefreshAll(frame, useValue) + UIDropDownMenu_RefreshAll(frame, useValue) +end + +function L_UIDropDownMenu_SetIconImage(icon, texture, info) + UIDropDownMenu_SetIconImage(icon, texture, info) +end + +function L_UIDropDownMenu_SetSelectedName(frame, name, useValue) + UIDropDownMenu_SetSelectedName(frame, name, useValue) +end + +function L_UIDropDownMenu_SetSelectedValue(frame, value, useValue) + UIDropDownMenu_SetSelectedValue(frame, value, useValue) +end + +function L_UIDropDownMenu_SetSelectedID(frame, id, useValue) + UIDropDownMenu_SetSelectedID(frame, id, useValue) +end + +function L_UIDropDownMenu_GetSelectedName(frame) + return UIDropDownMenu_GetSelectedName(frame) +end + +function L_UIDropDownMenu_GetSelectedID(frame) + return UIDropDownMenu_GetSelectedID(frame) +end + +function L_UIDropDownMenu_GetSelectedValue(frame) + return UIDropDownMenu_GetSelectedValue(frame) +end + +--function L_UIDropDownMenuButton_OnClick(self) -- Different in 4.0 +function L_HideDropDownMenu(level) + HideDropDownMenu(level) +end + +function L_ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, + autoHideDelay) + ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay) +end + +function L_CloseDropDownMenus(level) + CloseDropDownMenus(level) +end + +--function L_UIDropDownMenu_OnHide(self) -- Different in 4.0 +-- 4.0 has 'contains mouse' routines for retail only +function L_UIDropDownMenu_SetWidth(frame, width, padding) + UIDropDownMenu_SetWidth(frame, width, padding) +end + +function L_UIDropDownMenu_SetButtonWidth(frame, width) + UIDropDownMenu_SetButtonWidth(frame, width) +end + +function L_UIDropDownMenu_SetText(frame, text) + UIDropDownMenu_SetText(frame, text) +end + +function L_UIDropDownMenu_GetText(frame) + return UIDropDownMenu_GetText(frame) +end + +function L_UIDropDownMenu_ClearAll(frame) + UIDropDownMenu_ClearAll(frame) +end + +function L_UIDropDownMenu_JustifyText(frame, justification) + UIDropDownMenu_JustifyText(frame, justification) +end + +function L_UIDropDownMenu_SetAnchor(dropdown, xOffset, yOffset, point, relativeTo, relativePoint) + UIDropDownMenu_SetAnchor(dropdown, xOffset, yOffset, point, relativeTo, relativePoint) +end + +function L_UIDropDownMenu_GetCurrentDropDown() + return UIDropDownMenu_GetCurrentDropDown() +end + +function L_UIDropDownMenuButton_GetChecked(self) + return UIDropDownMenuButton_GetChecked(self) +end + +function L_UIDropDownMenuButton_GetName(self) + return UIDropDownMenuButton_GetName(self) +end + +function L_UIDropDownMenuButton_OpenColorPicker(self, button) + UIDropDownMenuButton_OpenColorPicker(self, button) +end + +function L_UIDropDownMenu_DisableButton(level, id) + UIDropDownMenu_DisableButton(level, id) +end + +function L_UIDropDownMenu_EnableButton(level, id) + UIDropDownMenu_EnableButton(level, id) +end + +function L_UIDropDownMenu_SetButtonText(level, id, text, colorCode) + UIDropDownMenu_SetButtonText(level, id, text, colorCode) +end + +function L_UIDropDownMenu_SetButtonNotClickable(level, id) + UIDropDownMenu_SetButtonNotClickable(level, id) +end + +function L_UIDropDownMenu_SetButtonClickable(level, id) + UIDropDownMenu_SetButtonClickable(level, id) +end + +function L_UIDropDownMenu_DisableDropDown(dropDown) + UIDropDownMenu_DisableDropDown(dropDown) +end + +function L_UIDropDownMenu_EnableDropDown(dropDown) + UIDropDownMenu_EnableDropDown(dropDown) +end + +function L_UIDropDownMenu_IsEnabled(dropDown) + return UIDropDownMenu_IsEnabled(dropDown) +end + +function L_UIDropDownMenu_GetValue(id) + return UIDropDownMenu_GetValue(id) +end + +--====== Right click menu routines - Retail dropdown menu UIDROPDOWNMENU + +---local Add menu button at the given level. +---@param info table Filled in button to add +---@param level number menu level +local function Add_button(info, level) + UIDropDownMenu_AddButton(info, level) +end + +---API Menu - Get the base frame name of the user selected menu (without level). +---@return string frame_name +function TitanPanelRightClickMenu_GetDropdownFrameBase() + local res = "" + + res = "DropDownList" -- Boo!! Per hard-coded Blizz UIDropDownMenu.lua + + return res +end + +---API Menu - Get the frame name of the user selected menu. +---@return string frame_name +function TitanPanelRightClickMenu_GetDropdownFrame() + local res = "" + + res = "DropDownList" .. tostring(UIDROPDOWNMENU_MENU_LEVEL) + + return res +end + +---API Menu - Get the current level of the user selected menu. +---@return number level +function TitanPanelRightClickMenu_GetDropdownLevel() + -- local res = _G[drop_down_1] + local res = 1 -- proper typing + + res = UIDROPDOWNMENU_MENU_LEVEL + + return res +end + +---API Menu - Get the current value of the user selected menu. +---@return any Value <button>.value usually a string; could be table to hold needed info +function TitanPanelRightClickMenu_GetDropdMenuValue() + local res = nil + res = UIDROPDOWNMENU_MENU_VALUE + return res +end + +---API Menu - add given info (button) at the given menu level. +---@param info table Filled in button to add +---@param level? number menu level or 1 +function TitanPanelRightClickMenu_AddButton(info, level) + level = level or 1 + if (info) then + Add_button(info, level) + end +end + +---API Menu - add a toggle Right Side (localized) command at the given level in the form of a button. Titan will properly control the "DisplayOnRightSide" +---@param id string Plugin id +---@param level? number menu level or 1 +function TitanPanelRightClickMenu_AddToggleRightSide(id, level) + level = level or 1 + local plugin = TitanUtils_GetPlugin(id) + if plugin and plugin.controlVariables and plugin.controlVariables.DisplayOnRightSide then + -- copy of TitanPanelRightClickMenu_AddToggleVar adding a remove button + local info = {}; + info.text = L["TITAN_CLOCK_MENU_DISPLAY_ON_RIGHT_SIDE"]; + info.value = { id, "DisplayOnRightSide" }; + info.func = function() + local bar = TitanUtils_GetWhichBar(id) + TitanPanelRightClickMenu_ToggleVar({ id, "DisplayOnRightSide" }) + TitanPanel_RemoveButton(id); + TitanUtils_AddButtonOnBar(bar, id) + end + info.checked = TitanGetVar(id, "DisplayOnRightSide"); + info.keepShownOnClick = 1; + Add_button(info, level); + end +end + +---API Menu - add a localized title at the given level in the form of a button. +---@param title string localized title +---@param level? number menu level or 1 +function TitanPanelRightClickMenu_AddTitle(title, level) + level = level or 1 + if (title) then + local info = {}; + info.text = title; + info.notCheckable = true; + info.notClickable = true; + info.isTitle = 1; + Add_button(info, level); + end +end + +---API Menu - add a toggle variable command at the given level in the form of a button. +---@param text string Localized text to show +---@param value string Internal button name +---@param functionName function | string Function to call on click +---@param level? number menu level +function TitanPanelRightClickMenu_AddCommand(text, value, functionName, level) + level = level or 1 + local info = {}; + info.notCheckable = true; + info.text = text; + info.value = value; + info.func = function() + if functionName then + local callback = functionName + + if type(callback) == 'string' then + -- Function MUST be in global namespace + callback = _G[callback] + elseif type(callback) == 'function' then + -- Can be global or local to the plugin + else + -- silently leave... + end + -- Redundant but the given string may not be a function + if type(callback) == "function" then + -- No return expected... + callback(value) + else + -- Must be a function - spank developer + end + else + -- Leave, creates an inactive button + end + end + Add_button(info, level); +end + +---API Menu - add a line at the given level in the form of an inactive button. +---@param level? number menu level or 1 +function TitanPanelRightClickMenu_AddSeparator(level) + level = level or 1 + + UIDropDownMenu_AddSeparator(level) +end + +---API Menu - add a blank line at the given level in the form of an inactive button. +---@param level? number menu level or 1 +function TitanPanelRightClickMenu_AddSpacer(level) + level = level or 1 + + UIDropDownMenu_AddSpace(level) +end + +---API This will remove the plugin from whichever Titan bar it is on. +---@param id string Plugin id +function TitanPanelRightClickMenu_Hide(id) + TitanPanel_RemoveButton(id); +end + +---API Menu - add a toggle variable command at the given level in the form of a button. +---@param text string Localized text to show +---@param id string Plugin id +---@param var string the saved variable of the plugin to toggle +---@param toggleTable nil ! NOT USED ! +---@param level number menu level +function TitanPanelRightClickMenu_AddToggleVar(text, id, var, toggleTable, level) + local info = {}; + info.text = text; + info.value = { id, var, toggleTable }; + info.func = function() + TitanPanelRightClickMenu_ToggleVar({ id, var, toggleTable }) + end + info.checked = TitanGetVar(id, var); + info.keepShownOnClick = 1; + Add_button(info, level); +end + +---API Menu - add a toggle Label (localized) command at the given level in the form of a button. Titan will properly control "ShowIcon" +---@param id string Plugin id +---@param level? number menu level or 1 +function TitanPanelRightClickMenu_AddToggleIcon(id, level) + level = level or 1 + local plugin = TitanUtils_GetPlugin(id) + if plugin and plugin.controlVariables and plugin.controlVariables.ShowIcon then + TitanPanelRightClickMenu_AddToggleVar(L["TITAN_PANEL_MENU_SHOW_ICON"], id, "ShowIcon", nil, level); + end +end + +---API Menu - add a toggle Label (localized) command at the given level in the form of a button. Titan will properly control "ShowLabelText" +---@param id string Plugin id +---@param level? number menu level or 1 +function TitanPanelRightClickMenu_AddToggleLabelText(id, level) + level = level or 1 + local plugin = TitanUtils_GetPlugin(id) + if plugin and plugin.controlVariables and plugin.controlVariables.ShowLabelText then + TitanPanelRightClickMenu_AddToggleVar(L["TITAN_PANEL_MENU_SHOW_LABEL_TEXT"], id, "ShowLabelText", nil, level); + end +end + +---API Menu - add a toggle Colored Text (localized) command at the given level in the form of a button. Titan will properly control "ShowColoredText" +---@param id string Plugin id +---@param level? number menu level or 1 +function TitanPanelRightClickMenu_AddToggleColoredText(id, level) + level = level or 1 + local plugin = TitanUtils_GetPlugin(id) + if plugin and plugin.controlVariables and plugin.controlVariables.ShowColoredText then + TitanPanelRightClickMenu_AddToggleVar(L["TITAN_PANEL_MENU_SHOW_COLORED_TEXT"], id, "ShowColoredText", nil, level); + end +end + +---API Menu - add a Hide (localized) command at the given level in the form of a button. When clicked this will remove the plugin from the Titan bar. +---@param id string Plugin id +---@param level? number menu level or 1 +function TitanPanelRightClickMenu_AddHide(id, level) + level = level or 1 + local info = {}; + info.notCheckable = true; + info.text = L["TITAN_PANEL_MENU_HIDE"]; + info.value = nil -- value; huh - what should this be? + info.func = function() + TitanPanelRightClickMenu_Hide(id) + end + Add_button(info, level); +end + +---API This will toggle the Titan variable and the update the button. +---@param value table Plugin id and var to toggle +--- Example: {TITAN_XP_ID, "ShowSimpleToLevel"} +function TitanPanelRightClickMenu_ToggleVar(value) + -- Update 2024 Mar - Removed the 'reverse' check. + -- Not sure it was ever used or even worked. + -- local id, var, toggleTable = "", nil, {} + local id, var = "", "" + + -- table expected else do nothing + if type(value) ~= "table" then return end + + if value and value[1] then id = value[1] end + if value and value[2] then var = value[2] end + -- if value and value[3] then toggleTable = value[3] end + + -- Toggle var + TitanToggleVar(id, var); + TitanPanelButton_UpdateButton(id); + --[=[]] + if ( TitanPanelRightClickMenu_AllVarNil(id, toggleTable) ) then + -- Undo if all vars in toggle table nil + TitanToggleVar(id, var); + else + -- Otherwise continue and update the button + TitanPanelButton_UpdateButton(id, 1); + end +--]=] +end + +---API Set backdrop of the plugin. Used for custom created controls (Clock / Volume) to give a consistent look. +---@param frame table Plugin control frame +function TitanPanelRightClickMenu_SetCustomBackdrop(frame) + --[[ +Blizzard decided to remove direct Backdrop API in 9.0 (Shadowlands) +so inherit the template (XML) and set the values in the code (Lua) + +9.5 The tooltip template was removed from the GameTooltip. +--]] + + frame:SetBackdrop({ + bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + tile = true, + tileEdge = true, + insets = { left = 1, right = 1, top = 1, bottom = 1 }, + tileSize = 8, + edgeSize = 8, + }) + + frame:SetBackdropBorderColor( + TOOLTIP_DEFAULT_COLOR.r, + TOOLTIP_DEFAULT_COLOR.g, + TOOLTIP_DEFAULT_COLOR.b); + frame:SetBackdropColor( + TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, + TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, + TOOLTIP_DEFAULT_BACKGROUND_COLOR.b + , 1); +end + +---API Menu - add the set of options per the plugin registry control variables. +---@param id string Plugin id +---@param level? number If not present, default to 1 (top) +function TitanPanelRightClickMenu_AddControlVars(id, level) + level = level or 1 -- assume top menu + TitanPanelRightClickMenu_AddSeparator(level) + + TitanPanelRightClickMenu_AddToggleIcon(id, level) + TitanPanelRightClickMenu_AddToggleLabelText(id, level) + TitanPanelRightClickMenu_AddToggleColoredText(id, level) + TitanPanelRightClickMenu_AddToggleRightSide(id, level) + + TitanPanelRightClickMenu_AddSpacer(); + TitanPanelRightClickMenu_AddCommand(L["TITAN_PANEL_MENU_HIDE"], id, TITAN_PANEL_MENU_FUNC_HIDE); +end + +--====== Right click menu routines for Titan Panel bars and plugins + +---Titan Close the right click menu of any plugin, if it was open. Only one can be open at a time. +function TitanUtils_CloseRightClickMenu() + if (_G["DropDownList1"]:IsVisible()) then + _G["DropDownList1"]:Hide(); + end +end + +local function PlaceMenu(self, menu) + -- Mar 2023 : Rewritten to place menu relative to the passed in frame (button) + -- Under the cover the menu is built as DropDownList1 + local frame = self:GetName() + local menu_height = menu:GetHeight() + local menu_width = menu:GetWidth() + + -- Adjust the Y offset as needed + local ftop = _G[frame]:GetTop() + local rel_y = ftop - menu_height + if rel_y > 0 then + menu.point = "TOP"; + menu.relativePoint = "BOTTOM"; + else + -- too close to bottom of screen + menu.point = "BOTTOM"; + menu.relativePoint = "TOP"; + end + + -- Adjust the X offset as needed + local x_offset = 0 + local left = 0 + local flft = _G[frame]:GetLeft() + local effscale = UIParent:GetEffectiveScale() + if TitanBarData[frame] then + -- on a Titan bar so use cursor for the 'left' + left = GetCursorPosition() -- get x; ignore y + left = left / effscale + -- correct for beginning of Titan bar + left = left - flft + else + -- a plugin + left = flft + end + local rel_x = left + menu_width + if (rel_x < GetScreenWidth()) then + -- menu will fit + menu.point = menu.point .. "LEFT"; + menu.relativePoint = menu.relativePoint .. "LEFT"; + + if TitanBarData[frame] then + x_offset = left + else + -- a plugin + x_offset = 0 + end + else + -- Menu would go off right side of the screen + menu.point = menu.point .. "RIGHT"; + menu.relativePoint = menu.relativePoint .. "RIGHT"; + + if TitanBarData[frame] then + -- correct is on Titan bar (bottom, far right) + -- flip calc since we flipped the anchor to right + x_offset = GetScreenWidth() - left + else + -- a plugin + x_offset = 0 + end + end + --[[ +print("RCM" +.." "..tostring(frame).."" +.." "..tostring(format("%0.1f", menu_height)).."" +.." "..tostring(format("%0.1f", menu_width)).."" +.." "..tostring(format("%0.1f", _G[frame]:GetLeft())).."" +.." "..tostring(menu.point).."" +.." "..tostring(menu.relativePoint).."" +.." "..tostring(format("%0.1f", left)).."" +) +--]] + ToggleDropDownMenu(1, nil, menu, frame, x_offset, 0, nil, self); +end + +---local Prepare the plugin right click menu using the function given by the plugin OR Titan bar. +---@param self table Titan Bar or Plugin frame +---@param menu table Frame to use as the menu +--- Set Titan_Debug.titan.menu to output the error to Chat. +local function TitanRightClickMenu_OnLoad(self, menu) + --[[ +: If menu is for a Titan bar then use TitanPanelRightClickMenu_PrepareBarMenu for ALL Titan bars. + +- If Function is a function then the routine can be local or in the global namespace +- If Function is a string then the routine MUST be in the global namespace. + +- The function to create the menu is determined in this order: +1. Use registry.menuContextFunction - New in 2026 Jan to use Blizzard_Menu scheme intro in 11.0.0 +2. Use registry.menuTextFunction - New in 2024 Feb to allow a explicit menu routine name +3. Assumed to be "TitanPanelRightClickMenu_Prepare"..plugin_id.."Menu" +: Titan was written in the beginning to look for this routine so we leave it to not break older plugins. +--]] + local id = "" + local err = "" + local context_menu = false + + if self.registry then + id = self.registry.id -- is a plugin + else + id = "Bar" -- is a Titan bar + end + + if id == "" then + err = "Could not display menu. " + .. "Unknown Titan ID for " + .. "'" .. (self:GetName() or "?") .. "'. " + else + -- local frame = TitanUtils_GetPlugin(id) -- get plugin frame + local frame = self.registry + local prepareFunction -- function to call + + if frame and frame.menuContextFunction then + prepareFunction = frame.menuContextFunction -- Blizzard_Menu 2026 Jan + context_menu = true + elseif frame and frame.menuTextFunction then + prepareFunction = frame.menuTextFunction -- Newer method 2024 Feb + else + -- Older method used when Titan was created + prepareFunction = "TitanPanelRightClickMenu_Prepare" .. id .. "Menu" + -- + end + + if type(prepareFunction) == 'string' then + -- Function MUST be in global namespace + -- Becomes nil if not found + prepareFunction = _G[prepareFunction] + elseif type(prepareFunction) == 'function' then + -- Can be global or local to the plugin + else + -- Invalid type, do not even try... + prepareFunction = nil + end + + if prepareFunction then + if context_menu then + -- using newer context menu for this plugin + Titan_Menu.AddContextMenu(self, prepareFunction) + else + -- deprecated, may be removed in future + UIDropDownMenu_Initialize(menu, prepareFunction, "MENU") + PlaceMenu(self, menu) + end + else + err = "Could not display menu. " + .. "No function for '" .. tostring(id) .. "' " + .. "[" .. tostring(type(prepareFunction)) .. "] " + .. "[" .. tostring(prepareFunction) .. "] " + .. ". " + end + end + + if err == "" then + -- all is good + else + Titan_Debug.Out('titan', 'menu', "Error: " .. err) + end +end + +---Titan Call the routine to build the plugin or bar menu then place it properly. +---@param self table Plugin frame +function TitanPanelRightClickMenu_Toggle(self) + -- There are two places for the menu creation routine + -- 1) Titan bar - creates same menu + -- 2) Plugin creation via the .registry + local frame = self:GetName() + local menu = _G[self:GetName() .. TITAN_PANEL_CLICK_MENU_SUFFIX] + + -- Create menu based on the frame's routine for right click menu + TitanRightClickMenu_OnLoad(self, menu) +end + +---Titan Determine if a right click menu is shown. There can only be one. +---@return boolean IsVisible +function TitanPanelRightClickMenu_IsVisible() + local res = false + if _G[drop_down_1] and _G[drop_down_1]:IsVisible() then + res = true + else + res = false + end + return res +end + +---Titan Close the right click menu if shown. There can only be one. +function TitanPanelRightClickMenu_Close() + if _G[drop_down_1] and _G[drop_down_1]:IsVisible() then + _G[drop_down_1]:Hide() + end +end + +--[=====[ NEW menu scheme Jan 2026 +Blizzard introduced a new menu scheme in 11.0.0 (July 2024) coded in Blizzard_Menu. +The menu scheme is so different new routines are needed so use a new namespace + +First: Blizzard_Menu works quite different than UIDropDownMenu. +UIDropDownMenu iterated over the code to create and show the menu. +Blizzard_Menu changed that scheme it iterates over the objects - not code. +It now expects a set of nested objects (sort of the old info) to be created. +One impact is - level and info.value disappear! +The dev no longer needs to check level and info.value to determine which portion of the menu to display. + +Now a 'root description' / menu is created to act as the new 'level 1' / main menu. +The routine to create the new menu widgets is passed to the menu create. +Nesting of submenus are created by attaching a new widget to a menu or button. +Much as child frames are created with a parent. This acts as the old info.hasArrow. + +Second: The scheme using UIDropDownMenu was deprecated and could be removed in the future. +This scheme *may* be introduced to Classic in the future. +Titan needs to keep new and old schemes working side by side. +Thankfully, the two menu schemes work side by side BUT look different. + +Fourth: Blizzard_Menu is intended for full frame options with full blown menu widgets +such as dropdowns, toggles, sliders, and more. It is used for Blizzard options, character creation, and more. + +We decided to KISS (Keep It Simple, Stupid) when using Blizzard_Menu. +We use a small number of routines designed to use menu default settings. There are very few options to tweak. +This should protect Titan when Blizzard changes the internal menu implementation. +Those routines are: +- MenuUtil.CreateContextMenu -- root of the menu; old UIDropDownMenu_Initialize +- MenuUtil.CreateButton -- old info.text; info.func +- MenuUtil.CreateCheckbox -- old info.text; info.checked; info.func +- MenuUtil.CreateRadio -- old info.text; info.checked; info.func +These handle over 90% of Titan and plugin needs. +Additionally we need to handle : +- owner:SetEnabled -- old info.disabled + +Fourth: Titan wraps the parts of Blizzard_Menu used in a new Titan_Menu table / class. +See Titan_Menu.lua for available wrappers - feel free to suggest more :). +Titan_Menu should protect Titan plugin devs when Blizzard changes the internal menu implementation. + +=== Implementation notes +A new Titan registry attribute, .menuContextFunction, was added to the .registry. +It was created to do explicitly state the plugin routine needed to create the menu widgets. +Titan will use, in order : +1) registry.menuContextFunction : NEW Jan 2026 +2) registry.menuTextFunction : Feb 2024 +3) "TitanPanelRightClickMenu_Prepare" .. id .. "Menu" : Old as Titan :) + +On right click, Titan will, in order : +1) create the context menu +2) add a menu title at top using .registry.id +3) call the plugin to fill it as before - using pcall, placing error in the menu +4) add the control vars + right side + Hide on bottom of menu +The top and bottom of the menu are common so Titan adds them for consistent style. + +The context menu holds all widgets - no nesting of context menus. +Titan provides routines in Titan_Menu to relieve the dev from some grunt work. +In both schemes, menu widgets are added in the order the code runs. + +The old create menu is left in TitanBag for comparison. As a quick example: +=== OLD + info = {}; + info.text = L["TITAN_BAG_MENU_OPEN_BAGS"] + info.func = function() + TitanToggleVar(TITAN_BAG_ID, "OpenBags") + end + info.checked = TitanGetVar(TITAN_BAG_ID, "OpenBags"); + TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); +== NEW + Titan_Menu.AddSelector(root, TITAN_BAG_ID, L["TITAN_BAG_MENU_OPEN_BAGS"], "OpenBags") +Where root is the context menu; teh locale string (L) will be placed inline at the main menu. +=== + +Only atomic elements / widgets can easily be added to the context menu. +Such as command buttons (info.func) or radio / checkbox (info.checked and info.func). +Title, spacer, and divider are available. +Using code, widgets can be enhanced and interact but a complex widget is not possible. + +It seems you can create frames and add new templates and widgets but additional code and knowledge will be needed :). +If you need complex widgets such as dropdown selector or slider you may need to create a virtual template; +meaning a fully fleshed frame in XML. This would be an options frame not a simple menu. + +--]=====] + +--[=====[ Wrapper implementation notes +Wrapper notes: +- The parameter 'owner' used below is a 'menu description' in the new terms. +-- Most Blizzard_Menu 'create' routines must have an owner to attach the widget to. +-- Most Blizzard_Menu 'create' routines return the resulting widget. + +- Blizzard_Menu create routines pass 'is selected' and 'set selected' as functions. +The wrappers continue this and extends to other needed actions. +- Adds 'update Titan button' where it makes sense, relieving the dev from including it 'all over'. +- When a single selector is created, Titan uses a checkbox. +- When multiple selectors are created, Titan uses a radio. +- When multiple selectors are created, a divider (line) is added at top. +- AddSelector* is used when checkbox or radio buttons will be created. + +--]=====] + +--== menu helpers +local nop = function(obj) end + +---local Helper Add a simple header for a list +---@param owner table Menu widget object +---@param label string Label of the selector +---@param color table Color object +---@return table elementDescription +local function GenHeader(owner, label, color) + if color == nil then + color = GRAY_FONT_COLOR + end + local elementDescription = + owner:CreateTitle(label, color) + + elementDescription:AddInitializer(function(frame, description, menu) + local fontFile, height, flags = frame.fontString:GetFont() + --[[ + print("Hdr" + .." "..tostring(fontFile).."" + .." "..tostring(height).."" + .." "..tostring(flags).."" + ) + --]] + end + ) + + -- in case we can and want need to modify in future... + return elementDescription +end + +---local Add a button that, when pressed runs a command passing any given parameters +---@param owner table Menu widget object +---@param id string Plugin ID +---@param label string Label of the selector +---@param function_name function +---@param ... any +---@return table elementDescription +local function GenCommand(owner, id, label, function_name, ...) + -- local callback = function_name + local params = ... + + local elementDescription = + owner:CreateButton(label, -- was info.text + function() -- was info.func + function_name(params) + end, + id + ) + -- in case we can and want need to modify in future... + return elementDescription + --[[ + if function_name then + if type(callback) == 'string' then + -- Function MUST be in global namespace + callback = _G[callback] + elseif type(callback) == 'function' then + -- Can be global or local to the plugin + else + -- silently leave... + end + -- Redundant but the given string may not be a function + if type(callback) == "function" then + -- No return expected... + callback(id) + else + -- Must be a function - spank developer + -- Leave, create an inactive button + callback = function() end + end + else + -- Leave, create an inactive button + callback = function() end + end +--]] +end + +---local Helper Add a simple radio +---@param owner table Menu widget object +---@param id string Plugin ID +---@param label string Label of the selector +---@param opt string Plugin option to read / change +---@return table elementDescription +local function GenRadio(owner, id, label, opt) + local elementDescription = + owner:CreateRadio(label, -- was info.text + function() -- isSelected was info.checked + return TitanGetVar(id, opt) + end, + function() -- SetSelected which was info.func + local val = not TitanGetVar(id, opt) + TitanSetVar(id, opt, val) + TitanPanelButton_UpdateButton(id); + end + ) + -- in case we can and want need to modify in future... + return elementDescription +end + +---local Helper Add a simple checkbox +---@param owner table Menu widget object +---@param id string Plugin ID +---@param label string Label of the selector +---@param opt string Plugin option to read / change +---@return table elementDescription +local function GenCheckbox(owner, id, label, opt) + local elementDescription = + owner:CreateCheckbox(label, -- was info.text + function() -- isSelected was info.checked + return TitanGetVar(id, opt) + end, + function() -- SetSelected which was info.func + local val = not TitanGetVar(id, opt) + TitanSetVar(id, opt, val) + TitanPanelButton_UpdateButton(id); + end + ) + -- in case we can and want need to modify in future... + return elementDescription +end + +---local Helper to Create a simple selector (radio) off the owner and call the function +---@param owner table Menu widget object +---@param id string Plugin ID +---@param label string Label of the selector +---@param opt string Plugin option to read / change +---@param sel_func function +---@param ... any +---@return table elementDescription +local function GenSelectorCommand(owner, id, label, opt, sel_func, ...) + local params = ... + + local elementDescription = + owner:CreateRadio(label, -- was info.text + function() -- isSelected was info.checked + return TitanGetVar(id, opt) + end, + function() -- SetSelected which was info.func + local val = not TitanGetVar(id, opt) + TitanSetVar(id, opt, val) + -- Once the opt is set run the command + sel_func(params) + -- Then update... + TitanPanelButton_UpdateButton(id); + end + ) + -- in case we can and want need to modify in future... + return elementDescription +end + +---local Add title to owner +---@param owner table Menu widget object +---@param label string Label of the selector +---@return table elementDescription +local function GenTitle(owner, label) + local elementDescription = owner:CreateTitle(label) + return elementDescription +end + +---local Add the desired control vars to the owner; this expected to end the menu! +---@param owner table Menu widget object +---@param id string Plugin ID +---@param add_hide boolean +local function GenControlVars(owner, id, add_hide) + owner:CreateDivider() + + local plugin = TitanUtils_GetPlugin(id) + + if plugin and plugin.controlVariables and plugin.controlVariables.ShowIcon then + GenCheckbox(owner, id, L["TITAN_PANEL_MENU_SHOW_ICON"], "ShowIcon") + end + if plugin and plugin.controlVariables and plugin.controlVariables.ShowLabelText then + GenCheckbox(owner, id, L["TITAN_PANEL_MENU_SHOW_LABEL_TEXT"], "ShowLabelText") + end + if plugin and plugin.controlVariables and plugin.controlVariables.ShowRegularText then --(LDB data sources only atm) + GenCheckbox(owner, id, L["TITAN_PANEL_MENU_SHOW_LABEL_TEXT"], "TITAN_PANEL_MENU_SHOW_PLUGIN_TEXT") + end + if plugin and plugin.controlVariables and plugin.controlVariables.ShowColoredText then + GenCheckbox(owner, id, L["TITAN_PANEL_MENU_SHOW_COLORED_TEXT"], "ShowColoredText") + end + + owner:CreateCheckbox(L["TITAN_CLOCK_MENU_DISPLAY_ON_RIGHT_SIDE"], + function() -- isSelected + return TitanGetVar(id, "DisplayOnRightSide") + end, + function() -- SetSelected + local bar = TitanUtils_GetWhichBar(id) + TitanPanelRightClickMenu_ToggleVar({ id, "DisplayOnRightSide" }) + TitanPanel_RemoveButton(id); + TitanUtils_AddButtonOnBar(bar, id) + end + ) + + if add_hide then + Titan_Menu.AddSpacer(owner) + + GenCommand(owner, id, L["TITAN_PANEL_MENU_HIDE"], TitanPanelRightClickMenu_Hide, id) + else + -- not requested + end +end + +local function MarkFromList(id, opt, list) + for idx = 1, #list do + local list_opt = list[idx][2] + + if list_opt == opt then + TitanSetVar(id, list_opt, true); + else + TitanSetVar(id, list_opt, false); + end + end +end + +---API Add divider (line) to owner +---@param owner table Menu widget object +---@return table elementDescription +function Titan_Menu.AddDivider(owner) + local elementDescription = owner:CreateDivider() + return elementDescription +end + +---API Add spacer (blank) to owner +---@param owner table Menu widget object +---@return table elementDescription +function Titan_Menu.AddSpacer(owner) + local elementDescription = owner:CreateSpacer() + return elementDescription +end + +---API Add text, no actions +---@param owner table Menu widget object +---@param label string Label of the selector +---@param color? table Color object, if nil defaults to gray +---@return table elementDescription +function Titan_Menu.AddText(owner, label, color) + local elementDescription = GenHeader(owner, label, color) + + return elementDescription +end + +---API Set Enabled attribute on a widget using a function +---@param owner table Menu widget object +---@param enabled boolean +function Titan_Menu.SetAtribEnabled(owner, enabled) + owner:SetEnabled(enabled) -- .isEnabled +end + +---API Add a simple button to owner; expect this to be a parent +---@param owner table Menu widget object +---@param label string Label of the selector +---@return table elementDescription +function Titan_Menu.AddButton(owner, label) + local elementDescription = owner:CreateButton(label) + return elementDescription +end + +---API Create a simple selector off the owner +---@param owner table Menu widget object +---@param id string Plugin ID +---@param label string Label of the selector +---@param opt string Plugin option to read / change +---@return table elementDescription +function Titan_Menu.AddSelector(owner, id, label, opt) + local elementDescription = GenCheckbox(owner, id, label, opt) + return elementDescription +end + +---API Create a simple selector off the owner +---@param owner table Menu widget object +---@param label string Label of the selector +---@param isSelected function +---@param setSelected function +---@param data table Pass to functions as is +---@return table elementDescription +function Titan_Menu.AddSelectorGeneric(owner, label, isSelected, setSelected, data) + local elementDescription = + owner:CreateCheckbox(label, -- was info.text + isSelected, + setSelected, + data -- passed to both functions as table + ) + -- in case we can and want need to modify in future... + return elementDescription +end + +---API Create a selector for each item in list; N selectors > N options (only one true) +---@param owner table Menu widget object +---@param id string Plugin ID +---@param label string? For Title, if desired +---@param list table Label - option pair table +function Titan_Menu.AddSelectorExclusiveList(owner, id, label, list) + Titan_Menu.AddDivider(owner) + + if label == nil then + -- no title wanted + else + GenHeader(owner, label, GRAY_FONT_COLOR) + end + + -- Whip through list of label - option (vars) + for idx = 1, #list do + local optlabel = list[idx][1] + local opt = list[idx][2] + owner:CreateRadio( + optlabel, + function() -- isSelected + return TitanGetVar(id, opt) + end, + function() -- SetSelected + MarkFromList(id, opt, list) + TitanPanelButton_UpdateButton(id); + end + ) + end +end + +---API Create a selector for each item in list; N selectors > 1 option +---@param owner table Menu widget object +---@param id string Plugin ID +---@param label string? For Title, if desired +---@param opt string Plugin option to read / change +---@param list table Label - Value pair table +---@param sel_func? function +---@param ... any +function Titan_Menu.AddSelectorList(owner, id, label, opt, list, sel_func, ...) + local params = ... + + Titan_Menu.AddDivider(owner) + + if label == nil then + -- no title wanted + else + GenHeader(owner, label, GRAY_FONT_COLOR) + end + + -- Whip through list of label - option (vars) + for idx = 1, #list do + local optlabel = list[idx][1] + local optvalue = list[idx][2] + owner:CreateRadio( + optlabel, + function() -- isSelected + return (TitanGetVar(id, opt) == optvalue) + end, + function() -- SetSelected + TitanSetVar(id, opt, optvalue) + -- Once the opt is set run the command + if sel_func == nil then + -- nothing requested + else + sel_func(params) + end + TitanPanelButton_UpdateButton(id); + end + ) + end +end + +---API Add a button that, when pressed runs a command passing any given paramters +---@param owner table Menu widget object +---@param id string Plugin ID +---@param label string Label of the selector +---@param function_name function +---@return table elementDescription +function Titan_Menu.AddCommand(owner, id, label, function_name, ...) + local params = ... + local elementDescription = GenCommand(owner, id, label, function_name, params) + return elementDescription +end + +---Titan Add the desired control vars to the owner; this expected to end the menu! +---@param owner table Menu widget object +---@param id string Plugin ID +function Titan_Menu.AddControlVars(owner, id) + GenControlVars(owner, id, false) +end + +---API Helper to Create a simple selector (radio) off the owner and call the function before updating buttonplugin text. +---@param owner table Menu widget object +---@param id string Plugin ID +---@param label string Label of the selector +---@param opt string Plugin option to read / change +---@param function_name function +---@param ... any +---@return table elementDescription +function Titan_Menu.AddSelectorCommand(owner, id, label, opt, function_name, ...) + local elementDescription = GenSelectorCommand(owner, id, label, opt, function_name, ...) + return elementDescription +end + +---Titan ONLY, called by Titan right click handler! +---Create Root menu description to attach menu widgets to +---@param owner table Plugin object / table +---@param gen_function function Used to add descriptions / widgets +---@return table Root Root description / widget +function Titan_Menu.AddContextMenu(owner, gen_function, ...) + local params = ... + + local function gen_menu(plugin_frame, rootDescription, params_gen) + local root = rootDescription + + -- Add a tile and divider to the menu + local id = "" + if plugin_frame.registry and plugin_frame.registry.menuText then + id = plugin_frame.registry.menuText + else + id = "??" + end + GenTitle(root, id) + Titan_Menu.AddDivider(root) + + -- Attach widgets or show error! + local succ, val = pcall(gen_function, plugin_frame, root, params) + if succ then + -- all good + else + GenHeader(root, id .. " !! " .. val, RED_FONT_COLOR) + end + + if plugin_frame and plugin_frame.registry.category == Titan_Global.categories.TitanBar then + -- Titan bar; do not show the control vars atm + else + -- Add the control variables + right side + Hide + GenControlVars(root, plugin_frame.registry.id, true) + end + end + + -- This does return a menu object but we choose to let Blizz handle opening through closing. + return MenuUtil.CreateContextMenu(owner, gen_menu, params) + + -- CreateContextMenu will take other parameters (as ...) which are passed to GeneratorFunction. + -- A handy feature but not used in Titan. +end diff --git a/Titan/TitanTemplate.lua b/Titan/TitanTemplate.lua index 637ec95..85b851f 100644 --- a/Titan/TitanTemplate.lua +++ b/Titan/TitanTemplate.lua @@ -7,7 +7,7 @@ Contains the routines to control a Titan template frame whether Titan bar or plu --[===[ Var API TitanPanelTemplate overview Creates the following frames: - TitanPanelBarButton : Main Titan frame handling events -TODO - TitanPanelTooltip : Used? Inherits from GameTooltipTemplate +- TitanPanelTooltip : Inherits from GameTooltipTemplate Contains the routines to control a Titan template frame. These could be: @@ -70,10 +70,7 @@ local pluginOnEnter = nil; -- Used for drag and drop, assuming one can only drag one plugin :) local TITAN_PANEL_MOVE_ADDON = ""; local TITAN_PANEL_DROPOFF_ADDON = ""; -local Drag_init = {} -local drag = Drag_init local FROM_BAR_SHORT = "" -local FROM_BAR_FRAME = "" -- Library instances local LibQTip = nil @@ -81,14 +78,6 @@ local _G = getfenv(0); local InCombatLockdown = _G.InCombatLockdown local media = LibStub("LibSharedMedia-3.0") ---[[ -print("B text" -.." "..tostring(id).."" -.." "..tostring(type(bFunction)).."" -.." '"..tostring(bFunction).."'" -.." '"..tostring(buttonTextFunction).."'" -) ---]] --========================== --[[ local @@ -141,7 +130,7 @@ local function TitanTooltip_AddTooltipText(text, frame) end end ----local Helper to set both the parent and the position of GameTooltip for the plugin tooltip. +---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 @@ -151,7 +140,7 @@ end ---@param frame table Tooltip frame --- Set Titan_Debug.titan.tool_tips to output debug local function TitanTooltip_SetOwnerPosition(parent, anchorPoint, relativeToFrame, relativePoint, xOffset, yOffset, frame) - -- Changes for 9.1.5 Removed the background template from the GameTooltip + -- Changes for 9.1.5 Removed the background template from the Tooltip -- Making changes to it difficult and possibly changing the tooltip globally. frame:SetOwner(parent, "ANCHOR_NONE"); @@ -168,24 +157,24 @@ local function TitanTooltip_SetOwnerPosition(parent, anchorPoint, relativeToFram frame:SetScale(TitanPanelGetVar("TooltipFont")); end - local dbg_msg = "_pos" - .. " '" .. tostring(frame:GetName()) .. "'" - .. " " .. tostring(frame:IsShown()) .. "" - .. " @ '" .. tostring(relativeToFrame) .. "'" - .. " " .. tostring(_G[relativeToFrame]:IsShown()) .. "" - Titan_Debug.Out('titan', '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('titan', 'tool_tips', dbg_msg) + local dbg_msg = "_pos" + .. " '" .. tostring(frame:GetName()) .. "'" + .. " " .. tostring(frame:IsShown()) .. "" + .. " @ '" .. tostring(relativeToFrame) .. "'" + .. " " .. tostring(_G[relativeToFrame]:IsShown()) .. "" + Titan_Debug.Out('titan', '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('titan', 'tool_tips', dbg_msg) end ---local Helper to set the screen position of the tooltip frame ----@param self table Tooltip frame +---@param self table Plugin frame ---@param id string Plugin id name ----@param frame table Tooltip frame - expected to be GameTooltip +---@param frame table Tooltip frame to use local function TitanTooltip_SetPanelTooltip(self, id, frame) local button = TitanUtils_GetButton(id) @@ -220,68 +209,105 @@ local function TitanTooltip_SetPanelTooltip(self, id, frame) end end ----local Set the tooltip (GameTooltip) of the given Titan plugin. ----@param self table Plugin frame ---- Set Titan_Debug.titan.tool_tips to output debug of this routine -local function TitanPanelButton_SetTooltip(self) - local dbg_msg = "TT:" +---Determine if the tooltip should be shown +---@param self table Tooltip frame +---@return boolean ok to show tooltip +local function AllowTooltip(self) local ok = false - local frame = GameTooltip - local id = self.registry.id - + local dbg_msg = "IsMenuOpen:" -- ensure that the 'self' passed is a valid frame reference if self:GetName() then + local menu_mgr = Menu.GetManager() + + local id = self.registry_id + local controlFrame = TitanUtils_GetControlFrame(id); + local plugin = _G[self.plugin_frame_str] + dbg_msg = dbg_msg .. "'" .. self:GetName() .. "'" -- sanity checks if (TitanPanelGetVar("HideTipsInCombat") and InCombatLockdown()) then dbg_msg = dbg_msg .. " HideTipsInCombat" + elseif (menu_mgr and menu_mgr:IsAnyMenuOpen()) then -- Blizzard_Menu + dbg_msg = dbg_msg .. " IsAnyMenuOpen" + elseif (controlFrame and controlFrame:IsVisible()) then -- Titan custom menu widget + dbg_msg = dbg_msg .. " controlFrame" + elseif TitanPanelRightClickMenu_IsVisible() then -- UIDropDownMenu + dbg_msg = dbg_msg .. " TitanPanelRightClickMenu_IsVisible" + elseif not TitanPanelGetVar("ToolTipsShown") then -- user does not want tooltips + dbg_msg = dbg_msg .. " not ToolTipsShown" + elseif plugin.isMoving then -- this plugin is moving + dbg_msg = dbg_msg .. " isMoving" + plugin:Hide() + elseif TITAN_PANEL_MOVING == 1 then -- another plugin is being moved + dbg_msg = dbg_msg .. " TITAN_PANEL_MOVING" else - if TitanPanelGetVar("ToolTipsShown") then - ok = true - else - dbg_msg = dbg_msg .. " ToolTipsShown false" - end + ok = true -- whew, we can actually show! end else dbg_msg = dbg_msg .. " No frame" -- Cannot even start end + local mods = false -- + local use_mod = TitanAllGetVar("UseTooltipModifer") + local use_alt = TitanAllGetVar("TooltipModiferAlt") + local use_ctrl = TitanAllGetVar("TooltipModiferCtrl") + local use_shift = TitanAllGetVar("TooltipModiferShift") + + if use_mod then + if (use_alt and IsAltKeyDown()) + or (use_ctrl and IsControlKeyDown()) + or (use_shift and IsShiftKeyDown()) + then + mods = true + end + else + mods = true + end + + return (ok and mods) +end + +---local Set the tooltip of the given Titan plugin. +---@param self table Plugin frame +--- Set Titan_Debug.titan.tool_tips to output debug of this routine +local function TitanPanelButton_SetTooltip(self) + local dbg_msg = "TT:" + local ok = false + local frame = TitanPanelTooltip --GameTooltip + local id = self.registry.id + -- Jan 2026 : Place all checks to NOT show tooltip here... + -- Checks in other places tooltips could show were causing visual oddities. + + frame.registry_id = id -- for use in other routines + frame.plugin_frame_str = self:GetName() + + ok = AllowTooltip(frame) + if ok then local call_success = nil local tmp_txt = "" - local use_mod = TitanAllGetVar("UseTooltipModifer") - local use_alt = TitanAllGetVar("TooltipModiferAlt") - local use_ctrl = TitanAllGetVar("TooltipModiferCtrl") - local use_shift = TitanAllGetVar("TooltipModiferShift") - - if use_mod then - if (use_alt and IsAltKeyDown()) - or (use_ctrl and IsControlKeyDown()) - or (use_shift and IsShiftKeyDown()) - then - ok = true - end - else - ok = true - end self.tooltipCustomFunction = nil; self.titan_tt_func = "" self.titan_tt_err = "" - if ok and (id and TitanUtils_IsPluginRegistered(id)) then + if (id and TitanUtils_IsPluginRegistered(id)) then local plugin = TitanUtils_GetPlugin(id) -- 2024 Jun Add id and frame name to 'pass' to tooltip routine. -- A compromise given that this mechanism is used by nearly all plugins. -- Used by Titan auto hide to better determine which bar the 'pin' / icon is on. self.plugin_id = id self.plugin_frame = TitanUtils_ButtonName(id) - if (plugin and plugin.tooltipCustomFunction) then - -- Hide the GameTooltip while being updated, to avoid race conditions. - frame:Hide() - -- Prep the tooltip frame - TitanTooltip_SetPanelTooltip(self, id, frame); + if (plugin and plugin.ldb) then + -- assume the TitanLDB processing will handle the tooltip. + elseif (plugin and plugin.tooltipCustomFunction) then + -- Hide the Titan Tooltip in case it is open. + frame:Hide() + -- 2026 Jan Switching to a Titan controlled frame made us realize + -- changing GameTooltip for custom tooltips creates a hybrid mess... + -- The plugin Dev should take full ownership of the tooltip :). + --TitanTooltip_SetPanelTooltip(self, id, frame); -- Fill the tooltip self.tooltipCustomFunction = plugin.tooltipCustomFunction; @@ -295,8 +321,10 @@ local function TitanPanelButton_SetTooltip(self) dbg_msg = dbg_msg .. " | Err: " .. tmp_txt end - frame:Show(); -- now show it - elseif (plugin and plugin.tooltipTitle) then + -- frame:Show(); -- now show it + elseif (plugin) then + -- 2026 Jan No longer require registry.tooltipTitle allowing dev to set their own + -- From Lingkan dev of Titan Rep Continued local tooltipTextFunc = {} ---@type function local tt_func = plugin.tooltipTextFunction @@ -314,18 +342,23 @@ local function TitanPanelButton_SetTooltip(self) end if (tooltipTextFunc) then - -- Hide the GameTooltip while being updated, to avoid race conditions. - frame:Hide() + -- Hide the Tooltip while being updated, to avoid race conditions. + frame:Hide() -- Prep the tooltip frame TitanTooltip_SetPanelTooltip(self, id, frame); - self.tooltipTitle = plugin.tooltipTitle; + if plugin.tooltipTitle then + self.tooltipTitle = plugin.tooltipTitle; + frame:SetText(self.tooltipTitle, + HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) + else + -- assume dev is doing their own thing + end call_success, -- for pcall tmp_txt = pcall(tooltipTextFunc, self) -- Fill the tooltip + -- If pcall errors, the error will be in the tooltip self.tooltipText = tmp_txt - frame:SetText(self.tooltipTitle, - HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b); if (self.tooltipText) then TitanTooltip_AddTooltipText(self.tooltipText, frame) dbg_msg = dbg_msg .. " | ok" @@ -337,14 +370,15 @@ local function TitanPanelButton_SetTooltip(self) end else -- no recognized method to create tooltip - dbg_msg = "No recognized tooltip method [.tooltipCustomFunction then .tooltipTitle /.tooltipText]" + dbg_msg = "No recognized tooltip method [.tooltipCustomFunction " + .."then tooltipTextFunction (with .tooltipTitle, if set)]" end end else -- no need to waste cycles end - Titan_Debug.Out('titan', 'tool_tips', dbg_msg) + Titan_Debug.Out('titan', 'tool_tips', dbg_msg) end ---local Is the given Titan plugin template type text? @@ -409,8 +443,8 @@ local function TitanPanelButton_OnDragStart(self) local plugin_id = TitanUtils_GetButtonID(frstr) local str = "" str = "_OnDragStart start " - .." "..tostring(plugin_id).."" --- .." from "..tostring(FROM_BAR_SHORT).."" + .. " " .. tostring(plugin_id) .. "" + -- .." from "..tostring(FROM_BAR_SHORT).."" Titan_Debug.Out('titan', 'plugin_drag_drop', str) @@ -423,7 +457,7 @@ local function TitanPanelButton_OnDragStart(self) -- Close any tooltips and control frames TitanUtils_CloseAllControlFrames(); TitanPanelRightClickMenu_Close(); - GameTooltip:Hide(); + TitanPanelTooltip:Hide(); -- LibQTip-1.0 support code LibQTip = LibStub("LibQTip-1.0", true) @@ -442,8 +476,8 @@ local function TitanPanelButton_OnDragStart(self) FROM_BAR_SHORT = TitanUtils_GetWhichBar(plugin_id) -- short name str = "_OnDragStart moving" - .." "..tostring(plugin_id).."" - .." from "..tostring(FROM_BAR_SHORT).."" + .. " " .. tostring(plugin_id) .. "" + .. " from " .. tostring(FROM_BAR_SHORT) .. "" Titan_Debug.Out('titan', 'plugin_drag_drop', str) -- Clear the plugin placement so we only move the intended plugin TitanPanel_RemoveButton(plugin_id, false) @@ -475,7 +509,7 @@ local function TitanPanelButton_OnDragStop(self) local str = "" str = "_OnDragStop start " - .." "..tostring(plugin_id).."" + .. " " .. tostring(plugin_id) .. "" Titan_Debug.Out('titan', 'plugin_drag_drop', str) if TITAN_PANEL_MOVING == 1 then @@ -488,9 +522,9 @@ local function TitanPanelButton_OnDragStop(self) local fbar = TitanGetVar(plugin_id, "ForceBar") str = "_OnDragStop " - .." "..tostring(plugin_id).."" + .. " " .. tostring(plugin_id) .. "" if fbar == nil - or fbar == false then + or fbar == false then -- Find which bar it was dropped on for idx, v in pairs(TitanBarData) do bar = idx @@ -501,17 +535,17 @@ local function TitanPanelButton_OnDragStop(self) if tbar == "" then -- not sure what the user did... -- Likely released on UI so put back on the bar it came from - str = str .." back to" + str = str .. " back to" tbar = FROM_BAR_SHORT else - str = str .." onto" + str = str .. " onto" end else - str = str .." force to" + str = str .. " force to" tbar = fbar -- put it back; allows user to shift it end - str = str .." "..tostring(tbar).."" + str = str .. " " .. tostring(tbar) .. "" Titan_Debug.Out('titan', 'plugin_drag_drop', str) TitanUtils_AddButtonOnBar(tbar, TITAN_PANEL_MOVE_ADDON) @@ -519,12 +553,11 @@ local function TitanPanelButton_OnDragStop(self) TITAN_PANEL_MOVE_ADDON = ""; if pluginOnEnter then -- Restore the OnEnter script handler - self:SetScript("OnEnter", pluginOnEnter) + self:SetScript("OnEnter", pluginOnEnter) else -- No OnEnter was found at drag start end pluginOnEnter = nil; - end end @@ -641,14 +674,13 @@ function TitanPanelButton_OnClick(self, button) TitanPanelRightClickMenu_Toggle(self); end - GameTooltip:Hide(); + TitanPanelTooltip:Hide(); end end ---API Handle the OnEnter event of the requested Titan plugin. ---@param self table Plugin frame ---- 1. The cursor has moved over the plugin so show the plugin tooltip. ---- 2. Return if plugin "is moving" or if tooltip is already shown. +--- The cursor has moved over the plugin so show the plugin tooltip if there are no blockers. function TitanPanelButton_OnEnter(self) local id = nil; -- ensure that the 'self' passed is a valid frame reference @@ -657,29 +689,12 @@ function TitanPanelButton_OnEnter(self) end if (id) then - local menu_mgr = Menu.GetManager() - - local controlFrame = TitanUtils_GetControlFrame(id); - if (menu_mgr and menu_mgr:IsAnyMenuOpen()) then - return - elseif (controlFrame and controlFrame:IsVisible()) then - return; - elseif (TitanPanelRightClickMenu_IsVisible()) then - return; - else - if TITAN_PANEL_MOVING == 0 then - TitanPanelButton_SetTooltip(self); - end - if self.isMoving then - GameTooltip:Hide(); - end - end + TitanPanelButton_SetTooltip(self) end end ---API Handle the OnLeave event of the requested Titan plugin. ---@param self table Plugin frame ---- 1. The cursor has moved over the plugin so hide the plugin tooltip. function TitanPanelButton_OnLeave(self) local id = nil; -- ensure that the 'self' passed is a valid frame reference @@ -687,15 +702,17 @@ function TitanPanelButton_OnLeave(self) id = TitanUtils_GetButtonID(self:GetName()) end - if (id) then - GameTooltip:Hide(); - end + -- The cursor has moved away from the plugin. + -- Let the tooltip SetScripts handle timer to Hide. + --if (id) then + -- TitanPanelTooltip:Hide(); + --end if TitanPanelGetVar("DisableTooltipFont") then -- use game font & scale else -- use Titan font & scale - GameTooltip:SetScale(TitanTooltipOrigScale); + TitanPanelTooltip:SetScale(TitanTooltipOrigScale); TitanTooltipScaleSet = 0; end end @@ -817,9 +834,9 @@ local function TitanPanelButton_SetButtonText(id) if show_label then if TitanGetVar(id, "CustomLabel2TextShow") then -- override the label per the user - label2 = " "..TitanGetVar(id, "CustomLabel2Text") + label2 = " " .. TitanGetVar(id, "CustomLabel2Text") else - label2 = " "..label2 + label2 = " " .. label2 end else label2 = " " @@ -830,9 +847,9 @@ local function TitanPanelButton_SetButtonText(id) if show_label then if TitanGetVar(id, "CustomLabel3TextShow") then -- override the label per the user - label3 = " "..TitanGetVar(id, "CustomLabel3Text") + label3 = " " .. TitanGetVar(id, "CustomLabel3Text") else - label3 = " "..label3 + label3 = " " .. label3 end else label3 = " " @@ -843,9 +860,9 @@ local function TitanPanelButton_SetButtonText(id) if show_label then if TitanGetVar(id, "CustomLabel43TextShow") then -- override the label per the user - label4 = " "..TitanGetVar(id, "CustomLabel4Text") + label4 = " " .. TitanGetVar(id, "CustomLabel4Text") else - label4 = " "..label4 + label4 = " " .. label4 end else label4 = " " @@ -869,18 +886,18 @@ local function TitanPanelButton_SetButtonText(id) label4 or "", value4 or "" ) --]==] - buttonText:SetText("" -- formatting was inserting undesired spaces - ..(label1 or "")..(value1 or "") - ..(label2 or "")..(value2 or "") - ..(label3 or "")..(value3 or "") - ..(label4 or "")..(value4 or "") + buttonText:SetText("" -- formatting was inserting undesired spaces + .. (label1 or "") .. (value1 or "") + .. (label2 or "") .. (value2 or "") + .. (label3 or "") .. (value3 or "") + .. (label4 or "") .. (value4 or "") ) end else -- no valid routine to update the plugin text dbg_msg = dbg_msg .. " | no valid routine found" end - Titan_Debug.Out('titan', 'plugin_text', dbg_msg) + Titan_Debug.Out('titan', 'plugin_text', dbg_msg) end ---local Set the width of the given Titan plugin - text only. @@ -984,7 +1001,7 @@ end ---@param id string Plugin id ---@param setButtonWidth? integer Width in pixels --- Use after any change to icon, label, or text (depending on Titan template used) ---- TitanPanelButton_UpdateButton(TITAN_CLOCK_ID) +--- TitanPanelButton_UpdateButton(ID) function TitanPanelButton_UpdateButton(id, setButtonWidth) -- Used by plugins local plugin = TitanUtils_GetPlugin(id) @@ -1017,7 +1034,7 @@ end ---@param self table Plugin frame function TitanPanelButton_UpdateTooltip(self) if not self then return end - if (GameTooltip:IsOwned(self)) then + if (TitanPanelTooltip:IsOwned(self)) then local id = TitanUtils_GetButtonID(self:GetName()); TitanPanelButton_SetTooltip(self); @@ -1057,10 +1074,6 @@ function TitanPanelPluginHandle_OnUpdate(table, oldarg) if (updateType == TITAN_PANEL_UPDATE_TOOLTIP or updateType == TITAN_PANEL_UPDATE_ALL) and MouseIsOver(_G[TitanUtils_ButtonName(id)]) then - if TitanPanelRightClickMenu_IsVisible() or TITAN_PANEL_MOVING == 1 then - return - end - TitanPanelButton_SetTooltip(_G[TitanUtils_ButtonName(id)]) end end @@ -1218,4 +1231,19 @@ function TitanOptionsSliderTemplate_OnLoad(self) tileSize = 8, edgeSize = 8, }) -end \ No newline at end of file +end + +-- Set tool tip scripts +local tt_frame = TitanPanelTooltip + +tt_frame:SetScript("OnShow", function(self) +end) +tt_frame:SetScript("OnEnter", function(self) + TitanUtils_StopFrameCounting(self) +end) +tt_frame:SetScript("OnLeave", function(self) + TitanUtils_StartFrameCounting(self, TitanPanelGetVar("TooltipTimeout")) +end) +tt_frame:SetScript("OnUpdate", function(self, elapsed) + TitanUtils_CheckFrameCounting(self, elapsed); +end) diff --git a/Titan/TitanUtils.lua b/Titan/TitanUtils.lua index 04810aa..5a8487c 100644 --- a/Titan/TitanUtils.lua +++ b/Titan/TitanUtils.lua @@ -32,22 +32,12 @@ local drop_down_1 = "" -- changes drop down menu version. Blizzard hard-codes th The L_* routines wrap the drop down menu API for Titan Classic plugins. - -Changes: -May 2025 : Replace the Ace lib for Drop Down menus with Blizz version; still need L_ wrappers for 3rd party Titan plugins. Need to implement our own menu timeout. -Nov 2023 : Merge Retail and Classic to minimize versions and maintainence and, hopefully, allow a consistent feature set. Ace drop down wrappers were added back. -Dec 2018 : Replace the Ace lib with the Blizzard drop down routines --]===] local _G = getfenv(0); local L = LibStub("AceLocale-3.0"):GetLocale(TITAN_ID, true) local AceHook = LibStub("AceHook-3.0") -local drop_down_1 = "" -- changes if using Blizz drop down (retail) or lib (Classic) - ---====== Set the default drop down menu routines per retail or Classic -drop_down_1 = "DropDownList1" -- Boo!! Per hard-coded Blizz UIDropDownMenu.lua - --[[ This set of routines controls the menu timer. It keeps the menu open as long as the mouse is over an open menu or sub menu. @@ -60,12 +50,6 @@ The OnUpdate must do the 'over menu' check. local function IsMouseOverMenu() for idx = 1, UIDROPDOWNMENU_MAXLEVELS do -- if _G["DropDownList" .. idx]:IsMouseOver() then - --[[ -print("TU _Mouse on menu" -.." "..tostring(idx).."" -.." / "..tostring(UIDROPDOWNMENU_MAXLEVELS).."" -) ---]] return true -- else -- not over, keep checking @@ -99,16 +83,6 @@ local function OnUpdateTimer(self, elapsed) str = str .. " " .. tostring(self.showTimer) .. "" .. " " .. tostring(self.isCounting) .. "" - --[[ -if str == tstr then --- same, prevent run away text -else -print(tostring(str) -.." "..tostring(format("%0.1f", (elapsed or 0.0))).."" -) -tstr = str -end ---]] end ---Start a timer to close menu @@ -127,14 +101,6 @@ local function StartCounting(self) self.showTimer = UIDROPDOWNMENU_SHOW_TIME; self.isCounting = 1; end - --[[ -print("TU _Leave Start" -.." "..tostring(str).."" -.." "..tostring(self:GetName()).."" -.." "..tostring(self.isCounting).."" -.." "..tostring(format("%0.1f", (self.showTimer or 0.0))).."" -) ---]] end ---Start a timer to close menu @@ -152,26 +118,12 @@ local function StopCounting(frame) str = str .. "nop" -- Nothing to do; if timing, allow to run out end - --[[ -print("TU _Enter Stop" -.." "..tostring(str).."" -.." "..tostring(frame:GetName()).."" -.." "..tostring(frame.isCounting).."" -.." "..tostring(format("%0.1f", (frame.showTimer or 0.0))).."" -) ---]] end ---Add scripts and start timer to menu being shown ---@param level number ---@param index number function TitanUtils_AddHide(level, index) - --[[ -print("TU _AddHide" -.." "..tostring(level).."" -.." "..tostring(index).."" -) ---]] local frame = _G["DropDownList" .. level] -- Add these to start and stop the hide timer frame:SetScript("OnEnter", function(self) StopCounting(self) end) @@ -193,15 +145,6 @@ if UIDropDownMenu_StartCounting then -- Post Hook the OnShow of DropDownList AceHook:SecureHookScript(DropDownList1, "OnShow", StartTimer) else - --[[ - for idx = 1, UIDROPDOWNMENU_MAXLEVELS do -- should be first 3 ... -print("TU _dd" -.." "..tostring(idx).."" -.." / "..tostring(UIDROPDOWNMENU_MAXLEVELS).."" -) - TitanUtils_AddHide(idx, 1) -- Add scripts to existing - end ---]] -- In case any code creates more than 3. ---@diagnostic disable-next-line: param-type-mismatch if not AceHook:IsHooked("UIDropDownMenu_CreateFrames", TitanUtils_AddHide) then @@ -215,337 +158,6 @@ print("TU _dd" end end - ---[===[ Var API Dropdown Menu wrappers -Right click menu routines for 3rd party plugins (mainly Classic WoW versions) - ---]===] - ---[[ -Local helper(s) from the Ace lib. ---]] --- L_UIDropDownMenuTemplate - ----Ensure the menu is created properly including back drop ----@param name table | string ----@param parent Frame ----@return any -local function create_DropDownMenu(name, parent) - local f - if type(name) == "table" then - f = name - name = f:GetName() - else - f = CreateFrame("Frame", name, parent or nil) - end - - --if not name then name = "" end - - f:SetSize(40, 32) - - f.Left = f:CreateTexture(name and (name .. "Left") or nil, "ARTWORK") - f.Left:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") - f.Left:SetSize(25, 64) - f.Left:SetPoint("TOPLEFT", f, 0, 17) - f.Left:SetTexCoord(0, 0.1953125, 0, 1) - - f.Middle = f:CreateTexture(name and (name .. "Middle") or nil, "ARTWORK") - f.Middle:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") - f.Middle:SetSize(115, 64) - f.Middle:SetPoint("LEFT", f.Left, "RIGHT") - f.Middle:SetTexCoord(0.1953125, 0.8046875, 0, 1) - - f.Right = f:CreateTexture(name and (name .. "Right") or nil, "ARTWORK") - f.Right:SetTexture("Interface\\Glues\\CharacterCreate\\CharacterCreate-LabelFrame") - f.Right:SetSize(25, 64) - f.Right:SetPoint("LEFT", f.Middle, "RIGHT") - f.Right:SetTexCoord(0.8046875, 1, 0, 1) - - f.Text = f:CreateFontString(name and (name .. "Text") or nil, "ARTWORK", "GameFontHighlightSmall") - f.Text:SetWordWrap(false) - f.Text:SetJustifyH("RIGHT") - f.Text:SetSize(0, 10) - f.Text:SetPoint("RIGHT", f.Right, -43, 2) - - f.Icon = f:CreateTexture(name and (name .. "Icon") or nil, "OVERLAY") - f.Icon:Hide() - f.Icon:SetSize(16, 16) - f.Icon:SetPoint("LEFT", 30, 2) - - -- // UIDropDownMenuButtonScriptTemplate - f.Button = CreateFrame("Button", name and (name .. "Button") or nil, f) - f.Button:SetMotionScriptsWhileDisabled(true) - f.Button:SetSize(24, 24) - f.Button:SetPoint("TOPRIGHT", f.Right, -16, -18) - - f.Button.NormalTexture = f.Button:CreateTexture(name and (name .. "NormalTexture") or nil) - f.Button.NormalTexture:SetTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up") - f.Button.NormalTexture:SetSize(24, 24) - f.Button.NormalTexture:SetPoint("RIGHT", f.Button, 0, 0) - f.Button:SetNormalTexture(f.Button.NormalTexture) - - f.Button.PushedTexture = f.Button:CreateTexture(name and (name .. "PushedTexture") or nil) - f.Button.PushedTexture:SetTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down") - f.Button.PushedTexture:SetSize(24, 24) - f.Button.PushedTexture:SetPoint("RIGHT", f.Button, 0, 0) - f.Button:SetPushedTexture(f.Button.PushedTexture) - - f.Button.DisabledTexture = f.Button:CreateTexture(name and (name .. "DisabledTexture") or nil) - f.Button.DisabledTexture:SetTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled") - f.Button.DisabledTexture:SetSize(24, 24) - f.Button.DisabledTexture:SetPoint("RIGHT", f.Button, 0, 0) - f.Button:SetDisabledTexture(f.Button.DisabledTexture) - - f.Button.HighlightTexture = f.Button:CreateTexture(name and (name .. "HighlightTexture") or nil) - f.Button.HighlightTexture:SetTexture("Interface\\Buttons\\UI-Common-MouseHilight") - f.Button.HighlightTexture:SetSize(24, 24) - f.Button.HighlightTexture:SetPoint("RIGHT", f.Button, 0, 0) - f.Button.HighlightTexture:SetBlendMode("ADD") - f.Button:SetHighlightTexture(f.Button.HighlightTexture) - - -- Button Script - f.Button:SetScript("OnEnter", function(self, motion) - local parent = self:GetParent() - local myscript = parent:GetScript("OnEnter") - if (myscript ~= nil) then - myscript(parent) - end - end) - f.Button:SetScript("OnLeave", function(self, motion) - local parent = self:GetParent() - local myscript = parent:GetScript("OnLeave") - if (myscript ~= nil) then - myscript(parent) - end - end) - f.Button:SetScript("OnMouseDown", function(self, button) - if self:IsEnabled() then - local parent = self:GetParent() - ToggleDropDownMenu(nil, nil, parent) - PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON) - end - end) - - -- UIDropDownMenu Script - f:SetScript("OnHide", function(self) - CloseDropDownMenus() - end) - - return f -end --- --- Wrap the drop down lib as if it were Ace lib 4.0 so Classic Titan plugins look the same --- These need to be global to act like the older version --- --- L_UIDropDownMenuDelegate_OnAttributeChanged -- Different in 4.0 -function L_UIDropDownMenu_InitializeHelper(frame) - UIDropDownMenu_InitializeHelper(frame) -end - -function L_Create_UIDropDownMenu(name, parent) - local f = create_DropDownMenu(name, parent) - return f -end - -function L_UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList) - UIDropDownMenu_Initialize(frame, initFunction, displayMode, level, menuList) -end - -function L_UIDropDownMenu_SetInitializeFunction(frame, initFunction) - UIDropDownMenu_SetInitializeFunction(frame, initFunction) -end - -function L_UIDropDownMenu_SetDisplayMode(frame, displayMode) - UIDropDownMenu_SetDisplayMode(frame, displayMode) -end - -function L_UIDropDownMenu_RefreshDropDownSize(self) - UIDropDownMenu_RefreshDropDownSize(self) -end - ---function L_UIDropDownMenu_OnUpdate(self, elapsed) -- Different in 4.0 -function L_UIDropDownMenu_StartCounting(frame) - ---@diagnostic disable-next-line: undefined-global - UIDropDownMenu_StartCounting(frame) -- CE file only -end - -function L_UIDropDownMenu_StopCounting(frame) - ---@diagnostic disable-next-line: undefined-global - UIDropDownMenu_StopCounting(frame) -- CE file only -end - ---function L_UIDropDownMenuButtonInvisibleButton_OnEnter(self)) -- Different in 4.0 ---function L_UIDropDownMenuButtonInvisibleButton_OnLeave(self)) -- Different in 4.0 ---function L_UIDropDownMenuButton_OnEnter(self) -- Different in 4.0 ---function L_UIDropDownMenuButton_OnLeave(self) -- Different in 4.0 -function L_UIDropDownMenu_CreateInfo() - return UIDropDownMenu_CreateInfo() -end - -function L_UIDropDownMenu_CreateFrames(level, index) - UIDropDownMenu_CreateFrames(level, index) -end - -function L_UIDropDownMenu_AddSeparator(level) - UIDropDownMenu_AddSeparator(level) -end - -function L_UIDropDownMenu_AddSpace(level) -- new in 4.0 - UIDropDownMenu_AddSpace(level) -end - -function L_UIDropDownMenu_AddButton(info, level) - UIDropDownMenu_AddButton(info, level) -end - -function L_UIDropDownMenu_CheckAddCustomFrame(self, button, info) - UIDropDownMenu_CheckAddCustomFrame(self, button, info) -end - -function L_UIDropDownMenu_RegisterCustomFrame(self, customFrame) - UIDropDownMenu_RegisterCustomFrame(self, customFrame) -end - -function L_UIDropDownMenu_GetMaxButtonWidth(self) - return UIDropDownMenu_GetMaxButtonWidth(self) -end - -function L_UIDropDownMenu_GetButtonWidth(button) - return UIDropDownMenu_GetButtonWidth(button) -end - -function L_UIDropDownMenu_Refresh(frame, useValue, dropdownLevel) - UIDropDownMenu_Refresh(frame, useValue, dropdownLevel) -end - -function L_UIDropDownMenu_RefreshAll(frame, useValue) - UIDropDownMenu_RefreshAll(frame, useValue) -end - -function L_UIDropDownMenu_SetIconImage(icon, texture, info) - UIDropDownMenu_SetIconImage(icon, texture, info) -end - -function L_UIDropDownMenu_SetSelectedName(frame, name, useValue) - UIDropDownMenu_SetSelectedName(frame, name, useValue) -end - -function L_UIDropDownMenu_SetSelectedValue(frame, value, useValue) - UIDropDownMenu_SetSelectedValue(frame, value, useValue) -end - -function L_UIDropDownMenu_SetSelectedID(frame, id, useValue) - UIDropDownMenu_SetSelectedID(frame, id, useValue) -end - -function L_UIDropDownMenu_GetSelectedName(frame) - return UIDropDownMenu_GetSelectedName(frame) -end - -function L_UIDropDownMenu_GetSelectedID(frame) - return UIDropDownMenu_GetSelectedID(frame) -end - -function L_UIDropDownMenu_GetSelectedValue(frame) - return UIDropDownMenu_GetSelectedValue(frame) -end - ---function L_UIDropDownMenuButton_OnClick(self) -- Different in 4.0 -function L_HideDropDownMenu(level) - HideDropDownMenu(level) -end - -function L_ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, - autoHideDelay) - ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset, menuList, button, autoHideDelay) -end - -function L_CloseDropDownMenus(level) - CloseDropDownMenus(level) -end - ---function L_UIDropDownMenu_OnHide(self) -- Different in 4.0 --- 4.0 has 'contains mouse' routines for retail only -function L_UIDropDownMenu_SetWidth(frame, width, padding) - UIDropDownMenu_SetWidth(frame, width, padding) -end - -function L_UIDropDownMenu_SetButtonWidth(frame, width) - UIDropDownMenu_SetButtonWidth(frame, width) -end - -function L_UIDropDownMenu_SetText(frame, text) - UIDropDownMenu_SetText(frame, text) -end - -function L_UIDropDownMenu_GetText(frame) - return UIDropDownMenu_GetText(frame) -end - -function L_UIDropDownMenu_ClearAll(frame) - UIDropDownMenu_ClearAll(frame) -end - -function L_UIDropDownMenu_JustifyText(frame, justification) - UIDropDownMenu_JustifyText(frame, justification) -end - -function L_UIDropDownMenu_SetAnchor(dropdown, xOffset, yOffset, point, relativeTo, relativePoint) - UIDropDownMenu_SetAnchor(dropdown, xOffset, yOffset, point, relativeTo, relativePoint) -end - -function L_UIDropDownMenu_GetCurrentDropDown() - return UIDropDownMenu_GetCurrentDropDown() -end - -function L_UIDropDownMenuButton_GetChecked(self) - return UIDropDownMenuButton_GetChecked(self) -end - -function L_UIDropDownMenuButton_GetName(self) - return UIDropDownMenuButton_GetName(self) -end - -function L_UIDropDownMenuButton_OpenColorPicker(self, button) - UIDropDownMenuButton_OpenColorPicker(self, button) -end - -function L_UIDropDownMenu_DisableButton(level, id) - UIDropDownMenu_DisableButton(level, id) -end - -function L_UIDropDownMenu_EnableButton(level, id) - UIDropDownMenu_EnableButton(level, id) -end - -function L_UIDropDownMenu_SetButtonText(level, id, text, colorCode) - UIDropDownMenu_SetButtonText(level, id, text, colorCode) -end - -function L_UIDropDownMenu_SetButtonNotClickable(level, id) - UIDropDownMenu_SetButtonNotClickable(level, id) -end - -function L_UIDropDownMenu_SetButtonClickable(level, id) - UIDropDownMenu_SetButtonClickable(level, id) -end - -function L_UIDropDownMenu_DisableDropDown(dropDown) - UIDropDownMenu_DisableDropDown(dropDown) -end - -function L_UIDropDownMenu_EnableDropDown(dropDown) - UIDropDownMenu_EnableDropDown(dropDown) -end - -function L_UIDropDownMenu_IsEnabled(dropDown) - return UIDropDownMenu_IsEnabled(dropDown) -end - -function L_UIDropDownMenu_GetValue(id) - return UIDropDownMenu_GetValue(id) -end - --[[ function L_OpenColorPicker(info) OpenColorPicker(info) @@ -674,21 +286,24 @@ end ---@param id string ---@return string? ShortName ---@return string? LocaleName +---@return string? FrameName function TitanUtils_GetWhichBar(id) local i = TitanPanel_GetButtonNumber(id); if TitanPanelSettings.Location[i] == nil then - return nil, nil + return nil, nil, nil else local internal = TitanPanelSettings.Location[i] local locale = "" + local frame_str = "" for _, v in pairs(TitanBarData) do if v.name == internal then locale = v.locale_name + frame_str = v.frame_name else -- not the Bar wanted end end - return internal, locale + return internal, locale, frame_str end end @@ -1369,315 +984,9 @@ function TitanUtils_CashToString(value, thousands_separator, decimal_separator, .. silver_str .. copper_str .. neg2 - --[[ -print("_CashToString:" -..(gold or "?").."g " -..(silver or "?").."s " -..(copper or "?").."c " -..(outstr or "?") -); ---]] return outstr, gold, silver, copper end ---====== Right click menu routines - Retail dropdown menu - ----local Add menu button at the given level. ----@param info table Filled in button to add ----@param level number menu level -local function Add_button(info, level) - UIDropDownMenu_AddButton(info, level) -end - ----API Menu - Get the base frame name of the user selected menu (without level). ----@return string frame_name -function TitanPanelRightClickMenu_GetDropdownFrameBase() - local res = "" - - res = "DropDownList" -- Boo!! Per hard-coded Blizz UIDropDownMenu.lua - - return res -end - ----API Menu - Get the frame name of the user selected menu. ----@return string frame_name -function TitanPanelRightClickMenu_GetDropdownFrame() - local res = "" - - res = "DropDownList" .. tostring(UIDROPDOWNMENU_MENU_LEVEL) - - return res -end - ----API Menu - Get the current level of the user selected menu. ----@return number level -function TitanPanelRightClickMenu_GetDropdownLevel() - -- local res = _G[drop_down_1] - local res = 1 -- proper typing - - res = UIDROPDOWNMENU_MENU_LEVEL - - return res -end - ----API Menu - Get the current value of the user selected menu. ----@return any Value <button>.value usually a string; could be table to hold needed info -function TitanPanelRightClickMenu_GetDropdMenuValue() - local res = nil - res = UIDROPDOWNMENU_MENU_VALUE - return res -end - ----API Menu - add given info (button) at the given menu level. ----@param info table Filled in button to add ----@param level? number menu level or 1 -function TitanPanelRightClickMenu_AddButton(info, level) - level = level or 1 - if (info) then - Add_button(info, level) - end -end - ----API Menu - add a toggle Right Side (localized) command at the given level in the form of a button. Titan will properly control the "DisplayOnRightSide" ----@param id string Plugin id ----@param level? number menu level or 1 -function TitanPanelRightClickMenu_AddToggleRightSide(id, level) - level = level or 1 - local plugin = TitanUtils_GetPlugin(id) - if plugin and plugin.controlVariables and plugin.controlVariables.DisplayOnRightSide then - -- copy of TitanPanelRightClickMenu_AddToggleVar adding a remove button - local info = {}; - info.text = L["TITAN_CLOCK_MENU_DISPLAY_ON_RIGHT_SIDE"]; - info.value = { id, "DisplayOnRightSide" }; - info.func = function() - local bar = TitanUtils_GetWhichBar(id) - TitanPanelRightClickMenu_ToggleVar({ id, "DisplayOnRightSide" }) - TitanPanel_RemoveButton(id); - TitanUtils_AddButtonOnBar(bar, id) - end - info.checked = TitanGetVar(id, "DisplayOnRightSide"); - info.keepShownOnClick = 1; - Add_button(info, level); - end -end - ----API Menu - add a localized title at the given level in the form of a button. ----@param title string localized title ----@param level? number menu level or 1 -function TitanPanelRightClickMenu_AddTitle(title, level) - level = level or 1 - if (title) then - local info = {}; - info.text = title; - info.notCheckable = true; - info.notClickable = true; - info.isTitle = 1; - Add_button(info, level); - end -end - ----API Menu - add a toggle variable command at the given level in the form of a button. ----@param text string Localized text to show ----@param value string Internal button name ----@param functionName function | string Function to call on click ----@param level? number menu level -function TitanPanelRightClickMenu_AddCommand(text, value, functionName, level) - level = level or 1 - local info = {}; - info.notCheckable = true; - info.text = text; - info.value = value; - info.func = function() - if functionName then - local callback = functionName - - if type(callback) == 'string' then - -- Function MUST be in global namespace - callback = _G[callback] - elseif type(callback) == 'function' then - -- Can be global or local to the plugin - else - -- silently leave... - end - -- Redundant but the given string may not be a function - if type(callback) == "function" then - -- No return expected... - callback(value) - else - -- Must be a function - spank developer - end - else - -- Leave, creates an inactive button - end - end - Add_button(info, level); -end - ----API Menu - add a line at the given level in the form of an inactive button. ----@param level? number menu level or 1 -function TitanPanelRightClickMenu_AddSeparator(level) - level = level or 1 - - UIDropDownMenu_AddSeparator(level) -end - ----API Menu - add a blank line at the given level in the form of an inactive button. ----@param level? number menu level or 1 -function TitanPanelRightClickMenu_AddSpacer(level) - level = level or 1 - - UIDropDownMenu_AddSpace(level) -end - ----API This will remove the plugin from whichever Titan bar it is on. ----@param id string Plugin id -function TitanPanelRightClickMenu_Hide(id) - TitanPanel_RemoveButton(id); -end - ----API Menu - add a toggle variable command at the given level in the form of a button. ----@param text string Localized text to show ----@param id string Plugin id ----@param var string the saved variable of the plugin to toggle ----@param toggleTable nil ! NOT USED ! ----@param level number menu level -function TitanPanelRightClickMenu_AddToggleVar(text, id, var, toggleTable, level) - local info = {}; - info.text = text; - info.value = { id, var, toggleTable }; - info.func = function() - TitanPanelRightClickMenu_ToggleVar({ id, var, toggleTable }) - end - info.checked = TitanGetVar(id, var); - info.keepShownOnClick = 1; - Add_button(info, level); -end - ----API Menu - add a toggle Label (localized) command at the given level in the form of a button. Titan will properly control "ShowIcon" ----@param id string Plugin id ----@param level? number menu level or 1 -function TitanPanelRightClickMenu_AddToggleIcon(id, level) - level = level or 1 - local plugin = TitanUtils_GetPlugin(id) - if plugin and plugin.controlVariables and plugin.controlVariables.ShowIcon then - TitanPanelRightClickMenu_AddToggleVar(L["TITAN_PANEL_MENU_SHOW_ICON"], id, "ShowIcon", nil, level); - end -end - ----API Menu - add a toggle Label (localized) command at the given level in the form of a button. Titan will properly control "ShowLabelText" ----@param id string Plugin id ----@param level? number menu level or 1 -function TitanPanelRightClickMenu_AddToggleLabelText(id, level) - level = level or 1 - local plugin = TitanUtils_GetPlugin(id) - if plugin and plugin.controlVariables and plugin.controlVariables.ShowLabelText then - TitanPanelRightClickMenu_AddToggleVar(L["TITAN_PANEL_MENU_SHOW_LABEL_TEXT"], id, "ShowLabelText", nil, level); - end -end - ----API Menu - add a toggle Colored Text (localized) command at the given level in the form of a button. Titan will properly control "ShowColoredText" ----@param id string Plugin id ----@param level? number menu level or 1 -function TitanPanelRightClickMenu_AddToggleColoredText(id, level) - level = level or 1 - local plugin = TitanUtils_GetPlugin(id) - if plugin and plugin.controlVariables and plugin.controlVariables.ShowColoredText then - TitanPanelRightClickMenu_AddToggleVar(L["TITAN_PANEL_MENU_SHOW_COLORED_TEXT"], id, "ShowColoredText", nil, level); - end -end - ----API Menu - add a Hide (localized) command at the given level in the form of a button. When clicked this will remove the plugin from the Titan bar. ----@param id string Plugin id ----@param level? number menu level or 1 -function TitanPanelRightClickMenu_AddHide(id, level) - level = level or 1 - local info = {}; - info.notCheckable = true; - info.text = L["TITAN_PANEL_MENU_HIDE"]; - info.value = nil -- value; huh - what should this be? - info.func = function() - TitanPanelRightClickMenu_Hide(id) - end - Add_button(info, level); -end - ----API This will toggle the Titan variable and the update the button. ----@param value table Plugin id and var to toggle ---- Example: {TITAN_XP_ID, "ShowSimpleToLevel"} -function TitanPanelRightClickMenu_ToggleVar(value) - -- Update 2024 Mar - Removed the 'reverse' check. - -- Not sure it was ever used or even worked. - -- local id, var, toggleTable = "", nil, {} - local id, var = "", "" - - -- table expected else do nothing - if type(value) ~= "table" then return end - - if value and value[1] then id = value[1] end - if value and value[2] then var = value[2] end - -- if value and value[3] then toggleTable = value[3] end - - -- Toggle var - TitanToggleVar(id, var); - TitanPanelButton_UpdateButton(id); - --[=[]] - if ( TitanPanelRightClickMenu_AllVarNil(id, toggleTable) ) then - -- Undo if all vars in toggle table nil - TitanToggleVar(id, var); - else - -- Otherwise continue and update the button - TitanPanelButton_UpdateButton(id, 1); - end ---]=] -end - ----API Set backdrop of the plugin. Used for custom created controls (Clock / Volume) to give a consistent look. ----@param frame table Plugin control frame -function TitanPanelRightClickMenu_SetCustomBackdrop(frame) - --[[ -Blizzard decided to remove direct Backdrop API in 9.0 (Shadowlands) -so inherit the template (XML) and set the values in the code (Lua) - -9.5 The tooltip template was removed from the GameTooltip. ---]] - - frame:SetBackdrop({ - bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", - edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", - tile = true, - tileEdge = true, - insets = { left = 1, right = 1, top = 1, bottom = 1 }, - tileSize = 8, - edgeSize = 8, - }) - - frame:SetBackdropBorderColor( - TOOLTIP_DEFAULT_COLOR.r, - TOOLTIP_DEFAULT_COLOR.g, - TOOLTIP_DEFAULT_COLOR.b); - frame:SetBackdropColor( - TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, - TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, - TOOLTIP_DEFAULT_BACKGROUND_COLOR.b - , 1); -end - ----API Menu - add the set of options per the plugin registry control variables. ----@param id string Plugin id ----@param level? number If not present, default to 1 (top) -function TitanPanelRightClickMenu_AddControlVars(id, level) - level = level or 1 -- assume top menu - TitanPanelRightClickMenu_AddSeparator(level) - - TitanPanelRightClickMenu_AddToggleIcon(id, level) - TitanPanelRightClickMenu_AddToggleLabelText(id, level) - TitanPanelRightClickMenu_AddToggleColoredText(id, level) - TitanPanelRightClickMenu_AddToggleRightSide(id, level) - - TitanPanelRightClickMenu_AddSpacer(); - TitanPanelRightClickMenu_AddCommand(L["TITAN_PANEL_MENU_HIDE"], id, TITAN_PANEL_MENU_FUNC_HIDE); -end - -------------------------------------------------------------- -- -- Plugin manipulation routines @@ -2122,13 +1431,13 @@ NOTE: if TitanPlugins[id].menuText == nil then TitanPlugins[id].menuText = TitanPlugins[id].id; end - TitanPlugins[id].menuText = NoColor(TitanPlugins[id].menuText) + TitanPlugins[id].menuText_NC = NoColor(TitanPlugins[id].menuText) table.insert(TitanPluginsIndex, self.registry.id); table.sort(TitanPluginsIndex, function(a, b) - return string.lower(TitanPlugins[a].menuText) - < string.lower(TitanPlugins[b].menuText); + return string.lower(TitanPlugins[a].menuText_NC) + < string.lower(TitanPlugins[b].menuText_NC); end ); end @@ -2298,201 +1607,13 @@ function TitanUtils_IsPluginRegistered(id) end end ---====== Right click menu routines for Titan Panel bars and plugins - ----Titan Close the right click menu of any plugin, if it was open. Only one can be open at a time. -function TitanUtils_CloseRightClickMenu() - if (_G["DropDownList1"]:IsVisible()) then - _G["DropDownList1"]:Hide(); - end -end - ----local Prepare the plugin right click menu using the function given by the plugin OR Titan bar. ----@param self table Titan Bar or Plugin frame ----@param menu table Frame to use as the menu ---- Determining the menu function ---- Old "TitanPanelRightClickMenu_Prepare"..plugin_id.."Menu" ---- New : .menuTextFunction in registry ---- UIDropDownMenu_Initialize will place (part of) the error in the menu - it is not progagated out. ---- Set Titan_Debug.titan.menu to output the error to Chat. -local function TitanRightClickMenu_OnLoad(self, menu) - --[[ -- The function to create the menu is either -1. Set in registry in .menuTextFunction -: New in 2024 Feb to allow the menu routine name to be explicit rather than assumed -: If .menuTextFunction ia a function then the routine can be local or in the global namespace -: If .menuTextFunction ia a string then the routine MUST be in the global namespace. -2. Assumed to be "TitanPanelRightClickMenu_Prepare"..plugin_id.."Menu" -: This is the way Titan was written in the beginning so we leave it to not break Classic Era and older plugins. -: If menu is for a Titan bar then use TitanPanelRightClickMenu_PrepareBarMenu for ALL Titan bars. ---]] - local id = "" - local err = "" - - if self.registry then - id = self.registry.id -- is a plugin - else - id = "Bar" -- is a Titan bar - end - - if id == "" then - err = "Could not display tooltip. " - .. "Unknown Titan ID for " - .. "'" .. (self:GetName() or "?") .. "'. " - else - -- local frame = TitanUtils_GetPlugin(id) -- get plugin frame - local frame = self.registry - local prepareFunction -- function to call - - if frame and frame.menuTextFunction then - prepareFunction = frame.menuTextFunction -- Newer method 2024 Feb - else - -- Older method used when Titan was created - prepareFunction = "TitanPanelRightClickMenu_Prepare" .. id .. "Menu" - -- - end - - if type(prepareFunction) == 'string' then - -- Function MUST be in global namespace - -- Becomes nil if not found - prepareFunction = _G[prepareFunction] - elseif type(prepareFunction) == 'function' then - -- Can be global or local to the plugin - else - -- Invalid type, do not even try... - prepareFunction = nil - end - - if prepareFunction then - UIDropDownMenu_Initialize(menu, prepareFunction, "MENU") - else - err = "Could not display tooltip. " - .. "No function for '" .. tostring(id) .. "' " - .. "[" .. tostring(type(prepareFunction)) .. "] " - .. "[" .. tostring(prepareFunction) .. "] " - .. ". " - end - end - - if err == "" then - -- all is good - else - Titan_Debug.Out('titan', 'menu', "Error: " .. err) - end - -- Under the cover the menu is built as DropDownList1 - -- return DropDownList1, DropDownList1:GetHeight(), DropDownList1:GetWidth() - return menu, menu:GetHeight(), menu:GetWidth() -end - ----Titan Call the routine to build the plugin or bar menu then place it properly. ----@param self table Plugin frame -function TitanPanelRightClickMenu_Toggle(self) - -- Mar 2023 : Rewritten to place menu relative to the passed in frame (button) - -- There are two places for the menu creation routine - -- 1) Titan bar - creates same menu - -- 2) Plugin creation via the .registry - local frame = self:GetName() - local menu = _G[self:GetName() .. TITAN_PANEL_CLICK_MENU_SUFFIX] - --[[ -print("_ toggle R menu" -.." "..tostring(frame).."" -) ---]] - -- Create menu based on the frame's routine for right click menu - local drop_menu, menu_height, menu_width = TitanRightClickMenu_OnLoad(self, menu) - - -- Adjust the Y offset as needed - local ftop = _G[frame]:GetTop() - local rel_y = ftop - menu_height - if rel_y > 0 then - menu.point = "TOP"; - menu.relativePoint = "BOTTOM"; - else - -- too close to bottom of screen - menu.point = "BOTTOM"; - menu.relativePoint = "TOP"; - end - - -- Adjust the X offset as needed - local x_offset = 0 - local left = 0 - local flft = _G[frame]:GetLeft() - local effscale = UIParent:GetEffectiveScale() - if TitanBarData[frame] then - -- on a Titan bar so use cursor for the 'left' - left = GetCursorPosition() -- get x; ignore y - left = left / effscale - -- correct for beginning of Titan bar - left = left - flft - else - -- a plugin - left = flft - end - local rel_x = left + menu_width - if (rel_x < GetScreenWidth()) then - -- menu will fit - menu.point = menu.point .. "LEFT"; - menu.relativePoint = menu.relativePoint .. "LEFT"; - - if TitanBarData[frame] then - x_offset = left - else - -- a plugin - x_offset = 0 - end - else - -- Menu would go off right side of the screen - menu.point = menu.point .. "RIGHT"; - menu.relativePoint = menu.relativePoint .. "RIGHT"; - - if TitanBarData[frame] then - -- correct is on Titan bar (bottom, far right) - -- flip calc since we flipped the anchor to right - x_offset = GetScreenWidth() - left - else - -- a plugin - x_offset = 0 - end - end - --[[ -print("RCM" -.." "..tostring(frame).."" -.." "..tostring(format("%0.1f", menu_height)).."" -.." "..tostring(format("%0.1f", menu_width)).."" -.." "..tostring(format("%0.1f", _G[frame]:GetLeft())).."" -.." "..tostring(menu.point).."" -.." "..tostring(menu.relativePoint).."" -.." "..tostring(format("%0.1f", left)).."" -) ---]] - ToggleDropDownMenu(1, nil, menu, frame, x_offset, 0, nil, self); -end - ----Titan Determine if a right click menu is shown. There can only be one. ----@return boolean IsVisible -function TitanPanelRightClickMenu_IsVisible() - local res = false - if _G[drop_down_1] and _G[drop_down_1]:IsVisible() then - res = true - else - res = false - end - return res -end - ----Titan Close the right click menu if shown. There can only be one. -function TitanPanelRightClickMenu_Close() - if _G[drop_down_1] and _G[drop_down_1]:IsVisible() then - _G[drop_down_1]:Hide() - end -end - --====== Titan utility routines ---Titan Parse the Titan player / profile name and return the parts. ---@param name string Titan player / profile name ---@return string player_name or "" ---@return string server_name or "" +---@return boolean is_custom function TitanUtils_ParseName(name) local server = "" local player = "" @@ -2504,7 +1625,7 @@ function TitanUtils_ParseName(name) end else end - return player, server + return player, server, (server == TITAN_CUSTOM_PROFILE_POSTFIX) end ---Titan Given the player name and server and return the Titan player name; also used as profile name. @@ -2540,6 +1661,27 @@ function TitanUtils_GetPlayer() return toon, playerName, serverName end +---Titan Get the Info table off player Titan settings, if it exists +---@param toon string A player name to look up +---@return boolean +---@return table? +function TitanUtils_GetPlayerInfo(toon) + local _, server, is_custom = TitanUtils_ParseName(toon) + local p_info = nil + if is_custom then + -- there is no Info table... cannnot log into a custom profile + elseif TitanSettings.Players[toon] + and TitanSettings.Players[toon].Info + then + p_info = TitanSettings.Players[toon].Info + else + -- May not have logged into this toon in ages :) + -- tell caller no Info exists + end + + return is_custom, p_info +end + ---Titan Return the screen size after scaling ---@return table screenXY { x | y | scaled_x | scaled_y } all numbers function TitanUtils_ScreenSize() @@ -2677,23 +1819,6 @@ function TitanUtils_DecompressData(data, dataType) return false, {} end ---[==[ - -local profile = TitanSettings.Players["Nycti@Staghelm"] --TitanSettings - -local out = CompressData(profile, "print") -print("====") -print(string.len(out)) -print(tostring(out)) -print("------") - -local in_p = DecompressData(out, "print") - -print(tostring(in_p)) -TitanDumpTable(in_p) -print("====") ---]==] - -------------------------------------------------------------- -- Various debug routines --[[ diff --git a/Titan/TitanVariables.lua b/Titan/TitanVariables.lua index 93c677c..77052a3 100644 --- a/Titan/TitanVariables.lua +++ b/Titan/TitanVariables.lua @@ -5,11 +5,10 @@ This file contains the routines to initialize, get, and set the basic data struc --[===[ Var TitanBarData ^^: Titan static bar reference and placement info TitanAll is used for settings used for Titan itself such as use global profile, tootip modifier, etc. -TitanSettings, TitanSkins, ServerTimeOffsets, ServerHourFormat are the structures saved to disk (listed in toc). +TitanSettings, TitanSkins, are the structures saved to disk (listed in toc). TitanSettings : is the table that holds the Titan variables by character and the plugins used by that character. TitanSkins : holds the list of Titan and custom skins available to the user. It is assumed that the skins are in the proper folder on the hard drive. Blizzard does not allow addons to access the disk. -ServerTimeOffsets and ServerHourFormat: are the tables that hold the user selected hour offset and display format per realm (server). TitanSettings has major sections with associated shortcuts in the code @@ -345,6 +344,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Bar2"] = { off_x = 0, @@ -359,6 +359,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "AuxBar2"] = { off_x = 0, @@ -373,6 +374,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "AuxBar"] = { off_x = 0, @@ -387,6 +389,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short01"] = { off_x = x_mid, @@ -401,6 +404,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short02"] = { off_x = x_mid, @@ -415,6 +419,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short03"] = { off_x = x_mid, @@ -429,6 +434,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short04"] = { off_x = x_mid, @@ -443,6 +449,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short05"] = { off_x = x_mid, @@ -457,6 +464,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short06"] = { off_x = x_mid, @@ -471,6 +479,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short07"] = { off_x = x_mid, @@ -485,6 +494,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short08"] = { off_x = x_mid, @@ -499,6 +509,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short09"] = { off_x = x_mid, @@ -513,6 +524,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, [TITAN_PANEL_DISPLAY_PREFIX .. "Short10"] = { off_x = x_mid, @@ -527,6 +539,7 @@ TitanBarVarsDefaults = { align = TITAN_PANEL_BUTTONS_ALIGN_LEFT, -- TITAN_PANEL_BUTTONS_ALIGN_CENTER hide_in_combat = false, hide_in_pvp = false, + plugin_off_y = 0, }, } @@ -595,6 +608,7 @@ TITAN_PANEL_SAVED_VARIABLES = { IconSpacing = 0, TooltipTrans = 1, TooltipFont = 1, + TooltipTimeout = .5, DisableTooltipFont = 1, FontName = TPC.FONT_NAME, FrameStrata = "LOW", @@ -744,7 +758,7 @@ local function TitanVariables_SyncRegisterSavedVariables(registeredVariables, sa -- Init registeredVariables for index, value in pairs(registeredVariables) do --[[ -print("_sync" +print(".._sync" .." "..tostring(index).."" .." : "..tostring(value).."" ) @@ -935,6 +949,13 @@ local function AdjBarVars(to_profile) if v.color_border == nil then -- NEW Jan 2026 BV[idx].color_border = true end + if v.plugin_off_y == nil then -- NEW Jan 2026 + BV[idx].plugin_off_y = 0 + end +--print("Vars Y" +-- .. " " .. tostring(idx) .. "" +-- .. " " .. tostring(BV[idx].plugin_off_y) .. "" +--) end end @@ -1479,7 +1500,6 @@ local function Init_player_settings(from_profile, to_profile, action) TitanPlayerSettings = TitanSettings.Players[to_profile]; TitanPluginSettings = TitanPlayerSettings["Plugins"]; TitanPanelSettings = TitanPlayerSettings["Panel"]; - -- TitanVariables_SyncRegisterSavedVariables(TitanBarVarsDefaults, TitanPlayerSettings["BarVars"]) -- ====== New May 2023 : Back to adjusting a couple frames per user settings TitanAdjustSettings = TitanPlayerSettings["Adjust"] diff --git a/Titan/_ATitanDoc.lua b/Titan/_ATitanDoc.lua index bdf174a..d684ca4 100644 --- a/Titan/_ATitanDoc.lua +++ b/Titan/_ATitanDoc.lua @@ -271,7 +271,7 @@ if ShowUsedSlots then === Where are these saved variables????? The saved variables are specified in the Titan toc : -## SavedVariables: TitanAll, TitanSettings, TitanSkins, ServerTimeOffsets, ServerHourFormat +## SavedVariables: TitanAll, TitanSettings, TitanSkins TitanSettings contains all the plugin saved variables. Titan uses the single table structure to store the saved variables across a user account. diff --git a/Titan/_TitanIDE.lua b/Titan/_TitanIDE.lua index 59b2f30..e8c6003 100644 --- a/Titan/_TitanIDE.lua +++ b/Titan/_TitanIDE.lua @@ -184,6 +184,35 @@ C_Bank = {} -- 11.0.0 New Warbank - Hopefully WoW API extension will catch up so ---@field short_name string Placeholder for short bar name ---@field RegisterForClicks function Variable params missed by VS Code plugin +--====== New Jan 2026 Implement wrappers for new Menu scheme +---@class Titan_Menu Wrappers for menu scheme +---@field AddDivider function Add an actual line into menu +---@field AddSpacer function Add a blank line into menu +---@field SetAtribEnabled function Set whether this widget is enabled (old info.isEnabled) +---@field AddButton function Add a button, used for submemu titles +---@field AddSelector function TitanAdd simple radio button +---@field AddSelectorExclusiveList function Add a list of radio that use different saved vars options +---@field AddSelectorList function Add a list of radio that use same saved vars options +---@field AddCommand function Add menu button that is a command (old info.func) +---@field AddSelectorCommand function Add radio with extra steps (code in a function) +---@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 +---@class CharInfo +---@field name 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 + --====== Profile output from Utils ---@class Get_Profile_Result ---@field ptype string Type of profile being used diff --git a/TitanBag/Artwork/TitanBag.tga b/TitanBag/Artwork/TitanBag.tga new file mode 100755 index 0000000..6a7ddda Binary files /dev/null and b/TitanBag/Artwork/TitanBag.tga differ diff --git a/TitanBag/TitanBag.lua b/TitanBag/TitanBag.lua index bcca2ac..a63e746 100644 --- a/TitanBag/TitanBag.lua +++ b/TitanBag/TitanBag.lua @@ -5,9 +5,16 @@ -- * By: The Titan Panel Development Team -- ************************************************************************** +local addonName, addon = ... + -- ******************************** Constants ******************************* local _G = getfenv(0); + +-- NOTE: The plugin id needs be unique across Titan plugins. +-- It does not need to match the addon id. +local artwork_path = "Interface\\AddOns\\" .. addonName .. "\\Artwork\\" local TITAN_BAG_ID = "Bag"; +-- NOTE: The convention is TitanPanel<id>Button to name Titan plugin frames local TITAN_BUTTON = "TitanPanel" .. TITAN_BAG_ID .. "Button" local TITAN_BAG_THRESHOLD_TABLE = { @@ -15,11 +22,8 @@ local TITAN_BAG_THRESHOLD_TABLE = { Colors = { HIGHLIGHT_FONT_COLOR, NORMAL_FONT_COLOR, ORANGE_FONT_COLOR, RED_FONT_COLOR }, } local L = LibStub("AceLocale-3.0"):GetLocale(TITAN_ID, true) ---local updateTable = {TITAN_BAG_ID, TITAN_PANEL_UPDATE_BUTTON}; -- ******************************** Variables ******************************* ---local AceTimer = LibStub("AceTimer-3.0") - local trace = false local MIN_BAGS = 0 @@ -226,6 +230,11 @@ local function OnClick(self, button) end end +--[[ Where the magic happens for plugin text! +It is good practice - and good memory - to document the 'why' the code does what it does. +And give details that are not obvious to the reader who did not write the code. +--]] + ---Generate the plugin button text ---@param id string ---@return string @@ -258,6 +267,7 @@ local function GetButtonText(id) ) end return L["TITAN_BAG_BUTTON_LABEL"], bagRichText + -- Notice the two return params - label and plugin text end ---Determine the color based on percentage @@ -321,12 +331,13 @@ local function GetTooltipText() if bag_data[bag].style == "profession" then bagRichText = TitanUtils_GetGrayText(bagText) else - bagRichText = ThresholdColor(bagText, show_color, bag_data[bag].used_slots, bag_data[bag].max_slots) + bagRichText = ThresholdColor(bagText, show_color, bag_data[bag].used_slots, + bag_data[bag].max_slots) end else bagRichText = "" end - -- Format bag name as 'normal' 2024 Aug + -- Format bag name as 'normal' 2024 Aug local name_text = TitanUtils_GetNormalText(bag_data[bag].name) returnstring = returnstring .. name_text .. "\t" .. bagRichText .. "\n"; else @@ -359,7 +370,10 @@ local function GetTooltipText() return returnstring end ----Generate and display rightclick menu options for user. +--[=====[ OLD menu scheme + Using registry.menuTextFunction +--]=====] +--Generate and display rightclick menu options for user. local function PrepareBagMenu() local info -- level 1 @@ -370,7 +384,7 @@ local function PrepareBagMenu() info.func = function() TitanSetVar(TITAN_BAG_ID, "ShowUsedSlots", 1); TitanPanelButton_UpdateButton(TITAN_BAG_ID); - end + end info.checked = TitanGetVar(TITAN_BAG_ID, "ShowUsedSlots"); TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); @@ -379,7 +393,7 @@ local function PrepareBagMenu() info.func = function() TitanSetVar(TITAN_BAG_ID, "ShowUsedSlots", nil); TitanPanelButton_UpdateButton(TITAN_BAG_ID); - end + end info.checked = TitanUtils_Toggle(TitanGetVar(TITAN_BAG_ID, "ShowUsedSlots")); TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); @@ -403,24 +417,112 @@ local function PrepareBagMenu() TitanPanelRightClickMenu_AddControlVars(TITAN_BAG_ID) end +--[=====[ NEW menu scheme Jan 2026 + +Blizzard introduced a new menu scheme in 11.0.0 (July 2024) coded in Blizzard_Menu. +Set registry.menuContextFunction !!! This is how Titan knows to use the Blizzard_Menu scheme!!! + +See TitanMenu.lua for more info on the wrappers Titan uses to help devs +and the differences in old and new schemes. + +A new Titan registry attribute, .menuContextFunction, was added to the .registry. +It was created to do explicitly state the new plugin menu routine needed to create the menu widgets. +Titan will use, in order : +1) registry.menuContextFunction : NEW Jan 2026 +2) registry.menuTextFunction : Feb 2024 +3) "TitanPanelRightClickMenu_Prepare" .. id .. "Menu" : Old as Titan :) + +On right click, Titan will create the context menu and call the plugin menu routine to fill it as before. +In both schemes, menu widgets are added in the order the code runs. + +The old create menu is left in TitanBag for comparison. As a quick example: +=== OLD + info = {}; + info.text = L["TITAN_BAG_MENU_OPEN_BAGS"] + info.func = function() + TitanToggleVar(TITAN_BAG_ID, "OpenBags") + end + info.checked = TitanGetVar(TITAN_BAG_ID, "OpenBags"); + TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); +== NEW + Titan_Menu.AddSelector(root, TITAN_BAG_ID, L["TITAN_BAG_MENU_OPEN_BAGS"], "OpenBags") +Where the parameters are: +- root - is the context menu to attach to +- id - plugin ID +- label - locale string 'Open Bags' +- opt - option as listed in .savedVariables +A labeled checkbox will be placed inline on the root menu. It will have a different style than the older TitanBag. +Note: 'root' could be at an arbitrary menu level. It is just a menu button. +Note: Titan_Menu.AddSelector passes the 'is selected' and 'set selected' as function. +As a simple toggle, these functions are known. + +--]=====] + +---Generate and display right click menu options for user. +---@param owner table Plugin frame +---@param rootDescription table Menu context root +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_BAG_ID + local root = rootDescription -- menu widget to start with + --[[ + 'GeneratorFunction' is what Blizzard uses in its implementation, this name is abitrary + + The Titan right click handler will initiate creating the context menu by calling MenuUtil.CreateContextMenu. + MenuUtil.CreateContextMenu will secure call this function with + - 'owner' - which is _G[TITAN_BUTTON], the plugin frame + - and + - 'rootDescription' - the menu object internally created to attach menu widgets to + + rootDescription is the new dropdown level 1. + Attaching a new menu object to a button description is the same as setting info.arrow. + + NOTES: + - The API routines used here are in TitanMenu.lua. They wrap the Blizz scheme in case they change it... + - The API routines add Titan patterns and conventions that used to be hand coded via info.* attributes. + Ideally relieving the dev from tedious setup. And giving Titan menus a more consistent look. + - + - Titan will add a menu title at top using .registry.id + - Titan will add the control vars on bottom of menu. + + Bags does not have a nested menu. + Use built-ins such as Gold for examples of nesting and more widget types. +--]] + + -- !! Title added by Titan + + -- These are simple toggles with Titan 'update button' on change + Titan_Menu.AddSelector(root, id, L["TITAN_BAG_MENU_SHOW_DETAILED"], "ShowDetailedInfo") + Titan_Menu.AddSelector(root, id, L["TITAN_BAG_MENU_OPEN_BAGS"], "OpenBags") + + local disp = { -- selectors using the same option - label, value + {L["TITAN_BAG_MENU_SHOW_USED_SLOTS"], true}, + {L["TITAN_BAG_MENU_SHOW_AVAILABLE_SLOTS"], false}, + } + -- This adds a divider before the selectors + Titan_Menu.AddSelectorList(root, id, nil, "ShowUsedSlots", disp) + + -- !! Control vars added by Titan +end ---plugin Registers the plugin and simple init ---@param self Button local function OnLoad(self) - local notes = "" + local notes = "" -- Added to Titan > Config > Plugin for user to read .. "Adds bag and free slot information to Titan Panel.\n" - .. "- Open bags should work... Retail taint fixed Apr 2024 (10.2.7).\n" - .. "- Professions counts moved to tooltip only : Aug 2024 (Titan 8.1.0).\n" + .. "- Menu moved to new scheme Jan 2026.\n" + + -- The guts of any Titan plugin! See comments at end of file below. self.registry = { id = TITAN_BAG_ID, category = "Built-ins", version = TITAN_VERSION, menuText = L["TITAN_BAG_MENU_TEXT"], - menuTextFunction = PrepareBagMenu, + menuTextFunction = PrepareBagMenu, -- OLD scheme (2nd priority) + menuContextFunction = GeneratorFunction, -- NEW scheme (1st priority) buttonTextFunction = GetButtonText, tooltipTitle = L["TITAN_BAG_TOOLTIP"], tooltipTextFunction = GetTooltipText, - icon = "Interface\\AddOns\\TitanBag\\TitanBag", + icon = artwork_path .. "TitanBag", iconWidth = 16, notes = notes, controlVariables = { @@ -473,18 +575,42 @@ local function Create_Frames() if _G[TITAN_BUTTON] then return -- if already created end + -- Using _G converts the string into a table reference in the global namespace -- general container frame local f = CreateFrame("Frame", nil, UIParent) -- f:Hide() -- Titan plugin button + --[[ + The plugin frame is created here. + All scripts and events are attached to this frame. + + The typical plugin is a 'combo' which includes + - an icon (can be shown or hidden) + - label - value pair where the label can be turned off + There can be multiple label - value pairs; TitanPerformance uses this scheme. + + The frame is 'forever' as are most of WoW game frames. + --]] local window = CreateFrame("Button", TITAN_BUTTON, f, "TitanPanelComboTemplate") window:SetFrameStrata("FULLSCREEN") -- Using SetScript("OnLoad", does not work OnLoad(window); -- TitanPanelButton_OnLoad(window); -- Titan XML template calls this... + --[[ + Below are the frame 'events' that need to be processed. + + The desired Titan design is : + - register events and timers when the user places the plugin on the bar (OnShow) + - unregister events and timers when the user hides the plugin (OnHide). + This reduces resources the plugin uses when the user does not want the plugin. + + Notes: + - If a Titan bar is hidden, the plugins on it will still run. + - Titan plugins are NOT child frames!! Plugins are not hidden (OnHide) when the bar they are on is hidden! + --]] window:SetScript("OnShow", function(self) OnShow(self); TitanPanelButton_OnShow(self); @@ -503,15 +629,466 @@ end Create_Frames() -- do the work ---[[ -TitanDebug("T isP 0:" - .." "..tostring(slot).."" - .." "..tostring(itemId).."" - .." '"..tostring(itemType).."'" - .." '"..tostring(itemSubType).."'" - .." "..tostring(itemEquipLoc).."" - .." '"..tostring(itemTexture).."'" - .." "..tostring(classID).."" - .." "..tostring(subclassID).."" - ) +--[[ Titan Bag with Explanation + +The intent is to clarify what may appear to be a daunting experience. + +We suggest you grab your favorite beverage, read this doc, and relax! +Many of Titan plugin mysteries will be explained; +helping you create a tool your audience will enjoy. 🙂 + +The Titan team and its users are available to answer questions. +The two most used ways are : +- The Titan Discord community - faster +- Curse comments under Titan Panel addon + +Using a text editor with code folding features will make this file easier to read and find information. +Notepad++ is a popular Windows code editor. +Visual Studio Code with a couple extensions is used to develop Titan and its built-ins. + +Before you start changing this example, it is HIGHLY recommended to install the following WoW addons: +- BugGrabber : Grabs errors and stores them +- BugSack : The visual part of BugGrabber +- WowLua or Script Library or another addon that allows you to try Lua code directly inside WoW. + +Small changes are recommended; then test your coding. +When testing, just start or reload WoW. All versions now check and load new files on reload. + +--]] + +--[[ Titan Panel Notes: +- Use the current version of Titan to ensure no errors. +- You may freely use this example for addon development and publish it on WoW addon sites like Curseforge. +- If published, please add the Titan addon tag for users. +- The terms addon and plugin are essentially the same. +Within this document, plugin is used when the addon is displayed by Titan. +- Titan includes several libraries under the Titan/libs folder. You are free to use these. +If you require additional libraries, please include them within your addon. + +=== Out of Scope Notes: +- A discussion on Lua syntax. A basic understanding of Lua is assumed. +- Timers are outside the scope of this example. +See other Titan built-in plugins that use timers (AceTimer) such as TitanClock. +- Localization of strings presented to the user. Titan uses AceLocale; other addons use different schemes. +- Titan includes the Ace libraries it uses - not the entire library. (https://www.wowace.com) +- The API for LDB (LibDataBroker) : (https://github.com/tekkub/libdatabroker-1-1) +- WoW images : Some image type info (https://warcraft.wiki.gg/wiki/API_TextureBase_SetTexture) +--]] + +--[[ “Best Practices” When Creating Your Addon/Plugin +=== Naming Convention +When publishing your addon/plugin please use this naming convention : + +Titan Panel [Name] + +Using this naming format, most Titan users will understand this plugin is intended for Titan Panel. +They should know to contact you first instead of the Titan Panel team. +The Titan team does receive comments and errors from time to time. We usually tell them to contact the plugin developer. + +=== Additional Help For You +A good Lua resource is https://www.lua.org/docs.html +NOTE: WoW uses Lua version 5.1 as its base. +NOTE: WoW does restrict, add, or even remove some Lua features. For example the file routines and many OS routines are not available to an addon. + +There are sites that have deeper explanations about addon development, such as +- Wowhead.com +- Warcraft wiki (Warcraft.Wiki.gg). +Please use these or other sites for more detailed addon and API information. The API does change over time. +--]] + +--[[ Running this right now! +The folder and .toc file prefix MUST be the same to load into WoW! +See the .toc section under Example Folder Structure. + +=== Steps needed to run this as another plugin called TitanPlugin: +- Copy this example to your WoW installation: ../World of Warcraft/_retail_/Interface/AddOns +- Ensure the folder name is TitanPlugin +- Change TitanBag.toc to TitanPlugin.toc +- Open TitanBag.lua change line(s) below: + +local TITAN_PLUGIN = "Bag" +==>> +local TITAN_PLUGIN = "Plugin" + + +- Start or reload WoW + +That is it! +You should see another Titan Bag icon in any version of WoW you are running. +You are now ready to start changing code. + +First Routines to change: +- GetBagData and local routines & variables will be replaced by your code. +- ToggleBags is called from OnClick. This will be replaced by your code that handles mouse clicks. +- CreateMenu will be changed to implement your right click menu, if one is needed. + +Change other routines as needed to implement your idea. +--]] + +--[[ Example Folder Structure +Inside this folder you will notice : +- Artwork folder : with one .tga file - the icon used by the plugin +- libs : empty, ready for any library routines you may need +- a .toc file +- one .lua file – for your great idea +- a ReadMe file - This file +--]] + +--[[ .toc + +The folder and the .toc files MUST have the same name! +Sort of... the name prior to the underscore(_) must be the same as the folder name. +The part after the underscore (postfix) has meaning to the WoW addon loader. +https://warcraft.wiki.gg/wiki/TOC_format : Contains the full list and A LOT more detail about .toc files + +=== .toc internals +NOTE: The ## Interface value should match the current interface value of the corresponding WoW version. +In BattleNet this is typically shown below the 'Play' button. +DragonFlight 10.02.05 is represented without dots - 100207 - in the .toc. + +If the interface value is higher or lower, WoW will complain that you are running 'out of date' addons. + +The value Bag is a list representing retail, Classic, and Classic Era WoW versions. + +== .lua + +This is the code for the plugin. + +Titan specific details will be noted and explained within the Lua file. +The comments will specify where names are important. + +The plugin starts with local constants; then local variables; then functions. + +Our suggestion to learn how plugins work is to start with Create_Frames routine at the bottom of the file. It is where the magic starts. + +NOTES: +- Titan locale strings (using AceLocale) were left in the code so the example will run as is. Please use your own strings - localized or not. +- Feel free to look at Titan code for Lua examples. +- Any Lua routine in the Titan folder marked with ---API can be used by a plugin. +Titan API routines will be maintained and the functionality expected to remain stable. +Any parameter or functionality changes to API will be 'broadcast' on delivery sites and our Discord site. + +=== .tga + +This file is the icon used by the plugin. +This file is also specified in the .registry of the Lua file – detailed later in this doc. +--]] + +--[[ Addon code flow + +First step: ==== Starting or reloading WoW +Wow will load this addon after Titan is loaded. + +NOTE: The .toc states Titan is required [## Dependencies: Titan]. +WoW will load Titan BEFORE this addon. + +Any code outside the Lua functions will be run. +Examples: +- local VERSION = GetAddOnMetadata(add_on, "Version") will run GetAddOnMetadata +- bag_info will be populated +- ... +- Create_Frames is called + +Create_Frames will create the addon frame and name it the string in TITAN_BUTTON. +NOTE: The check at the top prevents recreating frames on reload of WoW (includes any WoW 'splash' screen) +All created frames will be in the global namespace. +All created frames are forever – they are not touched by the Lua garbage collection. + +Then local OnLoad is called when WoW loads the frame into memory. + +OnLoad does two important things +1) Sets the .registry of the addon - See the .registry attributes comment block below +2) Registers for event PLAYER_ENTERING_WORLD + +NOTE: OnLoad should : +- Be small +- NOT assume plugin saved variable data are ready / loaded yet + +Then Create_frames sets the frame scripts for the addon. See Frame Scripts block. + +Next: ==== Waiting for WoW +WoW fires a bunch of events as this and other addons are loaded. + +Eventually the game and all addons are loaded and this plugin receives the PLAYER_ENTERING_WORLD event via the frame script OnEvent. +When processing PLAYER_ENTERING_WORLD, only register for events and access local data this plugin needs. +Do NOT assume saved variables from the registry or any server data are ready. + +Titan also receives the PLAYER_ENTERING_WORLD event. +It is best to assume there is NO guarantee this plugin receives the event before or after Titan! + +Titan then processes its own data, creates Titan bars, registers Titan plugins and LDB addons, and syncs plugin saved variables. +Titan will process any saved variables specified in the .registry of this plugin! + +Next: ==== Still waiting... +Titan shows the user requested bars with the user requested plugins. + +By default Titan third party plugins are not enabled. +The user will enable your plugin via Titan menu or Titan Config. +OnShow is called by Titan only if the user has enabled the plugin. +It is called on enabling and then each start or reload of WoW. + +OnShow now does the processing to set up this plugin and its data properly. +Lastly OnShow needs to call TitanPanelButton_UpdateButton to update the plugin text. +The plugin is now ready for the user. + +NOTES: For OnShow +- It is best to assume any saved variables in .registry are NOT ready until OnShow! +- Register for needed events here to reduce resource usage and avoid surprises. +- Enable any timers or OnUpdate after this point. +- Process any saved variable data such as user options +- Set the initial plugin - icon, label, text + +Next: ==== Ready to use your plugin. Yeah! +The plugin will be 'idle' until one of the following occur: +- Titan needs to (re)display this plugin - via TitanPanelButton_UpdateButton +- User changes a plugin option using the Titan plugin menu : TitanPanelButton_UpdateButton +- User clicks on this plugin - Right click calls routine in registry .menuTextFunction; any other OnClick enabled +- Any registered event is received - OnEvent +- User mouses over plugin - OnEnter calls routine in registry .buttonTextFunction +- User mouse leaves plugin - OnLeave clears tooltip on timeout or click elsewhere +- A timer or callback calls a plugin routine – AceTimer + +Next: ==== +The above steps continue until: +- User hides the plugin - OnHide +- The user logs out the character or exits WoW or reloads UI - Onhide +- Cleanup any plugin specific data or objects + +Notes: For Onhide : +- Any events should be unregistered here to reduce resources. +- Any timers should be stopped. + +On logout or exit the saved variables are saved to the local system - .registry.savedVariables . +No additional actions are required. + +==== TitanPanelButton_UpdateButton(TITAN_PLUGIN) should be called by this plugin whenever the plugin text changes : +- On processing an event registered for +- On user left click – some action taken +- On user right click – plugin menu changes + +TitanPanelButton_UpdateButton will call the routine in registry .menuTextFunction - GetButtonText. +This is the magic that updates your plugin button text! + +You will notice GetButtonText returns two values - a label and the actual text. +Display of the label is handled by the user selecting 'show label' in Titan config or Titan menu. +This is controlled by registry ShowLabelText. + +NOTE: TitanPanelButton_UpdateButton can handle up to 4 label - value pairs. +TitanPerformance is an example that uses and shows multiple label - value pairs, based on user selection. + +==== OnEnter and OnLeave +NOTE: The Titan template handles OnEnter and OnLeave to show or hide the tooltip. +Titan calls the specified routine to show the tooltip – registry.tooltipTextFunction. +Titan expects a formatted string as the return from the function. + +==== Additional saved variables specific to this addon must be handled by this addon and are outside the scope of this example. +You can specify your own table to be saved. Titan Gold is a Titan plugin that has its own saved variables. +--]] + +--[[ Frame Scripts + +The frame scripts are how WoW and Titan interact with this addon. + +NOTE: The creation of the frame also creates scripts handlers. +This is a bit hidden by the 'inherits' "TitanPanelComboTemplate" : + local window = CreateFrame("Button", TITAN_BUTTON, f, "TitanPanelComboTemplate") +TitanTemplate.xml defines TitanPanelButtonTemplate as the base for each of its plugin types - Combo / Text / Icon. +TitanPanelButtonTemplate sets OnLoad / OnShow / OnClick / OnEnter / OnLeave where each calls TitanPanelButton_On*. +If the script is overriden in the plugin, it should call the appropriate TitanPanelButton_On* routine as shown below. +In a few cases, the default is not called because the plugin replaces what Titan would do. +TitanPerformance, for example overrides OnClick to create a custom right click menu. + +==== OnShow script : +This is triggered when this plugin (frame) is shown. +Technically : +- WoW calls the now registered plugin frame - TITAN_BUTTON:OnShow() as set in Create_Frames +- Which calls the local OnShow to init the plugin +- Then calls TitanPanelButton_OnShow to update the plugin button text + +==== OnClick script : +This is triggered when this plugin (frame) has been clicked by the mouse. +Technically : +- WoW calls the now registered plugin frame - TITAN_BUTTON:OnClick() as set in Create_Frames +- Which calls the local OnClick to handle left click (or any click / mod-click other than right click) +- Then calls TitanPanelButton_OnClick to handle right click (plugin menu) – see ‘Right Click’ below + +== Right click: +TitanPanelButton_OnClick is called to handle right click generically because it will +- Close any open control frame +- Close any open tooltip +- Position the menu relative to the plugin on whatever Titan bar it is on +- Call the plugin routine to create the actual menu content +- (menuTextFunction = PrepareBagMenu) + +The plugin can inform Titan of the routine in one of two ways: +1) Specify in .registry.menuTextFunction - preferred +2) Named routine in the global namespace with the expected name of - TitanPanelRightClickMenu_Prepare<id>Menu +- For this plugin the name would be TitanPanelRightClickMenu_PluginMenu +Titan will use the registry over the created routine. It will not use both. + +==== OnEnter script : +OnEnter is handled by the Titan template to show the tooltip next to the plugin wherever it may be. +It calls the routine specified (tooltipTextFunction = GetTooltipText). +This routine is expected to return a formatted string to be shown in the tooltip. + +==== OnLeave script : +OnLeave is handled by the Titan template to hide the tooltip. + +==== OnHide script : +This is triggered when this plugin (frame) has been hidden by the user : +- via the Titan menu +- via Titan config +- On exit or logout or reload +Technically : +- WoW calls the now registered plugin frame - TITAN_BUTTON:OnHide() as set in Create_Frames +- Which calls the local OnHide + +==== OnEvent script : +This is triggered when any event this plugin (frame) has registered for is fired. +Technically : +- WoW calls the now registered plugin frame - TITAN_BUTTON:OnEvent() as set in Create_Frames +- Which calls the local OnEvent to handle all registered events + +BAG_UPDATE just updates the text (count) whenever this event is fired. +--]] + +--[[ .registry attributes +This is the GUTS of a Titan plugin. +The .registry table on the frame contains all the information to register the plugin for display. + +Every plugin registry with an id should appear in Titan > Configuration > Attempts. +Information about the plugin is shown there along with pass / fail information. + +Attributes: +.id : Required : must be unique across Titan plugins. If there are duplicates, the first one 'wins'. +.category : The general grouping this plugin is in. + The complete category list is in TITAN_PANEL_BUTTONS_PLUGIN_CATEGORY (TitanGlobal.lua) + "Built-ins" is reserved for plugins that Titan releases. +.version : plugin version shown in menus and config. +.menuText : Used as the title for the right click menu. +.menuTextFunction : See .registry Routines below. +.menuContextFunction : See .registry Routines below. NEW Jan 2026 +.buttonTextFunction : See .registry Routines below. +.tooltipTitle : Used as the title for the tool tip +.tooltipTextFunction : See .registry Routines below. +.icon : Path to the icon to be used. + It is recommended to store the icon in the plugin folder, even if exists within WoW. +.iconWidth : Best left at 16... +.notes : This is shown in Titan > Config > Plugins when this plugin is selected. +.controlVariables : This list is controls whether the variable is shown. See below. +.savedVariables : These are the variables stored in Titan saved variables. + The initial values are used only if that particular entry is 'new' to Titan + (new Titan install, new character, character new to Titan). + If a value is removed then it is removed from the saved variables as Titan is run for each character. + +== .controlVariables +These are used to show or hide 'controls' in the Titan config or Titan right click menu. +- ShowIcon +- ShowLabelText +- ShowColoredText +- DisplayOnRightSide +- ShowRegularText (LDB only) +If true, the control is shown to the user. +If false, the control is not shown to the user. +--]] + +--[[ .registry Saved Variables + +All saved variables for this plugin are listed within savedVariables + savedVariables = { + ShowUsedSlots = 1, + ShowDetailedInfo = false, + ShowIcon = 1, + ShowLabelText = 1, + ShowColoredText = 1, + DisplayOnRightSide = false, + OpenBags = true, + } + +Plugin variables : +- OpenBags : Whether to open bags on left click or not. +Included due to a taint issue introduced by WoW which has been fixed but left to allow user choice. + +Titan uses the below to control display of the plugin : +- ShowIcon : Whether the icon,if specified is shown +- ShowLabelText : Whether the labels returned by buttonTextFunction are shown +- ShowColoredText : Whether the text is 'colored' or not +- DisplayOnRightSide : Put this plugin in the right side of the Titan bar + +ShowColoredText is plugin specific. Generally used to indicate a range such as your bags are empty (green) to nearly full (red). +If the plugin does not need this then please set controlVariables > ShowColoredText to false to prevent the user from seeing +the option and potentially getting confused. + +NOTE: Titan routines have used 1 as true since inception so be careful on 'true checks'. +"if ShowUsedSlots then " *should* work fine if ShowUsedSlots is true or 1 + +--]] + +--[[ .registry Routines + +Titan looks for specified routines in the .registry : +- .buttonTextFunction : Routine that updates the plugin button text. +- .tooltipTextFunction : Routine that generates the tool tip text. +- .menuContextFunction : NOTE: Creating menu below +- .menuTextFunction : NOTE: Creating menu below + +.buttonTextFunction : This is called whenever the button is to be updated. + This is called from within the plugin and from Titan via TitanPanelButton_UpdateButton(TITAN_PLUGIN) . + Titan will usually return "<?>" if the routine dies. + If you need to see the error, search for this attribute in the Titan folder and uncomment the print of the error message. + This may generate a LOT of messages! +.tooltipTextFunction : This is called when the mouse enters the plugin frame - OnEnter. + The Titan templates set the OnEnter script for the plugin frame. + On a tooltip error, Titan will usually show part of the error in the tool tip. + If you need to see the full error, search for this attribute in the Titan folder and uncomment the print of the error message. + +NOTE: Each .registry routine is called using pcall to protect Titan. +These routines are expected to have NO parameters. Handling parameters was not implemented in any version of Titan. + +NOTE: Creating menu +Routine that creates the options for the menu (right click). Titan will use only one, if found, in order : +1) registry.menuContextFunction : NEW Jan 2026 +2) registry.menuTextFunction : Feb 2024 +3) "TitanPanelRightClickMenu_Prepare" .. id .. "Menu" : Old as Titan :) + +NOTE: Each routine can be specified : +- As a string, it MUST be in the global namespace. Strings were the only method for a long time until Feb 2024. +- As a function, it may be in the global namespace but could be local. +This example uses a local routine which is preferred. + +--]] + +--[[ Special Icons and Artwork + +Anyone can extract the Blizzard UI code and art from WoW. This can be handy to get code examples. +And to grab icons to use for a plugin. My understanding is any icon can be used within WoW without violating the ToS. +WoW icons tend to be .blp files. These files are NOT easy to look at or manipulate!! +You will need to research third party tools to manipulate .blp files. +BLPView (Windows only) from wowinterface is light and easy to view blp files as thumbnail pics in File Explorer. + +==== Extracting art and code +Add the command switch -console when starting WoW. +In BattleNet click the Settings (next to Play) then Game Settintgs. Add as an additional command line argument. + +Start WoW but stay on the character screen. +Hit the ~ (tilde) key to open a text console which will appear from the top of the screen. +Type exportInterfaceFiles (can tab to auto fill) with parameter code or art +exportInterfaceFiles code +exportInterfaceFiles art + +These must be run separately. Code should take a couple seconds, +Art may take some time and appear to hang the game, be patient :). + +The result will be here : +.../World of Warcraft/<version>/BlizzardInterfaceCode +.../World of Warcraft/<version>/BlizzardInterfaceArt +Where <version> is _retail_ for the current game expansion +--]] + +--[[ Files stored + +Addons are here : .../World of Warcraft/<version>/Interface/Addons/ +Saved Vars are here : .../World of Warcraft/<version>/WTF/Account/<your account>/SavedVariables/Titan.lua + +Where <version> is _retail_ for the current game expansion --]] diff --git a/TitanBag/TitanBag.tga b/TitanBag/TitanBag.tga deleted file mode 100644 index 6a7ddda..0000000 Binary files a/TitanBag/TitanBag.tga and /dev/null differ diff --git a/TitanBag/TitanBag.toc b/TitanBag/TitanBag.toc index 9c78b69..590591a 100644 --- a/TitanBag/TitanBag.toc +++ b/TitanBag/TitanBag.toc @@ -1,7 +1,7 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55fBag|r] |cff00aa009.0.2|r -## Version: 9.0.2 -## IconTexture: Interface\AddOns\TitanBag\TitanBag +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fBag|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre +## IconTexture: Interface\AddOns\TitanBag\Artwork\TitanBag ## Notes: Adds bag and free slot information to Titan Panel ## Author: Titan Panel Development Team ## SavedVariables: diff --git a/TitanClassic/TitanClassic.toc b/TitanClassic/TitanClassic.toc index 5d8585d..915fc5a 100644 --- a/TitanClassic/TitanClassic.toc +++ b/TitanClassic/TitanClassic.toc @@ -1,7 +1,7 @@ ## Interface: 20505, 11508, 50503 -## Title: Titan Panel [|cffeda55f_Classic_|r] |cff00aa009.0.2|r +## Title: Titan Panel [|cffeda55f_Classic_|r] |cff00aa009.1.0-pre|r ## Author: Titan Panel Dev Team -## Version: 9.0.2 +## Version: 9.1.0-pre ## IconTexture: Interface\Icons\Achievement_Dungeon_UlduarRaid_Titan_01 ## Notes: Adds display bars to show and control information/launcher plugins. ## Category-enUS: User Interface diff --git a/TitanClock/TitanClock.lua b/TitanClock/TitanClock.lua index 7d6b947..8795be3 100644 --- a/TitanClock/TitanClock.lua +++ b/TitanClock/TitanClock.lua @@ -8,7 +8,7 @@ --]] -- ******************************** Constants ******************************* -TITAN_CLOCK_ID = "Clock"; +local TITAN_CLOCK_ID = "Clock"; local TITAN_BUTTON = "TitanPanel" .. TITAN_CLOCK_ID .. "Button" local TITAN_CLOCK_FORMAT_12H = "12H"; @@ -234,91 +234,54 @@ end local function CreateMenu() TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_CLOCK_ID].menuText); - local info = {}; - info.text = L["TITAN_CLOCK_MENU_LOCAL_TIME"]; - info.func = function() - TitanSetVar(TITAN_CLOCK_ID, "TimeMode", "Local") - TitanPanelButton_UpdateButton(TITAN_CLOCK_ID) - end - info.checked = function() return TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "Local" end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_CLOCK_MENU_SERVER_TIME"]; - info.func = function() - TitanSetVar(TITAN_CLOCK_ID, "TimeMode", "Server") - TitanPanelButton_UpdateButton(TITAN_CLOCK_ID) - end - info.checked = function() return TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "Server" end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_CLOCK_MENU_SERVER_ADJUSTED_TIME"]; - info.func = function() - TitanSetVar(TITAN_CLOCK_ID, "TimeMode", "ServerAdjusted") - TitanPanelButton_UpdateButton(TITAN_CLOCK_ID) - end - info.checked = function() return TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "ServerAdjusted" end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_CLOCK_MENU_SERVER_TIME"] .. " & " .. L["TITAN_CLOCK_MENU_LOCAL_TIME"] - info.func = function() - TitanSetVar(TITAN_CLOCK_ID, "TimeMode", "ServerLocal") - TitanPanelButton_UpdateButton(TITAN_CLOCK_ID) - end - info.checked = function() return TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "ServerLocal" end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_CLOCK_MENU_SERVER_ADJUSTED_TIME"] .. " & " .. L["TITAN_CLOCK_MENU_LOCAL_TIME"] - info.func = function() - TitanSetVar(TITAN_CLOCK_ID, "TimeMode", "ServerAdjustedLocal") - TitanPanelButton_UpdateButton(TITAN_CLOCK_ID) - end - info.checked = function() return TitanGetVar(TITAN_CLOCK_ID, "TimeMode") == "ServerAdjustedLocal" end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; -- 12 or 24 hour format - info.text = L["TITAN_CLOCK_CHECKBUTTON"] - info.func = function() - if (TitanGetVar(TITAN_CLOCK_ID, "Format") == TITAN_CLOCK_FORMAT_12H) then - TitanSetVar(TITAN_CLOCK_ID, "Format", TITAN_CLOCK_FORMAT_24H); - else - TitanSetVar(TITAN_CLOCK_ID, "Format", TITAN_CLOCK_FORMAT_12H); - end - if (ServerHourFormat[realmName]) then - ServerHourFormat[realmName] = TitanGetVar(TITAN_CLOCK_ID, "Format"); - end - - TitanPanelButton_UpdateButton(TITAN_CLOCK_ID) - end - info.checked = function() - if (TitanGetVar(TITAN_CLOCK_ID, "Format") == TITAN_CLOCK_FORMAT_24H) then - return true - else - return false - end - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSpacer(); - - info = {}; - info.text = L["TITAN_CLOCK_MENU_HIDE_MAPTIME"]; - info.func = ToggleMapTime; - info.checked = TitanGetVar(TITAN_CLOCK_ID, "HideMapTime"); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_CLOCK_MENU_HIDE_CALENDAR"]; - info.func = ToggleGameTimeFrameShown; - info.checked = TitanGetVar(TITAN_CLOCK_ID, "HideGameTimeMinimap"); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); +end - TitanPanelRightClickMenu_AddControlVars(TITAN_CLOCK_ID) +---Generate and display right click menu options for user. +---@param owner table Plugin frame +---@param rootDescription table Menu context root +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_CLOCK_ID + local root = rootDescription -- menu widget to start with + + Titan_Menu.AddSelectorCommand(root, id, L["TITAN_CLOCK_MENU_HIDE_MAPTIME"], "HideMapTime", + function () + if TimeManagerClockButton and TimeManagerClockButton:GetName() then + if TitanGetVar(TITAN_CLOCK_ID, "HideMapTime") then + TimeManagerClockButton:Hide() + else + TimeManagerClockButton:Show() + end + else + print("TitanClock: no time widget") + end + end) + + Titan_Menu.AddSelectorCommand(root, id, L["TITAN_CLOCK_MENU_HIDE_CALENDAR"], "HideGameTimeMinimap", + function () + if GameTimeFrame and GameTimeFrame:GetName() then + if TitanGetVar(TITAN_CLOCK_ID, "HideGameTimeMinimap") then + GameTimeFrame:Hide() + else + GameTimeFrame:Show() + end + end + end) + + -- Which time(s) to shhow + local disp = { -- selectors using the same option + {L["TITAN_CLOCK_MENU_LOCAL_TIME"], "Local"}, + {L["TITAN_CLOCK_MENU_SERVER_TIME"], "Server"}, + {L["TITAN_CLOCK_MENU_SERVER_ADJUSTED_TIME"], "ServerAdjusted"}, + {L["TITAN_CLOCK_MENU_SERVER_TIME"] .. " & " .. L["TITAN_CLOCK_MENU_LOCAL_TIME"], "ServerLocal"}, + {L["TITAN_CLOCK_MENU_SERVER_ADJUSTED_TIME"] .. " & " .. L["TITAN_CLOCK_MENU_LOCAL_TIME"], "ServerAdjustedLocal"}, + } + Titan_Menu.AddSelectorList(root, id, nil, "TimeMode", disp) + + local hours = { -- selectors using the same option + {TITAN_CLOCK_FORMAT_12H, TITAN_CLOCK_FORMAT_12H}, + {TITAN_CLOCK_FORMAT_24H, TITAN_CLOCK_FORMAT_24H}, + } + Titan_Menu.AddSelectorList(root, id, nil, "Format", hours) end ---local Build the plugin .registry and register events @@ -332,7 +295,8 @@ local function OnLoad(self) category = "Built-ins", version = TITAN_VERSION, menuText = L["TITAN_CLOCK_MENU_TEXT"], - menuTextFunction = CreateMenu, + --menuTextFunction = CreateMenu, + menuContextFunction = GeneratorFunction, -- NEW scheme buttonTextFunction = GetButtonText, tooltipTitle = L["TITAN_CLOCK_TOOLTIP"], tooltipTextFunction = GetTooltipText, @@ -465,9 +429,6 @@ local function Slider_OnValueChangedWheel(self, a1) end TitanSetVar(TITAN_CLOCK_ID, "OffsetHour", 0 - self:GetValue()); - if (ServerTimeOffsets[realmName]) then - ServerTimeOffsets[realmName] = TitanGetVar(TITAN_CLOCK_ID, "OffsetHour"); - end TitanPanelButton_UpdateButton(TITAN_CLOCK_ID); -- Update GameTooltip @@ -482,9 +443,6 @@ local function Slider_OnValueChanged(self, a1) local step = self:GetValue() _G[self:GetName() .. "Text"]:SetText(GetOffsetText(0 - step)); TitanSetVar(TITAN_CLOCK_ID, "OffsetHour", 0 - step); - if (ServerTimeOffsets[realmName]) then - ServerTimeOffsets[realmName] = TitanGetVar(TITAN_CLOCK_ID, "OffsetHour"); - end TitanPanelButton_UpdateButton(TITAN_CLOCK_ID); -- Update GameTooltip diff --git a/TitanClock/TitanClock.toc b/TitanClock/TitanClock.toc index bbd44b7..18fa33f 100644 --- a/TitanClock/TitanClock.toc +++ b/TitanClock/TitanClock.toc @@ -1,6 +1,6 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55fClock|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fClock|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## IconTexture: Interface\Icons\Spell_Nature_TimeStop ## Notes: Adds a clock to Titan Panel ## Author: Titan Panel Development Team diff --git a/TitanGold/TitanGold.lua b/TitanGold/TitanGold.lua index 5b315f3..2a83b67 100644 --- a/TitanGold/TitanGold.lua +++ b/TitanGold/TitanGold.lua @@ -10,6 +10,8 @@ -- WoW method to get addon name local addonName = ... +TitanGold = {} -- for API routines + -- ******************************** Constants ******************************* local TITAN_GOLD_ID = "Gold"; local TITAN_BUTTON = "TitanPanel" .. TITAN_GOLD_ID .. "Button" @@ -18,9 +20,7 @@ local TITAN_GOLD_SPACERBAR = "-----------------------"; local updateTable = { TITAN_GOLD_ID, TITAN_PANEL_UPDATE_TOOLTIP }; -- ******************************** Variables ******************************* -GoldSave = {} -- saved vars in TOC local GOLD_INITIALIZED = false; -local GOLD_INDEX = ""; local GOLD_STARTINGGOLD; local GOLD_SESSIONSTART; local AceTimer = LibStub("AceTimer-3.0") @@ -48,7 +48,29 @@ local FACTION_HORDE = "Horde_debug" Titan_Debug.gold = {} Titan_Debug.gold.events = false Titan_Debug.gold.flow = false -Titan_Debug.gold.tooltip = false +Titan_Debug.gold.tool_tip = false +Titan_Debug.gold.total_gold = false +Titan_Debug.gold.eval = false + +---@class GoldData +---@field gold number +---@field show boolean +local GoldData = nil -- pointer to this player plugin data +local GoldInfo = nil ---@class CharInfo +--TitanSettings.Players[toon].Info ---@type CharInfo + +---@class IndexInfo Index flags +---@field valid boolean Saved toon is valid +---@field char_name string Saved toon name +---@field server string Saved toon server +---@field faction string Saved toon faction +---@field same_faction boolean Saved toon faction is same as player +---@field ignore_faction boolean User selection to ignore faction or not +---@field same_realm boolean Saved realm is same as this server +---@field merge_realm boolean Saved realm is in mergerd server list (connected servers) +---@field show_toon boolean Show server - simple test +---@field show boolean Show this toon +---@field gold number GHold on this toon -- ******************************** Functions ******************************* @@ -130,7 +152,7 @@ function Warband.SetSum() local ret_val = nil call_success, -- needed for pcall - ret_val = -- actual return values + ret_val = -- actual return values pcall(C_Bank.FetchDepositedMoney, Enum.BankType.Account) if call_success then @@ -141,7 +163,6 @@ function Warband.SetSum() sum = 0 end Warband.bank_sum = sum - else -- Likely Classic version end @@ -195,7 +216,7 @@ local function GetConnectedRealms() return realms end ----Take a table of indexes to sort GoldSave +---Take a table of indexes to sort gold ---@param gold_table table ---@return table sorted May not be need but it is explicit local function SortByIndex(gold_table) @@ -206,295 +227,108 @@ local function SortByIndex(gold_table) -- * grouping by realm if selected if by_name then table.sort(gold_table, function(key1, key2) - if by_realm then - if GoldSave[key1].realm ~= GoldSave[key2].realm then - return GoldSave[key1].realm < GoldSave[key2].realm - end - end - - return GoldSave[key1].name < GoldSave[key2].name + return key1 < key2 end) - else + elseif by_realm then table.sort(gold_table, function(key1, key2) - if by_realm then - if GoldSave[key1].realm ~= GoldSave[key2].realm then - return GoldSave[key1].realm < GoldSave[key2].realm - end + if gold_table[key1].realm ~= gold_table[key2].realm then + return gold_table[key1].realm < gold_table[key2].realm end - - return GoldSave[key1].gold > GoldSave[key2].gold + return false end) + else + -- just return the table untouched end return gold_table end ----local Create Gold index <character>_<server>::<faction>and see if the toon is in the table. ----@param character string ----@param charserver string ----@param char_faction string -local function CreateIndex(character, charserver, char_faction) - local index = character .. "_" .. charserver .. "::" .. char_faction - - -- See if this is a new toon to Gold; - -- There may be a timing issue on some systems where Gold is told to 'Show' - -- by Titan before Gold processes PEW event. - if (GoldSave[GOLD_INDEX] == nil) then - GoldSave[GOLD_INDEX] = {} - GoldSave[GOLD_INDEX] = { gold = 0, name = player_name } - end - - return index -end - ----local Break apart Gold index +---local Use index to get toon info from Titan ---@param info string ----@return string ----@return string ----@return string +---@return string Character name - no server +---@return string Server name +---@return string Faction internal, not localized local function GetIndexInfo(info) - local character, charserver, char_faction = string.match(info, '(.*)_(.*)::(.*)') + local t_info = TitanSettings.Players[info].Info ---@type CharInfo + local character = t_info.name + local charserver = t_info.server + local char_faction = t_info.factionName return character, charserver, char_faction end ----@class IndexInfo Index flags ----@field valid boolean Saved toon is valid ----@field char_name string Saved toon name ----@field server string Saved toon server ----@field faction string Saved toon faction ----@field same_faction boolean Saved toon faction is same as player ----@field ignore_faction boolean User selection to ignore faction or not ----@field same_realm boolean Saved realm is same as this server ----@field merge_realm boolean Saved realm is in mergerd server list (connected servers) ----@field show_toon boolean Show server - simple test - ---local Take Gold index and return parts plus various flags ---@param index string ---@return IndexInfo local function EvalIndexInfo(index) + local str = "" local res = { valid = false } - local character, charserver, char_faction = GetIndexInfo(index) + local character, charserver, is_custom = TitanUtils_ParseName(index) + local toon_info = TitanSettings.Players[index].Info ---@class CharInfo + if is_custom then + -- do not fill in + res.valid = false + + str = ""..tostring(index).." ignored : is_custom" + Titan_Debug.Out('gold', 'eval', str) + elseif toon_info == nil then + -- do not fill in + res.valid = false + + str = ""..tostring(index).." ignored : no data yet" + else + local toon_gold = toon_info[TITAN_GOLD_ID] ---@class GoldData - if character then res.valid = true - res.char_name = character - res.server = charserver - res.faction = char_faction + res.char_name = toon_info.name + res.server = toon_info.server + res.faction = toon_info.faction res.ignore_faction = TitanGetVar(TITAN_GOLD_ID, "IgnoreFaction") - if (char_faction == player_faction) then + if (res.faction == GoldInfo.faction) then res.same_faction = true else res.same_faction = false end - if (charserver == realmName) then + if (res.server == GoldInfo.server) then res.same_realm = true else res.same_realm = false end - local saved_server = string.gsub(charserver, "%s", "") -- GetAutoCompleteRealms removes spaces, idk why... + local saved_server = string.gsub(res.server, "%s", "") -- GetAutoCompleteRealms removes spaces, idk why... if merged_realms[saved_server] then res.merge_realm = true else res.merge_realm = false end - if (res.ignore_faction or res.same_faction) - and GoldSave[index].show then + -- Assume server option is satisfied; check other options + if (res.ignore_faction or res.same_faction) then res.show_toon = true else res.show_toon = false end - else - -- do not fill in - end - - return res -end - ----local Take the total cash and make it into a nice, colorful string of g s c (gold silver copper) ----@param value number ----@return string outstr Formatted cash for output ----@return integer gold part of value ----@return integer silver part of value ----@return integer copper part of value -local function NiceTextCash(value) - local sep = "" - local dec = "" - if (TitanGetVar(TITAN_GOLD_ID, "UseSeperatorComma")) then - sep = "," - dec = "." - elseif (TitanGetVar(TITAN_GOLD_ID, "UseSeperatorPeriod")) then - sep = "." - dec = "," - elseif (TitanGetVar(TITAN_GOLD_ID, "UseSeperatorSpace")) then - sep = " " - dec = "." - end - - local outstr, gold, silver, copper = - TitanUtils_CashToString(value, sep, dec, - TitanGetVar(TITAN_GOLD_ID, "ShowGoldOnly"), - true, --TitanGetVar(TITAN_GOLD_ID, "ShowCoinLabels"), - false, --TitanGetVar(TITAN_GOLD_ID, "ShowCoinIcons"), - TitanGetVar(TITAN_GOLD_ID, "ShowColoredText")) - return outstr, gold, silver, copper -end - ----local Create Show menu - list of characters in same faction ----@param faction string ----@param level number -local function ShowMenuButtons(faction, level) - TitanPanelRightClickMenu_AddTitle(L["TITAN_GOLD_SHOW_PLAYER"], level) - local info = {}; - -- Sort names for the menu list - local GoldSorted = {}; - for index, money in pairs(GoldSave) do - table.insert(GoldSorted, index) - end - GoldSorted = SortByIndex(GoldSorted) - - for i = 1, #GoldSorted do - local index = GoldSorted[i] - local character, charserver, char_faction = GetIndexInfo(index) - if character and (char_faction == faction) then - info.text = character .. " - " .. charserver.." "..NiceTextCash(GoldSave[index].gold)..""; - info.value = character; - info.keepShownOnClick = true; - info.checked = function() - return GoldSave[index].show - end - info.func = function() - GoldSave[index].show = not GoldSave[index].show; - TitanPanelButton_UpdateButton(TITAN_GOLD_ID) - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end - end -end - ----local Create Delete menu - list of characters in same faction ----@param faction string ----@param level number -local function DeleteMenuButtons(faction, level) - TitanPanelRightClickMenu_AddTitle(L["TITAN_GOLD_DELETE_PLAYER"], level) - - local info = {}; - local name = player_name - local server = realmName; - - -- Sort names for the menu list - local GoldSorted = {}; - for index, money in pairs(GoldSave) do - table.insert(GoldSorted, index) - end - GoldSorted = SortByIndex(GoldSorted) - - for i = 1, #GoldSorted do - local index = GoldSorted[i] - local character, charserver, char_faction = GetIndexInfo(index) - info.notCheckable = true - if character and (char_faction == faction) then - info.text = character .. " - " .. charserver.." "..NiceTextCash(GoldSave[index].gold)..""; - info.value = character; - info.func = function() - GoldSave[index] = {} - GoldSave[index] = nil - TitanPanelButton_UpdateButton(TITAN_GOLD_ID) - end - -- cannot delete current character - if name == character and server == charserver then - info.disabled = 1; - else - info.disabled = nil; - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end - end -end ----local Based on user Coin selection set None | Labels | Icons ----@param chosen string -local function ShowProperLabels(chosen) - if chosen == "ShowCoinNone" then - TitanSetVar(TITAN_GOLD_ID, "ShowCoinNone", true); - TitanSetVar(TITAN_GOLD_ID, "ShowCoinLabels", false); - TitanSetVar(TITAN_GOLD_ID, "ShowCoinIcons", false); - end - if chosen == "ShowCoinLabels" then - TitanSetVar(TITAN_GOLD_ID, "ShowCoinNone", false); - TitanSetVar(TITAN_GOLD_ID, "ShowCoinLabels", true); - TitanSetVar(TITAN_GOLD_ID, "ShowCoinIcons", false); - end - if chosen == "ShowCoinIcons" then - TitanSetVar(TITAN_GOLD_ID, "ShowCoinNone", false); - TitanSetVar(TITAN_GOLD_ID, "ShowCoinLabels", false); - TitanSetVar(TITAN_GOLD_ID, "ShowCoinIcons", true); - end - TitanPanelButton_UpdateButton(TITAN_GOLD_ID); -end + res.gold = toon_gold.gold ----local Based on user Seperator selection set Comma | Period | Space ----@param chosen string -local function Seperator(chosen) - if chosen == "UseSeperatorComma" then - TitanSetVar(TITAN_GOLD_ID, "UseSeperatorComma", true); - TitanSetVar(TITAN_GOLD_ID, "UseSeperatorPeriod", false); - TitanSetVar(TITAN_GOLD_ID, "UseSeperatorSpace", false); + str = "" + .." "..tostring(index).."" + .." n:"..tostring(res.char_name).."" + .." s:"..tostring(res.server).."" + .." ss:"..tostring(res.same_realm).."" + .." ms:"..tostring(res.merge_realm).."" + .." f:"..tostring(res.faction).."" + .." if:"..tostring(res.ignore_faction).."" + .." sf:"..tostring(res.same_faction).."" + .." show:"..tostring(res.show_toon).."" + .." gold:"..tostring(res.gold).."" + Titan_Debug.Out('gold', 'eval', str) end - if chosen == "UseSeperatorPeriod" then - TitanSetVar(TITAN_GOLD_ID, "UseSeperatorComma", false); - TitanSetVar(TITAN_GOLD_ID, "UseSeperatorPeriod", true); - TitanSetVar(TITAN_GOLD_ID, "UseSeperatorSpace", false); - end - if chosen == "UseSeperatorSpace" then - TitanSetVar(TITAN_GOLD_ID, "UseSeperatorComma", false); - TitanSetVar(TITAN_GOLD_ID, "UseSeperatorPeriod", false); - TitanSetVar(TITAN_GOLD_ID, "UseSeperatorSpace", true); - end - TitanPanelButton_UpdateButton(TITAN_GOLD_ID); -end - ----local Based on user Server selection set Merge | Seperate | All ----@param chosen string -local function Merger(chosen) - if chosen == "MergeServers" then - TitanSetVar(TITAN_GOLD_ID, "MergeServers", true); - TitanSetVar(TITAN_GOLD_ID, "SeparateServers", false); - TitanSetVar(TITAN_GOLD_ID, "AllServers", false); - end - if chosen == "SeparateServers" then - TitanSetVar(TITAN_GOLD_ID, "MergeServers", false); - TitanSetVar(TITAN_GOLD_ID, "SeparateServers", true); - TitanSetVar(TITAN_GOLD_ID, "AllServers", false); - end - if chosen == "AllServers" then - TitanSetVar(TITAN_GOLD_ID, "MergeServers", false); - TitanSetVar(TITAN_GOLD_ID, "SeparateServers", false); - TitanSetVar(TITAN_GOLD_ID, "AllServers", true); - end - TitanPanelButton_UpdateButton(TITAN_GOLD_ID); -end - ----local Toggles when the player selects the show gold/hour stats -local function GoldGPH_Toggle() - TitanToggleVar(TITAN_GOLD_ID, "DisplayGoldPerHour") - if TitanGetVar(TITAN_GOLD_ID, "DisplayGoldPerHour") then - if GoldTimerRunning then - -- Do not create a new one - else - GoldTimer = AceTimer:ScheduleRepeatingTimer(TitanPanelPluginHandle_OnUpdate, 1, updateTable) - GoldTimerRunning = true - end - elseif GoldTimer and not TitanGetVar(TITAN_GOLD_ID, "DisplayGoldPerHour") then - AceTimer:CancelTimer(GoldTimer) - GoldTimerRunning = false - end + return res end ---local Helper for TotalGold @@ -515,37 +349,57 @@ end ---@return integer local function TotalGold() -- EvalIndexInfo checks the toon info against the user options - -- then returns as a table of 'flags'. + -- then returns a table of 'flags'. -- The if within each loop checks the appropriate flags per user server display option. - - local ttlgold = 0; + local ttlgold = 0 if TitanGetVar(TITAN_GOLD_ID, "SeparateServers") then + Titan_Debug.Out('gold', 'total_gold', "=== SeparateServers") -- Parse the database and display all characters on this server - for index, money in pairs(GoldSave) do + for index, money in pairs(TitanSettings.Players) do local char = EvalIndexInfo(index) - if char.valid and char.same_realm and char.show_toon then - ttlgold = ToonAdd(GoldSave[index].show, GoldSave[index].gold, ttlgold) + if char.valid then + if char.same_realm and char.show_toon then + ttlgold = ToonAdd(true, char.gold, ttlgold) + Titan_Debug.Out('gold', 'total_gold', + index .. " > " .. NiceCash(char.gold, false, false) + .. " " .. NiceCash(ttlgold, false, false) + ) + end else -- Do not show per flags end end elseif TitanGetVar(TITAN_GOLD_ID, "MergeServers") then + Titan_Debug.Out('gold', 'total_gold', "=== MergeServers") -- Parse the database and display characters on merged / connected servers - for index, money in pairs(GoldSave) do + for index, money in pairs(TitanSettings.Players) do local char = EvalIndexInfo(index) - if char.valid and char.merge_realm and char.show_toon then - ttlgold = ToonAdd(GoldSave[index].show, GoldSave[index].gold, ttlgold) + if char.valid then + if char.merge_realm and char.show_toon then + ttlgold = ToonAdd(true, char.gold, ttlgold) + Titan_Debug.Out('gold', 'total_gold', + index .. " " .. NiceCash(char.gold, false, false) + .. " > " .. NiceCash(ttlgold, false, false) + ) + end else -- Do not show per flags end end elseif TitanGetVar(TITAN_GOLD_ID, "AllServers") then + Titan_Debug.Out('gold', 'total_gold', "=== AllServers") -- Parse the database and display characters on all servers - for index, money in pairs(GoldSave) do + for index, money in pairs(TitanSettings.Players) do local char = EvalIndexInfo(index) - if char.valid and char.show_toon then - ttlgold = ToonAdd(GoldSave[index].show, GoldSave[index].gold, ttlgold) + if char.valid then + if char.show_toon then + ttlgold = ToonAdd(true, char.gold, ttlgold) + Titan_Debug.Out('gold', 'total_gold', + index .. " " .. NiceCash(char.gold, false, false) + .. " > " .. NiceCash(ttlgold, false, false) + ) + end else -- Do not show per flags end @@ -558,7 +412,8 @@ local function TotalGold() ttlgold = ttlgold + Warband.GetSum() end - return ttlgold; + Titan_Debug.Out('gold', 'total_gold', "Total = " .. NiceCash(ttlgold, false, false)) + return ttlgold end -- ====== Tool tip routines @@ -569,7 +424,7 @@ local function GetTooltipText() local GoldSorted = {}; local currentMoneyRichText = ""; local countelements = 0; - local faction = player_faction + local faction = GoldInfo.factionName local ignore_faction = TitanGetVar(TITAN_GOLD_ID, "IgnoreFaction") for _ in pairs(realmNames) do @@ -580,27 +435,38 @@ local function GetTooltipText() if TitanGetVar(TITAN_GOLD_ID, "SeparateServers") then -- Parse the database and display characters from this server - for index, money in pairs(GoldSave) do + Titan_Debug.Out('gold', 'tool_tip', "=== SeparateServers") + for index, money in pairs(TitanSettings.Players) do local char = EvalIndexInfo(index) - if char.valid and char.same_realm and char.show_toon then - table.insert(GoldSorted, index); + if char.valid then + if char.same_realm and char.show_toon then + Titan_Debug.Out('gold', 'tool_tip', index.." "..NiceCash(char.gold, false, false)) + table.insert(GoldSorted, index); + end end end elseif TitanGetVar(TITAN_GOLD_ID, "MergeServers") then -- Parse the database and display characters from merged / connected servers - for index, money in pairs(GoldSave) do + Titan_Debug.Out('gold', 'tool_tip', "=== MergeServers") + for index, money in pairs(TitanSettings.Players) do local char = EvalIndexInfo(index) - - if char.valid and char.merge_realm and char.show_toon then - table.insert(GoldSorted, index); + if char.valid then + if char.merge_realm and char.show_toon then + Titan_Debug.Out('gold', 'tool_tip', index.." "..NiceCash(char.gold, false, false)) + table.insert(GoldSorted, index); + end end end elseif TitanGetVar(TITAN_GOLD_ID, "AllServers") then -- Parse the database and display characters from all servers - for index, money in pairs(GoldSave) do + Titan_Debug.Out('gold', 'tool_tip', "=== AllServers") + for index, money in pairs(TitanSettings.Players) do local char = EvalIndexInfo(index) - if char.valid and char.show_toon then - table.insert(GoldSorted, index); + if char.valid then + if char.show_toon then + Titan_Debug.Out('gold', 'tool_tip', index.." "..NiceCash(char.gold, false, false)) + table.insert(GoldSorted, index); + end end end end @@ -617,8 +483,10 @@ local function GetTooltipText() local show_realm = true local character, charserver, char_faction for i = 1, #GoldSorted do - character, charserver, char_faction = GetIndexInfo(GoldSorted[i]) - coin_str = NiceCash(GoldSave[GoldSorted[i]].gold, false, false) + local toon = GoldSorted[i] + character, charserver, char_faction = GetIndexInfo(toon) + local t_gold = TitanSettings.Players[toon].Info[TITAN_GOLD_ID].gold + coin_str = NiceCash(t_gold, false, false) show_dash = false show_realm = true @@ -667,13 +535,13 @@ local function GetTooltipText() -- if Warband.Use() then local cash = NiceCash(Warband.GetSum(), false, false) - local war_name = ""..Warband.GetName() -- localized + local war_name = "" .. Warband.GetName() -- localized currentMoneyRichText = currentMoneyRichText .. "\n" .. "------ \t +" .. "\n" .. war_name .. "\t" .. cash - local msg = "" .. war_name .. " ".. cash - Titan_Debug.Out('gold', 'tooltip', msg) + local msg = "" .. war_name .. " " .. cash + Titan_Debug.Out('gold', 'tool_tip', msg) end @@ -778,17 +646,6 @@ end -- ====== Right click menu routines ----local Toggle whether button shows player or total gold (based on other user selections). -local function ViewAll_Toggle() - TitanToggleVar(TITAN_GOLD_ID, "ViewAll") - TitanPanelButton_UpdateButton(TITAN_GOLD_ID) -end - ----local Toggle whether tooltip sorts by toon name or gold amount. -local function Sort_Toggle() - TitanToggleVar(TITAN_GOLD_ID, "SortByName") -end - local function ResetSession() GOLD_STARTINGGOLD = Get_Money(); GOLD_SESSIONSTART = GetTime(); @@ -805,55 +662,37 @@ local function Initialize_Array() -- already done else -- See if this is a new toon to Gold saved vars or reset - -- Set gold to 0; it will be set properly later - if (GoldSave[GOLD_INDEX] == nil) then - GoldSave[GOLD_INDEX] = {} - GoldSave[GOLD_INDEX] = { gold = 0, name = player_name } - end + local gindex, _, _ = TitanUtils_GetPlayer() + -- TitanSettings.Players[toon].Info.[TITAN_GOLD_ID] - Warband.Init() + GoldInfo = TitanSettings.Players[gindex].Info - -- Ensure the saved vars are usable - for index, money in pairs(GoldSave) do - local character, charserver, char_faction = GetIndexInfo(index) + if GoldInfo[TITAN_GOLD_ID] then + -- use existing data + else + GoldInfo[TITAN_GOLD_ID] = {} + GoldData = GoldInfo[TITAN_GOLD_ID] + GoldData.gold = 0 + end - -- Could be a new toon to Gold or an updated Gold - local show_toon = GoldSave[index].show - if show_toon == nil then - show_toon = true - end - GoldSave[index].show = show_toon - GoldSave[index].realm = charserver -- added July 2022 + Warband.Init() - -- added Aug 2022 for #1332. - -- Faction in index was not set for display in tool tip. - -- Created localized faction as a field; set every time in case user changes languages - if char_faction == TITAN_ALLIANCE then - GoldSave[index].faction = FACTION_ALLIANCE - elseif char_faction == TITAN_HORDE then - GoldSave[index].faction = FACTION_HORDE - else - GoldSave[index].faction = FACTION_OTHER - end - end GOLD_STARTINGGOLD = Get_Money(); GOLD_SESSIONSTART = GetTime(); GOLD_INITIALIZED = true; - -- added Jan 2025 - -- Also restore initial gold: - -- new toon; Titan install / update / reload - GoldSave[GOLD_INDEX].gold = Get_Money() + GoldData = GoldInfo[TITAN_GOLD_ID] + GoldData.gold = Get_Money() info = "" - .." "..tostring(GOLD_SESSIONSTART).."" - .." "..tostring(GOLD_STARTINGGOLD).."" - .." "..tostring(Warband.GetSum()).."" - end + .. " " .. tostring(GOLD_SESSIONSTART) .. "" + .. " " .. tostring(GOLD_STARTINGGOLD) .. "" + .. " " .. tostring(Warband.GetSum()) .. "" + end local msg = ">Init done : " - .." "..tostring(GOLD_INITIALIZED).."" - .." "..info.."" + .. " " .. tostring(GOLD_INITIALIZED) .. "" + .. " " .. info .. "" Titan_Debug.Out('gold', 'flow', msg) end @@ -862,7 +701,6 @@ end local function ClearData(self) GOLD_INITIALIZED = false; - GoldSave = {}; Initialize_Array(); TitanPanelButton_UpdateButton(TITAN_GOLD_ID) @@ -889,295 +727,58 @@ local function TitanGold_ClearDB() StaticPopup_Show("TITANGOLD_CLEAR_DATABASE"); end ----local Generate the tooltip display option menu -local function DisplayOptions() - local info = {}; - info.notCheckable = true - info.text = L["TITAN_GOLD_SORT_BY"]; - info.value = "Sorting"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - - -- Which characters to show - -- - Separate : this server - -- - Merge : connected / merged servers - -- - All : any server - info = {}; - info.text = L["TITAN_GOLD_SEPARATE"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "SeparateServers"); - info.func = function() - Merger("SeparateServers") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_GOLD_MERGE"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "MergeServers"); - info.func = function() - Merger("MergeServers") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_GOLD_ALL"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "AllServers"); - info.func = function() - Merger("AllServers") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - - -- Option to ignore faction - per 9.2.5 changes - info = {}; - info.text = L["TITAN_GOLD_IGNORE_FACTION"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "IgnoreFaction"); - info.func = function() - TitanToggleVar(TITAN_GOLD_ID, "IgnoreFaction"); - TitanPanelButton_UpdateButton(TITAN_GOLD_ID); - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - - -- What labels to show next to money : none / text / icon - info = {}; - info.text = L["TITAN_GOLD_COIN_NONE"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "ShowCoinNone"); - info.func = function() - ShowProperLabels("ShowCoinNone") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_GOLD_COIN_LABELS"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "ShowCoinLabels"); - info.func = function() - ShowProperLabels("ShowCoinLabels") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_GOLD_COIN_ICONS"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "ShowCoinIcons"); - info.func = function() - ShowProperLabels("ShowCoinIcons") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_GOLD_ID + local root = rootDescription -- menu widget to start with - -- Show gold only option - no silver, no copper - info = {}; - info.text = L["TITAN_GOLD_ONLY"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "ShowGoldOnly"); - info.func = function() - TitanToggleVar(TITAN_GOLD_ID, "ShowGoldOnly"); - TitanPanelButton_UpdateButton(TITAN_GOLD_ID); - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); + local opts_gold = Titan_Menu.AddButton(root, L["TITAN_GOLD_TOOLTIP_DISPLAY_OPTIONS"]) + do -- next level options + local list = { -- a mututally exclusive triple + { L["TITAN_GOLD_SEPARATE"], "SeparateServers" }, + { L["TITAN_GOLD_MERGE"], "MergeServers" }, + { L["TITAN_GOLD_ALL"], "AllServers" }, + } + Titan_Menu.AddSelectorExclusiveList(opts_gold, id, L["TITAN_GOLD_SORT_BY"], list) + Titan_Menu.AddSelector(opts_gold, id, L["TITAN_GOLD_IGNORE_FACTION"], "IgnoreFaction") - -- Use thousands separater : , . ' ' - info = {}; - info.text = L["TITAN_PANEL_USE_COMMA"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "UseSeperatorComma"); - info.func = function() - Seperator("UseSeperatorComma") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); + local coins = { -- a mututally exclusive triple + { L["TITAN_GOLD_COIN_NONE"], "ShowCoinNone" }, + { L["TITAN_GOLD_COIN_LABELS"], "ShowCoinLabels" }, + { L["TITAN_GOLD_COIN_ICONS"], "ShowCoinIcons" }, + } + Titan_Menu.AddSelectorExclusiveList(opts_gold, id, "Coin Labels", coins) - info = {}; - info.text = L["TITAN_PANEL_USE_PERIOD"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "UseSeperatorPeriod"); - info.func = function() - Seperator("UseSeperatorPeriod") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TITAN_PANEL_USE_SPACE = "Use Space" - info = {}; - info.text = TITAN_PANEL_USE_SPACE - info.checked = TitanGetVar(TITAN_GOLD_ID, "UseSeperatorSpace"); - info.func = function() - Seperator("UseSeperatorSpace") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); + local seps = { -- a mututally exclusive triple + { L["TITAN_PANEL_USE_COMMA"], "UseSeperatorComma" }, + { L["TITAN_PANEL_USE_PERIOD"], "UseSeperatorPeriod" }, + { "Use Space", "UseSeperatorSpace" }, + } + Titan_Menu.AddSelectorExclusiveList(opts_gold, id, "Seperator", seps) - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); + Titan_Menu.AddDivider(opts_gold) - -- Show session info - info = {}; - info.text = L["TITAN_GOLD_SHOW_STATS_TITLE"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "ShowSessionInfo"); - info.func = function() - TitanToggleVar(TITAN_GOLD_ID, "ShowSessionInfo"); - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); + Titan_Menu.AddSelector(opts_gold, id, L["TITAN_GOLD_SHOW_STATS_TITLE"], "ShowSessionInfo") - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); + Titan_Menu.AddDivider(opts_gold) - -- Function to toggle gold per hour sort - info = {}; - info.text = L["TITAN_GOLD_TOGGLE_GPH_SHOW"] - info.checked = TitanGetVar(TITAN_GOLD_ID, "DisplayGoldPerHour"); - info.func = function() - GoldGPH_Toggle() + Titan_Menu.AddSelector(opts_gold, id, L["TITAN_GOLD_TOGGLE_GPH_SHOW"], "DisplayGoldPerHour") end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); -end ----local Generate the options menu -local function CreateMenu() - if TitanPanelRightClickMenu_GetDropdownLevel() == 1 then - -- Menu title - TitanPanelRightClickMenu_AddTitle(L["TITAN_GOLD_ITEMNAME"]); - - -- Function to toggle button gold view - local info = {}; - info.text = L["TITAN_GOLD_TOGGLE_ALL_TEXT"] - info.checked = TitanGetVar(TITAN_GOLD_ID, "ViewAll"); - info.func = function() - ViewAll_Toggle() - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); + local disp = { -- selectors using the same option + { L["TITAN_GOLD_TOGGLE_ALL_TEXT"], true }, + { L["TITAN_GOLD_TOGGLE_PLAYER_TEXT"], false }, + } + Titan_Menu.AddSelectorList(root, id, nil, "ViewAll", disp) - info = {}; - info.text = L["TITAN_GOLD_TOGGLE_PLAYER_TEXT"] - info.checked = not TitanGetVar(TITAN_GOLD_ID, "ViewAll"); - info.func = function() - ViewAll_Toggle() - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - TitanPanelRightClickMenu_AddSeparator(); - - -- Display options - info = {}; - info.notCheckable = true - info.text = L["TITAN_GOLD_TOOLTIP_DISPLAY_OPTIONS"]; - info.value = "Display_Options"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(); - - if Warband.active then - -- Function to toggle show / hide of Warbank gold - info = {}; - info.text = L["TITAN_GOLD_INCLUDE_WARBANK"] - - info.checked = TitanGetVar(TITAN_GOLD_ID, "ShowWarband"); - info.func = function() - TitanToggleVar(TITAN_GOLD_ID, "ShowWarband") - TitanPanelButton_UpdateButton(TITAN_GOLD_ID) - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()) - else - -- Warbank not in this expansion - end - - -- Show / delete toons - info = {}; - info.notCheckable = true - info.text = L["TITAN_GOLD_SHOW_PLAYER"]; - info.value = "ToonShow"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_GOLD_DELETE_PLAYER"]; - info.value = "ToonDelete"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(); - - -- Option to clear the enter database - info = {}; - info.notCheckable = true - info.text = L["TITAN_GOLD_CLEAR_DATA_TEXT"]; - info.func = TitanGold_ClearDB; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddCommand(L["TITAN_GOLD_RESET_SESS_TEXT"], TITAN_GOLD_ID, ResetSession); - - TitanPanelRightClickMenu_AddControlVars(TITAN_GOLD_ID) - end - - -- Second (2nd) level for show / delete | sort by - if TitanPanelRightClickMenu_GetDropdownLevel() == 2 - and TitanPanelRightClickMenu_GetDropdMenuValue() == "ToonDelete" then - local info = {}; - info.notCheckable = true - info.text = L["TITAN_GOLD_FACTION_PLAYER_ALLY"]; - info.value = "DeleteAlliance"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info.text = L["TITAN_GOLD_FACTION_PLAYER_HORDE"]; - info.value = "DeleteHorde"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - elseif TitanPanelRightClickMenu_GetDropdownLevel() == 2 - and TitanPanelRightClickMenu_GetDropdMenuValue() == "ToonShow" then - local info = {}; - info.notCheckable = true - info.text = L["TITAN_GOLD_FACTION_PLAYER_ALLY"]; - info.value = "ShowAlliance"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info.text = L["TITAN_GOLD_FACTION_PLAYER_HORDE"]; - info.value = "ShowHorde"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - elseif TitanPanelRightClickMenu_GetDropdownLevel() == 3 - and TitanPanelRightClickMenu_GetDropdMenuValue() == "Sorting" then - -- Show gold only option - no silver, no copper - local info = {}; - info.text = L["TITAN_GOLD_TOGGLE_SORT_GOLD"] - info.checked = not TitanGetVar(TITAN_GOLD_ID, "SortByName"); - info.func = function() - Sort_Toggle() - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - local info = {}; - info.text = L["TITAN_GOLD_TOGGLE_SORT_NAME"] - info.checked = TitanGetVar(TITAN_GOLD_ID, "SortByName"); - info.func = function() - Sort_Toggle() - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - - local info = {}; - info.text = L["TITAN_GOLD_GROUP_BY_REALM"]; - info.checked = TitanGetVar(TITAN_GOLD_ID, "GroupByRealm") - info.func = function() - TitanToggleVar(TITAN_GOLD_ID, "GroupByRealm") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - elseif TitanPanelRightClickMenu_GetDropdownLevel() == 2 - and TitanPanelRightClickMenu_GetDropdMenuValue() == "Display_Options" then - DisplayOptions() + if Warband.active then + Titan_Menu.AddSelector(root, id, L["TITAN_GOLD_INCLUDE_WARBANK"], "ShowWarband") + else + -- Warbank not in this expansion end + Titan_Menu.AddDivider(root) - -- Third (3rd) level for the list of characters / toons - if TitanPanelRightClickMenu_GetDropdownLevel() == 3 and TitanPanelRightClickMenu_GetDropdMenuValue() == "DeleteAlliance" then - DeleteMenuButtons(TITAN_ALLIANCE, 3) - elseif TitanPanelRightClickMenu_GetDropdownLevel() == 3 and TitanPanelRightClickMenu_GetDropdMenuValue() == "DeleteHorde" then - DeleteMenuButtons(TITAN_HORDE, 3) - elseif TitanPanelRightClickMenu_GetDropdownLevel() == 3 and TitanPanelRightClickMenu_GetDropdMenuValue() == "ShowAlliance" then - ShowMenuButtons(TITAN_ALLIANCE, 3) - elseif TitanPanelRightClickMenu_GetDropdownLevel() == 3 and TitanPanelRightClickMenu_GetDropdMenuValue() == "ShowHorde" then - ShowMenuButtons(TITAN_HORDE, 3) - end +-- Titan_Menu.AddCommand(root, id, L["TITAN_GOLD_CLEAR_DATA_TEXT"], TitanGold_ClearDB) +-- Titan_Menu.AddCommand(root, id, L["TITAN_GOLD_RESET_SESS_TEXT"], ResetSession) end ---local Get the gold total the user wants (server or player). @@ -1194,7 +795,7 @@ local function FindGold() if TitanGetVar(TITAN_GOLD_ID, "ViewAll") then ttlgold = TotalGold() else - ttlgold = GoldSave[GOLD_INDEX].gold + ttlgold = GoldData.gold end ret_str = NiceCash(ttlgold, true, false) @@ -1215,7 +816,8 @@ local function OnLoad(self) category = "Built-ins", version = TITAN_GOLD_VERSION, menuText = L["TITAN_GOLD_MENU_TEXT"], - menuTextFunction = CreateMenu, + --menuTextFunction = CreateMenu, -- OLD + menuContextFunction = GeneratorFunction, -- NEW scheme tooltipTitle = L["TITAN_GOLD_TOOLTIP"], tooltipTextFunction = GetTooltipText, buttonTextFunction = FindGold, @@ -1226,7 +828,7 @@ local function OnLoad(self) ShowIcon = true, ShowLabelText = true, ShowRegularText = false, - ShowColoredText = false, + ShowColoredText = true, DisplayOnRightSide = true, }, savedVariables = { @@ -1257,7 +859,7 @@ local function OnLoad(self) }; self:RegisterEvent("ADDON_LOADED"); --- self:RegisterEvent("PLAYER_ENTERING_WORLD"); + -- self:RegisterEvent("PLAYER_ENTERING_WORLD"); end ---local When shown, register needed events and start timer for gold per hour @@ -1266,7 +868,7 @@ local function OnShow(self) Initialize_Array() self:RegisterEvent("PLAYER_MONEY") - if GoldSave and TitanGetVar(TITAN_GOLD_ID, "DisplayGoldPerHour") then + if TitanGetVar(TITAN_GOLD_ID, "DisplayGoldPerHour") then if GoldTimerRunning then -- Do not start a new one else @@ -1278,9 +880,9 @@ local function OnShow(self) end local msg = "" - .." "..Gold_debug("OnShow") + .. " " .. Gold_debug("OnShow") Titan_Debug.Out('gold', 'flow', msg) - end +end ---local When shown, unregister needed events and stop timer for gold per hour ---@param self Button @@ -1297,7 +899,7 @@ end local function OnEvent(self, event, a1, ...) if (event == "PLAYER_MONEY") then if (GOLD_INITIALIZED) then - GoldSave[GOLD_INDEX].gold = Get_Money() + GoldData.gold = Get_Money() TitanPanelButton_UpdateButton(TITAN_GOLD_ID) end elseif (event == "ADDON_LOADED") then @@ -1309,9 +911,6 @@ local function OnEvent(self, event, a1, ...) merged_realms[realm] = true end - -- Faction is English to use as index NOT display - GOLD_INDEX = CreateIndex(player_name, realmName, player_faction) - self:UnregisterEvent("ADDON_LOADED"); else -- Not this addon @@ -1342,21 +941,38 @@ local function OnClick(self, button) end end -function TitanPanel_GoldGetGold(player, server, faction) +---Get gold for given player or why it is not +---@param player string Titan format - name with server +---@param add_label boolean +---@return string +function TitanGold.GetInfo(player, add_label) local res = "" - -- Gold was written WAY before the profile changes so translate the index - local idx = CreateIndex(player, server, faction) - if _G[TITAN_BUTTON]:IsShown() - and GoldSave[idx] - then - res = NiceCash(GoldSave[idx].gold, true, false) + local label = "" + if add_label then + label = L["TITAN_GOLD_MENU_TEXT"] .. " : " + else + label = "" + end + + local character, charserver, is_custom = TitanUtils_ParseName(player) + if is_custom then + res = L["TITAN_PANEL_NA"] + elseif _G[TITAN_BUTTON]:IsShown() then + local toon_gold = nil + if TitanSettings.Players[player] + and TitanSettings.Players[player].Info + and TitanSettings.Players[player].Info[TITAN_GOLD_ID] then + toon_gold = TitanSettings.Players[player].Info[TITAN_GOLD_ID] ---@class GoldData + res = NiceCash(toon_gold.gold, true, false) + else + res = L["TITAN_PANEL_NA"].." - Not logged in yet with Gold enabled." + end else res = L["TITAN_PANEL_MENU_DISABLED"] end - return res + return label..res end - ---local Create required Gold frames local function Create_Frames() if _G[TITAN_BUTTON] then diff --git a/TitanGold/TitanGold.toc b/TitanGold/TitanGold.toc index 8a31630..ce47673 100644 --- a/TitanGold/TitanGold.toc +++ b/TitanGold/TitanGold.toc @@ -1,6 +1,6 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55fGold|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fGold|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## IconTexture: Interface\AddOns\TitanGold\Artwork\TitanGold ## Notes: Keeps track of all gold held by a player's toons on a per server/faction basis. ## Author: Titan Panel Development Team diff --git a/TitanLocation/TitanLocation.lua b/TitanLocation/TitanLocation.lua index 63fb9e7..a9f12fe 100755 --- a/TitanLocation/TitanLocation.lua +++ b/TitanLocation/TitanLocation.lua @@ -598,170 +598,51 @@ local function OnClick(self, button) end end ----local Create right click menu -local function CreateMenu() - local info - - -- level 1 - if TitanPanelRightClickMenu_GetDropdownLevel() == 1 then - -- level 1 - TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_LOCATION_ID].menuText); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_OPTIONS"]; - info.value = "Options" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_LOCATION_FORMAT_COORD_LABEL"]; - info.value = "CoordFormat" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = "WorldMap" - info.value = "WorldMap" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddControlVars(TITAN_LOCATION_ID) - -- level 2 - elseif TitanPanelRightClickMenu_GetDropdownLevel() == 2 then - if TitanPanelRightClickMenu_GetDropdMenuValue() == "Options" then - TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_OPTIONS"], TitanPanelRightClickMenu_GetDropdownLevel()); - info = {}; - info.text = L["TITAN_LOCATION_MENU_SHOW_REALM_ON_PANEL_TEXT"]; - info.func = function() - TitanToggleVar(TITAN_LOCATION_ID, "ShowRealmText"); - TitanPanelButton_UpdateButton(TITAN_LOCATION_ID); - end - info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowRealmText"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_LOCATION_MENU_SHOW_ZONE_ON_PANEL_TEXT"]; - info.func = function() - TitanToggleVar(TITAN_LOCATION_ID, "ShowZoneText"); - TitanPanelButton_UpdateButton(TITAN_LOCATION_ID); - end - info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowZoneText"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - --- if TITAN_ID == "Titan" then - info = {}; - info.text = L["TITAN_LOCATION_MENU_SHOW_SUBZONE_ON_PANEL_TEXT"]; - info.func = function() - TitanToggleVar(TITAN_LOCATION_ID, "ShowSubZoneText"); - TitanPanelButton_UpdateButton(TITAN_LOCATION_ID); - end - info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowSubZoneText"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); --- else - -- no work needed --- end - - info = {}; - info.text = L["TITAN_LOCATION_MENU_SHOW_COORDS_ON_PANEL_TEXT"]; - info.func = function() - TitanToggleVar(TITAN_LOCATION_ID, "ShowCoordsText"); - TitanPanelButton_UpdateButton(TITAN_LOCATION_ID); - end - info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsText"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); ---]] - end +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_LOCATION_ID + local root = rootDescription -- menu widget to start with + + local opts_loc = Titan_Menu.AddButton(root, L["TITAN_PANEL_OPTIONS"]) + do -- next level options + Titan_Menu.AddSelector(opts_loc, id, L["TITAN_LOCATION_MENU_SHOW_REALM_ON_PANEL_TEXT"], "ShowRealmText") + Titan_Menu.AddSelector(opts_loc, id, L["TITAN_LOCATION_MENU_SHOW_ZONE_ON_PANEL_TEXT"], "ShowZoneText") + Titan_Menu.AddSelector(opts_loc, id, L["TITAN_LOCATION_MENU_SHOW_SUBZONE_ON_PANEL_TEXT"], "ShowSubZoneText") + Titan_Menu.AddSelector(opts_loc, id, L["TITAN_LOCATION_MENU_SHOW_COORDS_ON_PANEL_TEXT"], "ShowCoordsText") + end - if TitanPanelRightClickMenu_GetDropdMenuValue() == "CoordFormat" then - TitanPanelRightClickMenu_AddTitle(L["TITAN_LOCATION_FORMAT_COORD_LABEL"], - TitanPanelRightClickMenu_GetDropdownLevel()); - info = {}; - info.text = L["TITAN_LOCATION_FORMAT_LABEL"]; - info.func = function() - TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat", L["TITAN_LOCATION_FORMAT"]); - TitanPanelButton_UpdateButton(TITAN_LOCATION_ID); - end - info.checked = (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat") == L["TITAN_LOCATION_FORMAT"]) - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_LOCATION_FORMAT2_LABEL"]; - info.func = function() - TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat", L["TITAN_LOCATION_FORMAT2"]); - TitanPanelButton_UpdateButton(TITAN_LOCATION_ID); - end - info.checked = (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat") == L["TITAN_LOCATION_FORMAT2"]) - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_LOCATION_FORMAT3_LABEL"]; - info.func = function() - TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat", L["TITAN_LOCATION_FORMAT3"]); - TitanPanelButton_UpdateButton(TITAN_LOCATION_ID); - end - info.checked = (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat") == L["TITAN_LOCATION_FORMAT3"]) - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end + local opts_coords = Titan_Menu.AddButton(root, L["TITAN_LOCATION_FORMAT_COORD_LABEL"]) + do -- next level options + local disp = { -- selectors using the same option + {L["TITAN_LOCATION_FORMAT_LABEL"], L["TITAN_LOCATION_FORMAT"]}, + {L["TITAN_LOCATION_FORMAT2_LABEL"], L["TITAN_LOCATION_FORMAT2"]}, + {L["TITAN_LOCATION_FORMAT3_LABEL"], L["TITAN_LOCATION_FORMAT3"]}, + } + Titan_Menu.AddSelectorList(opts_coords, id, nil, "CoordsFormat", disp) + end - if TitanPanelRightClickMenu_GetDropdMenuValue() == "WorldMap" then - TitanPanelRightClickMenu_AddTitle(L["TITAN_LOCATION_MENU_TEXT"], TitanPanelRightClickMenu_GetDropdownLevel()); - info = {}; - info.text = L["TITAN_LOCATION_MENU_SHOW_COORDS_ON_MAP_TEXT"]; - info.func = function() - TitanToggleVar(TITAN_LOCATION_ID, "ShowCoordsOnMap"); + local opts_map = Titan_Menu.AddButton(root, "WorldMap") + do -- next level options + Titan_Menu.AddSelectorCommand(opts_map, id, L["TITAN_LOCATION_MENU_SHOW_COORDS_ON_MAP_TEXT"], "ShowCoordsOnMap", + function () if (TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsOnMap")) then CoordFrames("start") else CoordFrames("stop") end end - info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsOnMap"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_LOCATION_MENU_UPDATE_WORLD_MAP"]; - info.func = function() - TitanToggleVar(TITAN_LOCATION_ID, "UpdateWorldmap"); - end - info.checked = TitanGetVar(TITAN_LOCATION_ID, "UpdateWorldmap"); - info.disabled = InCombatLockdown() - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - if TITAN_ID == "Titan" then - info = {}; - info.notCheckable = true - info.text = L["TITAN_LOCATION_MENU_TEXT"]; - info.value = "CoordsLoc" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - else - -- no work needed - end - end - - -- level 3 - elseif TitanPanelRightClickMenu_GetDropdownLevel() == 3 then - if TitanPanelRightClickMenu_GetDropdMenuValue() == "CoordsLoc" then - info = {}; - info.text = L["TITAN_PANEL_MENU_BOTTOM"]; - info.func = function() - TitanSetVar(TITAN_LOCATION_ID, "CoordsLoc", "Bottom"); - -- TitanPanelButton_UpdateButton(TITAN_LOCATION_ID); + ) + + if TITAN_ID == "Titan" then +-- local opts_map_loc = Titan_Menu.AddButton(opts_map, L["TITAN_LOCATION_MENU_TEXT"]) + do -- next level options + local disp = { -- selectors using the same option + {L["TITAN_PANEL_MENU_BOTTOM"], "Bottom"}, + {L["TITAN_PANEL_MENU_TOP"], "Top"}, + } + Titan_Menu.AddSelectorList(opts_map, id, nil, "ViewAll", disp) end - info.checked = (TitanGetVar(TITAN_LOCATION_ID, "CoordsLoc") == "Bottom") - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_PANEL_MENU_TOP"]; - info.func = function() - TitanSetVar(TITAN_LOCATION_ID, "CoordsLoc", "Top"); - -- TitanPanelButton_UpdateButton(TITAN_LOCATION_ID); - end - info.checked = (TitanGetVar(TITAN_LOCATION_ID, "CoordsLoc") == "Top") - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); + else + -- Classic style map, no work needed end end end @@ -779,7 +660,7 @@ local function OnLoad(self) category = "Built-ins", version = TITAN_LOCATION_VERSION, menuText = L["TITAN_LOCATION_MENU_TEXT"], - menuTextFunction = CreateMenu, + menuContextFunction = GeneratorFunction, -- NEW scheme buttonTextFunction = GetButtonText, tooltipTitle = L["TITAN_LOCATION_TOOLTIP"], tooltipTextFunction = GetTooltipText, diff --git a/TitanLocation/TitanLocation.toc b/TitanLocation/TitanLocation.toc index 567e76a..23e076a 100644 --- a/TitanLocation/TitanLocation.toc +++ b/TitanLocation/TitanLocation.toc @@ -1,6 +1,6 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55fLocation|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fLocation|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## IconTexture: Interface\AddOns\TitanLocation\TitanLocation ## Notes: Adds coordinates and location information to Titan Panel ## Author: Titan Panel Development Team diff --git a/TitanLootType/TitanLootType.lua b/TitanLootType/TitanLootType.lua index 111ca85..188c639 100644 --- a/TitanLootType/TitanLootType.lua +++ b/TitanLootType/TitanLootType.lua @@ -70,48 +70,6 @@ end -- DESC : Registers the plugin upon it loading -- ************************************************************************** --]] -function TitanPanelLootTypeButton_OnLoad(self) - local notes = "" - .."Adds group loot information to Titan Panel.\n" - .."- Option to add instance difficulty information.\n" - .."- Option to add current spec and loot spec.\n" - self.registry = { - id = TITAN_LOOTTYPE_ID, - category = "Built-ins", - version = TITAN_VERSION, - menuText = L["TITAN_LOOTTYPE_MENU_TEXT"], - buttonTextFunction = "TitanPanelLootTypeButton_GetButtonText", - tooltipTitle = L["TITAN_LOOTTYPE_TOOLTIP"], - tooltipTextFunction = "TitanPanelLootTypeButton_GetTooltipText", - icon = "Interface\\AddOns\\TitanLootType\\TitanLootType", - iconWidth = 16, - notes = notes, - controlVariables = { - ShowIcon = true, - ShowLabelText = true, - ShowColoredText = false, - DisplayOnRightSide = true, - }, - savedVariables = { - ShowIcon = 1, - ShowLabelText = 1, - RandomRoll = 100, - DisplayOnRightSide = false, - ShowDungeonDiff = false, - DungeonDiffType = "AUTO", - ShowLootType = true, - ShowLootSpec = true, - } - }; - - self:RegisterEvent("GROUP_ROSTER_UPDATE"); - self:RegisterEvent("RAID_ROSTER_UPDATE"); - self:RegisterEvent("PARTY_LOOT_METHOD_CHANGED"); - self:RegisterEvent("CHAT_MSG_SYSTEM"); - - self:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") - self:RegisterEvent("PLAYER_LOOT_SPEC_UPDATED") -end function TitanPanelLootTypeButton_GetDungeonDifficultyIDText(isRaid, withpar) local par1, par2 = "", "" @@ -151,6 +109,37 @@ function TitanPanelLootTypeButton_GetDungeonDifficultyIDText(isRaid, withpar) return diffstr end +local function GetDifficultyText(isRaid, withpar) + local par1, par2 = "", "" + if withpar then par1, par2 = "(", ")" end + local diffstr = "|cffffff9a"..par1.._G["UNKNOWN"]..par2.."|r" + local diff = nil + if isRaid then + -- raids + diff = GetRaidDifficultyID() + else + -- dungeons + diff = GetDungeonDifficultyID() + end + if diff == nil then + -- pass back default so user has something + else + local name, groupType, isHeroic, isChallengeMode, displayHeroic, displayMythic, toggleDifficultyID = GetDifficultyInfo(diff) + -- remove () chars from difficulty + local tmpstr = string.gsub(name, "%(", "") + tmpstr = string.gsub(tmpstr, "%)", "") + if displayMythic then + diffstr = _G["RED_FONT_COLOR_CODE"]..par1..tmpstr..par2.."|r" + elseif displayHeroic then + diffstr = _G["ORANGE_FONT_COLOR_CODE"]..par1..tmpstr..par2.."|r" + else -- normal + diffstr = _G["GREEN_FONT_COLOR_CODE"]..par1..tmpstr..par2.."|r" + end + end + + return diffstr +end + --[[ -- ************************************************************************** -- NAME : TitanPanelLootTypeButton_OnEvent() @@ -158,6 +147,9 @@ end -- ************************************************************************** --]] function TitanPanelLootTypeButton_OnEvent(self, event, ...) + --[[ 2026 Jan : Midnight secret values now throws errors + -- Comment out and let Loot update the button on any chat msg for now... + -- It was updating anyway - not sure what the difficulty check added... local arg1 = ...; if event == "CHAT_MSG_SYSTEM" then -- Match difficulty system message to alert addon for possible update @@ -191,6 +183,7 @@ function TitanPanelLootTypeButton_OnEvent(self, event, ...) end return; end + --]] TitanPanelPluginHandle_OnUpdate(updateTable) end @@ -216,14 +209,17 @@ function TitanPanelLootTypeButton_GetButtonText(id) if TitanGetVar(TITAN_LOOTTYPE_ID, "ShowDungeonDiff") then if TitanGetVar(TITAN_LOOTTYPE_ID, "DungeonDiffType") == "DUNGEON" then -- Dungeon - dungeondiff = dungeondiff.." "..TitanPanelLootTypeButton_GetDungeonDifficultyIDText(false, true) + dungeondiff = dungeondiff.." "..GetDifficultyText(false, true) elseif TitanGetVar(TITAN_LOOTTYPE_ID, "DungeonDiffType") == "RAID" then -- Raid - dungeondiff = dungeondiff.." "..TitanPanelLootTypeButton_GetDungeonDifficultyIDText(true, true) + dungeondiff = dungeondiff.." "..GetDifficultyText(true, true) elseif TitanGetVar(TITAN_LOOTTYPE_ID, "DungeonDiffType") == "AUTO" then -- Auto - if UnitExists("party1") and (GetNumGroupMembers() == 0 or GetNumGroupMembers() < 0) then dungeondiff = dungeondiff.." "..TitanPanelLootTypeButton_GetDungeonDifficultyIDText(false, true) end - if GetNumGroupMembers() > 0 then dungeondiff = dungeondiff.." "..TitanPanelLootTypeButton_GetDungeonDifficultyIDText(true, true) end + if UnitExists("party1") and (GetNumGroupMembers() == 0 or GetNumGroupMembers() < 0) then + dungeondiff = dungeondiff.." "..GetDifficultyText(false, true) + + end + if GetNumGroupMembers() > 0 then dungeondiff = dungeondiff.." "..GetDifficultyText(true, true) end end end @@ -307,8 +303,8 @@ function TitanPanelLootTypeButton_GetTooltipText() party = TitanUtils_GetNormalText(_G["ERR_NOT_IN_GROUP"]).."\n" end local tt = "".. - L["TITAN_LOOTTYPE_DUNGEONDIFF_LABEL"]..": \t"..TitanPanelLootTypeButton_GetDungeonDifficultyIDText().."\n".. - L["TITAN_LOOTTYPE_DUNGEONDIFF_LABEL2"]..": \t"..TitanPanelLootTypeButton_GetDungeonDifficultyIDText(true).."\n".. + L["TITAN_LOOTTYPE_DUNGEONDIFF_LABEL"]..": \t"..GetDifficultyText().."\n".. + L["TITAN_LOOTTYPE_DUNGEONDIFF_LABEL2"]..": \t"..GetDifficultyText(true).."\n".. (SPECIALIZATION or "Spec")..": \t"..current_spec.."\n".. (SELECT_LOOT_SPECIALIZATION or "Loot Spec")..": \t"..loot_spec_name.."\n".. party.. @@ -546,50 +542,6 @@ function TitanPanelRightClickMenu_PrepareLootTypeMenu() else TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_LOOTTYPE_ID].menuText); - info = {}; - info.notCheckable = true - info.text = L["TITAN_LOOTTYPE_SHOWDUNGEONDIFF_LABEL"] - info.value = "ShowDungeonDiffMenu" - info.func = function() TitanPanelRightClickMenu_ToggleVar({TITAN_LOOTTYPE_ID, "ShowDungeonDiff"}) end - info.checked = TitanGetVar(TITAN_LOOTTYPE_ID, "ShowDungeonDiff"); - info.keepShownOnClick = 1; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {} - info.notCheckable = true - info.text = L["TITAN_LOOTTYPE_SETDUNGEONDIFF_LABEL"]; - info.value = "SetDungeonDiff"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {} - info.notCheckable = true - info.text = L["TITAN_LOOTTYPE_SETRAIDDIFF_LABEL"]; - info.value = "SetRaidDiff"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSpacer(); - info = {}; - info.text = SHOW.." "..(LOOT_METHOD or "Loot Type") - info.func = function() TitanPanelRightClickMenu_ToggleVar({TITAN_LOOTTYPE_ID, "ShowLootType"}) end - info.checked = TitanGetVar(TITAN_LOOTTYPE_ID, "ShowLootType") - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = SHOW.." "..(SPECIALIZATION or "Spec") - info.func = function() TitanPanelRightClickMenu_ToggleVar({TITAN_LOOTTYPE_ID, "ShowLootSpec"}) end - info.checked = TitanGetVar(TITAN_LOOTTYPE_ID, "ShowLootSpec") - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSpacer(); - info = {}; - info.notCheckable = true - info.text = L["TITAN_LOOTTYPE_RANDOM_ROLL_LABEL"]; - info.value = "RandomRoll"; - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); TitanPanelRightClickMenu_AddControlVars(TITAN_LOOTTYPE_ID) end @@ -607,6 +559,57 @@ function TitanPanelLootTypeButton_OnClick(self, button) end end +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_LOOTTYPE_ID + local root = rootDescription -- menu widget to start with + + Titan_Menu.AddSelector(root, id, SHOW.." "..(LOOT_METHOD or "Loot Type"), "ShowLootType") + Titan_Menu.AddSelector(root, id, SHOW.." "..(SPECIALIZATION or "Spec"), "ShowLootSpec") +end + +function TitanPanelLootTypeButton_OnLoad(self) + local notes = "" + .."Adds group loot information to Titan Panel.\n" + .."- Option to add instance difficulty information.\n" + .."- Option to add current spec and loot spec.\n" + self.registry = { + id = TITAN_LOOTTYPE_ID, + category = "Built-ins", + version = TITAN_VERSION, + menuText = L["TITAN_LOOTTYPE_MENU_TEXT"], + menuContextFunction = GeneratorFunction, -- NEW scheme + buttonTextFunction = "TitanPanelLootTypeButton_GetButtonText", + tooltipTitle = L["TITAN_LOOTTYPE_TOOLTIP"], + tooltipTextFunction = "TitanPanelLootTypeButton_GetTooltipText", + icon = "Interface\\AddOns\\TitanLootType\\TitanLootType", + iconWidth = 16, + notes = notes, + controlVariables = { + ShowIcon = true, + ShowLabelText = true, + ShowColoredText = false, + DisplayOnRightSide = true, + }, + savedVariables = { + ShowIcon = 1, + ShowLabelText = 1, + RandomRoll = 100, + DisplayOnRightSide = false, + ShowDungeonDiff = false, + DungeonDiffType = "AUTO", + ShowLootType = true, + ShowLootSpec = true, + } + }; + + self:RegisterEvent("GROUP_ROSTER_UPDATE"); + self:RegisterEvent("RAID_ROSTER_UPDATE"); + self:RegisterEvent("PARTY_LOOT_METHOD_CHANGED"); + self:RegisterEvent("CHAT_MSG_SYSTEM"); + + self:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") + self:RegisterEvent("PLAYER_LOOT_SPEC_UPDATED") +end -- ====== Create needed frames local function Create_Frames() diff --git a/TitanLootType/TitanLootType.toc b/TitanLootType/TitanLootType.toc index 0a45220..1c2e23d 100644 --- a/TitanLootType/TitanLootType.toc +++ b/TitanLootType/TitanLootType.toc @@ -1,6 +1,6 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55fLootType|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fLootType|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## IconTexture: Interface\AddOns\TitanLootType\TitanLootType ## Notes: Adds group loot and instance difficulty information to Titan Panel ## Author: Titan Panel Development Team diff --git a/TitanLootType/TitanLootType_Classic.toc b/TitanLootType/TitanLootType_Classic.toc index 8b61f5b..d8299c0 100644 --- a/TitanLootType/TitanLootType_Classic.toc +++ b/TitanLootType/TitanLootType_Classic.toc @@ -1,6 +1,6 @@ ## Interface: 20505, 11508, 50503 -## Title: Titan Panel [|cffeda55fLootType|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Title: Titan Panel [|cffeda55fLootType|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## Notes: Adds group loot and instance difficulty information to Titan Panel ## Author: Titan Panel Development Team ## SavedVariables: TitanClassicLootTypeSaved diff --git a/TitanPerformance/TitanPerformance.lua b/TitanPerformance/TitanPerformance.lua index 4ad3841..7762ca0 100644 --- a/TitanPerformance/TitanPerformance.lua +++ b/TitanPerformance/TitanPerformance.lua @@ -51,25 +51,23 @@ local PerfTimerRunning = false local perf_stats = {} -- ******************************** Functions ******************************* ----local Use user selected with required min of 1 ----@param val number ----@return number -local function CalcAppNum(val) - local new_val = 1 -- always monitor at least one - - if val == nil or val < APP_MIN then - -- keep the default min +---Add another line to the passed in string; handle two columns if right is given +---@param line string +---@param left string +---@param right? string +---@return string +local function Add_line(line, left, right) + local new_line = "" + if right then + new_line = left.."\t"..right.."\n" else - -- return a value adjusted for the min - new_val = (APP_MAX + APP_MIN) - TitanUtils_Round(val) + new_line = left.."\n" end - return new_val + + return line..new_line end ----local Execute garbage collection for Leftclick on plugin ----@param self Button ----@param watchingCPU boolean -local function Stats_UpdateAddonsList(self, watchingCPU) +local function Update_Addons(self, watchingCPU, tip_str) if (watchingCPU) then UpdateAddOnCPUUsage() else @@ -99,28 +97,31 @@ local function Stats_UpdateAddonsList(self, watchingCPU) end end - GameTooltip:AddLine(' ') + tip_str = Add_line(tip_str, "") if (total > 0) then if (watchingCPU) then - GameTooltip:AddLine(TitanUtils_GetHexText(L["TITAN_PERFORMANCE_ADDON_CPU_USAGE_LABEL"], Titan_Global.colors.white)) + tip_str = Add_line(tip_str, TitanUtils_GetHexText(L["TITAN_PERFORMANCE_ADDON_CPU_USAGE_LABEL"], + Titan_Global.colors.white)) else - GameTooltip:AddLine(TitanUtils_GetHexText(L["TITAN_PERFORMANCE_ADDON_MEM_USAGE_LABEL"], Titan_Global.colors.white)) + tip_str = Add_line(tip_str, TitanUtils_GetHexText(L["TITAN_PERFORMANCE_ADDON_MEM_USAGE_LABEL"], + Titan_Global.colors.white)) end if not watchingCPU then if (showAddonRate == 1) then - GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_NAME_LABEL"], + tip_str = Add_line(tip_str, LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_NAME_LABEL"], LIGHTYELLOW_FONT_COLOR_CODE .. - L["TITAN_PERFORMANCE_ADDON_USAGE_LABEL"] .. "/" .. L["TITAN_PERFORMANCE_ADDON_RATE_LABEL"] .. ":") + L["TITAN_PERFORMANCE_ADDON_USAGE_LABEL"] .. + "/" .. L["TITAN_PERFORMANCE_ADDON_RATE_LABEL"] .. ":") else - GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_NAME_LABEL"], + tip_str = Add_line(tip_str, LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_NAME_LABEL"], LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_USAGE_LABEL"] .. ":") end end if watchingCPU then - GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_NAME_LABEL"], + tip_str = Add_line(tip_str, LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_NAME_LABEL"], LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_USAGE_LABEL"] .. ":") end @@ -131,15 +132,15 @@ local function Stats_UpdateAddonsList(self, watchingCPU) local incrate = ""; incrate = format("(%.2f%%)", diff); if (showAddonRate == 1) then - local str = TitanUtils_GetHexText(format("%.3f", addon.value) + local str = TitanUtils_GetHexText(format("%.3f", addon.value) .. L["TITAN_PANEL_MILLISECOND"], Titan_Global.colors.white) - .." " - ..TitanUtils_GetHexText(incrate, Titan_Global.colors.green) - GameTooltip:AddDoubleLine(wow_addon, str) + .. " " + .. TitanUtils_GetHexText(incrate, Titan_Global.colors.green) + tip_str = Add_line(tip_str, wow_addon,str) else - local str = TitanUtils_GetHexText(format("%.3f", addon.value) + local str = TitanUtils_GetHexText(format("%.3f", addon.value) .. L["TITAN_PANEL_MILLISECOND"], Titan_Global.colors.white) - GameTooltip:AddDoubleLine(wow_addon, str); + tip_str = Add_line(tip_str, wow_addon,str) end else local diff = addon.value - (memUsageSinceGC[addon.name]) @@ -181,49 +182,46 @@ local function Stats_UpdateAddonsList(self, watchingCPU) end end end - GameTooltip:AddDoubleLine(wow_addon, - TitanUtils_GetHexText(format(fmt, addon.value / div), Titan_Global.colors.white)..rate) + tip_str = Add_line(tip_str, wow_addon, + TitanUtils_GetHexText(format(fmt, addon.value / div), Titan_Global.colors.white) .. rate ) end end - GameTooltip:AddLine(' ') + tip_str = tip_str .. "\n" if (watchingCPU) then - GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_TOTAL_CPU_USAGE_LABEL"], - format("%.3f", total) .. L["TITAN_PANEL_MILLISECOND"]) + tip_str = Add_line(tip_str, LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_TOTAL_CPU_USAGE_LABEL"], + format("%.3f", total) .. L["TITAN_PANEL_MILLISECOND"] ) else if TitanGetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType") == 1 then - GameTooltip:AddDoubleLine( - LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_TOTAL_MEM_USAGE_LABEL"], + tip_str = Add_line(tip_str, + LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_TOTAL_MEM_USAGE_LABEL"], format(L["TITAN_PANEL_PERFORMANCE_MEMORY_FORMAT"], total / 1000)) else if total > 1000 then - GameTooltip:AddDoubleLine( - LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_TOTAL_MEM_USAGE_LABEL"], + tip_str = Add_line(tip_str, + LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_TOTAL_MEM_USAGE_LABEL"], format(L["TITAN_PANEL_PERFORMANCE_MEMORY_FORMAT"], total / 1000)) else - GameTooltip:AddDoubleLine( - LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_TOTAL_MEM_USAGE_LABEL"], - format(L["TITAN_PANEL_PERFORMANCE_MEMORY_FORMAT_KB"], total)) + tip_str = Add_line(tip_str, + LIGHTYELLOW_FONT_COLOR_CODE .. L["TITAN_PERFORMANCE_ADDON_TOTAL_MEM_USAGE_LABEL"], + format(L["TITAN_PANEL_PERFORMANCE_MEMORY_FORMAT_KB"], total) ) end end end end + + return tip_str end ----local Generate tootip text ----@param self Button -local function SetTooltip(self) - local button = _G["TitanPanelPerformanceButton"]; +local function GetTooltipText() local showFPS = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowFPS"); local showLatency = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowLatency"); local showWorldLatency = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowWorldLatency") local showMemory = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowMemory"); local showAddonMemory = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowAddonMemory"); - -- Tooltip title - GameTooltip:SetText(L["TITAN_PERFORMANCE_TOOLTIP"], HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, - HIGHLIGHT_FONT_COLOR.b); + local tool_tip = "" -- FPS tooltip if (showFPS) then local fpsText = format(L["TITAN_PANEL_PERFORMANCE_FPS_FORMAT"], perf_stats.fps); @@ -231,16 +229,16 @@ local function SetTooltip(self) local minFPSText = format(L["TITAN_PANEL_PERFORMANCE_FPS_FORMAT"], perf_stats.minFPS); local maxFPSText = format(L["TITAN_PANEL_PERFORMANCE_FPS_FORMAT"], perf_stats.maxFPS); - GameTooltip:AddLine("\n"); - GameTooltip:AddLine(TitanUtils_GetHighlightText(L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP"])); - GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP_CURRENT_FPS"], - TitanUtils_GetHighlightText(fpsText)); - GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP_AVG_FPS"], - TitanUtils_GetHighlightText(avgFPSText)); - GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP_MIN_FPS"], - TitanUtils_GetHighlightText(minFPSText)); - GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP_MAX_FPS"], - TitanUtils_GetHighlightText(maxFPSText)); + tool_tip = Add_line(tool_tip, "") + tool_tip = Add_line(tool_tip, TitanUtils_GetHighlightText(L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP"])) + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP_CURRENT_FPS"], + TitanUtils_GetHighlightText(fpsText)) + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP_AVG_FPS"], + TitanUtils_GetHighlightText(avgFPSText)) + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP_MIN_FPS"], + TitanUtils_GetHighlightText(minFPSText)) + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_FPS_TOOLTIP_MAX_FPS"], + TitanUtils_GetHighlightText(maxFPSText)) end -- Latency tooltip @@ -250,16 +248,20 @@ local function SetTooltip(self) local bandwidthInText = format(L["TITAN_PANEL_PERFORMANCE_LATENCY_BANDWIDTH_FORMAT"], perf_stats.bandwidthIn); local bandwidthOutText = format(L["TITAN_PANEL_PERFORMANCE_LATENCY_BANDWIDTH_FORMAT"], perf_stats.bandwidthOut); - GameTooltip:AddLine("\n"); - GameTooltip:AddLine(TitanUtils_GetHighlightText(L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP"])); - if showLatency then GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP_LATENCY_HOME"], - TitanUtils_GetHighlightText(latencyText)); end - if showWorldLatency then GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP_LATENCY_WORLD"], - TitanUtils_GetHighlightText(latencyWorldText)); end - GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP_BANDWIDTH_IN"], - TitanUtils_GetHighlightText(bandwidthInText)); - GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP_BANDWIDTH_OUT"], - TitanUtils_GetHighlightText(bandwidthOutText)); + tool_tip = Add_line(tool_tip, "") + tool_tip = Add_line(tool_tip, TitanUtils_GetHighlightText(L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP"])) + if showLatency then + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP_LATENCY_HOME"], + TitanUtils_GetHighlightText(latencyText)) + end + if showWorldLatency then + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP_LATENCY_WORLD"], + TitanUtils_GetHighlightText(latencyWorldText)) + end + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP_BANDWIDTH_IN"], + TitanUtils_GetHighlightText(bandwidthInText)) + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_LATENCY_TOOLTIP_BANDWIDTH_OUT"], + TitanUtils_GetHighlightText(bandwidthOutText)) end -- Memory tooltip @@ -267,36 +269,42 @@ local function SetTooltip(self) local memoryText = format(L["TITAN_PANEL_PERFORMANCE_MEMORY_FORMAT"], perf_stats.memory / 1024); local initialMemoryText = format(L["TITAN_PANEL_PERFORMANCE_MEMORY_FORMAT"], perf_stats.initialMemory / 1024); local sessionTime = time() - perf_stats.startSessionTime; - local rateRichText, timeToGCRichText, rate, timeToGC, color; + local rateRichText, rate, color if (sessionTime == 0) then rateRichText = TitanUtils_GetHighlightText("N/A"); else rate = (perf_stats.memory - perf_stats.initialMemory) / sessionTime; - color = TitanUtils_GetThresholdColor(TITAN_MEMORY_RATE_THRESHOLD_TABLE, rate); + color = TitanUtils_GetThresholdColor(TITAN_MEMORY_RATE_THRESHOLD_TABLE, rate) rateRichText = TitanUtils_GetColoredText(format(L["TITAN_PANEL_PERFORMANCE_MEMORY_RATE_FORMAT"], rate), color) end - if (perf_stats.memory == perf_stats.initialMemory) then - timeToGCRichText = TitanUtils_GetHighlightText("N/A"); - end + --if (perf_stats.memory == perf_stats.initialMemory) then + -- timeToGCRichText = TitanUtils_GetHighlightText("N/A"); + --end - GameTooltip:AddLine("\n"); - GameTooltip:AddLine(TitanUtils_GetHighlightText(L["TITAN_PANEL_PERFORMANCE_MEMORY_TOOLTIP"])); - GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_MEMORY_TOOLTIP_CURRENT_MEMORY"], - TitanUtils_GetHighlightText(memoryText)); - GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_MEMORY_TOOLTIP_INITIAL_MEMORY"], - TitanUtils_GetHighlightText(initialMemoryText)); - GameTooltip:AddDoubleLine(L["TITAN_PANEL_PERFORMANCE_MEMORY_TOOLTIP_INCREASING_RATE"], rateRichText); + tool_tip = Add_line(tool_tip, "") + tool_tip = Add_line(tool_tip, TitanUtils_GetHighlightText(L["TITAN_PANEL_PERFORMANCE_MEMORY_TOOLTIP"])) + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_MEMORY_TOOLTIP_CURRENT_MEMORY"], + TitanUtils_GetHighlightText(memoryText)) + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_MEMORY_TOOLTIP_INITIAL_MEMORY"], + TitanUtils_GetHighlightText(initialMemoryText)) + tool_tip = Add_line(tool_tip, L["TITAN_PANEL_PERFORMANCE_MEMORY_TOOLTIP_INCREASING_RATE"], + rateRichText) end - if (showAddonMemory == 1) then + if (showAddonMemory == true or showAddonMemory == 1) then for _, i in pairs(topAddOns) do i.name = ''; i.value = 0; end - Stats_UpdateAddonsList(_G[TITAN_BUTTON], GetCVar('scriptProfile') == '1' and not IsModifierKeyDown()) + tool_tip = Update_Addons(_G[TITAN_BUTTON], + GetCVar('scriptProfile') == '1' and not IsModifierKeyDown(), + tool_tip) end - GameTooltip:AddLine(TitanUtils_GetGreenText(L["TITAN_PERFORMANCE_TOOLTIP_HINT"])); + tool_tip = Add_line(tool_tip, "") + tool_tip = Add_line(tool_tip, TitanUtils_GetGreenText(L["TITAN_PERFORMANCE_TOOLTIP_HINT"])) + + return tool_tip end ---local Update real-time data, placing it on the plugin frame @@ -323,7 +331,7 @@ local function UpdateData() perf_stats.maxFPS = perf_stats.fps; end perf_stats.avgFPS = (perf_stats.avgFPS * (perf_stats.fpsSampleCount - 1) + perf_stats.fps) / - perf_stats.fpsSampleCount; + perf_stats.fpsSampleCount; end end @@ -460,189 +468,6 @@ local function GetButtonText(id) end end ----local Display Right click menu options -local function CreateMenu() - local info - - --[[ -print("TPref" -.." "..tostring(TitanPanelRightClickMenu_GetDropdownLevel()).."" -.." "..tostring(TitanPanelRightClickMenu_GetDropdMenuValue()).."" -) ---]] - -- level 3 - if TitanPanelRightClickMenu_GetDropdownLevel() == 3 and TitanPanelRightClickMenu_GetDropdMenuValue() == "AddonControlFrame" then - TitanPanelPerfControlFrame:Show() - return - end - - -- level 2 - if TitanPanelRightClickMenu_GetDropdownLevel() == 2 then - if TitanPanelRightClickMenu_GetDropdMenuValue() == "Options" then - TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_OPTIONS"], TitanPanelRightClickMenu_GetDropdownLevel()); - - local temptable = { TITAN_PERFORMANCE_ID, "ShowFPS" }; - info = {}; - info.text = L["TITAN_PERFORMANCE_MENU_SHOW_FPS"]; - info.value = temptable; - info.func = function() - TitanPanelRightClickMenu_ToggleVar(temptable) - end - info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowFPS"); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - local temptable = { TITAN_PERFORMANCE_ID, "ShowLatency" }; - info = {}; - info.text = L["TITAN_PERFORMANCE_MENU_SHOW_LATENCY"]; - info.value = temptable; - info.func = function() - TitanPanelRightClickMenu_ToggleVar(temptable) - end - info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowLatency"); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - local temptable = { TITAN_PERFORMANCE_ID, "ShowWorldLatency" }; - info = {}; - info.text = L["TITAN_PERFORMANCE_MENU_SHOW_LATENCY_WORLD"]; - info.value = temptable; - info.func = function() - TitanPanelRightClickMenu_ToggleVar(temptable) - end - info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowWorldLatency"); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - local temptable = { TITAN_PERFORMANCE_ID, "ShowMemory" }; - info = {}; - info.text = L["TITAN_PERFORMANCE_MENU_SHOW_MEMORY"]; - info.value = temptable; - info.func = function() - TitanPanelRightClickMenu_ToggleVar(temptable) - end - info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowMemory"); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end - - if TitanPanelRightClickMenu_GetDropdMenuValue() == "AddonUsage" then - TitanPanelRightClickMenu_AddTitle(L["TITAN_PERFORMANCE_ADDONS"], TitanPanelRightClickMenu_GetDropdownLevel()); - - local temptable = { TITAN_PERFORMANCE_ID, "ShowAddonMemory" }; - info = {}; - info.text = L["TITAN_PERFORMANCE_MENU_SHOW_ADDONS"]; - info.value = temptable; - info.func = function() - TitanPanelRightClickMenu_ToggleVar(temptable) - end - info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowAddonMemory"); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - local temptable = { TITAN_PERFORMANCE_ID, "ShowAddonIncRate" }; - info = {}; - info.text = L["TITAN_PERFORMANCE_MENU_SHOW_ADDON_RATE"]; - info.value = temptable; - info.func = function() - TitanPanelRightClickMenu_ToggleVar(temptable) - end - info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowAddonIncRate"); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PERFORMANCE_CONTROL_TOOLTIP"] - .. LIGHTYELLOW_FONT_COLOR_CODE .. tostring(TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons")); - info.value = "AddonControlFrame" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end - - if TitanPanelRightClickMenu_GetDropdMenuValue() == "AddonMemoryFormat" then - TitanPanelRightClickMenu_AddTitle(L["TITAN_PERFORMANCE_ADDON_MEM_FORMAT_LABEL"], - TitanPanelRightClickMenu_GetDropdownLevel()); - info = {}; - info.text = L["TITAN_PANEL_MEGABYTE"]; - info.checked = function() - if TitanGetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType") == 1 then return true else return nil end - end - info.func = function() TitanSetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType", 1) end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - info = {}; - info.text = L["TITAN_PANEL_PERFORMANCE_MEMORY_KBMB_LABEL"]; - info.checked = function() - if TitanGetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType") == 2 then return true else return nil end - end - info.func = function() TitanSetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType", 2) end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end - - if TitanPanelRightClickMenu_GetDropdMenuValue() == "CPUProfiling" then - if (GetCVar("scriptProfile") == "1") then - TitanPanelRightClickMenu_AddTitle( - L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL"] .. ": " .. GREEN_FONT_COLOR_CODE .. - L["TITAN_PANEL_MENU_ENABLED"], TitanPanelRightClickMenu_GetDropdownLevel()); - info = {}; - info.text = L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL_OFF"] .. - GREEN_FONT_COLOR_CODE .. L["TITAN_PANEL_MENU_RELOADUI"]; - info.func = function() - SetCVar("scriptProfile", "0") - ReloadUI() - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - else - TitanPanelRightClickMenu_AddTitle( - L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL"] .. ": " .. RED_FONT_COLOR_CODE .. - L["TITAN_PANEL_MENU_DISABLED"], TitanPanelRightClickMenu_GetDropdownLevel()); - info = {}; - info.text = L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL_ON"] .. - GREEN_FONT_COLOR_CODE .. L["TITAN_PANEL_MENU_RELOADUI"]; - info.func = function() - SetCVar("scriptProfile", "1") - ReloadUI() - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end - end - return - end - - -- level 1 - TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_PERFORMANCE_ID].menuText); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_OPTIONS"]; - info.value = "Options" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PERFORMANCE_ADDONS"]; - info.value = "AddonUsage" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PERFORMANCE_ADDON_MEM_FORMAT_LABEL"]; - info.value = "AddonMemoryFormat" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL"]; - info.value = "CPUProfiling" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddControlVars(TITAN_PERFORMANCE_ID) -end - local function Init() topAddOns = {} -- scan how many addons are active @@ -670,6 +495,72 @@ local function Init() end end +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_PERFORMANCE_ID + local root = rootDescription -- menu widget to start with + + local opts_perf = Titan_Menu.AddButton(root, L["TITAN_PANEL_OPTIONS"]) + do -- next level options + Titan_Menu.AddSelector(opts_perf, id, L["TITAN_PERFORMANCE_MENU_SHOW_FPS"], "ShowFPS") + Titan_Menu.AddSelector(opts_perf, id, L["TITAN_PERFORMANCE_MENU_SHOW_LATENCY"], "ShowLatency") + Titan_Menu.AddSelector(opts_perf, id, L["TITAN_PERFORMANCE_MENU_SHOW_LATENCY_WORLD"], "ShowWorldLatency") + Titan_Menu.AddSelector(opts_perf, id, L["TITAN_PERFORMANCE_MENU_SHOW_MEMORY"], "ShowMemory") + Titan_Menu.AddSelector(opts_perf, id, L["TITAN_PERFORMANCE_MENU_SHOW_ADDONS"], "ShowAddonMemory") + Titan_Menu.AddSelector(opts_perf, id, L["TITAN_PERFORMANCE_MENU_SHOW_ADDON_RATE"], "ShowAddonIncRate") + end + + ---[[ + -- local opts_adds = Titan_Menu.AddButton(root, L["TITAN_PERFORMANCE_ADDONS"]) + local tt_label = L["TITAN_PERFORMANCE_CONTROL_TOOLTIP"] + .. LIGHTYELLOW_FONT_COLOR_CODE .. tostring(TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons")) + local opts_num_adds = Titan_Menu.AddButton(root, tt_label) + do -- next level options + local num_addons = { -- selectors using the same option + { "1", 1 }, + { "5", 5 }, + { "10", 10 }, + { "15", 15 }, + { "20", 20 }, + { "25", 25 }, + { "30", 30 }, + { "35", 35 }, + { "40", 40 }, + } + Titan_Menu.AddSelectorList(opts_num_adds, id, nil, "NumOfAddons", num_addons, Init) + --[[ The slider frame does appear but the menu goes away... + -- Using alt method to get this out :) + --]] + end + --]] + Titan_Menu.AddDivider(root) + + -- local opts_cpu = Titan_Menu.AddButton(root, L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL"]) + do -- next level options + local s_title = "" + if (GetCVar("scriptProfile") == "1") then + s_title = L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL"] .. ": " + .. TitanUtils_GetGreenText(L["TITAN_PANEL_MENU_ENABLED"]) + .. " " .. L["TITAN_PANEL_MENU_RELOADUI"] + Titan_Menu.AddCommand(root, id, s_title, + function() + SetCVar("scriptProfile", "0") + ReloadUI() + end + ) + else + s_title = L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL"] .. ": " + .. TitanUtils_GetRedText(L["TITAN_PANEL_MENU_DISABLED"]) + .. " " .. L["TITAN_PANEL_MENU_RELOADUI"] + Titan_Menu.AddCommand(root, id, s_title, + function() + SetCVar("scriptProfile", "1") + ReloadUI() + end + ) + end + end +end + ---local Create plugin .registry and and init some variables and register for first events ---@param self Button local function OnLoad(self) @@ -681,9 +572,10 @@ local function OnLoad(self) category = "Built-ins", version = TITAN_VERSION, menuText = L["TITAN_PERFORMANCE_MENU_TEXT"], - menuTextFunction = CreateMenu, + menuContextFunction = GeneratorFunction, -- NEW scheme buttonTextFunction = GetButtonText, - tooltipCustomFunction = SetTooltip, + tooltipTitle = L["TITAN_PERFORMANCE_TOOLTIP"], + tooltipTextFunction = GetTooltipText, icon = "Interface\\AddOns\\TitanPerformance\\TitanPerformance", iconWidth = 16, notes = notes, @@ -722,9 +614,6 @@ end ---local Update button data local function TitanPanelPerformanceButtonHandle_OnUpdate() TitanPanelPluginHandle_OnUpdate(updateTable); - if not (TitanPanelRightClickMenu_IsVisible()) and _G["TitanPanelPerfControlFrame"]:IsVisible() and not (MouseIsOver(_G["TitanPanelPerfControlFrame"])) then - _G["TitanPanelPerfControlFrame"]:Hide(); - end end ---local Show the plugin and start timers @@ -756,131 +645,6 @@ local function OnClick(self, button) end end ----local Position tooltip over slider control ----@param self Button -local function Slider_OnEnter(self) - self.tooltipText = TitanOptionSlider_TooltipText(L["TITAN_PERFORMANCE_CONTROL_TOOLTIP"], - TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons")); - GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT"); - GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, 1); -end - ----local Hide tooltip after leaving slider ----@param self Button -local function Slider_OnLeave(self) - self.tooltipText = nil; - GameTooltip:Hide(); -end - ----local Generate tooltip over slider control ----@param self Slider plugin slider frame -local function Slider_OnShow(self) - _G[self:GetName() .. "Text"]:SetText(TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons")); - _G[self:GetName() .. "High"]:SetText(L["TITAN_PERFORMANCE_CONTROL_LOW"]); - _G[self:GetName() .. "Low"]:SetText(L["TITAN_PERFORMANCE_CONTROL_HIGH"]); - self:SetMinMaxValues(APP_MIN, APP_MAX); - self:SetValueStep(1); - self:SetObeyStepOnDrag(true) -- since 5.4.2 (Mists of Pandaria) - self:SetValue(CalcAppNum(TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons"))); - - local lev = TitanPanelRightClickMenu_GetDropdownLevel() - 1 - local dds = TitanPanelRightClickMenu_GetDropdownFrameBase() .. tostring(lev) - local drop_down = _G[dds] - -- local scale = TitanPanelPerfControlFrame:GetScale() - TitanPanelPerfControlFrame:ClearAllPoints(); - TitanPanelPerfControlFrame:SetPoint("LEFT", drop_down, "RIGHT", 0, 0); - local offscreenX, offscreenY = TitanUtils_GetOffscreen(TitanPanelPerfControlFrame); - if offscreenX == -1 or offscreenX == 0 then - TitanPanelPerfControlFrame:ClearAllPoints(); - TitanPanelPerfControlFrame:SetPoint("LEFT", drop_down, "RIGHT", 0, 0); - else - TitanPanelPerfControlFrame:ClearAllPoints(); - TitanPanelPerfControlFrame:SetPoint("RIGHT", drop_down, "LEFT", 0, 0); - end - - --[[ - local top_point, top_rel_to, top_rel_point, top_x, top_y = - TitanPanelPerfControlFrame:GetPoint(TitanPanelPerfControlFrame:GetNumPoints()) -print("TPref" -.." "..tostring(drop_down:GetName()).."" -.." "..tostring(offscreenX).."" -.." "..tostring(offscreenY).."" -) -print("TPref" -.." "..tostring(top_point).."" -.." "..tostring(top_rel_to:GetName()).."" -.." "..tostring(top_rel_point).."" -.." "..tostring(top_x).."" -.." "..tostring(top_y).."" -) ---]] -end - ----local Display slider tooltip text ----@param self Slider plugin slider frame ----@param a1 number positive or negative change to apply -local function Slider_OnValueChanged(self, a1) - local val = CalcAppNum(self:GetValue()) -- grab new value - - _G[self:GetName() .. "Text"]:SetText(val); - --[[ - if a1 == -1 then - self:SetValue(self:GetValue() + 1); - end - - if a1 == 1 then - self:SetValue(self:GetValue() - 1); - end ---]] - TitanSetVar(TITAN_PERFORMANCE_ID, "NumOfAddons", val); - - topAddOns = {}; - -- scan how many addons are active - local count = NumAddons(); - local ActiveAddons = 0; - for i = 1, count do - if IsAddOnLoaded(i) then - ActiveAddons = ActiveAddons + 1; - end - end - - if ActiveAddons < TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons") then - counter = ActiveAddons; - else - counter = TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons"); - end - - --set the counter to the proper number of active addons that are being monitored - for idx = 1, counter do - topAddOns[idx] = { name = '', value = 0 } - end - - -- Update GameTooltip - if (perf_stats.tooltipText) then - perf_stats.tooltipText = TitanOptionSlider_TooltipText(L["TITAN_PERFORMANCE_CONTROL_TOOLTIP"], tostring(val)) - GameTooltip:SetText(perf_stats.tooltipText, nil, nil, nil, nil, 1); - end -end - ----local Create performance menu / control frame ----@param self Frame -local function Control_OnLoad(self) - _G[self:GetName() .. "Title"]:SetText(L["TITAN_PERFORMANCE_CONTROL_TITLE"]); - TitanPanelRightClickMenu_SetCustomBackdrop(self) -end - ----local If dropdown is visible, see if its timer has expired. If expired, hide frame. ----@param self Frame ----@param elapsed number -local function Control_OnUpdate(self, elapsed) - -- local drop_down = TitanPanelRightClickMenu_GetDropdownFrame() - - if not MouseIsOver(_G["TitanPanelPerfControlFrame"]) - then - TitanUtils_CheckFrameCounting(self, elapsed); - end -end - ---local Create needed frames local function Create_Frames() if _G[TITAN_BUTTON] then @@ -912,63 +676,6 @@ local function Create_Frames() OnClick(self, button) TitanPanelButton_OnClick(self, button) end) - - - ---[===[ - -- Config screen - local cname = "TitanPanelPerfControlFrame" - local config = CreateFrame("Frame", cname, f, BackdropTemplateMixin and "BackdropTemplate") - config:SetFrameStrata("FULLSCREEN") - config:Hide() - config:SetWidth(120) - config:SetHeight(170) - - config:SetScript("OnEnter", function(self) - TitanUtils_StopFrameCounting(self) - end) - config:SetScript("OnLeave", function(self) - TitanUtils_StartFrameCounting(self, 0.5) - end) - config:SetScript("OnUpdate", function(self, elapsed) - Control_OnUpdate(self, elapsed) - end) - - -- Config Title - local str = nil - local style = "GameFontNormalSmall" - str = config:CreateFontString(cname .. "Title", "ARTWORK", style) - str:SetPoint("TOP", config, 0, -10) - - -- Config slider sections - local slider = nil - - -- Hours offset - local inherit = "TitanOptionsSliderTemplate" - local offset = CreateFrame("Slider", "TitanPanelPerfControlSlider", config, inherit) - offset:SetPoint("TOP", config, 0, -40) - offset:SetScript("OnShow", function(self) - Slider_OnShow(self) - end) - offset:SetScript("OnValueChanged", function(self, value) - Slider_OnValueChanged(self, value) - end) - offset:SetScript("OnMouseWheel", function(self, delta) - Slider_OnValueChanged(self, delta) - end) - offset:SetScript("OnEnter", function(self) - Slider_OnEnter(self) - end) - offset:SetScript("OnLeave", function(self) - Slider_OnLeave(self) - end) - - -- Now that the parts exist, initialize - Control_OnLoad(config) - - --]===] end - -if TITAN_ID then -- it exists - Create_Frames() -- do the work -end +Create_Frames() -- do the work diff --git a/TitanPerformance/TitanPerformance.toc b/TitanPerformance/TitanPerformance.toc index 5fc1ba0..cefab9d 100644 --- a/TitanPerformance/TitanPerformance.toc +++ b/TitanPerformance/TitanPerformance.toc @@ -1,6 +1,6 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55fPerformance|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fPerformance|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## IconTexture: Interface\AddOns\TitanPerformance\TitanPerformance ## Notes: Adds FPS and Garbage collection information to Titan Panel ## Author: Titan Panel Development Team diff --git a/TitanPost/TitanPost.lua b/TitanPost/TitanPost.lua new file mode 100644 index 0000000..000103c --- /dev/null +++ b/TitanPost/TitanPost.lua @@ -0,0 +1,841 @@ +-- ************************************************************************** +-- * TitanPost.lua +-- * +-- * By: The Titan Panel Development Team +-- ************************************************************************** + +-- ******************************** Constants ******************************* +local _G = getfenv(0); +local TITAN_POST_ID = "Post"; +local TITAN_BUTTON = "TitanPanel" .. TITAN_POST_ID .. "Button" + +-- Constants +local FolderPre = "Interface\\AddOns\\TitanPost\\artwork\\" + +-- Local variables +local L = LibStub("AceLocale-3.0"):GetLocale("Titan", true) +local AceConfigDialog = LibStub("AceConfigDialog-3.0") +local AceTimer = LibStub("AceTimer-3.0") +local AceHook = LibStub("AceHook-3.0") + +local mailbox = {} -- default on load; store display info here +--mailbox.opened = false +mailbox.open_now = false +mailbox.new = 0 +mailbox.expiry_text = "" +mailbox.expiry_num = 0 +mailbox.ignore_next_pending = false + +local player = TitanUtils_GetPlayer() +local debug = false; +local SECONDS_PER_DAY = 24 * 60 * 60 +local SECONDS_PER_HOUR = 60 * 60 +local MAX_MAIL_DAYS = 30 + +local expiry_warn_days = 7 +local expiry_err_days = 2 + +local DAYS_REM = "Days Remaining" +local MAIL_OPENED = "Opened" +local CHAR = "Character" + +local READ_PRE = " ?? " +local NEW_PRE = " ++ " +local EXP_PRE = " !! " +local READ_TT_POST = " : About read / total " +local NEW_TT_POST = " : New Mail this session " +local EXP_TT_POST = " : Characters with expiring Mail " +local MAIL_TT_PRE = "Mail opened : " + +TitanPost = {} +TitanPost.mailbox = mailbox + +Titan_Debug.post = {} +Titan_Debug.post.flow = false +Titan_Debug.post.events = false +Titan_Debug.post.expiry_flow = false +Titan_Debug.post.mail_box = false +--Titan_Debug.Out('post', 'events', "===") + +---------------------------------------------------------------------------------- + +local ThresholdTable = { + Values = { expiry_err_days, expiry_warn_days }, + Colors = { RED_FONT_COLOR, YELLOW_FONT_COLOR, GREEN_FONT_COLOR }, +} +--local ex_header = " " .. CHAR .. " : " .. DAYS_REM .. " : " .. MAIL_OPENED .. "\n" +local ex_header = " " .. CHAR .. " : " .. DAYS_REM .. "\n" + +local date_stamp = "%Y-%m-%d" +local time_stamp = "%H:%M" + +---Format time stamp +---@param time_sec number timestamp +---@param with_time boolean add time +---@return string Timestamp Formatted +local function FormatTS(time_sec, with_time) + local f = date_stamp + if with_time then + f = f .. " " .. time_stamp + else + -- just date w/o time + end + local str = date(f, time_sec) + + return str +end + +---Start / stop the timer to check expiry +---@param action string 'start' | 'stop' +local function ExpiryTimer(action) end -- real declaration later... + +---Format an expiry text for a single toon +---@param toon_name string +---@param toon_info table toon +---@return string +local function ShowExpiry(toon_name, toon_info) + local now = _G.time() + local res = "" + local use_color = true -- TitanGetVar(TITAN_POST_ID, "ShowColoredText") + + local days = math.floor((toon_info.nextExpiry - now) / SECONDS_PER_DAY) + local last = toon_info.lastUpdate_str + local estr = toon_name + .. " : " .. days + -- .. " : " .. last + .. "\n" + if (use_color == true) + or (use_color == 1) then + local color = TitanUtils_GetThresholdColor(ThresholdTable, days); + estr = TitanUtils_GetColoredText(estr, color) + else + -- leave alone + end + + res = res .. estr + + local str = "...ShowExpiry" + .. " " .. tostring(toon_name) .. "" + .. " " .. tostring(days) .. "" + -- .. " " .. tostring(last) .. "" + -- .." "..tostring(color).."" + .. " \n" .. tostring(res) .. "" + Titan_Debug.Out('post', 'expiry_flow', str) + + return res +end + +---Create time stamp from warning days + now +---@return integer Timestamp +local function ExpiryWarn() + local now = _G.time() + return (expiry_warn_days * SECONDS_PER_DAY) + now -- make timestamp +end + +---Get Post info from Titan, if known +---@param toon string +---@param reason string +---@return table? Post_info if known +local function GetPostInfo(toon, reason) + local custom_toon, toon_info = TitanUtils_GetPlayerInfo(toon) + + local res = nil + + if custom_toon then + -- no info available, can not log in + elseif toon_info == nil then + -- possible the toon has not been logged into post Titan changes + elseif toon_info[TITAN_POST_ID] then + res = toon_info[TITAN_POST_ID] + else + -- not filled in + local info = TitanSettings.Players[toon].Info + info[TITAN_POST_ID] = {} + local p = info[TITAN_POST_ID] + p.lastUpdate = 0 + p.mailCount = 0 + p.mailReadNum = 0 + p.nextExpiry = 0 + p.mailEntries = {} + + res = p + end + + return res +end + +---Check the saved vars for expiring mail, only from last time that toon opened mail +---@return integer Num of toons with expiring mail +---@return string Display text with name, num, and last time mail was opened +local function CheckExpiry() + local expiry_check = ExpiryWarn() + local res = "" + local exp_str = "" + + local has_expiry = false + local expiry_toons = 0 + local expiry_low = expiry_check + 1 + + local str = "" + + str = "CheckExpiry" + .. " @ " .. FormatTS(expiry_check, true) + .. " (" .. tostring(expiry_check) .. ")" + Titan_Debug.Out('post', 'expiry_flow', str) + + for toon_name, cdata in pairs(TitanSettings.Players) do + str = ".CheckExpiry" + .. " " .. tostring(toon_name) .. "" + Titan_Debug.Out('post', 'expiry_flow', str) + local pdata = GetPostInfo(toon_name, "CheckExpiry") + if (pdata and pdata.mailCount > 0) then + str = "...CheckExpiry" + .. " [" .. tostring(pdata.nextExpiry_str) .. "]" + .. " " .. tostring(pdata.nextExpiry) .. "" + .. " < " .. tostring(expiry_check) .. "" + .. " = " .. tostring((pdata.nextExpiry < expiry_check)) .. "" + Titan_Debug.Out('post', 'expiry_flow', str) + if (pdata.nextExpiry < expiry_check) then -- add to list for user + has_expiry = true + + local estr = ShowExpiry(toon_name, pdata) + + exp_str = exp_str .. estr + expiry_toons = expiry_toons + 1 -- count the number of toons with expiring mail + else + -- still time + end + else + -- mailbox empty last we knew + end + end + if has_expiry then -- add prefix for user + res = "Expired: " .. " " .. tostring(expiry_toons) .. "\n" + res = res .. ex_header + res = res .. exp_str + else + -- still time + end + + ExpiryTimer('start') + + str = "=CheckExpiry" + .. " " .. tostring(expiry_toons) .. "" + .. " \n" .. tostring(res) .. "" + Titan_Debug.Out('post', 'expiry_flow', str) + + return expiry_toons, res +end + +local expiry_timer = nil +function ExpiryTimer(action) -- prior declaration + if action == 'start' then + -- stop current, just in case for sanity + if expiry_timer == nil then + -- no timer + else + AceTimer.CancelTimer(_G[TITAN_BUTTON], expiry_timer) + end + local time_int = TitanGetVar(TITAN_POST_ID, "ExpiryTimer") + expiry_timer = + AceTimer.ScheduleRepeatingTimer(_G[TITAN_BUTTON], CheckExpiry, time_int * 60) -- in seconds + local str = "Expiry next check in" + .. " " .. tostring(time_int) .. " minutes" + Titan_Debug.Out('post', 'expiry_flow', str) + elseif action == 'stop' then + if expiry_timer == nil then + -- no timer + else + AceTimer.CancelTimer(_G[TITAN_BUTTON], expiry_timer) + expiry_timer = nil + end + end + + local str = "ExpiryTimer" + .. " " .. tostring(action) .. "" + Titan_Debug.Out('post', 'expiry_flow', str) +end + +---Create an x/y string for Mail +---@param playerName string +---@param addOpen boolean +---@return string +local function GetCountsStr(playerName, addOpen) + local toon = GetPostInfo(playerName, "Get Counts") + local res = "" + + if toon == nil then + -- nothing to count + else + if addOpen then + if toon.opened then + res = res .. " " -- counts should be accurate for this session + else + res = res .. READ_PRE -- counts may not be accurate + end + end + + if (toon.lastUpdate == 0) then + res = res .. L["TITAN_PANEL_NA"] --NOT_OPENED yet + else + if toon.mailCount > 0 then + res = res .. toon.mailReadNum .. "/" .. toon.mailCount + else + -- leave 0 as blank + end + end + end + + return res +end + +---Create plugin text +---@param id string +---@return string Label +---@return string Display text +local function GetButtonText(id) + local res = "" + + res = res .. GetCountsStr(player, true) + + local new = "" + if (mailbox.new > 0) then + new = NEW_PRE -- .. tostring(mailbox.new) + else + new = "" + end + + local expiry = "" + if (mailbox.expiry_num > 0) then + expiry = EXP_PRE .. tostring(mailbox.expiry_num) + else + expiry = "" + end + + res = res .. new .. expiry + + return "Mail : ", res +end + +---Create a tool tip +---@return string +function GetTooltipText() + local str = "" + local res = "" + + local toon = GetPostInfo(player, "Tool Tip") + if toon then + str = toon.lastUpdate_str + else + str = "" + end + + res = MAIL_TT_PRE .. tostring(str) .. "\n" + res = res .. " " + .. GetCountsStr(player, true) + .. READ_TT_POST .. "\n" + + + local new = "" + if (mailbox.new > 0) then + -- new = NEW_PRE .. tostring(mailbox.new) .. NEW_TT_POST .. "\n" + new = NEW_PRE .. NEW_TT_POST .. "\n" + else + new = "" + end + + local expiry = "" + if (mailbox.expiry_num > 0) then + expiry = EXP_PRE .. tostring(mailbox.expiry_num) .. EXP_TT_POST .. "\n" + else + expiry = "" + end + + res = res .. new .. expiry + res = res .. "\n" + res = res .. mailbox.expiry_text .. "\n" + + return res +end + +---Look at any mail, setting data for action +local function UpdateInboxData() + if not _G.MailFrame:IsVisible() then + return + end + + local inboxCount, totalCount = _G.GetInboxNumItems() + local playerData = GetPostInfo(player, "Update Inbox") + + if playerData == nil then + -- paranoid, this should never happen for a logged in toon + else + local remainingDays = MAX_MAIL_DAYS + local mailReadNum = 0 + + table.wipe(playerData.mailEntries) + local now = _G.time() + + local str = "UpdateInboxData" + .. " " .. tostring(playerData) .. "" + .. " #" .. tostring(inboxCount) .. "" + .. " #" .. tostring(totalCount) .. "" + Titan_Debug.Out('post', 'mail_box', str) + + for index = 1, inboxCount do + -- https://warcraft.wiki.gg/wiki/API_GetInboxHeaderInfo + -- packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, + -- wasReturned, textCreated, canReply, isGM = GetInboxHeaderInfo(index) + -- as of 2025 Dec + local _, _, senderName, subject, _, CODAmount, daysLeft, _, wasRead, + _, _, _, _ = _G.GetInboxHeaderInfo(index) + + if _G.type(daysLeft) == nil then -- sanity check + daysLeft = MAX_MAIL_DAYS + end + + if daysLeft < remainingDays then -- get shortest expiry + remainingDays = daysLeft + end + + if wasRead then -- + mailReadNum = mailReadNum + 1 + end + + str = "UpdateInboxData" + .. " #" .. tostring(index) .. "" + .. " '" .. tostring(senderName) .. "'" + .. " '" .. tostring(subject) .. "'" + .. " '" .. tostring(daysLeft) .. "'" + .. " '" .. tostring(remainingDays) .. "'" + Titan_Debug.Out('post', 'mail_box', str) + + table.insert(playerData.mailEntries, { + daysLeft = daysLeft, -- fractional number + -- packageIcon = packageIcon, + senderName = senderName, + -- stationaryIcon = stationaryIcon, + subject = subject, + wasRead = wasRead, + }) + end + + playerData.lastUpdate = now + playerData.lastUpdate_str = FormatTS(playerData.lastUpdate, true) + playerData.mailCount = inboxCount + playerData.mailReadNum = mailReadNum + local ex_ts = math.floor(remainingDays * SECONDS_PER_DAY) + now -- make timestamp + playerData.nextExpiry = ex_ts + playerData.nextExpiry_str = FormatTS(ex_ts, true) + end +end + +---Look for expiry notifications, the routine will include the current too +local function UpdateInfo() + local next_exp = 0 + mailbox.expiry_num, mailbox.expiry_text = CheckExpiry() + + local str = "UpdateInfo" + .. " " .. tostring(player) .. "" + Titan_Debug.Out('post', 'flow', str) +end + +---Ensure there is something in the saved vars +local function InitVars() + local str = "InitVars" + .. " " .. tostring(player) .. "" + Titan_Debug.Out('post', 'flow', str) + + local info = GetPostInfo(player, "Init") + -- should create a blank, not there +end + +---Process the MAIL_INBOX_UPDATE event while mailbox is open +local function MailInboxUpdate(reason) + local str = "MailInboxUpdate" + .. " o: " .. tostring(mailbox.opened) .. "" + .. " on: " .. tostring(mailbox.open_now) .. "" + .. " " .. tostring(reason) .. "" + Titan_Debug.Out('post', 'mail_box', str) + + local pdata = GetPostInfo(player, "Mail Inbox Update") + if pdata == nil then + -- paranoid... + else + pdata.opened = true + end + + UpdateInboxData() + + UpdateInfo() + + local numItems, totalItems = GetInboxNumItems() + Titan_Debug.Out('post', 'mail_box', + "Inbox: " + .. " #" .. numItems .. "" + .. " #" .. totalItems .. "" + ) + TitanPanelButton_UpdateButton(TITAN_POST_ID) +end + +local function OpenMailbox() + mailbox.opened = true -- this session only + mailbox.open_now = true + + MailInboxUpdate("Mailbox opened") +end + +local function CloseMailbox() + mailbox.open_now = false -- this session only + + if HasNewMail() then + -- has unread mail, expect a nag event :) + mailbox.ignore_next_pending = true + else + -- no unread mail + end + + local reason = "Mailbox closed " .. tostring(mailbox.ignore_next_pending) + MailInboxUpdate(reason) +end + +---Event handler for registered events +---@param self Button +---@param event string +---@param ... unknown +local function OnEvent(self, event, arg1, arg2, ...) + Titan_Debug.Out('post', 'events', "New > " + .. " " .. tostring(event) .. "" + .. " " .. tostring(arg1) .. "" + .. " " .. tostring(arg2) .. "" + ); + if (event == "PLAYER_ENTERING_WORLD") then + -- ignore 1st UPDATE_PENDING_MAIL event on entering world (first or instance or reload) + mailbox.ignore_next_pending = true + + if arg1 == true then + local pdata = GetPostInfo(player, "PEW") + if pdata == nil then + -- paranoid... + else + pdata.opened = false + end + else + -- reload / new instance / ... + end + end + ---[===[ + if (event == "MAIL_INBOX_UPDATE") then + --[[ Dec 2025 https://warcraft.wiki.gg/wiki/MAIL_INBOX_UPDATE +Fires when the inbox list is loaded while the frame is open +Fires when mail item changes from new to read +Fires when mail item is opened for the first time in a session + --]] + MailInboxUpdate() + end + --]===] +end + +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_POST_ID + local root = rootDescription -- menu widget to start with + + Titan_Menu.AddCommand(root, id, L["TITAN_PANEL_MENU_PROFILES"] .. " " .. L["TITAN_PANEL_MENU_CONFIGURATION"], + function() + TitanUpdateConfig("init") + -- Open the profile config as distinct frame + AceConfigDialog:Open("Titan Panel Addon Chars") + end + ) + + local minutes = { -- selectors using the same option + { "1", 1 }, + { "10", 10 }, + { "30", 30 }, + { "60", 60 }, + } + Titan_Menu.AddSelectorList(root, id, "Expiry Check Interval - minutes", "ExpiryTimer", minutes) +end + +---Register events when active +---@param self Button +local function OnShow(self) + Titan_Debug.Out('post', 'flow', "OnShow ") + + InitVars() + + -- Register for events + self:RegisterEvent("MAIL_INBOX_UPDATE") + self:RegisterEvent("UPDATE_PENDING_MAIL") + self:RegisterEvent("PLAYER_ENTERING_WORLD") + + -- Ace does parameter shuffling under the hood depending on the types passed + -- hence the ignore diagnostic... + ---@diagnostic disable-next-line: param-type-mismatch + if AceHook:IsHooked("MailFrame_Show", OpenMailbox) then + -- Already hooked + else + AceHook:SecureHook("MailFrame_Show", OpenMailbox) -- MailFrame.lua + end + ---@diagnostic disable-next-line: param-type-mismatch + if AceHook:IsHooked("MailFrame_Hide", CloseMailbox) then + -- Already hooked + else + -- Ace does parameter shuffling under the hood depending on the types passed + AceHook:SecureHook("MailFrame_Hide", CloseMailbox) -- MailFrame.lua + end + + UpdateInfo() + TitanPanelButton_UpdateButton(TITAN_POST_ID) +end + +---Unregister events when not active +---@param self Button +local function OnHide(self) + Titan_Debug.Out('post', 'flow', "OnHide ") + -- UnregisterEvent for events + self:UnregisterEvent("MAIL_INBOX_UPDATE"); + self:UnregisterEvent("UPDATE_PENDING_MAIL"); + self:UnregisterEvent("PLAYER_ENTERING_WORLD"); + + ---@diagnostic disable-next-line: param-type-mismatch + if AceHook:IsHooked("MailFrame_Show", OpenMailbox) then + ---@diagnostic disable-next-line: param-type-mismatch + AceHook:Unhook("MailFrame_Show", OpenMailbox) -- MailFrame.lua + else + -- nothing to do + end + ---@diagnostic disable-next-line: param-type-mismatch + if AceHook:IsHooked("MailFrame_Hide", CloseMailbox) then + ---@diagnostic disable-next-line: param-type-mismatch + AceHook:Unhook("MailFrame_Hide", CloseMailbox) -- MailFrame.lua + else + -- nothing to do + end + + ExpiryTimer('stop') +end + +---Handle any mouse clicks +---@param self Button +---@param button string Mouse click +local function OnClick(self, button) + if (button == "LeftButton") then + -- ToggleBags(); + end +end + +---Registry for Titan; first events +---@param self Button +local function OnLoad(self) + local notes = "" + .. "Adds mail information to Titan Panel.\n" + .. "- ?? : Have opened Mail this session; counts not known.\n" + .. "- ?? <read>/<total> : Have not opened Mail this session; x/y from last time Mail opened with TitanPost running.\n" + .. "- <read>/<total> : Opened Mail this session; x/y known counts.\n" + .. "- ++ new mail this session; no number given - counts may not be accurate.\n" + .. "- !! x : x characters with expiring Mail.\n" + .. "- NOTE: New mail counts NOT given may not be accurate!\n" + .. "- NOTE: New mail counts NOT added to x/y!\n" + .. "- New built-in Jan 2026.\n" + self.registry = { + id = TITAN_POST_ID, + menuText = TITAN_POST_ID, + category = "Built-ins", + buttonTextFunction = GetButtonText, + menuContextFunction = GeneratorFunction, -- NEW scheme + tooltipTitle = TITAN_POST_ID, + tooltipTextFunction = GetTooltipText, + icon = FolderPre .. "Mail", + version = TITAN_VERSION, + iconWidth = 16, + notes = notes, + controlVariables = { + ShowIcon = true, + ShowLabelText = true, + -- ShowColoredText = true, + DisplayOnRightSide = true, + }, + savedVariables = { + ShowIcon = 1, + ShowLabelText = true, + -- ShowColoredText = true, + DisplayOnRightSide = false, + ExpiryTimer = 10, + ShowToonList = true, + } + }; +end + +local function FormatCounts(playerName, now) + local toon = playerName -- GetPostInfo(playerName, "Format Counts") + local res = "" + local div = " : " + + local last_open = "" + local counts = "" + local warning = "" + if (toon.lastUpdate == 0) then + last_open = UNKNOWN --L["TITAN_PANEL_NA"] --NOT_OPENED yet + else + last_open = tostring(toon.lastUpdate_str) + + if toon.mailCount >= 0 then + -- counts may not be accurate + counts = div .. READ_PRE .. toon.mailReadNum .. "/" .. toon.mailCount + else + -- leave blank + end + + if (toon.nextExpiry < ExpiryWarn()) then + -- add to list for user + local days = math.floor((toon.nextExpiry - now) / SECONDS_PER_DAY) + local color = TitanUtils_GetThresholdColor(ThresholdTable, days) + local days_str = DAYS_REM .. " : " .. tostring(days) + days_str = TitanUtils_GetColoredText(days_str, color) + warning = div .. days_str + else + -- no mail to warn about + warning = "" + end + end + + res = last_open .. counts .. warning + + return res +end + + +---Titan Allow Titan to lookup mail info for a toon; return a formatted string +---@param playerName string +---@return string +function TitanPost.GetInfo(playerName, add_label) + local res = "" + local now = _G.time() + + local str = "GetMailInfo" + .. " " .. tostring(playerName) .. "" + Titan_Debug.Out('post', 'flow', str) + + if add_label then + res = res .. MAIL_OPENED .. " : " + else + res = "" + end + + if _G[TITAN_BUTTON]:IsShown() then + local pdata = GetPostInfo(playerName, "API Get Info") + if pdata then + res = res .. FormatCounts(pdata, now) + else + res = res .. UNKNOWN + end + else + res = res .. L["TITAN_PANEL_MENU_DISABLED"] + end + + str = "..GetMailInfo" + .. " '" .. tostring(res) .. "'" + Titan_Debug.Out('post', 'flow', str) + + return res +end + +---Create needed plugin frames +local function Create_Frames() + if _G[TITAN_BUTTON] then + return -- if already created + end + + -- general container frame + local f = CreateFrame("Frame", TITAN_BUTTON .. "Frame", UIParent) + -- f:Hide() + + -- Titan plugin button + local window = CreateFrame("Button", TITAN_BUTTON, f, "TitanPanelComboTemplate") + window:SetFrameStrata("FULLSCREEN") + -- Using SetScript("OnLoad", does not work + OnLoad(window); + -- TitanPanelButton_OnLoad(window); -- Titan XML template calls this... + + window:SetScript("OnShow", function(self) + OnShow(self); + 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) + OnClick(self, button); + TitanPanelButton_OnClick(self, button); + end) +end + +Create_Frames() -- do the work + +--==== For debug access and testing +--[===[ +print("======") +local TITAN_POST_ID = "Post"; +local TITAN_BUTTON = "TitanPanel" .. TITAN_POST_ID .. "Button" + +local SECONDS_PER_DAY = 24 * 60 * 60 +local now = _G.time() +local player = "Syldil@Staghelm" +local pdata = GetPostInfo(player, "CheckExpiry") + +local sender = "Lascar@Staghelm" +--[[ +local p = GetPostInfo(player, "CheckExpiry") +p.lastUpdate = now +p.mailCount = 1 +p.mailReadNum = 0 +p.nextExpiry = math.floor(30 * SECONDS_PER_DAY) + now -- make timestamp + +table.wipe(pdata.mailEntries) +p.mailEntries = {} +p.mailEntries[1] = {} +local m = p.mailEntries[1] +m.daysLeft = 30 +m.senderName = sender +m.subject = "Debug Msg" +m.wasRead = false +--]] + + +--FormatTS(1768597331, true) +-- 1768597331 -- 2026-01-16 16:00 +--print(FormatTS(1768597331, false)) -- 2026-01-16 16:00 +--print(FormatTS(1768597331, true)) -- 2026-01-16 04:00 PM + +TitanDumpTable(p) --(playerData) +-- +-- + +TitanPanelButton_UpdateButton(TITAN_POST_ID) +-- + +-- Simulate an event manually DOES NOT WORK +TitanPanelPostButton:OnEvent("PLAYER_REGEN_ENABLED", "player") + +--]===] + + + +-- ==== Simulate firing the events +-- frame:OnEvent("MY_CUSTOM_EVENT", "arg1", "arg2") -- Does NOT appear to work... + +function TitanPost.SimUpdateExpiry() + UpdateInfo() + + local numItems, totalItems = GetInboxNumItems() + local str = "Inbox Sim : " + .. " " .. numItems .. "" + .. " " .. totalItems .. "" + Titan_Debug.Out('post', 'flow', str); + + TitanPanelButton_UpdateButton(TITAN_POST_ID) +end diff --git a/TitanPost/TitanPost.toc b/TitanPost/TitanPost.toc new file mode 100644 index 0000000..b128562 --- /dev/null +++ b/TitanPost/TitanPost.toc @@ -0,0 +1,10 @@ +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fPost|r] |cff00aa009.1.0-pre.0|r +## Version: 9.1.0-pre +## Notes: Adds mail information to Titan Panel +## Author: Titan Panel Development Team +## SavedVariables: +## Dependencies: Titan +## OptionalDeps: +TitanPost.lua + diff --git a/TitanPost/artwork/Mail.blp b/TitanPost/artwork/Mail.blp new file mode 100644 index 0000000..44252f7 Binary files /dev/null and b/TitanPost/artwork/Mail.blp differ diff --git a/TitanPost/artwork/mail_here.mp3 b/TitanPost/artwork/mail_here.mp3 new file mode 100644 index 0000000..9de61cb Binary files /dev/null and b/TitanPost/artwork/mail_here.mp3 differ diff --git a/TitanRegen/TitanRegen.lua b/TitanRegen/TitanRegen.lua index 7c52d67..70fff6e 100644 --- a/TitanRegen/TitanRegen.lua +++ b/TitanRegen/TitanRegen.lua @@ -48,40 +48,6 @@ local function SetTextColorRBG(text, r, g, b) return str end ----local Build the plugin .registry and register events ----@param self Button plugin frame -function OnLoad(self) - local notes = "" - .."Adds a regen monitor to Titan Panel to show HP/MANA regen - Classic versions only.\n" - self.registry = { - id = TITAN_REGEN_ID, - category = "Built-ins", - version = TITAN_VERSION, - menuText = L["TITAN_REGEN_MENU_TEXT"], - buttonTextFunction = "GetButtonText", - tooltipTitle = L["TITAN_REGEN_MENU_TOOLTIP_TITLE"], - tooltipTextFunction = "TitanPanelRegenButton_GetTooltipText", - icon = "Interface\\AddOns\\TitanRegen\\TitanRegen", - iconWidth = 16, - notes = notes, - controlVariables = { - ShowIcon = true, - ShowLabelText = true, - ShowRegularText = false, - ShowColoredText = true, - DisplayOnRightSide = true, - }, - savedVariables = { - ShowIcon = true, - ShowLabelText = 1, - ShowHPRegen = 1, - ShowPercentage = false, - ShowColoredText = false, - DisplayOnRightSide = false, - } - } -end - ---local Handle events the clock plugin is interested in. ---@param self Button plugin frame ---@param event string Event @@ -254,34 +220,6 @@ function TitanPanelRegenButton_GetTooltipText() return txt end ----Generate right click menu options -function TitanPanelRightClickMenu_PrepareRegenMenu() - local id = TITAN_REGEN_ID; - local info; - - TitanPanelRightClickMenu_AddTitle(TitanPlugins[id].menuText); - - info = {}; - info.text = L["TITAN_REGEN_MENU_HP"]; - info.func = function() - TitanToggleVar(TITAN_REGEN_ID, "ShowHPRegen"); - TitanPanelButton_UpdateButton(TITAN_REGEN_ID); - end - info.checked = TitanGetVar(TITAN_REGEN_ID,"ShowHPRegen"); - L_UIDropDownMenu_AddButton(info); - - info = {}; - info.text = L["TITAN_REGEN_MENU_PERCENT"]; - info.func = function() - TitanToggleVar(TITAN_REGEN_ID, "ShowPercentage"); - TitanPanelButton_UpdateButton(TITAN_REGEN_ID); - end - info.checked = TitanGetVar(TITAN_REGEN_ID,"ShowPercentage"); - L_UIDropDownMenu_AddButton(info); - - TitanPanelRightClickMenu_AddControlVars(TITAN_REGEN_ID) -end - local function OnShow(self) self:RegisterEvent("UNIT_HEALTH"); self:RegisterEvent("UNIT_POWER_UPDATE"); @@ -296,6 +234,50 @@ local function OnHide(self) self:UnregisterEvent("PLAYER_REGEN_ENABLED"); end +---Generate right click menu options +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_REGEN_ID + local root = rootDescription -- menu widget to start with + + Titan_Menu.AddSelector(root, id, L["TITAN_REGEN_MENU_HP"], "ShowHPRegen") + Titan_Menu.AddSelector(root, id, L["TITAN_REGEN_MENU_PERCENT"], "ShowPercentage") +end + +---local Build the plugin .registry and register events +---@param self Button plugin frame +function OnLoad(self) + local notes = "" + .."Adds a regen monitor to Titan Panel to show HP/MANA regen - Classic versions only.\n" + self.registry = { + id = TITAN_REGEN_ID, + category = "Built-ins", + version = TITAN_VERSION, + menuText = L["TITAN_REGEN_MENU_TEXT"], + menuContextFunction = GeneratorFunction, -- NEW scheme + buttonTextFunction = "GetButtonText", + tooltipTitle = L["TITAN_REGEN_MENU_TOOLTIP_TITLE"], + tooltipTextFunction = "TitanPanelRegenButton_GetTooltipText", + icon = "Interface\\AddOns\\TitanRegen\\TitanRegen", + iconWidth = 16, + notes = notes, + controlVariables = { + ShowIcon = true, + ShowLabelText = true, + ShowRegularText = false, + ShowColoredText = true, + DisplayOnRightSide = true, + }, + savedVariables = { + ShowIcon = true, + ShowLabelText = 1, + ShowHPRegen = 1, + ShowPercentage = false, + ShowColoredText = false, + DisplayOnRightSide = false, + } + } +end + -- ====== Create needed frames local function Create_Frames() if _G[TITAN_BUTTON] then diff --git a/TitanRegen/TitanRegen_TBC.toc b/TitanRegen/TitanRegen_TBC.toc new file mode 100644 index 0000000..61d7c81 --- /dev/null +++ b/TitanRegen/TitanRegen_TBC.toc @@ -0,0 +1,9 @@ +## Interface: 20505 +## Title: Titan Panel [|cffeda55fRegen|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre +## Notes: Adds a regen monitor to Titan Panel to show HP/MANA regen - Classic versions only +## Author: Titan Panel Development Team +## SavedVariables: +## OptionalDeps: +## Dependencies: Titan +TitanRegen.lua \ No newline at end of file diff --git a/TitanRegen/TitanRegen_Vanilla.toc b/TitanRegen/TitanRegen_Vanilla.toc index bff4ce0..947467d 100644 --- a/TitanRegen/TitanRegen_Vanilla.toc +++ b/TitanRegen/TitanRegen_Vanilla.toc @@ -1,6 +1,6 @@ -## Interface: 20505, 11508, 50503 -## Title: Titan Panel [|cffeda55fRegen|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Interface: 11507, 50503 +## Title: Titan Panel [|cffeda55fRegen|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## Notes: Adds a regen monitor to Titan Panel to show HP/MANA regen - Classic versions only ## Author: Titan Panel Development Team ## SavedVariables: diff --git a/TitanRepair/TitanRepair.lua b/TitanRepair/TitanRepair.lua index 17eb4d2..62ccc87 100644 --- a/TitanRepair/TitanRepair.lua +++ b/TitanRepair/TitanRepair.lua @@ -148,6 +148,15 @@ local function RepairInit() dur_per = TR.equip_most_default.dur_per, cost = TR.equip_most_default.cost, } + + -- Jan 2026 : New saved var - DiscountNone - ensure it is set as needed + -- Added to fit Titan_Menu patterns + local disc = not -- true if no other discount is set + (TitanGetVar(TITAN_REPAIR_ID,"DiscountFriendly") + and TitanGetVar(TITAN_REPAIR_ID,"DiscountHonored") + and TitanGetVar(TITAN_REPAIR_ID,"DiscountRevered") + and TitanGetVar(TITAN_REPAIR_ID,"DiscountExalted")) + TitanSetVar(TITAN_REPAIR_ID,"DiscountNone", disc) end --[[ local @@ -1374,48 +1383,6 @@ local function CreateMenu() if TitanPanelRightClickMenu_GetDropdMenuValue() == "AutoRepair" then TitanPanelRightClickMenu_AddTitle(L["TITAN_REPAIR_LOCALE_AUTOREPLABEL"], TitanPanelRightClickMenu_GetDropdownLevel()); - info = {}; - info.text = L["TITAN_REPAIR_LOCALE_POPUP"]; - info.func = function() - TitanToggleVar(TITAN_REPAIR_ID, "ShowPopup"); - if TitanGetVar(TITAN_REPAIR_ID,"ShowPopup") and TitanGetVar(TITAN_REPAIR_ID,"AutoRepair") then - TitanSetVar(TITAN_REPAIR_ID,"AutoRepair",nil); - end - end - info.checked = TitanGetVar(TITAN_REPAIR_ID,"ShowPopup"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_REPAIR_LOCALE_AUTOREPITEMLABEL"]; - info.func = function() - TitanToggleVar(TITAN_REPAIR_ID, "AutoRepair"); - if TitanGetVar(TITAN_REPAIR_ID,"AutoRepair") and TitanGetVar(TITAN_REPAIR_ID,"ShowPopup") then - TitanSetVar(TITAN_REPAIR_ID,"ShowPopup",nil); - end - end - info.checked = TitanGetVar(TITAN_REPAIR_ID,"AutoRepair"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_REPAIR_REPORT_COST_MENU"] - info.func = function() TitanToggleVar(TITAN_REPAIR_ID, "AutoRepairReport"); end - info.checked = TitanGetVar(TITAN_REPAIR_ID,"AutoRepairReport"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - if Titan_Global.switch.classic_era then - -- skip, no guild bank available - else - local g_enable = false -- assume not in guild - if IsInGuild() and CanGuildBankRepair() then - g_enable = true - end - info = {} - info.text = L["TITAN_REPAIR_GBANK_USEFUNDS"] - info.disabled = not g_enable - info.func = function() TitanToggleVar(TITAN_REPAIR_ID, "UseGuildBank"); end - info.checked = TitanGetVar(TITAN_REPAIR_ID,"UseGuildBank"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end end if TitanPanelRightClickMenu_GetDropdMenuValue() == "TooltipOptions" then @@ -1470,20 +1437,6 @@ local function CreateMenu() info = {}; info.notCheckable = true - info.text = L["TITAN_PANEL_OPTIONS"]; - info.value = "Options" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_REPAIR_LOCALE_AUTOREPLABEL"]; - info.value = "AutoRepair" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true info.text = L["TITAN_REPAIR_LOCALE_DISCOUNT"]; info.value = "Discount" info.hasArrow = 1; @@ -1499,6 +1452,54 @@ local function CreateMenu() TitanPanelRightClickMenu_AddControlVars(TITAN_REPAIR_ID) end +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_REPAIR_ID + local root = rootDescription -- menu widget to start with + + local opts_discount = Titan_Menu.AddButton(root, L["TITAN_PANEL_OPTIONS"]) + do -- next level options + Titan_Menu.AddSelector(opts_discount, id, L["TITAN_REPAIR_SHOW_TOTAL"], "ShowTotals") + Titan_Menu.AddSelector(opts_discount, id, L["TITAN_REPAIR_LOCALE_MOSTDAMAGED"], "ShowMostDamaged") + Titan_Menu.AddSelector(opts_discount, id, L["TITAN_REPAIR_LOCALE_SHOWINVENTORY"], "ShowInventory") + Titan_Menu.AddDivider(opts_discount) + Titan_Menu.AddSelector(opts_discount, id, L["TITAN_REPAIR_LOCALE_SHOWREPAIRCOST"], "ShowRepairCost") + Titan_Menu.AddSelector(opts_discount, id, L["TITAN_REPAIR_LOCALE_SHOWREPAIRCOST"].." Gold Only" , "ShowCostGoldOnly") + Titan_Menu.AddSelector(opts_discount, id, "Show "..ITEM_QUALITY0_DESC.." Total", "ShowGray") + Titan_Menu.AddDivider(opts_discount) + Titan_Menu.AddSelector(opts_discount, id, "Sell ALL "..ITEM_QUALITY0_DESC.." Items - CAUTION", "SellAllGray") + end + + --==== Display options + local opts_auto_repair = Titan_Menu.AddButton(root, L["TITAN_REPAIR_LOCALE_AUTOREPLABEL"]) + do -- next level options + Titan_Menu.AddSelectorCommand(opts_auto_repair, id, L["TITAN_REPAIR_LOCALE_POPUP"], "AutoRepair", + function () + if TitanGetVar(TITAN_REPAIR_ID,"ShowPopup") and TitanGetVar(TITAN_REPAIR_ID,"AutoRepair") then + TitanSetVar(TITAN_REPAIR_ID,"AutoRepair",nil); + end + end + ) + Titan_Menu.AddSelectorCommand(opts_auto_repair, id, L["TITAN_REPAIR_LOCALE_AUTOREPITEMLABEL"], "ShowPopup", + function () + if TitanGetVar(TITAN_REPAIR_ID,"AutoRepair") and TitanGetVar(TITAN_REPAIR_ID,"ShowPopup") then + TitanSetVar(TITAN_REPAIR_ID,"ShowPopup",nil); + end + end + ) + + Titan_Menu.AddSelector(opts_auto_repair, id, L["TITAN_REPAIR_REPORT_COST_MENU"], "AutoRepairReport") + + -- Need the menu widget to set enabled + -- Tis is evaluated and set only each time the menu is created. + local use_guild = Titan_Menu.AddSelector(opts_auto_repair, id, L["TITAN_REPAIR_GBANK_USEFUNDS"], "UseGuildBank") + local g_enable = false -- assume not in guild + if IsInGuild() and CanGuildBankRepair() then + g_enable = true + end + Titan_Menu.SetAtribEnabled(use_guild, g_enable) + end +end + ---local Create the .registry for the plugin. ---@param self Button local function OnLoad(self) @@ -1512,7 +1513,8 @@ local function OnLoad(self) category = "Built-ins", version = TITAN_VERSION, menuText = L["TITAN_REPAIR_LOCALE_MENU"], - menuTextFunction = CreateMenu, +-- menuTextFunction = CreateMenu, + menuContextFunction = GeneratorFunction, -- NEW scheme buttonTextFunction = GetButtonText, tooltipTitle = L["TITAN_REPAIR_LOCALE_TOOLTIP"], tooltipTextFunction = GetTooltipText, @@ -1533,6 +1535,7 @@ local function OnLoad(self) ShowUndamaged = false, ShowPopup = false, AutoRepair = false, + DiscountNone = false, DiscountFriendly = false, DiscountHonored = false, DiscountRevered = false, @@ -1561,6 +1564,7 @@ local function Create_Frames() return -- if already created end + -- Used to get repair costs of items in user bags if C_TooltipInfo then -- use a proxy for retail (true) versus classic (false) -- Not needed for retail else diff --git a/TitanRepair/TitanRepair.toc b/TitanRepair/TitanRepair.toc index bb36cbc..b9c91c8 100644 --- a/TitanRepair/TitanRepair.toc +++ b/TitanRepair/TitanRepair.toc @@ -1,6 +1,6 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55fRepair|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fRepair|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## IconTexture: Interface\AddOns\TitanRepair\TitanRepair ## Notes: Provides a configurable durability display. Also adds the ability to auto repair items and inventory at vendors. Adds selling of grey items. ## Author: Titan Panel Development Team diff --git a/TitanUI/TitanUI.toc b/TitanUI/TitanUI.toc index 236351c..2b95a79 100755 --- a/TitanUI/TitanUI.toc +++ b/TitanUI/TitanUI.toc @@ -1,7 +1,7 @@ -## Interface: 120001, 120000, 110205, 50502, 20505, 11508 -## Title: Titan Panel [|cffeda55fUI|r] |cff00aa009.0.2|r +## Interface: 120000, 110205, 50502, 20505, 11508 +## Title: Titan Panel [|cffeda55fUI|r] |cff00aa009.1.0-pre|r ## Author: Titan Panel Dev Team -## Version: 9.0.2 +## Version: 9.1.0-pre ## Notes: Adds Reload and select functions in a plugin ## Author: Titan Panel Development Team ## IconTexture: Interface\AddOns\TitanUI\Artwork\TitanReload diff --git a/TitanUI/Tools.lua b/TitanUI/Tools.lua index 7f094d7..52ec364 100755 --- a/TitanUI/Tools.lua +++ b/TitanUI/Tools.lua @@ -21,78 +21,61 @@ local VERSION = C_AddOns.GetAddOnMetadata(add_on, "Version") -- ******************************** Variables ******************************* local trace = false -- true / false Make true when debug output is needed. +--[[ local function SendSlash(slash, params) DEFAULT_CHAT_FRAME.editBox:SetText(_G[slash] .. " " .. tostring(params)) ChatEdit_SendText(DEFAULT_CHAT_FRAME.editBox, 0) end +SendSlash("SLASH_TitanPanel1", "reset") +--]] +local function SendSlash(slash) + DEFAULT_CHAT_FRAME.editBox:SetText(slash) + ChatEdit_SendText(DEFAULT_CHAT_FRAME.editBox, 0) +end --- Create the right click menu for this plugin -local function CreateMenu() - local info = {}; - - TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_PLUGIN].menuText); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_MENU_OPTIONS_BARS"] - info.func = function() - TitanUpdateConfig("init") - AceConfigDialog:Open("Titan Panel Bars") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_MENU_PLUGINS"] - info.func = function() - TitanUpdateConfig("init") - AceConfigDialog:Open("Titan Panel Addon Control") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_MENU_PROFILES"] - info.func = function() - TitanUpdateConfig("init") - AceConfigDialog:Open("Titan Panel Addon Chars") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - -- Option to toggle the framestack cmd - info = {}; - info.notCheckable = true - info.text = "/titanpanel reset" - info.func = function() - SendSlash("SLASH_TitanPanel1", "reset") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - -- Option to toggle the framestack cmd - info = {}; - info.notCheckable = true - info.text = "Toggle frame details" - info.func = function() - SendSlash("SLASH_FRAMESTACK1") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); - - -- Option to open WoWLua, if loaded - info = {}; - info.notCheckable = true - info.text = "Open WoWLua" - ---@diagnostic disable-next-line: undefined-global - info.disabled = (SLASH_WOWLUA1 == nil) - info.func = function() - SendSlash("SLASH_WOWLUA1") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddControlVars(TITAN_PLUGIN) +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_PLUGIN + local root = rootDescription -- menu widget to start with + + local config = L["TITAN_PANEL_MENU_CONFIGURATION"].." " + Titan_Menu.AddCommand(root, id, config..L["TITAN_PANEL_MENU_OPTIONS_BARS"], + function() + TitanUpdateConfig("init") + AceConfigDialog:Open("Titan Panel Bars") + end) + + Titan_Menu.AddCommand(root, id, config..L["TITAN_PANEL_MENU_PLUGINS"], + function() + TitanUpdateConfig("init") + AceConfigDialog:Open("Titan Panel Addon Control") + end) + + Titan_Menu.AddCommand(root, id, config..L["TITAN_PANEL_MENU_PROFILES"], + function() + TitanUpdateConfig("init") + AceConfigDialog:Open("Titan Panel Addon Chars") + end) + + Titan_Menu.AddDivider(root) + local t_reset = "/titanpanel reset" + Titan_Menu.AddCommand(root, id, t_reset, + function() + SendSlash(t_reset) + end) + + Titan_Menu.AddDivider(root) + local fstack = "/fstack" + Titan_Menu.AddCommand(root, id, fstack, + function() + SendSlash(fstack) + end) + + Titan_Menu.AddDivider(root) + local lua_cmd = "/lua" + Titan_Menu.AddCommand(root, id, lua_cmd, + function() + SendSlash(lua_cmd) + end) end -- Grab the button text to display @@ -147,7 +130,8 @@ local function OnLoad(self) category = "Built-ins", version = VERSION, menuText = TITLE, - menuTextFunction = CreateMenu, + -- menuTextFunction = CreateMenu, + menuContextFunction = GeneratorFunction, -- NEW scheme buttonTextFunction = GetButtonText, tooltipTitle = TITLE, tooltipTextFunction = GetTooltipText, diff --git a/TitanVolume/TitanVolume.lua b/TitanVolume/TitanVolume.lua index f6a6732..6eb2e8f 100644 --- a/TitanVolume/TitanVolume.lua +++ b/TitanVolume/TitanVolume.lua @@ -281,27 +281,16 @@ local function GetTooltipText() return text end ----local Generate the right click menu -local function CreateMenu() - TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_VOLUME_ID].menuText); - - local info = {}; - info.notCheckable = true - info.text = L["TITAN_VOLUME_MENU_AUDIO_OPTIONS_LABEL"]; - info.func = function() - ShowUIPanel(VideoOptionsFrame); - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); +---Generate and display right click menu options for user. +---@param owner table Plugin frame +---@param rootDescription table Menu context root +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_VOLUME_ID + local root = rootDescription -- menu widget to start with - info.text = L["TITAN_VOLUME_MENU_OVERRIDE_BLIZZ_SETTINGS"]; - info.notCheckable = false - info.func = function() - TitanToggleVar(TITAN_VOLUME_ID, "OverrideBlizzSettings"); - end - info.checked = TitanGetVar(TITAN_VOLUME_ID, "OverrideBlizzSettings"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); + Titan_Menu.AddCommand(root, id, L["TITAN_VOLUME_MENU_AUDIO_OPTIONS_LABEL"], ShowUIPanel, VideoOptionsFrame) - TitanPanelRightClickMenu_AddControlVars(TITAN_VOLUME_ID) + Titan_Menu.AddSelector(root, id, L["TITAN_VOLUME_MENU_OVERRIDE_BLIZZ_SETTINGS"], "OverrideBlizzSettings") end ---local On double click toggle the all sound mute; will flash the slider frame... @@ -336,7 +325,8 @@ local function OnLoad(self) category = "Built-ins", version = TITAN_VERSION, menuText = L["TITAN_VOLUME_MENU_TEXT"], - menuTextFunction = CreateMenu, +-- menuTextFunction = CreateMenu, + menuContextFunction = GeneratorFunction, -- NEW scheme tooltipTitle = VOLUME, --L["TITAN_VOLUME_TOOLTIP"], tooltipTextFunction = GetTooltipText, iconWidth = 32, @@ -409,6 +399,10 @@ local function Create_Frames() config:SetScript("OnUpdate", function(self, elapsed) TitanUtils_CheckFrameCounting(self, elapsed) end) + window:SetScript("OnClick", function(self, button) + -- prevent frame flash +-- TitanPanelButton_OnClick(self, button) + end) window:SetScript("OnDoubleClick", function(self, button) OnDoubleClick(self, button) -- TitanPanelButton_OnClick(self, button) diff --git a/TitanVolume/TitanVolume.toc b/TitanVolume/TitanVolume.toc index f882d12..ca41a45 100644 --- a/TitanVolume/TitanVolume.toc +++ b/TitanVolume/TitanVolume.toc @@ -1,6 +1,6 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55fVolume|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fVolume|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## IconTexture: Interface\AddOns\TitanVolume\Artwork\TitanVolumeHigh ## Notes: Adds a volume control icon on your Titan Bar ## Author: Titan Panel Development Team diff --git a/TitanXP/TitanXP.lua b/TitanXP/TitanXP.lua index 51f6044..8cef68e 100644 --- a/TitanXP/TitanXP.lua +++ b/TitanXP/TitanXP.lua @@ -271,16 +271,6 @@ local function OnEvent(self, event, a1, a2, ...) end end ----local Display XP / hour to level data. -local function ShowXPPerHourLevel() - TitanSetVar(TITAN_XP_ID, "DisplayType", "ShowXPPerHourLevel"); - TitanPanelButton_UpdateButton(TITAN_XP_ID); - TitanSetVar(TITAN_XP_ID, "ShowSimpleRested", false); - TitanSetVar(TITAN_XP_ID, "ShowSimpleToLevel", false); - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfKills", false); - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfGains", false); -end - ---local Determine the plugin button text based on user preferences. ---@param id string ---@return string text_label @@ -506,135 +496,48 @@ local function GetTooltipText() return res end ----local Place commas or periods in the number per user options. ----@param chosen string -local function Seperator(chosen) - if chosen == "UseSeperatorComma" then - TitanSetVar(TITAN_XP_ID, "UseSeperatorComma", true); - TitanSetVar(TITAN_XP_ID, "UseSeperatorPeriod", false); - end - if chosen == "UseSeperatorPeriod" then - TitanSetVar(TITAN_XP_ID, "UseSeperatorComma", false); - TitanSetVar(TITAN_XP_ID, "UseSeperatorPeriod", true); - end - TitanPanelButton_UpdateButton(TITAN_XP_ID); -end - ----local Display XP per hour this session. -local function ShowXPPerHourSession() - TitanSetVar(TITAN_XP_ID, "DisplayType", "ShowXPPerHourSession"); - TitanPanelButton_UpdateButton(TITAN_XP_ID); - TitanSetVar(TITAN_XP_ID, "ShowSimpleRested", false); - TitanSetVar(TITAN_XP_ID, "ShowSimpleToLevel", false); - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfKills", false); - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfGains", false); -end - ----local Display session time. -local function ShowSessionTime() - TitanSetVar(TITAN_XP_ID, "DisplayType", "ShowSessionTime"); - TitanPanelButton_UpdateButton(TITAN_XP_ID); - TitanSetVar(TITAN_XP_ID, "ShowSimpleRested", false); - TitanSetVar(TITAN_XP_ID, "ShowSimpleToLevel", false); - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfKills", false); - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfGains", false); -end - ----local Display simple XP data (% level, rest, xp to level). -local function ShowXPSimple() - TitanSetVar(TITAN_XP_ID, "DisplayType", "ShowXPSimple"); - TitanPanelButton_UpdateButton(TITAN_XP_ID); -end - ----local Generate right click menu. -local function CreateMenu() - local info = {}; - if TitanPanelRightClickMenu_GetDropdownLevel() == 2 then - TitanPanelRightClickMenu_AddTitle(L["TITAN_XP_MENU_SIMPLE_BUTTON_TITLE"], 2); - - info = {}; - info.text = L["TITAN_XP_MENU_SIMPLE_BUTTON_RESTED"]; - info.func = function() TitanPanelRightClickMenu_ToggleVar({ TITAN_XP_ID, "ShowSimpleRested" }) end - info.checked = TitanUtils_Ternary(TitanGetVar(TITAN_XP_ID, "ShowSimpleRested"), 1, nil); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_XP_MENU_SIMPLE_BUTTON_TOLEVELUP"]; - info.func = function() TitanPanelRightClickMenu_ToggleVar({ TITAN_XP_ID, "ShowSimpleToLevel" }) end - info.checked = TitanUtils_Ternary(TitanGetVar(TITAN_XP_ID, "ShowSimpleToLevel"), 1, nil); - info.keepShownOnClick = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_XP_MENU_SIMPLE_BUTTON_KILLS"]; - info.func = function() - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfKills", true) - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfGains", false) - end - info.checked = TitanUtils_Ternary(TitanGetVar(TITAN_XP_ID, "ShowSimpleNumOfKills"), 1, nil); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_XP_MENU_SIMPLE_BUTTON_XPGAIN"]; - info.func = function() - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfGains", true) - TitanSetVar(TITAN_XP_ID, "ShowSimpleNumOfKills", false) - end - info.checked = TitanUtils_Ternary(TitanGetVar(TITAN_XP_ID, "ShowSimpleNumOfGains"), 1, nil); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - return - elseif TitanPanelRightClickMenu_GetDropdownLevel() == 1 then - TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_XP_ID].menuText); - info = {}; - info.text = L["TITAN_XP_MENU_SHOW_XPHR_THIS_SESSION"]; - info.func = ShowXPPerHourSession; - info.checked = TitanUtils_Ternary("ShowXPPerHourSession" == TitanGetVar(TITAN_XP_ID, "DisplayType"), 1, nil); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_XP_MENU_SHOW_XPHR_THIS_LEVEL"]; - info.func = ShowXPPerHourLevel; - info.checked = TitanUtils_Ternary("ShowXPPerHourLevel" == TitanGetVar(TITAN_XP_ID, "DisplayType"), 1, nil); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_XP_MENU_SHOW_SESSION_TIME"]; - info.func = ShowSessionTime; - info.checked = TitanUtils_Ternary("ShowSessionTime" == TitanGetVar(TITAN_XP_ID, "DisplayType"), 1, nil); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_XP_MENU_SHOW_RESTED_TOLEVELUP"]; - info.func = ShowXPSimple; - info.hasArrow = 1; - info.checked = TitanUtils_Ternary("ShowXPSimple" == TitanGetVar(TITAN_XP_ID, "DisplayType"), 1, nil); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSpacer(); - TitanPanelRightClickMenu_AddCommand(L["TITAN_XP_MENU_RESET_SESSION"], TITAN_XP_ID, ResetThisSession); - TitanPanelRightClickMenu_AddCommand(L["TITAN_XP_MENU_REFRESH_PLAYED"], TITAN_XP_ID, RefreshPlayed); - end - - TitanPanelRightClickMenu_AddSpacer(); - - info = {}; - info.text = L["TITAN_PANEL_USE_COMMA"]; - info.checked = TitanGetVar(TITAN_XP_ID, "UseSeperatorComma"); - info.func = function() - Seperator("UseSeperatorComma") +---Generate and display right click menu options for user. +---@param owner table Plugin frame +---@param rootDescription table Menu context root +local function GeneratorFunction(owner, rootDescription) + local id = TITAN_XP_ID + local root = rootDescription -- menu widget to start with + + Titan_Menu.AddCommand(root, id, L["TITAN_XP_MENU_RESET_SESSION"], ResetThisSession) + Titan_Menu.AddCommand(root, id, L["TITAN_XP_MENU_REFRESH_PLAYED"], RefreshPlayed) + + -- orig menu had logic to set several *'simple'* options to false + -- This was nice but over complicated the menu. + -- GetButtonText logic handles the options correctly. + -- It should not confuse the user :) seeing the *'simple'* options selected but used only when + -- ShowXPSimple is set. + local disp = { -- selectors using the same option + {L["TITAN_XP_MENU_SHOW_XPHR_THIS_SESSION"], "ShowXPPerHourSession"}, + {L["TITAN_XP_MENU_SHOW_XPHR_THIS_LEVEL"], "ShowXPPerHourLevel"}, + {L["TITAN_XP_MENU_SHOW_SESSION_TIME"], "ShowSessionTime"}, + {L["TITAN_XP_MENU_SHOW_RESTED_TOLEVELUP"], "ShowXPSimple"}, + } + Titan_Menu.AddSelectorList(root, id, nil, "DisplayType", disp) + + local opts_simple = Titan_Menu.AddButton(root, L["TITAN_XP_MENU_SHOW_RESTED_TOLEVELUP"]) + do + Titan_Menu.AddSelector(opts_simple, id, L["TITAN_XP_MENU_SIMPLE_BUTTON_RESTED"], "ShowSimpleRested") + Titan_Menu.AddSelector(opts_simple, id, L["TITAN_XP_MENU_SIMPLE_BUTTON_TOLEVELUP"], "ShowSimpleToLevel") + + local estimate = { -- mututally exclusive + {L["TITAN_XP_MENU_SIMPLE_BUTTON_KILLS"], "ShowSimpleNumOfKills"}, + {L["TITAN_XP_MENU_SIMPLE_BUTTON_XPGAIN"], "ShowSimpleNumOfGains"}, + } + Titan_Menu.AddSelectorExclusiveList(opts_simple, id, "Coin Labels", estimate) end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - info = {}; - info.text = L["TITAN_PANEL_USE_PERIOD"]; - info.checked = TitanGetVar(TITAN_XP_ID, "UseSeperatorPeriod"); - info.func = function() - Seperator("UseSeperatorPeriod") - end - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); + Titan_Menu.AddDivider(root) - TitanPanelRightClickMenu_AddControlVars(TITAN_XP_ID) + local sep = { -- mututally exclusive + {L["TITAN_PANEL_USE_COMMA"], "UseSeperatorComma"}, + {L["TITAN_PANEL_USE_PERIOD"], "UseSeperatorPeriod"}, + } + Titan_Menu.AddSelectorExclusiveList(root, id, "Separator", sep) end ---local Create plugin .registry and and init some variables and register for first events @@ -648,7 +551,7 @@ local function OnLoad(self) category = "Built-ins", version = TITAN_VERSION, menuText = L["TITAN_XP_MENU_TEXT"], - menuTextFunction = CreateMenu, + menuContextFunction = GeneratorFunction, -- NEW scheme (1st priority) buttonTextFunction = GetButtonText, tooltipTitle = L["TITAN_XP_TOOLTIP"], tooltipTextFunction = GetTooltipText, diff --git a/TitanXP/TitanXP.toc b/TitanXP/TitanXP.toc index ef26f22..a2c1412 100644 --- a/TitanXP/TitanXP.toc +++ b/TitanXP/TitanXP.toc @@ -1,6 +1,6 @@ -## Interface: 120001, 120000, 110207, 50503, 20505, 11508 -## Title: Titan Panel [|cffeda55fXP|r] |cff00aa009.0.2|r -## Version: 9.0.2 +## Interface: 120000, 110207, 50503, 20505, 11508 +## Title: Titan Panel [|cffeda55fXP|r] |cff00aa009.1.0-pre|r +## Version: 9.1.0-pre ## IconTexture: Interface\Icons\xp_icon ## Notes: Adds information to Titan Panel about XP earned and time to level ## Author: Titan Panel Development Team