--[===[ File A "bridge" module to ensure proper registration and communication of LDB plugins with Titan Panel By Titan Dev team Originally by Tristanian aka "TristTitan" as a Titan member Created and initially commited on : July 29th, 2008 --]===] --[===[ Var Titan LDB overview The spec: https://github.com/tekkub/libdatabroker-1-1 LDB (libdatabroker) is a small library that enables an addon to hook into a 'display' addon such as Titan. === Creation The addon dev creates an LDB object which the lib places in storage accessible by lib:DataObjectIterator(). It also fires a "LibDataBroker_DataObjectCreated" callback. LDB objects work by callbacks. When an LDB addon changes one of its values, the lib fires a callback for the display addon. The LDB addon may declare scripts (tooltip, mouse clicks, etc.) per the spec for the display addon to use. === Starting from Titan view On PLAYER_ENTERING_WORLD, Titan will use the iterator to wrap each LDB type addon into a Titan plugin. Once done processing the known LDB objects, Titan registers for the callback to handle LDB objects created later or on demand. Titan registers for callbacks on text and icon updates - depending on the LDB type. === Running from Titan view The LDB addon is responsible for setting and changing its text and icon. Titan is responsible for updating the Titan plugin in response. The Titan plugin will use the LDB addon scripts IF declared, again depending on the LDB type. === Supported Only LDB types listed in the LDB 1.1 spec are supported by Titan. - "launcher" become "icon" plugins - TitanPanelIconTemplate icon* - always shown OnClick* - label^ - right side^ - default tooltip - "data source" become "combo" plugins - TitanPanelComboTemplate icon^ - OnClick - text*^ - or value & suffix label^ - OnEnter - OnLeave - tooltip OnTooltipShow - * required by LDB spec ^ Titan user controlled show / hide --]===] local xcategories = { -- Titan categories mapping to match addon metadata information ["Combat"] = "Combat", ["General"] = "General", ["Information"] = "Information", ["Interface"] = "Interface", ["Profession"] = "Profession", -- Ace2 table mapping to Titan categories in order to match -- addon metadata information ["Action Bars"] = "Interface", ["Auction"] = "Information", ["Audio"] = "Interface", ["Battlegrounds/PvP"] = "Information", ["Buffs"] = "Information", ["Chat/Communication"] = "Interface", ["Druid"] = "Information", ["Hunter"] = "Information", ["Mage"] = "Information", ["Paladin"] = "Information", ["Priest"] = "Information", ["Rogue"] = "Information", ["Shaman"] = "Information", ["Warlock"] = "Information", ["Warrior"] = "Information", ["Healer"] = "Information", ["Tank"] = "Information", ["Caster"] = "Information", -- ["Combat"] = "Combat", ["Compilations"] = "General", ["Data Export"] = "General", ["Development Tools "] = "General", ["Guild"] = "Information", ["Frame Modification"] = "Interface", ["Interface Enhancements"] = "Interface", ["Inventory"] = "Information", ["Library"] = "General", ["Map"] = "Interface", ["Mail"] = "Information", ["Miscellaneous"] = "General", ["Misc"] = "General", ["Quest"] = "Information", ["Raid"] = "Information", ["Tradeskill"] = "Profession", ["UnitFrame"] = "Interface", } local LAUNCHER = "launcher" local DATA_SOURCE = "data source" local SupportedDOTypes = { DATA_SOURCE, LAUNCHER } -- in the 1.1 spec -- "macro" : this was attempted but Blizzard locked most macro to 'user click only'. -- By adding a Titan template to any secure button, WoW thinks it could be a bot and errors. -- constants & variables local CALLBACK_PREFIX = "LibDataBroker_AttributeChanged_" local _G = getfenv(0); local InCombatLockdown = _G.InCombatLockdown; -- Create control frame so we can get events local LDBToTitan = CreateFrame("Frame", "LDBTitan") local ldb = LibStub:GetLibrary("LibDataBroker-1.1") local Tablet, LibQTip = nil, nil local media = LibStub("LibSharedMedia-3.0") -- generic icon in case the DO does not provide one local iconTitanDefault = "Interface\\PVPFrame\\PVP-ArenaPoints-Icon"; -- Events we want for LDBToTitan LDBToTitan:RegisterEvent("PLAYER_LOGIN") --LDBToTitan:RegisterEvent("PLAYER_ENTERING_WORLD") ---local OK to show tooltip? ---@return boolean local function If_Show_Tooltip() local use_mod = TitanAllGetVar("UseTooltipModifer") local use_alt = TitanAllGetVar("TooltipModiferAlt") local use_ctrl = TitanAllGetVar("TooltipModiferCtrl") local use_shift = TitanAllGetVar("TooltipModiferShift") local ok = false local tmp_txt = "" 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 return ok end ---Titan Properly anchor tooltips of the Titan (LDB) plugin ---@param parent table Parent frame ---@param anchorPoint string ---@param relativeToFrame table ---@param relativePoint string ---@param xOffset number ---@param yOffset number ---@param frame table Tolltip frame function LDBToTitan:TitanLDBSetOwnerPosition(parent, anchorPoint, relativeToFrame, relativePoint, xOffset, yOffset, frame) if frame:GetName() == "GameTooltip" then -- Changes for 9.1.5 Removed the background template from the GameTooltip -- Making changes to it difficult and possibly changing the tooltip globally. frame:SetOwner(parent, "ANCHOR_NONE"); -- set font size for the Game Tooltip if not TitanPanelGetVar("DisableTooltipFont") then if TitanTooltipScaleSet < 1 then TitanTooltipOrigScale = GameTooltip:GetScale(); TitanTooltipScaleSet = TitanTooltipScaleSet + 1; end frame:SetScale(TitanPanelGetVar("TooltipFont")); end end frame:ClearAllPoints(); frame:SetPoint(anchorPoint, relativeToFrame, relativePoint, xOffset, yOffset); end ---Titan Fill in the tooltip for the Titan (LDB) plugin ---@param name string Plugin id name for LDB ---@param frame table Tooltip frame ---@param func function Tooltip function to be run function LDBToTitan:TitanLDBSetTooltip(name, frame, func) -- Check to see if we allow tooltips to be shown if not TitanPanelGetVar("ToolTipsShown") or (TitanPanelGetVar("HideTipsInCombat") and InCombatLockdown()) then return end local button = TitanUtils_GetButton(name); local scale = TitanPanelGetVar("Scale"); local offscreenX, offscreenY; local i = TitanPanel_GetButtonNumber(name); local bar = TITAN_PANEL_DISPLAY_PREFIX .. TitanUtils_GetWhichBar(name) local vert = TitanBarData[bar].vert -- Get TOP or BOTTOM for the anchor and relative anchor local rel_pt, pt if vert == TITAN_TOP then pt = "TOP" rel_pt = "BOTTOM" else pt = "BOTTOM" rel_pt = "TOP" end if _G[bar] and button then self:TitanLDBSetOwnerPosition(button, pt .. "LEFT", button:GetName(), rel_pt .. "LEFT", -10, 0, frame); -- y 4 * scale -- Adjust frame position if it's off the screen offscreenX, offscreenY = TitanUtils_GetOffscreen(frame); if (offscreenX == -1) then self:TitanLDBSetOwnerPosition(button, pt .. "LEFT", bar, rel_pt .. "LEFT", 0, 0, frame); elseif (offscreenX == 1) then self:TitanLDBSetOwnerPosition(button, pt .. "RIGHT", bar, rel_pt .. "RIGHT", 0, 0, frame); end else end if func and If_Show_Tooltip() then func(frame) end; -- TODO: use pcall?? frame:Show(); end ---Titan Script Handler for the Titan (LDB) plugin --- This implementation will work fine for a static tooltip but may have implications for dynamic ones so for now, --- we'll only set it once (no callback) and see what happens ---@param event string Event name ---@param name string Plugin id name for LDB ---@param _ any not used ---@param func function LDB data object ---@param obj table LDB data object function LDBToTitan:TitanLDBHandleScripts(event, name, _, func, obj) local TitanPluginframe = _G["TitanPanel" .. name .. "Button"]; -- tooltip if event:find("tooltip") and not event:find("OnTooltipShow") then local pluginframe = _G[obj.tooltip] or obj.tooltip if pluginframe then TitanPluginframe:SetScript("OnEnter", function(self) TitanPanelButton_OnEnter(self); LDBToTitan:TitanLDBSetTooltip(name, pluginframe, nil) end ) TitanPluginframe:SetScript("OnMouseDown", function(self) pluginframe:Hide(); end ) if pluginframe:GetScript("OnLeave") then -- do nothing else TitanPluginframe:SetScript("OnLeave", function(self) if obj.OnLeave then obj.OnLeave(self) end pluginframe:Hide(); TitanPanelButton_OnLeave(self); end ) end if pluginframe:GetName() ~= "GameTooltip" then if pluginframe:GetScript("OnShow") then -- do nothing else pluginframe:SetScript("OnShow", function(self) LDBToTitan:TitanLDBSetTooltip(name, pluginframe, nil) end ) end end end -- OnTooltipShow elseif event:find("OnTooltipShow") then TitanPluginframe:SetScript("OnEnter", function(self) if TITAN_PANEL_MOVING == 0 and func then LDBToTitan:TitanLDBSetTooltip(name, GameTooltip, func); end TitanPanelButton_OnEnter(self); end ) TitanPluginframe:SetScript("OnLeave", function(self) GameTooltip:Hide(); TitanPanelButton_OnLeave(self); end ) -- OnDoubleClick elseif event:find("OnDoubleClick") and not event:find("OnClick") then TitanPluginframe:SetScript("OnDoubleClick", function(self, button) if TITAN_PANEL_MOVING == 0 then func(self, button) end end ) -- OnClick elseif event:find("OnClick") then TitanPluginframe:SetScript("OnClick", function(self, button) if TITAN_PANEL_MOVING == 0 then func(self, button) end -- implement a safeguard, since the DO may actually use -- Blizzy dropdowns ! if not TitanPanelRightClickMenu_IsVisible() then TitanPanelButton_OnClick(self, button); else TitanUtils_CloseAllControlFrames(); end end ) -- OnEnter else TitanPluginframe:SetScript("OnEnter", function(self) -- Check for tooltip libs without embedding them if AceLibrary and AceLibrary:HasInstance("Tablet-2.0") then Tablet = AceLibrary("Tablet-2.0") end LibQTip = LibStub("LibQTip-1.0", true) -- Check to see if we allow tooltips to be shown if not TitanPanelGetVar("ToolTipsShown") or (TitanPanelGetVar("HideTipsInCombat") and InCombatLockdown()) then -- if a plugin is using tablet, then detach and close the tooltip if Tablet and Tablet:IsRegistered(TitanPluginframe) and Tablet:IsAttached(TitanPluginframe) then Tablet:Detach(TitanPluginframe); Tablet:Close(TitanPluginframe); end return; else -- if a plugin is using tablet, then re-attach the tooltip -- (it will auto-open on mouseover) if Tablet and Tablet:IsRegistered(TitanPluginframe) and not Tablet:IsAttached(TitanPluginframe) then Tablet:Attach(TitanPluginframe); end end -- if a plugin is using tablet then set its transparency -- and font size accordingly if Tablet and Tablet:IsRegistered(TitanPluginframe) then Tablet:SetTransparency(TitanPluginframe, TitanPanelGetVar("TooltipTrans")) if not TitanPanelGetVar("DisableTooltipFont") then Tablet:SetFontSizePercent(TitanPluginframe, TitanPanelGetVar("TooltipFont")) elseif TitanPanelGetVar("DisableTooltipFont") and Tablet:GetFontSizePercent(TitanPluginframe) ~= 1 then Tablet:SetFontSizePercent(TitanPluginframe, 1) end end -- set original tooltip scale for GameTooltip if not TitanPanelGetVar("DisableTooltipFont") then TitanTooltipOrigScale = GameTooltip:GetScale(); end -- call OnEnter on LDB Object if TITAN_PANEL_MOVING == 0 and func and If_Show_Tooltip() then func(self) end TitanPanelButton_OnEnter(self); -- LibQTip-1.0 support code if LibQTip then local tt = nil local key, tip for key, tip in LibQTip:IterateTooltips() do if tip then local _, relativeTo = tip:GetPoint() if relativeTo and relativeTo:GetName() == TitanPluginframe:GetName() then tt = tip break end end end if tt then -- set transparency local red, green, blue, _ = tt:GetBackdropColor() local red2, green2, blue2, _ = tt:GetBackdropBorderColor() tt:SetBackdropColor(red, green, blue, TitanPanelGetVar("TooltipTrans")) tt:SetBackdropBorderColor(red2, green2, blue2, TitanPanelGetVar("TooltipTrans")) end end -- /LibQTip-1.0 support code end ) -- OnLeave TitanPluginframe:SetScript("OnLeave", function(self) if obj.OnLeave then obj.OnLeave(self) end TitanPanelButton_OnLeave(self); end ) end end ---Titan Text callback for the Titan (LDB) plugin when the LDB addon changes display text of the LDB object ---@param _ any not used ---@param name string Plugin id name for LDB ---@param attr string "value" or "suffix" or "text" or "label" ---@param value any Should be string ---@param dataobj table LDB data object function LDBToTitan:TitanLDBTextUpdate(_, name, attr, value, dataobj) -- just in case the LDB is active before Titan can register it... if not Titan__InitializedPEW then -- plugins have not been registered yet. return end -- This check is overkill but just in case... local plugin = TitanUtils_GetPlugin(name) local ldb = plugin and plugin.LDBVariables if not ldb then -- This plugin has not been registered return end -- Accept the various display elements and update the Titan plugin if attr == "value" then ldb.value = value end if attr == "suffix" then ldb.suffix = value end if attr == "text" then ldb.text = value end if attr == "label" then ldb.label = value end -- Now update the button with the change TitanPanelButton_UpdateButton(name) end ---Titan Text callback when the LDB addon changes display text ---@param name string Plugin id name for LDB ---@return string label ---@return string value function TitanLDBShowText(name) -- Set 'label1' and 'value1' for the Titan button display local nametrim = string.gsub(name, "LDBT_", ""); local fontstring = _G[TitanUtils_ButtonName(nametrim) .. TITAN_PANEL_TEXT]; local separator = ": " local lab1, val1 = "", "" local plugin = TitanUtils_GetPlugin(name) local ldb = plugin and plugin.LDBVariables if ldb then -- sanity check -- Check for display label if TitanGetVar(name, "ShowLabelText") then lab1 = (ldb.label or "") else lab1 = "" end if lab1 == "" then -- leave alone else lab1 = lab1 .. separator end -- Check for display text -- Check for display text -- .text is required to show -- .value is the text of the value - 100.0 in 100.0 FPS -- .suffix is the text after the value - FPS in 100.0 FPS if TitanGetVar(name, "ShowRegularText") then val1 = (ldb.text or "") else val1 = "" end else -- return values will be empty strings end if lab1 == "" then -- just empty else lab1 = TitanUtils_GetNormalText(lab1) end if val1 == "" then -- just empty else val1 = TitanGetVar(name, "ShowColoredText") and TitanUtils_GetGreenText(val1) or TitanUtils_GetHighlightText(val1) end return lab1, val1 end ---Titan Icon callback for the Titan (LDB) plugin when the LDB addon changes the icon of the LDB object ---@param _ any not used ---@param name string Plugin id name for LDB ---@param attr string "icon" or "iconCoords" or "iconR" "iconB" "iconR" ---@param value any icon : Path to icon file; iconCoords : coords ---@param dataobj table LDB data object function LDBToTitan:TitanLDBIconUpdate(_, name, attr, value, dataobj) -- just in case the LDB is active before Titan can register it... if not Titan__InitializedPEW then -- no plugins are registered yet return end -- This check is overkill but just in case... local plugin = TitanUtils_GetPlugin(name) local ldb = plugin and plugin.LDBVariables if ldb then if attr == "icon" then TitanPlugins[name].icon = value; TitanPanelButton_SetButtonIcon(name); end -- support for iconCoords, iconR, iconG, iconB attributes if attr == "iconCoords" then TitanPanelButton_SetButtonIcon(name, value); end if attr == "iconR" or attr == "iconB" or attr == "iconG" then TitanPanelButton_SetButtonIcon(name, nil, dataobj.iconR, dataobj.iconG, dataobj.iconB); end else -- This plugin is not registered yet return end end ---Titan Refresh all text & icon for LDB addons that were successfully registered --- Ensure all the LDB buttons are updated. --- This is called once x seconds after PEW. This helps close the gap where LDB addons set their text on their PEW event function TitanLDBRefreshButton() -- TitanDebug("LDB: RefreshButton") for name, obj in ldb:DataObjectIterator() do if obj then local unused = nil LDBToTitan:TitanLDBTextUpdate(unused, name, "text", (obj.text or ""), obj) LDBToTitan:TitanLDBIconUpdate(unused, name, "icon", (obj.icon or iconTitanDefault), obj) else -- TitanDebug("LDB: '"..name.."' no refresh") end end end ---Titan Create a Titan plugin from the DO (Data Object) --- This is the heart of the LDB to Titan. It reads the LDB DO (Data Object) and creates a Titan plugin. --- This takes a stricter interpretation of the LDB 1.1 spec rather than guessing what LDB addon developers intended. ---@param self table LDB frame ---@param name_str string LDB id name ---@param obj table LDB data object function TitanLDBCreateObject(self, name_str, obj) local name = name_str if Titan_Global.debug.ldb_setup then TitanDebug(tostring(name) .. " : Attempting to register "); end -- couple sanity checks -- if not obj or not name then if name and type(name) == 'string' then -- The name should be reasonable else local issue = "LDB request name " .. " '" .. tostring(name) .. "'" .. " unrecognizable !!!!" if Titan_Global.debug.ldb_setup then TitanDebug(issue); end error(issue) -- get out end if obj and type(obj) == 'table' then -- The LDB obj should be reasonable else local object = "" if obj then object = "is not a table" else object = "does not exist" end local issue = "LDB request object for " .. " '" .. tostring(name) .. "'" .. " " .. tostring(object) .. "" .. " !!!!" if Titan_Global.debug.ldb_setup then TitanDebug(issue); end error(issue) -- get out end -- anything to pass to the developer / user local notes = "" -- sanity check for supported types obj.type = obj.type or "Unknown" local supported = false -- assume failure for idx in ipairs(SupportedDOTypes) do if obj.type and obj.type == SupportedDOTypes[idx] then supported = true end end if supported then -- all is good - continue plugin creation else -- Create enough of a plugin to tell the user / developer -- that this plugin failed miserably local issue = "Unsupported LDB type '" .. tostring(obj.type) .. "'" if Titan_Global.debug.ldb_setup then TitanDebug(TITAN_REGISTER_FAILED .. " " .. issue); end error(issue) -- return TITAN_REGISTER_FAILED -- get out, there is nothing more that can be done end -- -- Handle the display attributes of the DO and register the appropriate callbacks -- -- Init the display elements of the plugin local ldb__label = obj.label or "" local ldb__suffix = obj.suffix or "" local ldb__value = obj.value or "" local ldb__text = obj.text or "" local ldb__icon = obj.icon or iconTitanDefault -- if .icon exists honor it and assume the addon may change it if obj.icon then ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_icon", "TitanLDBIconUpdate") end -- LAUNCHER text display elements if obj.type == LAUNCHER then if obj.label then ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_label", "TitanLDBTextUpdate") elseif obj.text then -- This is a 'be nice' check. It technically violates the 1.1 spec. -- Blank the .text so the rest of the routines work ldb__label = obj.text obj.text = "" ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_text", "TitanLDBTextUpdate") notes = notes .. "\n" .. "This is a LDB '" .. LAUNCHER .. "' without .label using .text instead!!!!" end end if Titan__InitializedPEW then notes = notes .. "\n" .. "Will be registered as single LDB plugin after the normal registration." end -- DATA_SOURCE text display elements if obj.type == DATA_SOURCE then -- .text so always allow it ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_text", "TitanLDBTextUpdate") if obj.label then ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_label", "TitanLDBTextUpdate") end if obj.suffix then ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_suffix", "TitanLDBTextUpdate") end if obj.value then ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_value", "TitanLDBTextUpdate") end end -- -- These are icon extensions listed within the 1.1 spec -- -- support for iconCoords, iconR, iconG, iconB attributes -- Due to the callbacks being fired these can easily affect -- performance, BEWARE when using them ! -- -- capture the icon coords & color for the Titan plugin if obj.iconCoords then self:TitanLDBIconUpdate(nil, name, "iconCoords", obj.iconCoords, obj) ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_iconCoords", "TitanLDBIconUpdate") end if obj.iconR and obj.iconG and obj.iconB then self:TitanLDBIconUpdate(nil, name, "iconR", obj.iconR, obj) ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_iconR", "TitanLDBIconUpdate") ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_iconG", "TitanLDBIconUpdate") ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_iconB", "TitanLDBIconUpdate") end -- -- Setup the Titan plugin for this LDB addon -- -- Create the appropriate Titan registry for the DO local registry = { id = name, ldb = tostring(obj.type), -- per 1.1 spec if .label exists use it else use data object's name menuText = obj.label or name, buttonTextFunction = "TitanLDBShowText", icon = ldb__icon, iconWidth = 16, controlVariables = { ShowIcon = true, ShowLabelText = true, ShowRegularText = false, ShowColoredText = false, DisplayOnRightSide = true }, savedVariables = { ShowIcon = true, ShowLabelText = true, ShowRegularText = true, ShowColoredText = false, DisplayOnRightSide = false }, LDBVariables = { value = ldb__value, suffix = ldb__suffix, text = ldb__text, label = ldb__label, name = name, type = (obj.type or ""), }, notes = notes, iconCoords = (obj.iconCoords or nil), iconR = (obj.iconR or nil), iconB = (obj.iconB or nil), iconG = (obj.iconG or nil), }; if Titan_Global.debug.ldb_setup then TitanDebug("" .. " type: '" .. tostring(registry.ldb) .. "' " ) end -- Set the plugin category, if it exists, else default to "General" -- Per the 1.1 LDB spec we check for a tocname attrib first, -- if found we use it, if not we assume that the DO "name" -- attribute is the same as the actual -- addon name, which might not always be the case. -- Titan defaults again to "General" if no categoy is found -- via a check in the menu implementation, later on. local addoncategory, addonversion; local tempname = obj.tocname or name; -- This was a sanity check but does not allow for multiple -- LDB to be within an addon yet act as their own addon. -- if IsAddOnLoaded(tempname) then addoncategory = TitanUtils_GetAddOnMetadata(tempname, "X-Category"); registry.category = (addoncategory and xcategories[addoncategory]) or (obj.category) or "General" addonversion = TitanUtils_GetAddOnMetadata(tempname, "Version") or (obj.version) or "" registry["version"] = addonversion; registry["notes"] = (TitanUtils_GetAddOnMetadata(tempname, "Notes") or "") .. "\n" -- end -- Depending on the LDB type set the control and saved Variables appropriately if obj.type == LAUNCHER then -- controls -- one interpretation of the LDB spec is launchers -- should always have an icon. registry["controlVariables"].ShowIcon = true; registry["controlVariables"].ShowRegularText = false; -- no text -- defaults registry["savedVariables"].ShowRegularText = false; registry["savedVariables"].DisplayOnRightSide = true; -- start on right side end if obj.type == DATA_SOURCE then -- controls registry["controlVariables"].ShowRegularText = true; -- defaults registry["savedVariables"].ShowRegularText = true; end -- -- Create the Titan frame for this LDB addon -- Titan _OnLoad will be used to request the plugin be registered by Titan (Template) local newTitanFrame -- a frame --[===[ if obj.type == "macro" then -- custom newTitanFrame = CreateFrame("Button", TitanUtils_ButtonName(name), UIParent, "SecureActionButtonTemplate, TitanPanelComboTemplate") -- UIParent, "TitanPanelComboTemplate") newTitanFrame:RegisterForClicks("AnyUp", "AnyDown") newTitanFrame:SetMouseClickEnabled(true) newTitanFrame:SetAttribute("type", "macro") -- newTitanFrame:SetAttribute("macro", obj.commandtext) newTitanFrame:SetAttribute("macrotext", obj.commandtext) newTitanFrame:SetScript("OnClick", function(self, button, down) SecureUnitButton_OnClick(self, button, down) --TitanPanelBarButton_OnClick(self, button) end) if Titan_Global.debug.ldb_setup then TitanDebug("" .." macrotext cmd: '"..tostring(obj.commandtext).."' " ) end else newTitanFrame = CreateFrame("Button", TitanUtils_ButtonName(name), UIParent, "TitanPanelComboTemplate") end --]===] newTitanFrame = CreateFrame("Button", TitanUtils_ButtonName(name), UIParent, "TitanPanelComboTemplate") newTitanFrame.TitanCreatedBy = "LDB" -- newTitanFrame.TitanType = "macro" newTitanFrame.TitanName = (name or "?") newTitanFrame.TitanAction = (obj.commandtext or "None") newTitanFrame.registry = registry newTitanFrame:SetFrameStrata("FULLSCREEN"); newTitanFrame:SetToplevel(true); newTitanFrame:RegisterForClicks("LeftButtonUp", "RightButtonUp"); -- Use the routines given by the DO in this precedence -- tooltip > OnEnter > OnTooltipShow > -- or register a callback in case it is created later. Per the 1.1 LDB spec if obj.tooltip then self:TitanLDBHandleScripts("tooltip", name, nil, obj.tooltip, obj) elseif obj.OnEnter then self:TitanLDBHandleScripts("OnEnter", name, nil, obj.OnEnter, obj) elseif obj.OnTooltipShow then self:TitanLDBHandleScripts("OnTooltipShow", name, nil, obj.OnTooltipShow, obj) else self:TitanLDBHandleScripts("OnEnter", name, nil, nil, obj) ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_OnEnter", "TitanLDBHandleScripts") ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_OnTooltipShow", "TitanLDBHandleScripts") end -- Use the OnClick given by the DO -- or register a callback in case it is created later. if obj.OnClick then self:TitanLDBHandleScripts("OnClick", name, nil, obj.OnClick) else ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_OnClick", "TitanLDBHandleScripts") end -- -- OnDoubleClick is UNDOCUMENTED in the 1.1 spec -- but was implemented by the original developer -- -- Use the OnDoubleClick given by the DO -- or register a callback in case it is created later. if obj.OnDoubleClick then self:TitanLDBHandleScripts("OnDoubleClick", name, nil, obj.OnDoubleClick) else ldb.RegisterCallback(self, CALLBACK_PREFIX .. name .. "_OnDoubleClick", "TitanLDBHandleScripts") end local pew = "event" if Titan__InitializedPEW then pew = "post event" -- Plugins have already been registered and loaded -- Get this one loaded -- This works because the .registry is now set TitanUtils_RegisterPluginList() TitanVariables_SyncSinglePluginSettings(registry.id) TitanPanel_InitPanelButtons() -- Show it... end if Titan_Global.debug.ldb_setup then TitanDebug("LDB create" .. " " .. tostring(pew) .. "" .. " '" .. tostring(registry.id) .. "'" .. " '" .. tostring(registry.ldb) .. "'" .. "\n...'" .. tostring(newTitanFrame:GetName()) .. "'" ) end return "Success" end ---Titan OnEvent handler for LDBToTitan --- Read through all the LDB objects requesting creation so far. Try to create cooresponding Titan plugins. ---@param sender any !! Not Used !! ---@param name string LDB id name ---@param obj table LDB data object function LDBToTitan:TitanLDBCreateObject(sender, name, obj) local call_success = true local ret_val = "" call_success, -- needed for pcall ret_val = -- actual return values pcall(TitanLDBCreateObject, self, name, obj) if call_success then -- Registration request created else -- Create enough of a plugin to tell the user / developer -- that this plugin failed local plugin = { self = nil, button = nil, isChild = nil, name = tostring(name), issue = ret_val, notes = "", status = TITAN_REGISTER_FAILED, category = "", plugin_type = tostring(obj.type or "LDB"), } TitanUtils_PluginFail(plugin) end if Titan_Global.debug.ldb_setup then TitanDebug("LDB Create:" -- .." "..tostring(sender).."" .. " " .. tostring(name) .. "" .. " " .. tostring(call_success) .. "" .. " " .. tostring(ret_val) .. "" ) end end --- OnEvent - PLAYER_LOGIN - handler for LDBToTitan ---@param self table Plugin frame ---@param event string Event name ---@param ... any Event args LDBToTitan:SetScript("OnEvent", function(self, event, ...) if (event == "PLAYER_LOGIN") then self:UnregisterEvent("PLAYER_LOGIN") -- Register the LDB plugins that have been created so far for name, obj in ldb:DataObjectIterator() do local call_success = true local ret_val = "" -- Just in case, catch any errors call_success, -- needed for pcall ret_val = -- actual return values pcall(TitanLDBCreateObject, self, name, obj) if call_success then -- Registration request created else -- Create enough of a plugin to tell the user / developer -- that this plugin failed local plugin = { self = nil, button = nil, isChild = nil, name = tostring(name), issue = ret_val, notes = "", status = TITAN_REGISTER_FAILED, category = "", plugin_type = tostring(obj.type or "LDB"), } TitanUtils_PluginFail(plugin) end if Titan_Global.debug.ldb_setup then TitanDebug("LDB" .. " " .. tostring(name) .. "" .. " " .. tostring(call_success) .. "" .. " " .. tostring(ret_val) .. "" ) end end -- In case a LDB plugin is created later... ldb.RegisterCallback(self, "LibDataBroker_DataObjectCreated", "TitanLDBCreateObject") end end )