---@diagnostic disable: duplicate-set-field --[[ File NAME: TitanPanel.lua DESC: Contains the basic routines of Titan. All the event handler routines, initialization routines, Titan menu routines, and select plugin handler routines. --]] -- Locals local TPC = TITAN_PANEL_CONSTANTS -- shortcut local TITAN_PANEL_BUTTONS_INIT_FLAG = nil; local _G = _G --getfenv(0); local InCombatLockdown = _G.InCombatLockdown; local IsTitanPanelReset = nil; -- Library references local L = LibStub("AceLocale-3.0"):GetLocale(TITAN_ID, true) local AceTimer = LibStub("AceTimer-3.0") local media = LibStub("LibSharedMedia-3.0") local AceConfigDialog = LibStub("AceConfigDialog-3.0") -- TitanDebug (cmd.." : "..p1.." "..p2.." "..p3.." "..#cmd_list) -------------------------------------------------------------- -- function TitanPanel_OkToReload() StaticPopupDialogs["TITAN_RESET_RELOAD"] = { text = TitanUtils_GetNormalText(L["TITAN_PANEL_MENU_TITLE"]) .. "\n\n" .. L["TITAN_PANEL_RESET_WARNING"], button1 = ACCEPT, button2 = CANCEL, OnAccept = function(self) ReloadUI() end, showAlert = 1, timeout = 0, whileDead = 1, hideOnEscape = 1 }; StaticPopup_Show("TITAN_RESET_RELOAD"); end --[[ Titan NAME: TitanPanel_ResetToDefault DESC: Give the user a 'are you sure'. If the user accepts then reset current toon back to default Titan settings. VAR: None OUT: None NOTE: - Even if the user was using global profiles they will not when this is done. :NOTE --]] function TitanPanel_ResetToDefault() StaticPopupDialogs["TITAN_RESET_BAR"] = { text = TitanUtils_GetNormalText(L["TITAN_PANEL_MENU_TITLE"]) .. "\n\n" .. L["TITAN_PANEL_RESET_WARNING"], button1 = ACCEPT, button2 = CANCEL, OnAccept = function(self) TitanVariables_UseSettings(TitanSettings.Player, TITAN_PROFILE_RESET); IsTitanPanelReset = true; ReloadUI() end, showAlert = 1, timeout = 0, whileDead = 1, hideOnEscape = 1 }; StaticPopup_Show("TITAN_RESET_BAR"); end --[[ Titan NAME: TitanPanel_SaveCustomProfile DESC: The user wants to save a custom Titan profile. Show the user the dialog boxes to make it happen. VAR: None OUT: None NOTE: - The profile is written to the Titan saved variables. A reload of the UI is needed to ensure the profile is written to disk for the user to load later. :NOTE --]] function TitanPanel_SaveCustomProfile() -- Create the dialog box code we'll need... -- helper to actually write the profile to the Titan saved vars local function Write_profile(name) local currentprofilevalue, _, _ = TitanUtils_GetPlayer() local profileName = TitanUtils_CreateName(name, TITAN_CUSTOM_PROFILE_POSTFIX) TitanSettings.Players[profileName] = TitanSettings.Players[currentprofilevalue] TitanPrint(L["TITAN_PANEL_MENU_PROFILE_SAVE_PENDING"] .. "'" .. name .. "'" , "info") end -- helper to ask the user to overwrite a profile local function Overwrite_profile(name) local dialogFrame = StaticPopup_Show("TITAN_OVERWRITE_CUSTOM_PROFILE", name); if dialogFrame then dialogFrame.data = name; end end -- helper to handle getting the profile name from the user local function Get_profile_name(self) local rawprofileName = self.editBox:GetText(); -- remove any spaces the user may have typed in the name local conc2profileName = string.gsub(rawprofileName, " ", ""); if conc2profileName == "" then return; end -- no '@' is allowed or it will mess with the Titan profile naming convention local concprofileName = string.gsub(conc2profileName, TITAN_AT, "-"); local profileName = TitanUtils_CreateName(concprofileName, TITAN_CUSTOM_PROFILE_POSTFIX) if TitanSettings.Players[profileName] then -- Warn the user of an existing profile Overwrite_profile(rawprofileName) self:Hide(); return; else -- Save the requested profile Write_profile(rawprofileName) self:Hide(); StaticPopup_Show("TITAN_RELOADUI"); end end -- Dialog box to warn the user that the UI will be reloaded -- This ensures the profile is written to disk StaticPopupDialogs["TITAN_RELOADUI"] = { text = TitanUtils_GetNormalText(L["TITAN_PANEL_MENU_TITLE"]) .. "\n\n" .. L["TITAN_PANEL_MENU_PROFILE_RELOADUI"], button1 = "OKAY", OnAccept = function(self) ReloadUI(); -- ensure profile is written to disk end, showAlert = 1, whileDead = 1, timeout = 0, }; -- Dialog box to warn the user that an existing profile will be overwritten. StaticPopupDialogs["TITAN_OVERWRITE_CUSTOM_PROFILE"] = { text = TitanUtils_GetNormalText(L["TITAN_PANEL_MENU_TITLE"]) .. "\n\n" .. L["TITAN_PANEL_MENU_PROFILE_ALREADY_EXISTS"], button1 = ACCEPT, button2 = CANCEL, OnAccept = function(self, data) Write_profile(data) self:Hide(); StaticPopup_Show("TITAN_RELOADUI"); end, showAlert = 1, whileDead = 1, timeout = 0, hideOnEscape = 1 }; -- Dialog box to save the profile. StaticPopupDialogs["TITAN_SAVE_CUSTOM_PROFILE"] = { text = TitanUtils_GetNormalText(L["TITAN_PANEL_MENU_TITLE"]) .. "\n\n" .. L["TITAN_PANEL_MENU_PROFILE_SAVE_CUSTOM_TITLE"], button1 = ACCEPT, button2 = CANCEL, hasEditBox = 1, maxLetters = 20, OnAccept = function(self) -- self refers to this frame with the Accept button Get_profile_name(self) end, OnShow = function(self) self.editBox:SetFocus(); end, OnHide = function(self) self.editBox:SetText(""); end, EditBoxOnEnterPressed = function(self) -- We need to get the parent because self refers to the edit box. Get_profile_name(self:GetParent()) end, EditBoxOnEscapePressed = function(self) self:GetParent():Hide(); end, timeout = 0, exclusive = 1, whileDead = 1, hideOnEscape = 1 }; StaticPopup_Show("TITAN_SAVE_CUSTOM_PROFILE"); -- Can NOT cleanup. Execution does not stop when a dialog box is invoked! -- StaticPopupDialogs["TITAN_RELOADUI"] = {} -- StaticPopupDialogs["TITAN_OVERWRITE_CUSTOM_PROFILE"] = {} -- StaticPopupDialogs["TITAN_SAVE_CUSTOM_PROFILE"] = {} end --[[ Titan NAME: TitanSetPanelFont DESC: Set or change the font and font size of text on the Titan bar. This affects ALL plugins. VAR: fontname - The text name of the font to use. Defaults to Titan default if none given. VAR: fontsize - The size of the font to use. Defaults to Titan default if none given. OUT: None NOTE: - Each registered plugin will have its font updated. Then all plugins will be refreshed to show the new font. :NOTE --]] function TitanSetPanelFont(fontname, fontsize) -- a couple of arg checks to avoid unpleasant things... if not fontname then fontname = TPC.FONT_NAME end if not fontsize then fontsize = TPC.FONT_SIZE end local newfont = media:Fetch("font", fontname) for index, id in pairs(TitanPluginsIndex) do local button = TitanUtils_GetButton(id) if button then local buttonText = _G[button:GetName() .. TITAN_PANEL_TEXT]; if buttonText then buttonText:SetFont(newfont, fontsize); end -- account for plugins with child buttons local childbuttons = { button:GetChildren() }; for _, child in ipairs(childbuttons) do if child then local bname = _G[child:GetName()] if bname then local childbuttonText = _G[child:GetName() .. TITAN_PANEL_TEXT]; if childbuttonText then childbuttonText:SetFont(newfont, fontsize); end end end end end end TitanPanel_RefreshPanelButtons(); end local function RegisterForEvents() -- Need to be careful of regeristering for events that initiate -- show / hide of Bars before the Bars can be initialized... _G[TITAN_PANEL_CONTROL]:RegisterEvent("CVAR_UPDATE"); _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_LOGOUT"); -- For the pet battle - for now we'll hide the Titan bars... -- Cannot seem to move the 'top' part of the pet battle frame. _G[TITAN_PANEL_CONTROL]:RegisterEvent("PET_BATTLE_OPENING_START"); _G[TITAN_PANEL_CONTROL]:RegisterEvent("PET_BATTLE_CLOSE"); -- Hide Titan bars in combat (global or per bar); may be useful when using Short bars _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_REGEN_ENABLED"); _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_REGEN_DISABLED"); -- User request to hide Top bar(s) in BG or arena; more areas later? _G[TITAN_PANEL_CONTROL]:RegisterEvent("ZONE_CHANGED"); _G[TITAN_PANEL_CONTROL]:RegisterEvent("ZONE_CHANGED_INDOORS"); _G[TITAN_PANEL_CONTROL]:RegisterEvent("ZONE_CHANGED_NEW_AREA"); end -------------------------------------------------------------- _G[TITAN_PANEL_CONTROL]:RegisterEvent("ADDON_LOADED"); -- -- Event routine : redirects to TitanPanelBarButton:<registered event> routines below. _G[TITAN_PANEL_CONTROL]:SetScript("OnEvent", function(_, event, ...) _G[TITAN_PANEL_CONTROL][event](_G[TITAN_PANEL_CONTROL], ...) end) --[[ Titan NAME: TitanPanel_PlayerEnteringWorld DESC: Do all the setup needed when a user logs in / reload UI / enter or leave an instance. VAR: None OUT: None NOTE: - This is called after the 'player entering world' event is fired by Blizz. - This is also used when a LDB plugin is created after Titan runs the 'player entering world' code. :NOTE --]] function TitanPanel_PlayerEnteringWorld(reload) --[[ print("PEW" .." "..tostring(Titan__InitializedPEW).."" ) --]] if Titan__InitializedPEW then -- Currently no additional steps needed else -- Get Profile and Saved Vars TitanVariables_InitTitanSettings(); if TitanAllGetVar("Silenced") then -- No header output else 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 TitanPanelTopAnchor:ClearAllPoints(); TitanPanelTopAnchor:SetPoint("TOPLEFT", "UIParent", "TOPLEFT", 0, 0); TitanPanelBottomAnchor:ClearAllPoints(); TitanPanelBottomAnchor:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", 0, 0); -- Ensure the bars are created before the plugins are registered. for idx, v in pairs(TitanBarData) do TitanPanelButton_CreateBar(idx) end -- Titan_AutoHide_Create_Frames() -- 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 --[[ With user able to move the UI around and short bars, remove this feature -- Check to see if we should kill off the OrderHallCommandBar if not TitanAllGetVar("OrderHall") then local TitanPanelAce = LibStub("AceAddon-3.0"):NewAddon("TitanPanelOHCB", "AceHook-3.0") TitanPanelAce:SecureHook("OrderHall_CheckCommandBar", function() if OrderHallCommandBar then OrderHallCommandBar:Hide() OrderHallCommandBar:UnregisterAllEvents() OrderHallCommandBar.Show = function () end end end ) else local TitanPanelAce = LibStub("AceAddon-3.0"):NewAddon("TitanPanelOHCB", "AceHook-3.0") TitanPanelAce:Unhook("OrderHall_CheckCommandBar") end --]] -- Should be safe to register for events that could show / hide Bars RegisterForEvents() end local _ = nil TitanSettings.Player, _, _ = TitanUtils_GetPlayer() -- Some addons wait to create their LDB component or a Titan addon could -- create additional buttons as needed. -- So we need to sync their variables and set them up TitanUtils_RegisterPluginList() TitanVariables_UseSettings(nil, TITAN_PROFILE_INIT) -- all addons are loaded so update the config (options) -- some could have registered late... TitanUpdateConfig("init") -- Init panel font local isfontvalid = media:IsValid("font", TitanPanelGetVar("FontName")) if isfontvalid then TitanSetPanelFont(TitanPanelGetVar("FontName"), TitanPanelGetVar("FontSize")) else -- if the selected font is not valid, revert to default (Friz Quadrata TT) TitanPanelSetVar("FontName", TPC.FONT_NAME); TitanSetPanelFont(TPC.FONT_NAME, TitanPanelGetVar("FontSize")) end -- Init panel frame strata TitanVariables_SetPanelStrata(TitanPanelGetVar("FrameStrata")) -- Titan Panel has initialized its variables and registered plugins. -- Allow Titan - and others - to adjust the bars Titan__InitializedPEW = true -- Move frames if TITAN_ID == "TitanClassic" then TitanMovable_SecureFrames() TitanPanel_AdjustFrames() else -- No need end -- Also sync LDB object text with their created Titan plugin TitanLDBRefreshButton() end -------------------------------------------------------------- -- -- Event handlers -- --[===[ local WoWClassicEra, WoWClassicTBC, WoWWOTLKC, WoWRetail if wowversion < 20000 then WoWClassicEra = true elseif wowversion < 30000 then WoWClassicTBC = true elseif wowversion < 40000 then WoWWOTLKC = true elseif wowversion > 90000 then WoWRetail = true else -- n/a end --]===] function TitanPanelBarButton:ADDON_LOADED(addon) if addon == TITAN_ID then --[[ print("ADDON_LOADED" .." "..tostring(addon).."" ) --]] _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_ENTERING_WORLD") TitanVariables_InitTitanSettings() -- Min table setup to start. --[===[ -- Determine WoW TOC Version local wowversion = select(4, GetBuildInfo()) if wowversion >= 100000 then -- Initialize Titan _G[TITAN_PANEL_CONTROL]:RegisterEvent("PLAYER_ENTERING_WORLD") TitanVariables_InitTitanSettings() -- Min table setup to start. else -- User loaded wrong Titan version; tried to use retail on Classic or Classic Era -- Could save the user grief; Titan could mangle the saved vars on a version mismatch. TitanPrint("Titan did not initialize!!!!" , "error") TitanPrint("This version needs API released with " .." "..tostring(EXPANSION_NAME9).."" .." (10.00.xx)" , "error") end --]===] -- Unregister event - saves a few event calls. self:UnregisterEvent("ADDON_LOADED"); self.ADDON_LOADED = nil end end function TitanPanelBarButton:PLAYER_ENTERING_WORLD(arg1, arg2) local call_success = nil local ret_val = nil --[[ print("PLAYER_ENTERING_WORLD" .." "..tostring(arg1).."" .." "..tostring(arg2).."" ) --]] call_success, -- needed for pcall ret_val = -- actual return values pcall(TitanPanel_PlayerEnteringWorld, arg2) -- pcall does not allow errors to propagate out. Any error -- is returned as text with the success / fail. -- Think of it as a try - catch block --[[ print("_PlayerEnteringWorld" .." "..tostring(call_success).."" ) --]] if call_success then -- Titan initialized properly else -- something really bad occured... TitanPrint("Titan could not initialize!!!! Cleaning up...", "error") TitanPrint("--" .. ret_val, "error") -- Clean up best we can and tell the user to submit a ticket. -- This could be the 1st log in or a reload (reload, instance, boat, ...) -- Hide the bars. At times they are there but at 0% transparency. -- They can be over the Blizz action bars creating havoc. TitanPrint("-- Hiding Titan bars...", "warning") TitanPanelBarButton_HideAllBars() -- Remove the options pages TitanUpdateConfig("nuke") -- What else to clean up??? -- raise the error to WoW for display, if display errors is set. -- This *must be* the last statement of the routine! error(ret_val, 1) end end function TitanPanelBarButton:CVAR_UPDATE(cvarname, cvarvalue) if cvarname == "USE_UISCALE" or cvarname == "WINDOWED_MODE" or cvarname == "uiScale" then if TitanPlayerSettings and TitanPanelGetVar("Scale") then TitanPanel_InitPanelBarButton("CVAR_ " .. tostring(cvarname)) if TITAN_ID == "TitanClassic" then -- Adjust frame positions TitanPanel_AdjustFrames("PLAYER_REGEN_ENABLED") else -- No need end end end end function TitanPanelBarButton:PLAYER_LOGOUT() if not IsTitanPanelReset then -- for debug if TitanPanelRegister then TitanPanelRegister.ToBe = TitanPluginToBeRegistered TitanPanelRegister.ToBeNum = TitanPluginToBeRegisteredNum TitanPanelRegister.TitanPlugins = TitanPlugins end end Titan__InitializedPEW = false end function TitanPanelBarButton:ZONE_CHANGED() TitanPanelBarButton_DisplayBarsWanted("ZONE_CHANGED") end function TitanPanelBarButton:ZONE_CHANGED_INDOORS() TitanPanelBarButton_DisplayBarsWanted("ZONE_CHANGED_INDOORS") end function TitanPanelBarButton:ZONE_CHANGED_NEW_AREA() TitanPanelBarButton_DisplayBarsWanted("ZONE_CHANGED_NEW_AREA") end function TitanPanelBarButton:PET_BATTLE_OPENING_START() TitanPanelBarButton_DisplayBarsWanted("PET_BATTLE_OPENING_START") end function TitanPanelBarButton:PET_BATTLE_CLOSE() TitanPanelBarButton_DisplayBarsWanted("PET_BATTLE_CLOSE") end local in_combat = false -- seems InCombatLockdown may not be set fast enough to reliably hide bars... function TitanPanelBarButton:PLAYER_REGEN_ENABLED() in_combat = false TitanPanelBarButton_DisplayBarsWanted("PLAYER_REGEN_ENABLED") if TITAN_ID == "TitanClassic" then -- Adjust frame positions TitanPanel_AdjustFrames() else -- No need end end function TitanPanelBarButton:PLAYER_REGEN_DISABLED() in_combat = true TitanPanelBarButton_DisplayBarsWanted("PLAYER_REGEN_DISABLED") end if TITAN_ID == "TitanClassic" then function TitanPanelBarButton:ACTIVE_TALENT_GROUP_CHANGED() -- Is this needed?? -- TitanMovable_AdjustTimer("DualSpec") end function TitanPanelBarButton:UNIT_ENTERED_VEHICLE(self, ...) TitanUtils_CloseAllControlFrames(); TitanUtils_CloseRightClickMenu(); -- Needed because 8.0 made changes to the menu bar processing (see TitanMovable) TitanMovable_MenuBar_Disable() end function TitanPanelBarButton:UNIT_EXITED_VEHICLE(self, ...) -- A combat check will be done inside the adjust TitanPanel_AdjustFrames(true) end --]] -- else -- No need end --[[ Titan NAME: TitanPanelBarButton_OnClick DESC: Handle the button clicks on any Titan bar. VAR: self - expected to be a Titan bar VAR: button - which mouse button was clicked OUT: None NOTE: - This only reacts to the right or left mouse click without modifiers. - Used in the set script for the Titan display and hider frames :NOTE --]] function TitanPanelBarButton_OnClick(self, button) -- ensure that the right-click menu will not appear on "hidden" bottom bar(s) --[[ print("_OnClick" .." "..tostring(bar).."" ) --]] if (button == "LeftButton") then TitanUtils_CloseAllControlFrames(); TitanUtils_CloseRightClickMenu(); elseif (button == "RightButton") then TitanUtils_CloseAllControlFrames(); TitanPanelRightClickMenu_Close(); -- Show RightClickMenu anyway TitanPanelRightClickMenu_Toggle(self) end end -- -- Slash command handler -- --[[ local NAME: TitanPanel_ParseSlashCmd DESC: Helper to parse the user commands. VAR: cmd - user string from the command 'window' OUT: table - table of 'words' the user typed in NOTE: - each 'word' in words table is made lower case for comparison simplicity :NOTE --]] local function TitanPanel_ParseSlashCmd(cmd) local words = {} for w in string.gmatch(cmd, "%w+") do words[#words + 1] = (w and string.lower(w) or "?") end --[[ local tmp = "" for idx,v in pairs (words) do tmp = tmp.."'"..words[idx].."' " end TitanDebug (tmp.." : "..#words) --]] return words end --[[ local NAME: handle_slash_help DESC: Helper to tell the user the relevant Titan commands. VAR: cmd - string 'all' | 'reset' | 'gui' | 'silent' OUT: None NOTE: - Depending on cmd put to chat the appropriate help :NOTE --]] local function handle_slash_help(cmd) cmd = cmd or "all" -- Give the user the general help if we can not figure out what they want TitanPrint("", "header") -- Cannot count registered plugins after initial registration TitanUtils_RegisterPluginList() if cmd == "reset" then TitanPrint(L["TITAN_PANEL_SLASH_RESET_0"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_RESET_1"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_RESET_2"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_RESET_3"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_RESET_4"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_RESET_5"], "plain") end if cmd == "gui" then TitanPrint(L["TITAN_PANEL_SLASH_GUI_0"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_GUI_1"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_GUI_2"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_GUI_3"], "plain") end if cmd == "profile" then TitanPrint(L["TITAN_PANEL_SLASH_PROFILE_0"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_PROFILE_1"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_PROFILE_2"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_PROFILE_3"], "plain") end if cmd == "silent" then TitanPrint(L["TITAN_PANEL_SLASH_SILENT_0"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_SILENT_1"], "plain") end if cmd == "orderhall" then TitanPrint(L["TITAN_PANEL_SLASH_ORDERHALL_0"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_ORDERHALL_1"], "plain") end if cmd == "help" then TitanPrint(L["TITAN_PANEL_SLASH_HELP_0"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_HELP_1"], "plain") end if cmd == "all" then TitanPrint(L["TITAN_PANEL_SLASH_ALL_0"], "plain") TitanPrint(L["TITAN_PANEL_SLASH_ALL_1"], "plain") end end --[[ local NAME: handle_reset_cmds DESC: Helper to execute the various reset commands from the user. VAR: cmd_list - A table containing the list of 'words' the user typed in OUT: None --]] local function handle_reset_cmds(cmd_list) local cmd = cmd_list[1] local p1 = cmd_list[2] or nil -- sanity check if (not cmd == "reset") then return end if p1 == nil then TitanPanel_ResetToDefault(); elseif p1 == "tipfont" then TitanPanelSetVar("TooltipFont", 1); GameTooltip:SetScale(TitanPanelGetVar("TooltipFont")); TitanPrint(L["TITAN_PANEL_SLASH_RESP1"], "info") --[[ elseif p1 == "tipalpha" then TitanPanelSetVar("TooltipTrans", 1); local red, green, blue, _ = GameTooltip:GetBackdropColor(); local red2, green2, blue2, _ = GameTooltip:GetBackdropBorderColor(); GameTooltip:SetBackdropColor(red,green,blue,TitanPanelGetVar("TooltipTrans")); GameTooltip:SetBackdropBorderColor(red2,green2,blue2,TitanPanelGetVar("TooltipTrans")); TitanPrint(L["TITAN_PANEL_SLASH_RESP2"], "info") --]] elseif p1 == "panelscale" then if not InCombatLockdown() then TitanPanelSetVar("Scale", 1); TitanPanel_InitPanelBarButton("/panelscale reset ") if TITAN_ID == "TitanClassic" then -- Adjust frame positions TitanPanel_AdjustFrames() else -- No need end TitanPrint(L["TITAN_PANEL_SLASH_RESP3"], "info") else TitanPrint(L["TITAN_PANEL_MENU_IN_COMBAT_LOCKDOWN"], "warning") end elseif p1 == "spacing" then TitanPanelSetVar("ButtonSpacing", 20); TitanPanel_InitPanelButtons(); TitanPrint(L["TITAN_PANEL_SLASH_RESP4"], "info") else handle_slash_help("reset") end end --[[ local NAME: handle_giu_cmds DESC: Helper to execute the gui related commands from the user. VAR: cmd_list - A table containing the list of 'words' the user typed in OUT: None --]] local function handle_giu_cmds(cmd_list) local cmd = cmd_list[1] local p1 = cmd_list[2] or nil -- sanity check if (not cmd == "gui") then return end -- DF changed how options are called. The best I get is the Titan 'about', not deeper. Settings.OpenToCategory(TITAN_PANEL_CONFIG.topic.About, TITAN_PANEL_CONFIG.topic.scale) -- so the below does not work as expected... end --[[ local NAME: handle_profile_cmds DESC: Helper to execute the profile related commands from the user. VAR: cmd_list - A table containing the list of 'words' the user typed in OUT: None --]] local function handle_profile_cmds(cmd_list) local cmd = cmd_list[1] local p1 = cmd_list[2] or nil local p2 = cmd_list[3] or nil local p3 = cmd_list[4] or nil -- sanity check if (not cmd == "profile") then return end if p1 == "use" and p2 and p3 then if TitanAllGetVar("GlobalProfileUse") then TitanPrint(L["TITAN_PANEL_GLOBAL_ERR_1"], "info") else TitanVariables_UseSettings(TitanUtils_CreateName(p2, p3), TITAN_PROFILE_USE) end else handle_slash_help("profile") end end --[[ local NAME: handle_silent_cmds DESC: Helper to execute the silent commands from the user. VAR: cmd_list - A table containing the list of 'words' the user typed in OUT: None --]] local function handle_silent_cmds(cmd_list) local cmd = cmd_list[1] local p1 = cmd_list[2] or nil -- sanity check if (not cmd == "silent") then return end if TitanAllGetVar("Silenced") then TitanAllSetVar("Silenced", false); TitanPrint(L["TITAN_PANEL_MENU_SILENT_LOAD"] .. " " .. L["TITAN_PANEL_MENU_DISABLED"], "info") else TitanAllSetVar("Silenced", true); TitanPrint(L["TITAN_PANEL_MENU_SILENT_LOAD"] .. " " .. L["TITAN_PANEL_MENU_ENABLED"], "info") end end --[[ local NAME: handle_orderhall_cmds DESC: Helper to execute the orderhall commands from the user. VAR: cmd_list - A table containing the list of 'words' the user typed in OUT: None --]] local function handle_orderhall_cmds(cmd_list) local cmd = cmd_list[1] local p1 = cmd_list[2] or nil -- sanity check if (not cmd == "orderhall") then return end if TitanAllGetVar("OrderHall") then TitanAllSetVar("OrderHall", false); TitanPrint(L["TITAN_PANEL_MENU_HIDE_ORDERHALL"] .. " " .. L["TITAN_PANEL_MENU_ENABLED"], "info") StaticPopupDialogs["TITAN_RELOAD"] = { text = TitanUtils_GetNormalText(L["TITAN_PANEL_MENU_TITLE"]) .. "\n\n" .. L["TITAN_PANEL_RELOAD"], button1 = ACCEPT, button2 = CANCEL, OnAccept = function(self) ReloadUI(); end, showAlert = 1, timeout = 0, whileDead = 1, hideOnEscape = 1 }; StaticPopup_Show("TITAN_RELOAD"); else TitanAllSetVar("OrderHall", true); TitanPrint(L["TITAN_PANEL_MENU_HIDE_ORDERHALL"] .. " " .. L["TITAN_PANEL_MENU_DISABLED"], "info") StaticPopupDialogs["TITAN_RELOAD"] = { text = TitanUtils_GetNormalText(L["TITAN_PANEL_MENU_TITLE"]) .. "\n\n" .. L["TITAN_PANEL_RELOAD"], button1 = ACCEPT, button2 = CANCEL, OnAccept = function(self) ReloadUI(); end, showAlert = 1, timeout = 0, whileDead = 1, hideOnEscape = 1 }; StaticPopup_Show("TITAN_RELOAD"); end end --[[ local NAME: handle_help_cmds DESC: Helper to execute the help commands from the user. VAR: cmd_list - A table containing the list of 'words' the user typed in OUT: None --]] local function handle_help_cmds(cmd_list) local cmd = cmd_list[1] local p1 = cmd_list[2] or nil -- sanity check if (not cmd == "help") then return end handle_slash_help(p1 or "all") end --[[ local NAME: TitanPanel_RegisterSlashCmd DESC: Helper to parse and execute all the Titan slash commands from the user. VAR: cmd - The command (string) the user typed in OUT: None --]] local function TitanPanel_RegisterSlashCmd(cmd_str) local cmd_list = {} -- parse what the user typed cmd_list = TitanPanel_ParseSlashCmd(cmd_str) local cmd = cmd_list[1] or "" local p1 = cmd_list[2] or "" local p2 = cmd_list[3] or "" local p3 = cmd_list[4] or "" if (cmd == "reset") then handle_reset_cmds(cmd_list) elseif (cmd == "gui") then handle_giu_cmds(cmd_list) elseif (cmd == "profile") then handle_profile_cmds(cmd_list) elseif (cmd == "silent") then handle_silent_cmds(p1) elseif (cmd == "orderhall") then handle_orderhall_cmds(p1) elseif (cmd == "help") then handle_slash_help(p1) else handle_slash_help("all") end end --====== Register slash commands for Titan Panel SlashCmdList["TitanPanel"] = TitanPanel_RegisterSlashCmd; SLASH_TitanPanel1 = "/titanpanel"; SLASH_TitanPanel2 = "/titan"; -------------------------------------------------------------- -- -- Texture routines local function Set_Color(frame, tex, color) --[[ print("_Set bar color" .." "..tostring(TitanBarData[frame].tex_name).."" --.." "..tostring(tex:GetName()).."" .." "..tostring(format("%0.1f", color.r)).."" .." "..tostring(format("%0.1f", color.g)).."" .." "..tostring(format("%0.1f", color.b)).."" .." "..tostring(format("%0.1f", color.alpha)).."" ) --]] _G[frame]:SetBackdrop({ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", -- edgeFile="Interface\\Tooltips\\UI-Tooltip-Border", -- edgeFile="Interface\\DialogFrame\\UI-DialogBox-Gold-Border", edgeFile = "Interface\\Glues\\Common\\TextPanel-Border", tile = true, tileEdge = true, -- insets = { left = 1, right = 1, top = 1, bottom = 1 }, tileSize = 8, edgeSize = 8, }) _G[frame]:SetBackdropBorderColor( TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b); _G[frame]:SetBackdropColor( color.r, color.g, color.b, color.alpha); --[[ -- Apply the texture to the bar, using the system repeat to fill it tex:SetColorTexture( color.r, color.g, color.b, color.alpha ) tex:SetAllPoints() tex:SetHorizTile(true) -- ensures repeat; 'smears' if not sest to true tex:SetVertTile(true) -- ensures image is 'full' height of frame --]] end local function Set_Skin(frame, tex, skin) -- Use the texture / skin per user selectable options -- skins are in two parts - top & bottom... -- TODO : have Short bars choose top or bottom skin?? local edge = "" if TitanBarData[frame].vert == TITAN_BOTTOM then edge = TITAN_BOTTOM else edge = TITAN_TOP end -- Apply the texture to the bar, using the system repeat to fill it local texture_file = skin.path .. "TitanPanelBackground" .. edge .. "0" --[[ print("_Skin" .." "..tostring(TitanBarData[frame].tex_name.."" --.." "..tostring(tex:GetName()).."" .." "..tostring(skin.path).."" --.."\n "..tostring(edge).."" --.." "..tostring(skin.alpha).."" --.."\n "..tostring(tex:GetTexture()).."" ) --]] --[[ -- appears seeting image this way just smears image... _G[frame]:SetBackdrop({ bgFile=texture_file, -- edgeFile=nil, tile = true, -- tileSize = 256, -- tileEdge = true, -- insets = { left = 1, right = 1, top = 1, bottom = 1 }, -- tileSize = 8, -- edgeSize = 8, }) --]] tex:SetAllPoints() tex:SetHorizTile(true) -- ensures repeat; 'smears' if not sest to true tex:SetTexture(texture_file, "REPEAT") tex:SetVertTile(true) -- ensures image is 'full' height of frame -- tex:SetHeight(TITAN_PANEL_BAR_TEXTURE_HEIGHT) -- leaves a gap if used tex:SetAlpha(skin.alpha) end function TitanPanel_SetBarTexture(frame) if frame and TitanBarData[frame] then -- proceed else return end -- Create the path & file name to the texture local tex = TitanBarData[frame].tex_name local titanTexture = {} if _G[tex] then titanTexture = _G[tex] else titanTexture = _G[frame]:CreateTexture(tex, "BACKGROUND") end titanTexture:SetTexture() _G[frame]:SetBackdrop({ bgFile = "", }) --[[ print("_Tex" .." "..tostring(TitanBarData[frame].name).."" --.." "..tostring(tex).."" .." "..tostring(titanTexture:GetName()).."" --.." "..tostring(skin.path).."" --.."\n "..tostring(edge).."" --.." "..tostring(skin.alpha).."" --.."\n "..tostring(tex:GetTexture()).."" .." "..tostring(TitanBarDataVars["Global"].texure).."" .." "..tostring(TitanBarDataVars[frame].texure).."" ) --]] -- 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) elseif TitanBarDataVars[frame].texure == Titan_Global.SKIN then Set_Skin(frame, titanTexture, TitanBarDataVars[frame].skin) elseif TitanBarDataVars[frame].texure == Titan_Global.COLOR then Set_Color(frame, titanTexture, TitanBarDataVars[frame].color) end end -------------------------------------------------------------- -- -- auto hide event handlers --[[ Titan NAME: TitanPanelBarButton_OnLeave DESC: On leaving the display check if we have to hide the Titan bar. A timer is used - when it expires the bar is hid. VAR: self - expected to be a Titan bar OUT: None --]] function TitanPanelBarButton_OnLeave(self) local frame = (self and self:GetName() or nil) local bar = (TitanBarData[frame] and TitanBarData[frame].name or nil) -- if auto hide is active then let the timer hide the bar local hide = (bar and TitanBarDataVars[frame].auto_hide or nil) -- local hide = (bar and TitanPanelGetVar(bar.."_Hide") or nil) if hide then Titan_AutoHide_Timers(frame, "Leave") end end --[[ Titan NAME: TitanPanelBarButton_OnEnter DESC: No code - this is a place holder for the XML template. VAR: self - expected to be a Titan bar OUT: None --]] function TitanPanelBarButton_OnEnter(self) -- no work to do end --[[ Titan NAME: TitanPanelBarButtonHider_OnLeave DESC: No code - this is a place holder for the XML template. VAR: self - expected to be a Titan bar OUT: None --]] function TitanPanelBarButtonHider_OnLeave(self) -- no work to do end --[[ Titan NAME: TitanPanelBarButtonHider_OnEnter DESC: On entering the hider check if we need to show the display bar. VAR: self - expected to be a Titan hider bar OUT: None NOTE: - No action is taken if the user is on combat. :NOTE --]] function TitanPanelBarButtonHider_OnEnter(self) -- make sure self is valid local index = self and self:GetName() or nil if not index then return end -- sanity check -- so the bar does not 'appear' when moused over in combat if TitanPanelGetVar("LockAutoHideInCombat") and InCombatLockdown() then return end -- find the relevant bar data local frame = nil for idx, v in pairs(TitanBarData) do if index == TitanBarData[idx].hider then frame = idx end end -- Now process that bar if frame then Titan_AutoHide_Timers(frame, "Enter") TitanPanelBarButton_Show(frame) end end --====== Titan Frames for CLASSIC versions -- --========================== -- Routines to handle adjusting some UI frames -- --[[ Titan NAME: TitanPanelBarButton_ToggleAlign DESC: Align the buttons per the user's new choice. VAR: align - left or center OUT: None --]] function TitanPanelBarButton_ToggleAlign(align) -- toggle between left or center if (TitanPanelGetVar(align) == TITAN_PANEL_BUTTONS_ALIGN_CENTER) then TitanPanelSetVar(align, TITAN_PANEL_BUTTONS_ALIGN_LEFT); else TitanPanelSetVar(align, TITAN_PANEL_BUTTONS_ALIGN_CENTER); end -- Justify button position TitanPanelButton_Justify(); end --[[ Titan NAME: TitanPanelBarButton_ToggleAutoHide DESC: Toggle the auto hide of the given Titan bar per the user's new choice. VAR: frame - expected to be a Titan bar OUT: None --]] function TitanPanelBarButton_ToggleAutoHide(frame) local frName = _G[frame] local plugin = (TitanBarData[frame] and TitanBarData[frame].auto_hide_plugin or nil) if frName then Titan_AutoHide_ToggleAutoHide(_G[plugin]) end end --[[ Titan NAME: TitanPanelBarButton_ToggleScreenAdjust DESC: Toggle whether Titan adjusts 'top' frames around Titan bars per the user's new choice. VAR: None NOTE: - Another addon can tell Titan to NOT adjust some or all frames. :NOTE --]] function TitanPanelBarButton_ToggleScreenAdjust() -- Turn on / off adjusting of other frames around Titan TitanPanelToggleVar("ScreenAdjust"); TitanPanel_AdjustFrames(true) end --[[ Titan NAME: TitanPanelBarButton_ToggleAuxScreenAdjust DESC: Toggle whether Titan adjusts 'bottom' frames around Titan bars per the user's new choice. VAR: None OUT: None NOTE: - Another addon can tell Titan to NOT adjust some or all frames. :NOTE --]] function TitanPanelBarButton_ToggleAuxScreenAdjust() -- turn on / off adjusting of frames at the bottom of the screen TitanPanelToggleVar("AuxScreenAdjust"); TitanPanel_AdjustFrames(true) end --====== Titan Bar -- --========================== -- Routines to handle moving and sizing of short bars -- --[[ local NAME: TitanPanel_SetScale DESC: Set the scale of each plugin and each Titan bar. VAR: None OUT: None --]] local function CheckBarBounds(self, width) local trace = false -- true false local result = {} result.ok = true result.err = "" local err = "" local f_name = self:GetName() local bar_name = TitanBarData[f_name].name local locale_name = TitanBarData[f_name].locale_name local escale = UIParent:GetEffectiveScale() if TitanBarData[f_name].user_move and TitanBarDataVars[f_name].show then if trace then print("Bounds" .. " " .. tostring(bar_name) .. "" .. " " .. tostring(width) .. "" ) end local tscale = TitanPanelGetVar("Scale") local screen = TitanUtils_ScreenSize() local screen_right_scaled = screen.scaled_x local screen_top_scaled = screen.scaled_y local screen_right = screen.x local screen_top = screen.y local screen_right_t = screen.x * tscale local screen_top_t = screen.y * tscale -- Apply the Titan scaling to get 'real' position within WoW window; -- Use floor to trunc decimal places where the side could be right on the edge of the screen. local orig_w = self:GetWidth() -- * tscale --math.floor(self:GetWidth() * tscale) local l_off = math.floor(self:GetLeft() * tscale) local r_off = math.floor(self:GetRight() * tscale) local t_off = math.floor(self:GetTop() * tscale) local b_off = math.floor(self:GetBottom() * tscale) local hght = math.floor(t_off - b_off) if trace then print(">Bounds" .. "\n" .. " L " .. tostring(format("%0.1f", l_off)) .. "" .. " R " .. tostring(format("%0.1f", r_off)) .. "" .. " T " .. tostring(format("%0.1f", t_off)) .. "" .. " B " .. tostring(format("%0.1f", b_off)) .. "" .. " W " .. tostring(format("%0.1f", orig_w)) .. "" .. " H " .. tostring(format("%0.1f", hght)) .. "" .. "\n" .. " SR " .. tostring(format("%0.1f", screen_right)) .. "" .. " ST " .. tostring(format("%0.1f", screen_top)) .. "" .. " SR_t " .. tostring(format("%0.1f", screen_right_t)) .. "" .. " ST_t " .. tostring(format("%0.1f", screen_top_t)) .. "" ) end local w = 0 local x_off = 0 local y_off = 0 local w_off = 0 -- Assume all ok :) x_off = l_off y_off = b_off if (width == 0) then -- drag & drop OR entry / reload -- Assumes BOTTOMLEFT of screen per Short bar defaults. -- if resolution is not 'pixel perfect' rounding could cause algorithm to think bar is off screen -- Keep the width w_off = orig_w if l_off < 0 then x_off = 0 err = "Off left of screen, snap to edge" elseif (r_off) > screen_right then x_off = math.floor(screen_right - (r_off - l_off)) err = "Off right side of screen, snap to edge" end if err ~= "" then result.ok = false result.err = err if trace then TitanPrint(locale_name .. " " .. err .. "!!!!" , "warning") end end err = "" if (t_off) > screen_top then y_off = math.floor(screen_top - (t_off - b_off)) err = "Off top of screen, snap to edge" elseif b_off < 0 then y_off = 0 err = "Off bottom of screen, snap to edge" end if err ~= "" then result.ok = false result.err = result.err .. "\n" .. err if trace then TitanPrint(locale_name .. " " .. err .. "!!!!" .. " [" .. tostring(format("%0.1f", x_off)) .. "]" .. " [" .. tostring(format("%0.1f", y_off)) .. "]" , "warning") end end else -- width change local min_w, min_h, max_w, max_h = self:GetResizeBounds() -- Keep the X and Y local w_new = orig_w + width if w_new < min_w then -- do nothing - too small w_off = min_w err = "Width too small. Set to min width." elseif w_new > max_w then w_off = max_w err = "Width too big. Set to max width." -- too wide elseif x_off + (w_new * tscale) > screen_right then w_off = orig_w err = "Off right of screen, snap to edge" else w_off = w_new end self:SetSize(w_off, TITAN_PANEL_BAR_HEIGHT) -- self:SetWidth(w_off) end -- Back out Titan scaling x_off = x_off / tscale y_off = y_off / tscale w_off = w_off --/ tscale TitanVariables_SetBarPos(self, false, x_off, y_off, w_off) if trace then print(">>Bounds" .. " " .. tostring(result.ok) .. "" .. " X " .. tostring(format("%0.1f", x_off)) .. "" .. " Y " .. tostring(format("%0.1f", y_off)) .. "" .. " W " .. tostring(format("%0.1f", w_off)) .. "" ) if err ~= "" then TitanPrint(locale_name .. " " .. err .. "!!!!" .. " [" .. tostring(format("%0.1f", x_off)) .. "]" .. " [" .. tostring(format("%0.1f", y_off)) .. "]" .. " [" .. tostring(format("%0.1f", w_off)) .. "]" , "warning") end end else -- Controlled with anchor points; cannot move so no check is needed end return result end --[[ local NAME: OnMoveStart DESC: Start the grap of a Short Titan bar if Shift and left mouse are held. VAR: self - the bar frame OUT: None --]] local function OnMoveStart(self) if IsShiftKeyDown() then if self:IsMovable() then self.isMoving = true self:StartMoving() _G.GameTooltip:Hide() end else -- Do not move end end --[[ local NAME: OnMovingStop DESC: When a Short Titan bar drag is stopped. VAR: self - the bar frame OUT: None --]] local function OnMovingStop(self) self:StopMovingOrSizing() self.isMoving = nil local res = CheckBarBounds(self, 0) if res.ok then -- placement ok else -- Need to 'snap' it to an edge TitanPanel_InitPanelBarButton("OnMovingStop") end -- Seems overkill - this will recalc all bars... end --[[ local NAME: OnMouseWheel DESC: Change the width of a Short Titan bar when mouse is over the bar and Shift is held when the mouse wheel is used. VAR: self - the bar frame VAR: d - mouse wheel direction; assuming a 1 'click' is a pixel OUT: None NOTE: - Can get noisy, "Initializes" all bars at each click to ensure the bar is drawn. :NOTE --]] local function OnMouseWheel(self, d) if IsShiftKeyDown() then local old_w = self:GetWidth() local delta = d if IsControlKeyDown() then delta = d * 10 else -- use 1 end local res = CheckBarBounds(self, delta) if res.ok then end --[[ print("wheel" .." "..tostring(self:GetName()).."" .." "..tostring(d).."" .." old: "..tostring(format("%0.1f", old_w)).."" .." new: "..tostring(format("%0.1f", self:GetWidth())).."" .." ok: "..tostring(res.ok).."" ) --]] -- TitanPanel_InitPanelBarButton("OnMouseWheel") end end --[[ Titan NAME: TitanPanelBarButton_ForceLDBLaunchersRight DESC: Force all plugins created from LDB addons, visible or not, to be on the right side of the Titan bar. Any visible plugin will be forced to the right side on the same bar it is currently on. VAR: None OUT: None --]] function TitanPanelBarButton_ForceLDBLaunchersRight() local plugin = {} for index, id in pairs(TitanPluginsIndex) do plugin = TitanUtils_GetPlugin(id); if plugin and plugin.ldb == "launcher" and not TitanGetVar(id, "DisplayOnRightSide") then TitanToggleVar(id, "DisplayOnRightSide"); local button = TitanUtils_GetButton(id) if button then local buttonText = _G[button:GetName() .. TITAN_PANEL_TEXT]; if not TitanGetVar(id, "ShowIcon") then TitanToggleVar(id, "ShowIcon"); end TitanPanelButton_UpdateButton(id); if buttonText then buttonText:SetText("") button:SetWidth(16); TitanPlugins[id].buttonTextFunction = nil; _G[TitanUtils_ButtonName(id) .. TITAN_PANEL_TEXT] = nil; if button:IsVisible() then local bar = TitanUtils_GetWhichBar(id) TitanPanel_RemoveButton(id); TitanUtils_AddButtonOnBar(bar, id) end end end end end end --[[ local NAME: TitanAnchors DESC: Helper to create the 'anchor' frames used by other addons that need to adjust so Titan can be visible. The anchor frames are adjusted depending on which Titan bars the user selects to show. VAR: None OUT: None NOTE: - TitanPanelTopAnchor - the frame at the bottom of the top bar(s) shown. - TitanPanelBottomAnchor - the frame at the top of the bottom bar(s) shown. :NOTE --]] local function TitanAnchors() local anchor_top = TitanMovable_GetPanelYOffset(TITAN_PANEL_PLACE_TOP) local anchor_bot = TitanMovable_GetPanelYOffset(TITAN_PANEL_PLACE_BOTTOM) anchor_top = anchor_top <= TITAN_WOW_SCREEN_TOP and anchor_top or TITAN_WOW_SCREEN_TOP anchor_bot = anchor_bot >= TITAN_WOW_SCREEN_BOT and anchor_bot or TITAN_WOW_SCREEN_BOT local top_point, top_rel_to, top_rel_point, top_x, top_y = TitanPanelTopAnchor:GetPoint(TitanPanelTopAnchor :GetNumPoints()) local bot_point, bot_rel_to, bot_rel_point, bot_x, bot_y = TitanPanelBottomAnchor:GetPoint(TitanPanelBottomAnchor :GetNumPoints()) top_y = floor(tonumber(top_y) + 0.5) bot_y = floor(tonumber(bot_y) + 0.5) --[[ TitanDebug("Anc top: "..top_y.." bot: "..bot_y .." a_top: "..anchor_top.." a_bot: "..anchor_bot ) --]] if top_y ~= anchor_top then TitanPanelTopAnchor:ClearAllPoints() TitanPanelTopAnchor:SetPoint(top_point, top_rel_to, top_rel_point, top_x, anchor_top); end if bot_y ~= anchor_bot then TitanPanelBottomAnchor:ClearAllPoints() TitanPanelBottomAnchor:SetPoint(bot_point, bot_rel_to, bot_rel_point, bot_x, anchor_bot) end end --[[ Titan NAME: TitanPanelBarButton_DisplayBarsWanted DESC: Show all the Titan bars the user has selected. VAR: None OUT: None --]] function TitanPanelBarButton_DisplayBarsWanted(reason) local trace = false if trace then print("_DisplayBarsWanted" .. " " .. tostring(reason) .. "" ) end -- Check all bars to see if the user has requested they be shown for idx, v in pairs(TitanBarData) do -- Show / hide plus kick auto hide, if needed Titan_AutoHide_Init(idx) end -- Set anchors for other addons to use. TitanAnchors() if TITAN_ID == "TitanClassic" then -- Adjust other frames because the bars shown / hidden may have changed TitanPanel_AdjustFrames(true) else -- Not needed with UI movable widgets end end --[[ Titan NAME: TitanPanelBarButton_HideAllBars DESC: This routine will hide all the Titan bars (and hiders) regardless of what the user has selected. VAR: None OUT: None NOTE: - For example when the pet battle is active. We cannot figure out how to move the pet battle frame so we are punting and hiding Titan... - We only need to hide the bars (and hiders) - not adjust frames :NOTE --]] function TitanPanelBarButton_HideAllBars() for idx, v in pairs(TitanBarData) do TitanPanelBarButton_Hide(idx) end end local function showBar(frame_str) local flag = true -- only set false for known conditions if frame_str == TitanVariables_GetFrameName("Bar") or frame_str == TitanVariables_GetFrameName("Bar2") then -- ===== Battleground or Arena : User selected if (TitanPanelGetVar("HideBarsInPVP")) and (C_PvP.IsBattleground() or C_PvP.IsArena() -- or GetZoneText() == "Stormwind City" -- or GetZoneText() == "Tempest Keep" ) then flag = false end end -- ===== In Combat : User selected if TitanBarDataVars[frame_str].hide_in_combat or TitanPanelGetVar("HideBarsInCombat") then if in_combat then -- InCombatLockdown() too slow flag = false end end if TITAN_ID == "TitanClassic" then -- skip, no pet battles yet else -- ===== In Pet Battle if C_PetBattles.IsInBattle() then if TitanBarData[frame_str].user_move then -- leave as is else flag = false end end end --[[ print("showBar" --.." "..tostring(C_PetBattles.IsInBattle()).."" .." > "..tostring(flag).."" .." '"..tostring(frame_str).."'" ) --]] return flag end local function SetBar(frame) local trace = false local display = _G[frame]; -- local res = CheckBarBounds(display, 0) local x, y, w = TitanVariables_GetBarPos(frame) local tscale = TitanPanelGetVar("Scale") local show = TitanBarData[frame].show local bott = TitanBarData[frame].bott display:ClearAllPoints() if trace then -- local screen = TitanUtils_ScreenSize() -- local sx = screen.scaled_x -- local sy = screen.scaled_y print("SetBar" .. " " .. tostring(TitanBarData[frame].name) .. "" .. " x:" .. tostring(format("%0.1f", x)) .. "" .. " y:" .. tostring(format("%0.1f", y)) .. "" .. " w:" .. tostring(format("%0.1f", w)) .. "" ) end if TitanBarData[frame].user_move then display:SetPoint(show.pt, show.rel_fr, show.rel_pt, x, y) display:SetSize(w, TITAN_PANEL_BAR_HEIGHT) else display:SetPoint(show.pt, show.rel_fr, show.rel_pt, x, y) local h = TITAN_PANEL_BAR_HEIGHT display:SetPoint(bott.pt, bott.rel_fr, bott.rel_pt, x, y - h) end end --[[ Titan NAME: TitanPanelBarButton_Show DESC: Show / hide the given Titan bar based on the user selection. VAR: frame - expected to be a Titan bar name (string) OUT: None NOTE: - Hide moves rather than just 'not shown'. Otherwise the buttons will stay visible defeating the purpose of hide. :NOTE --]] function TitanPanelBarButton_Show(frame) local display = _G[frame]; if display and TitanBarData[frame].name then if TitanBarDataVars[frame].show -- User requested and showBar(frame) -- No preventing condition then -- Place Bar SetBar(frame) ---[[ -- The bar may need to be moved back onto the screen. local res = CheckBarBounds(display, 0) if res.ok then -- placement ok else -- Need to 'snap' it to an edge SetBar(frame) end --]] TitanPanel_SetBarTexture(frame) if TitanBarData[frame].hider then _G[TitanBarData[frame].hider]:Hide() else -- not allowed for this bar end else -- The user has not elected to show this bar TitanPanelBarButton_Hide(frame) end end end --[[ Titan NAME: TitanPanelBarButton_Hide DESC: Hide the given Titan bar based on the user selection. VAR: frame - expected to be a Titan bar name (string) OUT: None NOTE: - Hide moves rather than just 'not shown'. Otherwise the buttons will stay visible defeating the purpose of hide. - Also moves the hider bar if auto hide is not selected. :NOTE --]] function TitanPanelBarButton_Hide(frame) if TITAN_PANEL_MOVING == 1 then return end local display = _G[frame] local data = TitanBarData[frame] if display and data then local x, y, w = TitanVariables_GetBarPos(frame) -- This moves rather than hides. If we just hide then the plugins will still show. -- Hide by ensuriing the Y offset is off the screen. display:ClearAllPoints() local h = (math.abs(y) + TITAN_PANEL_BAR_HEIGHT * 2) * (-1 * y) local h = data.hide_y --[[ print("_Hide" --.." "..tostring(frame).."" .." "..tostring(data.name).."" .." "..tostring(TitanBarDataVars[frame].show).."" .." "..tostring(h).."" ) --]] if TitanBarData[frame].user_move then display:SetPoint(data.show.pt, data.show.rel_fr, data.show.rel_pt, x, h) else display:SetPoint(data.show.pt, data.show.rel_fr, data.show.rel_pt, x, h) display:SetPoint(data.bott.pt, data.bott.rel_fr, data.bott.rel_pt, x, h - TITAN_PANEL_BAR_HEIGHT) end if TitanBarData[frame].hider then local hider = _G[data.hider] if TitanBarDataVars[frame].show and TitanBarDataVars[frame].auto_hide then -- if (TitanPanelGetVar(data.name.."_Show")) and (TitanPanelGetVar(data.name.."_Hide")) then -- Auto hide is requested so show the hider bar in the right place hider:ClearAllPoints(); hider:SetPoint(data.show.pt, data.show.rel_fr, data.show.rel_pt, x, y); hider:Show() else -- The bar was not requested hider:Hide() end else -- not allowed for this bar end end end --[[ Titan NAME: TitanPanel_InitPanelButtons DESC: Show all user selected plugins on the Titan bar(s) then justify per the user selection. VAR: None OUT: None --]] function TitanPanel_InitPanelButtons() local button local r_prior = {} local l_prior = {} local scale = TitanPanelGetVar("Scale"); local button_spacing = TitanPanelGetVar("ButtonSpacing") * scale local icon_spacing = TitanPanelGetVar("IconSpacing") * scale local prior = {} -- set prior to the starting offsets -- The right side plugins are set here. -- Justify adjusts the left side start according to the user setting -- The effect is left side plugins has spacing on the right side and -- right side plugins have spacing on the left. for idx, v in pairs(TitanBarData) do local bar = TitanBarData[idx].name local y_off = TitanBarData[idx].plugin_y_offset prior[bar] = { right = { button = TitanVariables_GetFrameName(bar), anchor = "RIGHT", x = 5, -- Offset of first plugin to right side of screen y = y_off, }, left = { button = TitanVariables_GetFrameName(bar), anchor = "LEFT", x = 0, -- Justify adjusts - center or not y = y_off, }, } end -- TitanPanelBarButton_DisplayBarsWanted("TitanPanel_InitPanelButtons"); -- Position all the buttons for i = 1, table.maxn(TitanPanelSettings.Buttons) do local id = TitanPanelSettings.Buttons[i]; if (TitanUtils_IsPluginRegistered(id)) then local i = TitanPanel_GetButtonNumber(id); button = TitanUtils_GetButton(id); if button then -- If the plugin has asked to be on the right if TitanUtils_ToRight(id) then -- ========================= -- position the plugin relative to the prior plugin -- or the bar if it is the 1st r_prior = prior[TitanPanelSettings.Location[i]].right -- ========================= button:ClearAllPoints(); button:SetPoint("RIGHT", _G[r_prior.button]:GetName(), r_prior.anchor, (-(r_prior.x) * scale), r_prior.y) -- ========================= -- capture the button for the next plugin r_prior.button = TitanUtils_ButtonName(id) -- set prior[x] the anchor points and offsets for the next plugin r_prior.anchor = "LEFT" r_prior.x = icon_spacing r_prior.y = 0 -- ========================= else -- handle plugins on the left side of the bar -- -- ========================= -- position the plugin relative to the prior plugin -- or the bar if it is the 1st l_prior = prior[TitanPanelSettings.Location[i]].left --[===[ print("Bar plugins" .." "..tostring(i).."" .." "..tostring(TitanPanelSettings.Location[i]).."" .." "..tostring(id).."" ) --]===] -- ========================= -- button:ClearAllPoints(); button:SetPoint("LEFT", _G[l_prior.button]:GetName(), l_prior.anchor, l_prior.x * scale, l_prior.y); -- ========================= -- capture the next plugin l_prior.button = TitanUtils_ButtonName(id) -- set prior[x] (anchor points and offsets) for the next plugin l_prior.anchor = "RIGHT" l_prior.x = (button_spacing) l_prior.y = 0 -- ========================= end button:Show() end end end -- Set panel button init flag TITAN_PANEL_BUTTONS_INIT_FLAG = 1; TitanPanelButton_Justify(); end --[[ Titan NAME: TitanPanel_ReOrder DESC: Reorder all the shown all user selected plugins on the Titan bar(s). Typically used after a button has been removed / hidden. VAR: index - the index of the plugin removed so the list can be updated OUT: None --]] function TitanPanel_ReOrder(index) for i = index, table.getn(TitanPanelSettings.Buttons) do TitanPanelSettings.Location[i] = TitanPanelSettings.Location[i + 1] end end --[[ Titan NAME: TitanPanel_RemoveButton DESC: Remove a plugin then show all the shown all user selected plugins on the Titan bar(s). VAR: id - the plugin name (string) OUT: None NOTE: - This cancels all timers of name "TitanPanel"..id as a safeguard to destroy any active plugin timers based on a fixed naming convention : TitanPanel..id, eg. "TitanPanelClock" this prevents "rogue" timers being left behind by lack of an OnHide check :NOTE --]] function TitanPanel_RemoveButton(id) if (not TitanPanelSettings) then return; end local i = TitanPanel_GetButtonNumber(id) local currentButton = TitanUtils_GetButton(id); -- safeguard ... if id then AceTimer.CancelAllTimers("TitanPanel" .. id) end TitanPanel_ReOrder(i); table.remove(TitanPanelSettings.Buttons, TitanUtils_GetCurrentIndex(TitanPanelSettings.Buttons, id)); --TitanDebug("_Remove: "..(id or "?").." "..(i or "?")) if currentButton then currentButton:Hide(); end -- Show the existing buttons TitanPanel_InitPanelButtons(); end --[[ Titan NAME: TitanPanel_GetButtonNumber DESC: Get the index of the given plugin from the Titan plugin displayed list. VAR: id - the plugin name (string) OUT: index of the plugin in the Titan plugin list or the end of the list. The routine returns +1 if not found so it is 'safe' to update / add to the Location --]] function TitanPanel_GetButtonNumber(id) if (TitanPanelSettings) then for i = 1, table.getn(TitanPanelSettings.Buttons) do if (TitanPanelSettings.Buttons[i] == id) then return i; end end return table.getn(TitanPanelSettings.Buttons) + 1; else return 0; end end --[[ Titan NAME: TitanPanel_RefreshPanelButtons DESC: Update / refresh each plugin from the Titan plugin list. Used when a Titan option is changed that effects all plugins. VAR: None OUT: None --]] function TitanPanel_RefreshPanelButtons() if (TitanPanelSettings) then for i = 1, table.getn(TitanPanelSettings.Buttons) do TitanPanelButton_UpdateButton(TitanPanelSettings.Buttons[i], 1); end end end --[[ Titan NAME: TitanPanelButton_Justify DESC: Justify the plugins on each Titan bar. Used when the user changes the 'center' option on a Titan bar. VAR: None OUT: None --]] function TitanPanelButton_Justify() -- Only the left side buttons are justified. if (not TITAN_PANEL_BUTTONS_INIT_FLAG or not TitanPanelSettings) then return; end if InCombatLockdown() then --TitanDebug("_Justify during combat!!!") return; -- Issue 856 where some taint is caused if the plugin size is updated during combat. Seems since Mists was released... end local bar local x_offset local y_offset local firstLeftButton local scale = TitanPanelGetVar("Scale"); local button_spacing = TitanPanelGetVar("ButtonSpacing") * scale local icon_spacing = TitanPanelGetVar("IconSpacing") * scale local leftWidth = 0; local rightWidth = 0; local counter = 0; local align = 0; local center_offset = 0; -- Look at each bar for plugins. for idx, v in pairs(TitanBarData) do bar = TitanBarData[idx].name y_offset = TitanBarData[idx].plugin_y_offset x_offset = TitanBarData[idx].plugin_x_offset firstLeftButton = TitanUtils_GetButton(TitanPanelSettings.Buttons [TitanUtils_GetFirstButtonOnBar(bar, TITAN_LEFT)]) align = TitanBarDataVars[idx].align --TitanPanelGetVar(bar.."_Align") leftWidth = 0; rightWidth = 0; counter = 0; -- If there is a plugin on this bar then justify the first button. -- The other buttons are relative to the first. if (firstLeftButton) then if (align == TITAN_PANEL_BUTTONS_ALIGN_LEFT) then -- Now offset the plugins firstLeftButton:ClearAllPoints(); firstLeftButton:SetPoint("LEFT", idx, "LEFT", x_offset, y_offset); end -- Center if requested if (align == TITAN_PANEL_BUTTONS_ALIGN_CENTER) then leftWidth = 0; rightWidth = 0; counter = 0; -- Calc the total width of the icons so we know where to start for index, id in pairs(TitanPanelSettings.Buttons) do local button = TitanUtils_GetButton(id); if button and button:GetWidth() then if TitanUtils_GetWhichBar(id) == bar then if (TitanGetVar(id, "DisplayOnRightSide")) then rightWidth = rightWidth + icon_spacing + button:GetWidth(); else counter = counter + 1; leftWidth = leftWidth + button_spacing + button:GetWidth() end end end end -- Now offset the plugins on the bar firstLeftButton:ClearAllPoints(); -- remove the last spacing otherwise the buttons appear justified too far left center_offset = (0 - (leftWidth - button_spacing) / 2) firstLeftButton:SetPoint("LEFT", idx, "CENTER", center_offset, y_offset); end end end end -------------------------------------------------------------- -- -- Local routines for Titan menu creation local R_ADDONS = "Addons_" local R_PLUGIN = "Plugin_" local R_SETTINGS = "Settings" local R_PROFILE = "Profile_" --[[ local NAME: BuildMainMenu DESC: Show main Titan (right click) menu. VAR: None OUT: None --]] 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 -- for index, id in pairs(L["TITAN_PANEL_MENU_CATEGORIES"]) do for index = 1, 6, 1 do info = {}; info.notCheckable = true -- bit of a kludge but a decent way to handle something that rarely changes info.text = L["TITAN_PANEL_MENU_CATEGORIES_" .. string.format("%02d", index)] info.value = R_ADDONS .. TITAN_PANEL_BUTTONS_PLUGIN_CATEGORY[index]; info.hasArrow = 1; TitanPanelRightClickMenu_AddButton(info); end TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); ----------------- -- Options - just one button to open the first Titan option screen do info = {}; info.notCheckable = true info.text = L["TITAN_PANEL_MENU_CONFIGURATION"]; info.value = "Bars"; info.func = function() TitanUpdateConfig("init") Settings.OpenToCategory(TITAN_PANEL_CONFIG.topic.About) end TitanPanelRightClickMenu_AddButton(info); end TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); ----------------- -- Profiles TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_MENU_PROFILES"]); ----------------- -- Load/Delete info = {}; info.notCheckable = true info.text = L["TITAN_PANEL_MENU_MANAGE_SETTINGS"]; info.value = R_SETTINGS info.hasArrow = 1; -- lock this menu in combat if InCombatLockdown() then info.disabled = 1; info.hasArrow = nil; info.text = info.text .. " " .. _G["GREEN_FONT_COLOR_CODE"] .. L["TITAN_PANEL_MENU_IN_COMBAT_LOCKDOWN"]; end TitanPanelRightClickMenu_AddButton(info); ----------------- -- Save info = {}; info.notCheckable = true info.text = L["TITAN_PANEL_MENU_SAVE_SETTINGS"]; info.value = "SettingsCustom"; info.func = TitanPanel_SaveCustomProfile; -- lock this menu in combat if InCombatLockdown() then info.disabled = 1; info.text = info.text .. " " .. _G["GREEN_FONT_COLOR_CODE"] .. L["TITAN_PANEL_MENU_IN_COMBAT_LOCKDOWN"]; end TitanPanelRightClickMenu_AddButton(info); -- TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); local glob, toon, player, server = TitanUtils_GetGlobalProfile() info = {}; -- info.text = "Use Global Profile\n "..toon info.text = L["TITAN_PANEL_GLOBAL_USE"] .. "\n " .. toon; info.value = "Use Global Profile" info.func = function() TitanUtils_SetGlobalProfile(not glob, toon) TitanVariables_UseSettings(nil, TITAN_PROFILE_USE) end; info.checked = glob --TitanAllGetVar("GlobalProfileUse") info.keepShownOnClick = nil TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); TitanPanelRightClickMenu_AddSeparator(TitanPanelRightClickMenu_GetDropdownLevel()); ----------------- -- Hide this bar info = {}; info.text = (HIDE or "Hide") info.value = "HideMe" info.notCheckable = true 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 NAME: BuildServerProfilesMenu DESC: Show list of servers / custom submenu off Profiles/Manage from the Titan (right click) menu. VAR: None OUT: None --]] local function BuildServerProfilesMenu() local info = {}; local servers = {}; local player = nil; local server = nil; local s, e, ident; local setonce = 0; if (TitanPanelRightClickMenu_GetDropdMenuValue() == R_SETTINGS) then TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_MENU_PROFILE_SERVERS"], TitanPanelRightClickMenu_GetDropdownLevel()); -- Normal profile per toon for index, id in pairs(TitanSettings.Players) do player, server = TitanUtils_ParseName(index) if TitanUtils_GetCurrentIndex(servers, server) == nil then if server ~= TITAN_CUSTOM_PROFILE_POSTFIX then table.insert(servers, server); info = {}; info.notCheckable = true info.text = server; info.value = R_PROFILE .. server; info.hasArrow = 1; TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); end end end -- Custom profiles for index, id in pairs(TitanSettings.Players) do player, server = TitanUtils_ParseName(index) if TitanUtils_GetCurrentIndex(servers, server) == nil then if server == TITAN_CUSTOM_PROFILE_POSTFIX then if setonce and setonce == 0 then TitanPanelRightClickMenu_AddTitle("", TitanPanelRightClickMenu_GetDropdownLevel()); TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_MENU_PROFILE_CUSTOM"], TitanPanelRightClickMenu_GetDropdownLevel()); setonce = 1; end info = {}; info.notCheckable = true info.text = player; info.value = R_PROFILE .. player; info.hasArrow = 1; TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); end end end end end --[[ local NAME: BuildPluginMenu DESC: Show list of plugin defined options from the Titan right click menu. VAR: None OUT: None --]] local function BuildPluginMenu() -- local info = {}; -- Handle the plugins 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 --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 --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 --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 -- 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 end end --[[ local NAME: BuildPluginMenu DESC: Show alphabetical list of toons submenu off Profiles/Manage/<server or custom> from the Titan right click menu. VAR: None OUT: None --]] local function BuildProfileMenu() -- local info = {}; local setonce = 0; -- -- Handle the profiles -- for idx = 1, #Titan_Global.players do local index = Titan_Global.players[idx] local player, server = TitanUtils_ParseName(index) local off = (index == TitanSettings.Player) or ((index == TitanAllGetVar("GlobalProfileUse")) and (TitanAllGetVar("GlobalProfileUse"))) local par_val = TitanPanelRightClickMenu_GetDropdMenuValue() local menu_val = string.gsub(par_val, R_PROFILE, "") -- handle custom profiles here if server == TITAN_CUSTOM_PROFILE_POSTFIX and player == menu_val then info = {}; info.notCheckable = true info.disabled = TitanAllGetVar("GlobalProfileUse") info.text = L["TITAN_PANEL_MENU_LOAD_SETTINGS"]; info.value = index; info.func = function() TitanVariables_UseSettings(index, TITAN_PROFILE_USE) end TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); info = {}; info.notCheckable = true info.disabled = off info.text = L["TITAN_PANEL_MENU_DELETE_SETTINGS"]; info.value = index; info.arg1 = index; info.func = function(self, player) -- (self, info.arg1, info.arg2) if TitanSettings.Players[player] then TitanSettings.Players[player] = nil; local profname = TitanUtils_ParseName(index) TitanPrint( L["TITAN_PANEL_MENU_PROFILE"] .. " '" .. profname .. "' " .. L["TITAN_PANEL_MENU_PROFILE_DELETED"] , "info") TitanPanelRightClickMenu_Close(); end end TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); end -- if server and player -- handle regular profiles here if server == menu_val then -- Set the label once if setonce and setonce == 0 then TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_MENU_PROFILE_CHARS"], TitanPanelRightClickMenu_GetDropdownLevel()); setonce = 1; end info = {}; info.notCheckable = true info.text = player; info.value = index; info.hasArrow = 1; TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); end end -- for players end --[[ local NAME: BuildAProfileMenu DESC: Show save / load submenu off Profiles/Manage/<server or custom>/<profile> from the Titan (right click) menu. VAR: None OUT: None --]] local function BuildAProfileMenu() local info = {}; info = {}; info.notCheckable = true info.disabled = TitanAllGetVar("GlobalProfileUse") info.text = L["TITAN_PANEL_MENU_LOAD_SETTINGS"]; info.value = TitanPanelRightClickMenu_GetDropdMenuValue(); info.func = function() TitanVariables_UseSettings(TitanPanelRightClickMenu_GetDropdMenuValue(), TITAN_PROFILE_USE) end TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); info = {}; info.notCheckable = true info.disabled = (TitanPanelRightClickMenu_GetDropdMenuValue() == TitanSettings.Player) or ((TitanPanelRightClickMenu_GetDropdMenuValue() == TitanAllGetVar("GlobalProfileName")) and (TitanAllGetVar("GlobalProfileUse"))) info.text = L["TITAN_PANEL_MENU_DELETE_SETTINGS"]; info.value = TitanPanelRightClickMenu_GetDropdMenuValue(); info.func = function() -- do not delete if current profile - .disabled if TitanSettings.Players[info.value] then TitanSettings.Players[info.value] = nil; TitanPrint( L["TITAN_PANEL_MENU_PROFILE"] .. " '" .. info.value .. "' " .. L["TITAN_PANEL_MENU_PROFILE_DELETED"] , "info") TitanPanelRightClickMenu_Close(); end end TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); end --[[ local NAME: BuildPluginCategoryMenu DESC: Show the submenu with list of plugin off the category from the Titan (right click) menu. VAR: None OUT: None --]] local function BuildPluginCategoryMenu(frame) local info = {}; 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 not TitanGetVar(id, "ForceBar") or (TitanGetVar(id, "ForceBar") == TitanBarData[frame].name) then info = {}; local ver = plugin and plugin.version or "" if TitanPanelGetVar("VersionShown") then if ver == nil or ver == "" then ver = "" -- safety in case of nil else ver = TitanUtils_GetGreenText(" (" .. ver .. ")") end else ver = "" -- not requested end 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()); end end else end end end --[[ Titan NAME: TitanPanelRightClickMenu_PrepareBarMenu DESC: This is the controller of the Titan (right click) menu. VAR: self - expected to be the Titan bar that was right clicked OUT: None NOTE: - Frame name used is <Titan bar name>RightClickMenu :NOTE --]] 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).."" ) --]] -- 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 if (lev == 2) then if string.find(TitanPanelRightClickMenu_GetDropdMenuValue(), R_ADDONS) then BuildPluginCategoryMenu(frame) end if (TitanPanelRightClickMenu_GetDropdMenuValue() == R_SETTINGS) then BuildServerProfilesMenu() 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() end if string.find(TitanPanelRightClickMenu_GetDropdMenuValue(), R_PROFILE) then BuildProfileMenu() end return; end -- Level 4 -- Profiles > Server / Realm list > Character on realm list > Load / Delete if (lev == 4) then BuildAProfileMenu() return; end end --[[ Titan NAME: TitanPanel_IsPluginShown DESC: Determine if the given plugin is shown on a Titan bar. The Titan bar could be not shown or on auto hide and the plugin will still be 'shown'. VAR: id - plugin name (string) OUT: int - index of the plugin or nil --]] function TitanPanel_IsPluginShown(id) if (id and TitanPanelSettings) then return TitanUtils_TableContainsValue(TitanPanelSettings.Buttons, id); end end --[[ Titan NAME: TitanPanel_GetPluginSide DESC: Determine if the given plugin is or would be on right or left of a Titan bar. This returns right or left regardless of whether the plugin is 'shown'. VAR: id - plugin name (string) OUT: string - "Right" or "Left" --]] function TitanPanel_GetPluginSide(id) if (TitanGetVar(id, "DisplayOnRightSide")) then return TITAN_RIGHT; else return TITAN_LEFT; end end --[[ print("OnMoveStart" .." "..tostring(self:GetName()).."" .." "..tostring(IsShiftKeyDown()).."" .." "..tostring(IsAltKeyDown()).."" .."\n" .." x "..tostring(format("%0.1f", self:GetLeft())).."" .." y "..tostring(format("%0.1f", self:GetTop())).."" ) --]] --[[ Titan NAME: TitanPanel_InitPanelBarButton DESC: Set the scale, texture (graphic), and transparancy of all the Titan bars based on the user selection. VAR: None OUT: None --]] function TitanPanel_InitPanelBarButton(reason) -- Set initial Panel Scale TitanPanel_SetScale(); --[[ print("_InitPanelBarButton" .." "..tostring(reason).."" ) --]] --[===[ for idx,v in pairs (TitanBarData) do CheckBarBounds(_G[idx], 0) TitanPanel_SetBarTexture(idx) end --]===] TitanPanelBarButton_DisplayBarsWanted("InitPanelBarButton") end -- --========================== -- Routines to handle creation of Titan bars -- --[[ Titan NAME: TitanPanelButton_CreateBar(frame_str) DESC: Create a Titan bar that can show plugins. VAR: frame_str - name of the frame NOTE: - This assumes ... :NOTE --]] function TitanPanelButton_CreateBar(frame_str) local this_bar = frame_str local a_bar = CreateFrame("Button", this_bar, UIParent, "Titan_Bar__Display_Template") local bar_data = TitanBarData[this_bar] -- ====== -- Scripts a_bar:SetScript("OnEnter", function(self) TitanPanelBarButton_OnEnter(self) end) a_bar:SetScript("OnLeave", function(self) TitanPanelBarButton_OnLeave(self) end) a_bar:SetFrameStrata("DIALOG") -- local x, y, w = TitanVariables_GetBarPos(frame_str) -- local tscale = TitanPanelGetVar("Scale") --[[ print("_Create bar" .." "..tostring(bar_data.name).."" .."\n " .." "..tostring(bar_data.name).."" .." "..tostring(bar_data.show.pt).."" .." "..tostring(bar_data.show.rel_fr).."" .." "..tostring(bar_data.show.rel_pt).."" .."\n " .." "..tostring(bar_data.name).."" .." "..tostring(format("%0.1f", x)).."" .." "..tostring(format("%0.1f", y)).."" .." "..tostring(format("%0.1f", w)).."" ) --]] if bar_data.user_move then -- a_bar:SetPoint(bar_data.show.pt, bar_data.show.rel_fr, bar_data.show.rel_pt, x, y) a_bar:SetMovable(true) a_bar:SetResizable(true) a_bar:EnableMouse(true) a_bar:RegisterForDrag("LeftButton") a_bar:SetScript("OnDragStart", OnMoveStart) a_bar:SetScript("OnDragStop", OnMovingStop) a_bar:SetScript("OnMouseWheel", OnMouseWheel) -- a_bar:SetSize(w / tscale, TITAN_PANEL_BAR_HEIGHT) else -- Static full width bar -- a_bar:SetPoint(bar_data.show.pt, bar_data.show.rel_fr, bar_data.show.rel_pt, x, y) -- a_bar:SetPoint(bar_data.show.pt, bar_data.show.rel_fr, bar_data.show.rel_pt, x, y - TITAN_PANEL_BAR_HEIGHT) end -- ====== -- Bounds only effective on Short bars for now -- Min : No smaller than the padding & one icon -- Max : No wider than the screen -- does not seem to work to restrict size automatically... local screen = TitanUtils_ScreenSize() a_bar:SetResizeBounds(TitanBarData[this_bar].plugin_x_offset + 16, TITAN_PANEL_BAR_HEIGHT, screen.x, TITAN_PANEL_BAR_HEIGHT) a_bar:RegisterForClicks("LeftButtonUp", "RightButtonUp"); a_bar:SetScript("OnClick", function(self, button) TitanPanelBarButton_OnClick(self, button) end) -- ====== -- Frame for right clicks -- Use one bar to rule them all -- Use the plugin naming scheme -- 2024 Feb : Change to match plugin right click menu scheme so one routine can be used. local f = CreateFrame("Frame", this_bar .. TITAN_PANEL_CLICK_MENU_SUFFIX, UIParent, "UIDropDownMenuTemplate") --[[ local tool_tip = Titan_Panel.plugin.PRE.."Bar"..Titan_Panel.plugin.POST if _G[tool_tip] then -- already created else f = CreateFrame("Frame", tool_tip, UIParent, "UIDropDownMenuTemplate") end --]] -- ====== -- Hider for auto hide feature local hide_bar_name = TITAN_PANEL_HIDE_PREFIX .. bar_data.name if bar_data.hider then --[[ print("_Create hide bar" .." "..tostring(bar_data.name).."" .." "..tostring(hide_bar_name).."" ) --]] local hide_bar = CreateFrame("Button", hide_bar_name, UIParent, "TitanPanelBarButtonHiderTemplate") hide_bar:SetFrameStrata("DIALOG") -- hide_bar:SetPoint(bar_data.show.pt, bar_data.show.rel_fr, bar_data.show.rel_pt, x, -y) -- Set script handlers for display hide_bar:RegisterForClicks("LeftButtonUp", "RightButtonUp"); hide_bar:SetScript("OnEnter", function(self) TitanPanelBarButtonHider_OnEnter(self) end) hide_bar:SetScript("OnLeave", function(self) TitanPanelBarButtonHider_OnLeave(self) end) hide_bar:SetScript("OnClick", function(self, button) TitanPanelBarButton_OnClick(self, button) end) hide_bar:SetFrameStrata("BACKGROUND") hide_bar:SetSize(screen.x, TITAN_PANEL_BAR_HEIGHT) else -- Not allowed for this bar end 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 --]====]