diff --git a/TitanExampleLDB/Artwork/Starter.tga b/TitanExampleLDB/Artwork/Starter.tga deleted file mode 100644 index 6a7ddda..0000000 Binary files a/TitanExampleLDB/Artwork/Starter.tga and /dev/null differ diff --git a/TitanExampleLDB/Starter.tga b/TitanExampleLDB/Starter.tga deleted file mode 100644 index 6a7ddda..0000000 Binary files a/TitanExampleLDB/Starter.tga and /dev/null differ diff --git a/TitanExampleLDB/StarterLDB.lua b/TitanExampleLDB/StarterLDB.lua deleted file mode 100644 index 5bb5e18..0000000 --- a/TitanExampleLDB/StarterLDB.lua +++ /dev/null @@ -1,296 +0,0 @@ ---[[ -StarterLDB.lua -This is a simplistic example of a LDB (LibDataBroker) Addon. -It is assumed that you understand the Blizzard addon basics. -It is based loosely on the Titan Bag addon but is not Titan specific. - -It is not required that a display addon exist for your addon to run; Such as Titan :-) -However your addon will need to enable command line commands or the user will not be able to see or do anything. - -If running this example, it shows up in the Titan right click menu > General > LDBStarter - -NOTE: Before running this addon, the folder and file prefix must be the same to be considered for loading into WoW! -For example to just run this as is, remove the 'Example' from the folder name then start or reload WoW. -This is explained in more detail below in 'Folder Structure'. - -Enjoy! -By: The Titan Development Team ---]] - ---[[ Folder Structure -NOTE: Before running this addon, the folder and file prefix must be the same to be considered for loading into WoW! -For example, to just run this as is, remove the 'Example' from the folder name then start or reload WoW. -This is explained in more detail below. - - -This plugin folder must be added to the Addon folder to be considered for loading into WoW. -Inside this folder you will notice : -- three .toc files -- one .lua file -- one .tga file. - -There are sites (wowhead or wow wiki as examples) that have deeper explainations on addon development. -Please use these sites for more general addon information. - -=== .toc -The folder and the .toc files MUST have the same name! -Sort of... the name prior to the underscore(_) must be the same. The name after that (postfix) has meaning to WoW. -WoW has three versions represented by the three postix values. -_Mainline : current retail version -_Wrath : Wrath of the Lich King version. -_Vanilla : Classic Era version -These values may change as the versions evolve, say Cata is added to Wrath. -Or they may not :). Years from now we may wonder why Wrath represents Dragonflight! - -If your plugin is only for Classic Era then delete or rename the 'mainline' and 'wrath' .toc files. -Changing the filename will prevent WoW from loading the addon into that version of the game. - -Titan uses this method. Notice Titan folder has no 'wrath' or 'vanilla' .toc. -TitanClassic has has both 'wrath' and 'vanilla' .toc but no 'mainline' .toc. -This allows Titan plugins intended for Classic versions to run without change. - -NOTE: The ## Interface value should match the current interface value of the coorsponding WoW version. -In BattleNet this typcially shown below the 'Play' button. -DragonFlight 10.02.05 is represented without dots - 100205 - in the .toc. - -If the interface value is close (but lower) WoW will complain that you are running 'older' addons. -If WoW finds a Classic Era value (say 11500) in a 'mainline' .toc, it will just ignore it (not load). -The reverse (a higher value) is true as well. - -=== .lua -This is the code for the plugin - and this file. - -=== .tga -This file is the icon used by the plugin. -It is specified in the .obj created for the LDB init routine. -WoW can use several different types of icons. This discussion is outside the scope of this example. - -=== libs -This file implementing the LDB functions. -See https://github.com/tekkub/libdatabroker-1-1/wiki/ for an API description. -LibDataBroker-1.1.lua at https://github.com/tekkub/libdatabroker-1-1/ -It *should* be included in the LDB compliant display addon. -It *should* included in the display addon. - - -Anyone can extract the code and art from WoW. This can be handy to get code examples. -And to grab icons to use for a plugin. My undestanding is any icon can be used within WoW without violating the ToS. -WoW icons tend to be .blp files. These files are NOT easy to look at or manipulate!! -You will need to research third party tools to manipulate .blp files. ---]] - --- ******************************** Constants ******************************* -local ADDON_NAME = ... --- Set the name we want in the global name space. Ensure the name is unique across all addons. -StarterLDB = {} - -local id = "LDBStarter"; -- What the user will see as the name -local addon = ADDON_NAME -- addon name / folder name / toc name - --- Localized strings are outside the scope of this example. - ---[[ -The artwork path must start with Interface\\AddOns -Then the name of the plugin -Then any additional folder(s) to your artwork / icons. ---]] -local artwork_path = "Interface\\AddOns\\TitanLDB\\" - --- Get data from the TOC file. -local version = tostring(GetAddOnMetadata(addon, "Version")) or "Unknown" -local author = GetAddOnMetadata(addon, "Author") or "Unknown" --- NOTE: GetAddOnMetadata expects the addon name : --- The addon folder name or .toc name needs to be the same. --- ******************************** Variables ******************************* -local trace = false -- toggle to show / hide debug statements in this addon - --- ******************************** Functions ******************************* -local function Debug(debug_message, debug_type) - if trace then - local dtype = "" - local time_stamp = "" - local msg = "" - if debug_type == "error" then - dtype = "Error: " - elseif debug_type == "warning" then - dtype = "Warning: " - end - if debug_type == "normal" then - time_stamp = "" - else - time_stamp = date("%H:%M:%S")..": " - end - - msg = - "Debug".." " - ..time_stamp - ..dtype - ..debug_message - - _G["DEFAULT_CHAT_FRAME"]:AddMessage(msg) - else - -- not requested - end - --date("%m/%d/%y %H:%M:%S") -end - --- Calculate bag space then return text and icon to display -local function GetBagSlotInfo() - local totalSlots, usedSlots, availableSlots, icon - totalSlots = 0; - usedSlots = 0; - for bag = 0, 4 do - local size = C_Container.GetContainerNumSlots(bag); - if (size and size > 0) then - totalSlots = totalSlots + size; - local free = C_Container.GetContainerNumFreeSlots(bag) - local used = size - free - usedSlots = usedSlots + used; - end - end - availableSlots = totalSlots - usedSlots; - - local i,r = math.modf(availableSlots/2) - if (r == 0) then - icon = artwork_path.."Starter.tga" - else - icon = "Interface\\PetPaperDollFrame\\UI-PetHappiness" --PET_DISMISS_TEXTURE - end - - local bagText - bagText = format("%d/%d", availableSlots, totalSlots); - - bagText = HIGHLIGHT_FONT_COLOR_CODE..bagText..FONT_COLOR_CODE_CLOSE - - return bagText, icon ---]] -end - --- Create the tooltip -local function LDB_OnTooltipShow(tooltip) - tooltip = tooltip or GameTooltip - local tt_str = "" - ----[[ -print("LDB OTS" -.." "..tostring(id).."" -) ---]] - tt_str = - GREEN_FONT_COLOR_CODE - ..id.." Info" - ..FONT_COLOR_CODE_CLOSE - tooltip:AddLine(tt_str) - - local text, icon = GetBagSlotInfo() - tt_str = "Available bag slots" - .." "..text.."\n" - .."\n".."Hint: Left-click to open all bags." - - tooltip:AddLine(tt_str) -end - -local function LDB_Init(LDB_frame) - Debug(id.." Init ..."); - --[[ - Initialize the Data Broker 'button'. - This is the heart of a LDB plugin. It determines how the display addon is to treat this addon. - - Setting the type is required so the LDB lib and display addon know what to do. See the LDB spec. - --]] - -- The .obj is the key link to the display addon!! - LDB_frame.obj = - LibStub("LibDataBroker-1.1"):NewDataObject(id, { - type = "data source", -- required - -- SDK: The two options are: - -- "data source" - A data source is expected to show some type of info - -- "launcher" - Expected to open another window or perform some action - icon = artwork_path.."Starter.tga", -- The icon to display on the display addon - label = id, -- label is the text the user will use to find this addon in the display addon. - text = "nyl", -- will be updated later - OnTooltipShow = function(tooltip) - LDB_OnTooltipShow(tooltip) - end, - OnClick = function(self, button) - if ( button == "LeftButton" ) then - -- Just a simple action to illustrate an LDB addon. - ToggleAllBags(); - elseif ( button == "RightButton" ) then - -- There is no action to take in this example. - --[[ Add code here if your addon needs to do something on right click. - Typically an options menu which is outside the scope of this example. - --]] - end - end, - }) - Debug(id.." Init fini."); ---]===] -end - --- Update the Bags Data Broker 'button' -local function LDB_Update(LDB_frame) - local text, icon = GetBagSlotInfo() - LDB_frame.obj.text = text - LDB_frame.obj.icon = icon -end - --- Parse events registered to plugin and act on them -local function Button_OnEvent(self, event, ...) - Debug("OnEvent" - .." "..tostring(event).."" - ) - if (event == "PLAYER_ENTERING_WORLD") then - -- Do any additional set up needed - -- - print("" - .." "..tostring(id).."" - .." "..tostring(version).."" - .." by "..tostring(author).."" - ) - - -- Now that events have settled, register the one(s) we really want. - -- This may not be needed but it could reduce churn and possible timing issues. - self:RegisterEvent("BAG_UPDATE"); - - -- Unregister events no longer needed. - -- Good practice although this event is only fired on login - self:UnregisterEvent("PLAYER_ENTERING_WORLD"); - end - if event == "BAG_UPDATE" then - LDB_Update(self) - end -end - --- ====== Create needed frames -local function Create_Frames() - -- general container frame - -- The frame pointer is passed as a parameter rather than an addon local. - local window = CreateFrame("Frame", "StarterLDBExample", UIParent) --- window:Hide() - - -- Set strata as desired - window:SetFrameStrata("FULLSCREEN") - -- Using SetScript("OnLoad", does not work - - window:SetScript("OnEvent", function(self, event, ...) - Button_OnEvent(self, event, ...) - end) - - -- Tell Blizzard this frame needs player entering world event. - window:RegisterEvent("PLAYER_ENTERING_WORLD"); - - -- Any other addon specific "on load" code here - LDB_Init(window) - -- Update the text (bag numbers) - LDB_Update(window) - - -- shamelessly print a load message to chat window - DEFAULT_CHAT_FRAME:AddMessage( - GREEN_FONT_COLOR_CODE - ..addon..id.." "..version - .." by " - ..FONT_COLOR_CODE_CLOSE - .."|cFFFFFF00"..author..FONT_COLOR_CODE_CLOSE); -end - -Create_Frames() -- do the work diff --git a/TitanExampleLDB/TitanLDB_Mainline.toc b/TitanExampleLDB/TitanLDB_Mainline.toc deleted file mode 100644 index 44af1ac..0000000 --- a/TitanExampleLDB/TitanLDB_Mainline.toc +++ /dev/null @@ -1,12 +0,0 @@ -## Interface: 100205 -## Title: StarterLDB -## Notes: LDB example -## Author: Titan Dev Team -## DefaultState: Enabled -## SavedVariables: -## OptionalDeps: -## Dependencies: -## Version: 1.1 -## X-Child-Of: -libs/LibDataBroker-1.1.lua -StarterLDB.lua diff --git a/TitanExampleLDB/TitanLDB_Vanilla.toc b/TitanExampleLDB/TitanLDB_Vanilla.toc deleted file mode 100644 index a294486..0000000 --- a/TitanExampleLDB/TitanLDB_Vanilla.toc +++ /dev/null @@ -1,12 +0,0 @@ -## Interface: 11500 -## Title: StarterLDB -## Notes: LDB example -## Author: Titan Dev Team -## DefaultState: Enabled -## SavedVariables: -## OptionalDeps: -## Dependencies: -## Version: 1.1 -## X-Child-Of: -libs/LibDataBroker-1.1.lua -StarterLDB.lua diff --git a/TitanExampleLDB/TitanLDB_Wrath.toc b/TitanExampleLDB/TitanLDB_Wrath.toc deleted file mode 100644 index 40aa326..0000000 --- a/TitanExampleLDB/TitanLDB_Wrath.toc +++ /dev/null @@ -1,12 +0,0 @@ -## Interface: 30403 -## Title: StarterLDB -## Notes: LDB example -## Author: Titan Dev Team -## DefaultState: Enabled -## SavedVariables: -## OptionalDeps: -## Dependencies: -## Version: 1.1 -## X-Child-Of: -libs/LibDataBroker-1.1.lua -StarterLDB.lua diff --git a/TitanExampleLDB/libs/LibDataBroker-1.1.lua b/TitanExampleLDB/libs/LibDataBroker-1.1.lua deleted file mode 100644 index f47c0cd..0000000 --- a/TitanExampleLDB/libs/LibDataBroker-1.1.lua +++ /dev/null @@ -1,90 +0,0 @@ - -assert(LibStub, "LibDataBroker-1.1 requires LibStub") -assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0") - -local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4) -if not lib then return end -oldminor = oldminor or 0 - - -lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib) -lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {} -local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks - -if oldminor < 2 then - lib.domt = { - __metatable = "access denied", - __index = function(self, key) return attributestorage[self] and attributestorage[self][key] end, - } -end - -if oldminor < 3 then - lib.domt.__newindex = function(self, key, value) - if not attributestorage[self] then attributestorage[self] = {} end - if attributestorage[self][key] == value then return end - attributestorage[self][key] = value - local name = namestorage[self] - if not name then return end - callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self) - callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self) - callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self) - callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self) - end -end - -if oldminor < 2 then - function lib:NewDataObject(name, dataobj) - if self.proxystorage[name] then return end - - if dataobj then - assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table") - self.attributestorage[dataobj] = {} - for i,v in pairs(dataobj) do - self.attributestorage[dataobj][i] = v - dataobj[i] = nil - end - end - dataobj = setmetatable(dataobj or {}, self.domt) - self.proxystorage[name], self.namestorage[dataobj] = dataobj, name - self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj) - return dataobj - end -end - -if oldminor < 1 then - function lib:DataObjectIterator() - return pairs(self.proxystorage) - end - - function lib:GetDataObjectByName(dataobjectname) - return self.proxystorage[dataobjectname] - end - - function lib:GetNameByDataObject(dataobject) - return self.namestorage[dataobject] - end -end - -if oldminor < 4 then - local next = pairs(attributestorage) - function lib:pairs(dataobject_or_name) - local t = type(dataobject_or_name) - assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)") - - local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name - assert(attributestorage[dataobj], "Data object not found") - - return next, attributestorage[dataobj], nil - end - - local ipairs_iter = ipairs(attributestorage) - function lib:ipairs(dataobject_or_name) - local t = type(dataobject_or_name) - assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)") - - local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name - assert(attributestorage[dataobj], "Data object not found") - - return ipairs_iter, attributestorage[dataobj], 0 - end -end diff --git a/TitanExamplePlugin/TitanPlugin_Mainline.toc b/TitanExamplePlugin/TitanPlugin_Mainline.toc deleted file mode 100644 index 2b4dc88..0000000 --- a/TitanExamplePlugin/TitanPlugin_Mainline.toc +++ /dev/null @@ -1,8 +0,0 @@ -## Interface: 100205 -## Title: Titan Starter -## Version: 1.0.0 -## Notes: Adds bag and free slot information to Titan Panel -## Author: Titan Panel Development Team (http://www.titanpanel.org) -## SavedVariables: -## Dependencies: Titan -TitanStarter.lua diff --git a/TitanExamplePlugin/TitanPlugin_Vanilla.toc b/TitanExamplePlugin/TitanPlugin_Vanilla.toc deleted file mode 100644 index d781ee4..0000000 --- a/TitanExamplePlugin/TitanPlugin_Vanilla.toc +++ /dev/null @@ -1,9 +0,0 @@ -## Interface: 11500 -## Title: TitanStarter -## Version: 1.0.0 -## Notes: Adds bag and free slot information to Titan Panel -## Author: Titan Panel Development Team (http://www.titanpanel.org) -## SavedVariables: -## OptionalDeps: -## Dependencies: TitanClassic -TitanStarter.lua diff --git a/TitanExamplePlugin/TitanPlugin_Wrath.toc b/TitanExamplePlugin/TitanPlugin_Wrath.toc deleted file mode 100644 index 4f74b27..0000000 --- a/TitanExamplePlugin/TitanPlugin_Wrath.toc +++ /dev/null @@ -1,9 +0,0 @@ -## Interface: 30403 -## Title: Titan Starter -## Version: 1.0.0 -## Notes: Adds bag and free slot information to Titan Panel -## Author: Titan Panel Development Team (http://www.titanpanel.org) -## SavedVariables: -## OptionalDeps: -## Dependencies: TitanClassic -TitanStarter.lua diff --git a/TitanExamplePlugin/TitanStarter.lua b/TitanExamplePlugin/TitanStarter.lua deleted file mode 100644 index 8634f8b..0000000 --- a/TitanExamplePlugin/TitanStarter.lua +++ /dev/null @@ -1,852 +0,0 @@ ---[[ --- ************************************************************************** --- * TitanStarter.lua --- * --- * By: The Titan Panel Development Team --- ************************************************************************** ---]] ---[[ Example -This is an example Titan (Titen Panel) plugin based on Titan Bag. -It is intended to introduce Titan plugin essentials by using a basic addon -with a lot of comments. This can be run as is then changed to implement your great idea! - -NOTE: The terms addon and plugin are essentially the same. -Here plugin is used when the addon is displayed by Titan. ---]] - ---[[ Folder Structure -NOTE: Before running this addon, the folder and file prefix must be the same to be considered for loading into WoW! -For example to just run this as is, remove the 'Example' from the folder name then start or reload WoW. -This is explained in more detail below. - - -This plugin folder must be added to the Addon folder to be considered for loading into WoW. -Inside this folder you will notice : -- three .toc files -- one .lua file -- one .tga file. - -There are sites (wowhead or wow wiki as examples) that have deeper explainations on addon development. -Please use these sites for more general addon information. - -=== .toc -The folder and the .toc files MUST have the same name! -Sort of... the name prior to the underscore(_) must be the same. The name after that (postfix) has meaning to WoW. -WoW has three versions represented by the three postix values. -_Mainline : current retail version -_Wrath : Wrath of the Lich King version. -_Vanilla : Classic Era version -These values may change as the versions evolve, say Cata is added to Wrath. -Or they may not :). Years from now we may wonder why Wrath represents Dragonflight! - -If your plugin is only for Classic Era then delete or rename the 'mainline' and 'wrath' .toc files. -Changing the filename will prevent WoW from loading the addon into that version of the game. - -Titan uses this method. Notice Titan folder has no 'wrath' or 'vanilla' .toc. -TitanClassic has has both 'wrath' and 'vanilla' .toc but no 'mainline' .toc. -This allows Titan plugins intended for Classic versions to run without change. - -NOTE: The ## Interface value should match the current interface value of the coorsponding WoW version. -In BattleNet this typcially shown below the 'Play' button. -DragonFlight 10.02.05 is represented without dots - 100205 - in the .toc. - -If the interface value is close (but lower) WoW will complain that you are running 'older' addons. -If WoW finds a Classic Era value (say 11500) in a 'mainline' .toc, it will just ignore it (not load). -The reverse (a higher value) is true as well. - -=== .lua -This is the code for the plugin - and this file. - -=== .tga -This file is the icon used by the plugin. -It is specified in the .registry used by Titan. -WoW can use several different types of icons. This discussion is outside the scope of this example. - -Anyone can extract the code and art from WoW. This can be handy to get code examples. -And to grab icons to use for a plugin. My undestanding is any icon can be used within WoW without violating the ToS. -WoW icons tend to be .blp files. These files are NOT easy to look at or manipulate!! -You will need to research third party tools to manipulate .blp files. ---]] - ---[[ Editting -This example may seem daunting at first. We decided to leave Bag as is to give plenty of coding examples. - -GetBagData will be replaced by your code. It uses IsProfessionBagID. -ToggleBags is called from OnClick. This will be replaced by your code. - -TitanPanelRightClickMenu_PrepareStarterMenu will need its name changed. - -The other routines will be modified to impement your idea. ---]] - ---[[ Code flow -NOTE: The .toc states Titan is required [## Dependencies: Titan]. -WoW insures Titan is loaded BEFORE this addon. - -First step: ==== Starting WoW -Wow will 'load' this addon. Any code outside the Lua functions will be run. -- local VERSION = GetAddOnMetadata(add_on, "Version") will run GetAddOnMetadata -- bag_info will be populated -- ... -- Create_Frames is called - -Create_Frames will create the addon frame - TITAN_BUTTON - and call local OnLoad. -Create_Frames also sets the event scripts for the addon. -This is how WoW and Titan interact with this addon. -NOTE: The frame is created using a Titan template. This template handles some frame processing. - -OnLoad does two important things -1) Sets the .registry of the addon - See the .registry comment block -2) Registers for PLAYER_ENTERING_WORLD -NOTE: OnLoad should be small and not assume data is ready yet. - -Next: ==== Waiting for WoW -WoW fires a bunch of events as this and other addons are loaded. - -Eventually the game and all addons are loaded and this plugin receives the -PLAYER_ENTERING_WORLD event via OnEvent. -When processing PLAYER_ENTERING_WORLD only register for events and access local data. - -Titan also receives the PLAYER_ENTERING_WORLD event. There is NO guarantee this plugin -receives the event before or after Titan! -Titan then processes its own data and saved variables. -Titan will process and set any saved variables specified in the .registry of this plugin! -Then Titan starts registering plugins using each addon .registry. -It also loads any LDB plugins found. - -Next: ==== Still waiting for WoW -Titan shows the user requested bars with plugins. -OnShow is called by Titan when placing this plugin on a bar or the user requests the plugin to be shown. -Technically Titan calls the now registered frame - TITAN_BUTTON - :Show -then WoW calls the frame script :OnShow eventually calling OnShow in this addon set by Create_Frames. - -NOTE: Do not assume any saved variables in .registry are ready until OnShow! - -OnShow now does all processing to set up this plugin properly. Once done it calls TitanPanelButton_UpdateButton. -Now the plugin is ready for the user. - -Next: ==== Ready to play WoW -The plugin is now 'idle' until : -- Titan calls TitanPanelButton_UpdateButton(TITAN_PLUGIN) to (re)display this plugin -- Any registered event is received -- A timer or callback calls the routine - via Titan or this plugin code - -TitanPanelButton_UpdateButton(TITAN_PLUGIN) called when: -- User does a reload or user action - via Titan -- User changes a plugin option using Titan menu -- User changes a plugin option using Titan configuration -- A Titan timer expires such as auto hide bar is active or pet battle or ... - -Events occur when: -- User clicks on this plugin to take an action or show menu - OnClick -- User mouses over this plugin to display tool tip - OnEnter -- Any registered event is received - OnEvent -- Your timer expires - be very careful here! :) -- Your callback happens such as waiting for WoW server info - -OnClick is the TITAN_BUTTON frame script. -Left click is procssed by this plugin. -Right click is handled by the Titan template to invoke plugin menu (TitanPanelRightClickMenu_PrepareStarterMenu) - -OnEnter and OnLeave are the TITAN_BUTTON frame scripts. -OnEnter is handled by the Titan template to show the tool tip (.registry.tooltipTextFunction). -OnLeave is handled by the Titan template to hide the tool tip. - -Next: ==== -The above step continues until: -- User hides the plugin -- The user logs out the character or exits WoW - -Either action causes OnHide to be called. -OnHide should : -- Do any cleanup -- Stop any timers -- Unregister any events -These steps keep processing to a minimum and reduces the chance of errors to the user. - -NOTE: Any saved variables - in .registry or specific to this plugin - are saved by WoW on logout or exit. -No specific actions are required. - ---]] - ---[[ Structure -The plugin starts with local constants used throughout. -Then local variables; then functions. - -The design uses local functions sa much as practical. Mainly for clarity and a small speed increase. -Titan specific details will be noted and explained. -The comments will specify where names are important. -Any local routine or variable with 'bag' in the name can be changed to your design or deleted. - -Suggested path is start with Create_Frames at the bottom of the file. It is where the magic starts. - -Note: Feel free to look at Titan code. Pay attention to the comments. Any routine labeled as API -can be used by a plugin. API routines will be maintained and the functionality expected to remain stable. -Any parameter or functionality changes to API will be 'broadcast' on delivery sites and our sites (Discord, our web page). - -Of course feel free to reach out on our Discord site with any questions or suggestions! ---]] - ---[[ .registry -This is the GUTS of a Titan plugin. The .registry on the frame contains all -the info to register / create a plugin. - -Every registry with an id should appear in Titan > Configuration > Attempts. -Info is shown there along with pass / fail. -If the plugin failed to register, the error is shown there. - -NOTE: Titan expects 3 routines to be in the global namespace: -- Routine that updates the plugin : .buttonTextFunction -- Routine that creates the tool tip : .tooltipTextFunction -- Routine that creates the options : .menuTextFunction OR "TitanPanelRightClickMenu_Prepare"<id>"Menu" - -Attributes: -.id : Required : must be unique across plugins. If there are duplicates, the first one 'wins'. -.category : The list is in TITAN_PANEL_BUTTONS_PLUGIN_CATEGORY (TitanGlobal.lua) - "Built-ins" is reserved for plugins that Titan releases. -.version : plugin version sown in menus and config. -.menuText : Used by as the title for the right click menu. -.menuTextFunction : This is called for the right click menu. - NOTE : This is the newer, prefered method which makes the options menu routine explicit. - OLD METHOD: Still supported! - Titan builds the function name as "TitanPanelRightClickMenu_Prepare"<id>"Menu" - TitanPanelRightClickMenu_PrepareStarterMenu in this example. -.buttonTextFunction : This is called whenever the button is to be updated - TitanPanelButton_UpdateButton(TITAN_PLUGIN) - This is called from within the the plugin and from Titan core. - The specified routine is expected to be global. - It is called securely (pcall) so a plugin will not crash Titan (hopefully). - Titan will usually show "<?>" if the routine dies. - If this occurs and you need to see the error, search for this attribute in Titan folder and - uncomment the print of the error message. -.tooltipTitle : Used as the title for the tool tip -.tooltipTextFunction : This is called when OnEnter of the plugin frame is triggered. - It is expected to be global. - It is called securely (pcall) so a plugin will not crash Titan (hopefully). - Titan will usually show part of the error in the tool tip if the routine dies. -.icon : Allowed path to the icon to be used. It is recommended to store the icon in the plugin folder, - even if copied from WoW folder. -.iconWidth : Best left at 16... -.notes : This is shown in Titan > Config > Plugins when this plugin is selected. -.controlVariables : This list is used by TitanPanelRightClickMenu_AddControlVars(TITAN_PLUGIN) - true : Will be included in the menu - false : Will not be included in the menu -.savedVariables : These are the variables stored in Titan saved variables. - The initial values are used only if that particular is 'new' to that character (new Titan install, new character). - If a value is removed then it is removed from the saved variables as Titan is run for each character. - ---]] - --- ******************************** Constants ******************************* -local add_on = ... -local _G = getfenv(0); -local artwork_path = "Interface\\AddOns\\TitanPlugin\\" --- NOTE: This is the plugin id which should be unique across Titan plugins --- It does not need to match the addon id. -local TITAN_PLUGIN = "Starter" --- NOTE: The convention is TitanPanel <id> Button -local TITAN_BUTTON = "TitanPanel"..TITAN_PLUGIN.."Button" -local VERSION = GetAddOnMetadata(add_on, "Version") - -local TITAN_BAG_THRESHOLD_TABLE = { - Values = { 0.5, 0.75, 0.9 }, - Colors = { HIGHLIGHT_FONT_COLOR, NORMAL_FONT_COLOR, ORANGE_FONT_COLOR, RED_FONT_COLOR }, -} -local updateTable = {TITAN_PLUGIN, TITAN_PANEL_UPDATE_BUTTON}; --- ******************************** Variables ******************************* -local AceTimer = LibStub("AceTimer-3.0") -local L = LibStub("AceLocale-3.0"):GetLocale(TITAN_ID, true) -local BagTimer - -local bag_info = { -- itemType : warcraft.wiki.gg/wiki/itemType - [1] = -- Soul bag - { color = {r=0.96,g=0.55,b=0.73}}, -- PINK - [2] = -- HERBALISM = - { color = {r=0,g=1,b=0}}, -- GREEN - [3] = -- ENCHANTING = - { color = {r=0,g=0,b=1}}, -- BLUE - [4] = -- ENGINEERING = - { color = {r=1,g=0.49,b=0.04}}, -- ORANGE - [5] = -- JEWELCRAFTING = - { color = {r=1,g=0,b=0}}, -- RED - [6] = -- MINING = - { color = {r=1,g=1,b=1}}, -- WHITE - [7] = -- LEATHERWORKING = - { color = {r=0.78,g=0.61,b=0.43}}, -- TAN - [8] = -- INSCRIPTION = - { color = {r=0.58,g=0.51,b=0.79}}, -- PURPLE - [9] = -- FISHING = - { color = {r=0.41,g=0.8,b=0.94}}, -- LIGHT_BLUE - [10] = -- COOKING = - { color = {r=0.96,g=0.55,b=0.73}}, -- PINK - -- These are Classic arrow or bullet bags - [22] = -- Classic arrow - { color = {r=1,g=.4,b=0}}, -- copper - [23] = -- Classic bullet - { color = {r=0.8,g=0.8,b=0.8}}, -- silver -} - -local trace = false -- true / false Make true when debug output is needed. - -local MIN_BAGS = 0 -local MAX_BAGS = Constants.InventoryConstants.NumBagSlots -local bag_data = {} -- to hold the user bag data - --- ******************************** Functions ******************************* - -local function IsProfessionBagID(slot) - -- The info needed is available using GetItemInfoInstant; only the bag / item id is required - -- itemType : warcraft.wiki.gg/wiki/itemType - local res = false - local style = "" - local info, itemId, itemType, itemSubType, itemEquipLoc, itemTexture, classID, subclassID - local inv_id = C_Container.ContainerIDToInventoryID(slot) - - if inv_id == nil then - -- Only works on bag and bank bags NOT backpack! - else - info = GetInventoryItemLink("player", inv_id) - itemId, itemType, itemSubType, itemEquipLoc, itemTexture, classID, subclassID = GetItemInfoInstant(info) - style = subclassID ---[[ -TitanDebug("T isP 0:" - .." "..tostring(slot).."" - .." "..tostring(itemId).."" - .." '"..tostring(itemType).."'" - .." '"..tostring(itemSubType).."'" - .." "..tostring(itemEquipLoc).."" - .." '"..tostring(itemTexture).."'" - .." "..tostring(classID).."" - .." "..tostring(subclassID).."" - ) ---]] - if classID == 1 then -- is a container / bag - if subclassID >= 1 then - -- profession bag of some type [2 - 10] Jan 2024 (DragonFlight / Wrath / Classic Era) - -- OR soul bag [1] - res = true - else - -- is a arrow or bullet; only two options - end - elseif classID == 6 then -- is a 'projectile' holder - res = true - -- is a ammo bag or quiver; only two options - elseif classID == 11 then -- is a 'quiver'; Wrath and CE - res = true - -- is a ammo pouch or quiver; only two options - style = subclassID + 20 -- change to get local color for name - else - -- not a bag - end - end - - if trace then - TitanDebug("T isP:" - .." "..tostring(res).."" - .." "..tostring(style).."" - .." "..tostring(itemId).."" - .." "..tostring(classID).."" - .." "..tostring(subclassID).."" - .." "..tostring(inv_id).."" - ) - end - - return res, style -end - -local function ToggleBags() - if TitanGetVar(TITAN_PLUGIN, "OpenBags") then - ToggleAllBags() - else - end -end - ---[[ -Where the magic happens! -It is good practice - and good memory - to document the 'why' the code does what it does. -And give details that are not obvious to the reader who did not write the code. ---]] -local function GetBagData(id) - --[[ - The bag name is not always available when player entering world - Grabbing the total slots is available though to determine if a bag exists. - The user may see bag name as UNKNOWN until an event triggers a bag check AND the name is available. - --]] - - local total_slots = 0 - local total_free = 0 - local total_used = 0 - - local count_prof = TitanGetVar(TITAN_PLUGIN, "CountProfBagSlots") - - for bag_slot = MIN_BAGS, MAX_BAGS do -- assuming 0 (Backpack) will not be a profession bag - local slots = C_Container.GetContainerNumSlots(bag_slot) - - -- Ensure a blank structure exists - bag_data[bag_slot] = { - has_bag = false, - name = "", - maxi_slots = 0, - free_slots = 0, - used_slots = 0, - style = "", - color = "", - } - - if slots > 0 then - bag_data[bag_slot].has_bag = true - - local bag_name = (C_Container.GetBagName(bag_slot) or UNKNOWN) - bag_data[bag_slot].name = bag_name - bag_data[bag_slot].maxi_slots = slots - - local free = C_Container.GetContainerNumFreeSlots(bag_slot) - local used = slots - free - bag_data[bag_slot].free_slots = free - bag_data[bag_slot].used_slots = used - - -- some info is not known until the name is available... - -- The API requires name to get the bag ID. - local bag_type = "none" - local color = {r=0,g=0,b=0} -- black (should never be used...) - - if bag_name == UNKNOWN then - -- name not available yet - else - end - - -- Jan 2024 : Moved away from named based to an id based. Allows name to come later from server - local is_prof_bag, style = IsProfessionBagID(bag_slot) ---[[ -if trace then -TitanDebug("T Bag...:" -.." "..tostring(bag_slot).."" -.." "..tostring(is_prof_bag).."" -.." '"..tostring(style).."'" -.." "..tostring(itemClassID).."" -.." "..tostring(itemSubClassID).."" -) -end ---]] - if is_prof_bag then - color = bag_info[style].color - bag_type = "profession" - else - bag_type = "normal" - end - bag_data[bag_slot].style = bag_type - bag_data[bag_slot].color = color - - -- add to total - if bag_data[bag_slot].style == "profession" then - if count_prof then - total_slots = total_slots + slots - total_free = total_free + free - total_used = total_used + used - else - -- ignore in totals - end - else - total_slots = total_slots + slots - total_free = total_free + free - total_used = total_used + used - end - else - bag_data[bag_slot].has_bag = false - end - - if trace then - TitanDebug("T info" - .." "..tostring(bag_slot).."" - .." ?:"..tostring(bag_data[bag_slot].has_bag).."" - .." max: "..tostring(bag_data[bag_slot].maxi_slots).."" - .." used: "..tostring(bag_data[bag_slot].used_slots).."" - .." free: "..tostring(bag_data[bag_slot].free_slots).."" - .." type: "..tostring(bag_data[bag_slot].style).."" - .." count: "..tostring(count_prof).."" - .." '"..tostring(bag_data[bag_slot].name).."'" - ) - end - end - - bag_data.total_slots = total_slots - bag_data.total_free = total_free - bag_data.total_used = total_used - - local bagText = "" - if (TitanGetVar(TITAN_PLUGIN, "ShowUsedSlots")) then - bagText = format(L["TITAN_BAG_FORMAT"], total_used, total_slots); - else - bagText = format(L["TITAN_BAG_FORMAT"], total_free, total_slots); - end - - local bagRichText = "" - if ( TitanGetVar(TITAN_PLUGIN, "ShowColoredText") ) then - local color = "" - color = TitanUtils_GetThresholdColor(TITAN_BAG_THRESHOLD_TABLE, total_used / total_slots); - bagRichText = TitanUtils_GetColoredText(bagText, color); - else - bagRichText = TitanUtils_GetHighlightText(bagText); - end - - bagRichText = bagRichText --..bagRichTextProf[1]..bagRichTextProf[2]..bagRichTextProf[3]..bagRichTextProf[4]..bagRichTextProf[5]; - - return L["TITAN_BAG_BUTTON_LABEL"], bagRichText -end - -local function CreateMenu() - if trace then - TitanDebug("TS event" - .." "..tostring(TitanPanelRightClickMenu_GetDropdownLevel()).."" - .." '"..tostring(TitanPanelRightClickMenu_GetDropdMenuValue()).."'" - ) - end - local info - -- level 2 - if TitanPanelRightClickMenu_GetDropdownLevel() == 2 then - if TitanPanelRightClickMenu_GetDropdMenuValue() == "Options" then - TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_OPTIONS"], TitanPanelRightClickMenu_GetDropdownLevel()) - info = {}; - info.text = L["TITAN_BAG_MENU_SHOW_USED_SLOTS"]; - info.func = function() - TitanSetVar(TITAN_PLUGIN, "ShowUsedSlots", 1); - TitanPanelButton_UpdateButton(TITAN_PLUGIN); - end - info.checked = TitanGetVar(TITAN_PLUGIN, "ShowUsedSlots"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_BAG_MENU_SHOW_AVAILABLE_SLOTS"]; - info.func = function() - TitanSetVar(TITAN_PLUGIN, "ShowUsedSlots", nil); - TitanPanelButton_UpdateButton(TITAN_PLUGIN); - end - info.checked = TitanUtils_Toggle(TitanGetVar(TITAN_PLUGIN, "ShowUsedSlots")); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_BAG_MENU_SHOW_DETAILED"]; - info.func = function() - TitanToggleVar(TITAN_PLUGIN, "ShowDetailedInfo"); - end - info.checked = TitanGetVar(TITAN_PLUGIN, "ShowDetailedInfo"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - info = {}; - info.text = L["TITAN_BAG_MENU_OPEN_BAGS"] - info.func = function() - TitanToggleVar(TITAN_PLUGIN, "OpenBags") - end - info.checked = TitanGetVar(TITAN_PLUGIN, "OpenBags"); - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - end - return - end - - -- level 1 - TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_PLUGIN].menuText); - - info = {}; - info.notCheckable = true - info.text = L["TITAN_PANEL_OPTIONS"]; - info.value = "Options" - info.hasArrow = 1; - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddSpacer(); - info = {}; - info.text = L["TITAN_BAG_MENU_IGNORE_PROF_BAGS_SLOTS"]; - info.func = function() - TitanToggleVar(TITAN_PLUGIN, "CountProfBagSlots"); - TitanPanelButton_UpdateButton(TITAN_PLUGIN); - end - info.checked = not TitanGetVar(TITAN_PLUGIN, "CountProfBagSlots") - TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel()); - - TitanPanelRightClickMenu_AddControlVars(TITAN_PLUGIN) -end - -local function GetButtonText(id) - local strA, strB = GetBagData(id) - return strA, strB -end - -local function GetTooltipText() - local totalSlots, usedSlots, availableSlots; - local returnstring = ""; - - if trace then - TitanDebug("TS tool tip" - .." detail "..tostring(TitanGetVar(TITAN_PLUGIN, "ShowDetailedInfo")).."" - .." used "..tostring(TitanGetVar(TITAN_PLUGIN, "ShowUsedSlots")).."" - .." prof "..tostring(TitanGetVar(TITAN_PLUGIN, "CountProfBagSlots")).."" - .." color "..tostring(TitanGetVar(TITAN_PLUGIN, "ShowColoredText")).."" - .." open "..tostring(TitanGetVar(TITAN_PLUGIN, "OpenBags")).."" - ) - end - - if TitanGetVar(TITAN_PLUGIN, "ShowDetailedInfo") then - returnstring = "\n"; - if TitanGetVar(TITAN_PLUGIN, "ShowUsedSlots") then - returnstring = returnstring..TitanUtils_GetNormalText(L["TITAN_BAG_MENU_TEXT"]) - ..":\t"..TitanUtils_GetNormalText(L["TITAN_BAG_USED_SLOTS"])..":\n"; - else - returnstring = returnstring..TitanUtils_GetNormalText(L["TITAN_BAG_MENU_TEXT"]) - ..":\t"..TitanUtils_GetNormalText(L["TITAN_BAG_FREE_SLOTS"])..":\n"; - end - - for bag = MIN_BAGS, MAX_BAGS do - local bagText, bagRichText, color; ---[[ -TitanDebug("T Bag: TT" -.." "..tostring(bag).."" -.." "..tostring(bag_data[bag].has_bag).."" -.." "..tostring(bag_data[bag].name).."" -.." "..tostring(bag_data[bag].maxi_slots).."" -.." "..tostring(bag_data[bag].used_slots).."" -.." "..tostring(bag_data[bag].free_slots).."" -) ---]] - if bag_data[bag] and bag_data[bag].has_bag then - if (TitanGetVar(TITAN_PLUGIN, "ShowUsedSlots")) then - bagText = format(L["TITAN_BAG_FORMAT"], bag_data[bag].used_slots, bag_data[bag].maxi_slots); - else - bagText = format(L["TITAN_BAG_FORMAT"], bag_data[bag].free_slots, bag_data[bag].maxi_slots); - end - - if bag_data[bag].style == "profession" - and not TitanGetVar(TITAN_PLUGIN, "CountProfBagSlots") - then - bagRichText = "|cffa0a0a0"..bagText.."|r" -- show as gray - elseif ( TitanGetVar(TITAN_PLUGIN, "ShowColoredText") ) then - if bag_data[bag].maxi_slots == 0 then - color = TitanUtils_GetThresholdColor(TITAN_BAG_THRESHOLD_TABLE, 1 ); - else - color = TitanUtils_GetThresholdColor(TITAN_BAG_THRESHOLD_TABLE, bag_data[bag].used_slots / bag_data[bag].maxi_slots); - end - bagRichText = TitanUtils_GetColoredText(bagText, color); - else - -- use without color - bagRichText = TitanUtils_GetHighlightText(bagText); - end - - local name_text = bag_data[bag].name - if bag_data[bag].style == "profession" - then - name_text = TitanUtils_GetColoredText(name_text, bag_data[bag].color) - else - -- use without color - end - returnstring = returnstring..name_text.."\t"..bagRichText.."\n"; - else - returnstring = returnstring..NONE.."\n"; - end - end - returnstring = returnstring.."\n"; - end - - if TitanGetVar(TITAN_PLUGIN, "ShowUsedSlots") then - local xofy = ""..tostring(bag_data.total_used) - .."/"..tostring(bag_data.total_slots).."\n" - returnstring = returnstring..TitanUtils_GetNormalText(L["TITAN_BAG_USED_SLOTS"]) - ..":\t"..xofy - else - local xofy = ""..tostring(bag_data.total_free) - .."/"..tostring(bag_data.total_slots).."\n" - returnstring = returnstring..TitanUtils_GetNormalText(L["TITAN_BAG_USED_SLOTS"]) - ..":\t"..xofy - end - - -- Add Hint - if TitanGetVar(TITAN_PLUGIN, "OpenBags") then - returnstring = returnstring..TitanUtils_GetGreenText(L["TITAN_BAG_TOOLTIP_HINTS"]) - else - -- nop - end - return returnstring -end - -local function OnLoad(self) - local notes = "" - .."Adds bag and free slot information to Titan Panel.\n" --- .."- xxx.\n" - self.registry = { - id = TITAN_PLUGIN, - category = "Information", - version = VERSION, - menuText = L["TITAN_BAG_MENU_TEXT"], - menuTextFunction = CreateMenu, - buttonTextFunction = GetButtonText, - tooltipTitle = L["TITAN_BAG_TOOLTIP"], - tooltipTextFunction = GetTooltipText, - icon = artwork_path.."TitanStarter", - iconWidth = 16, - notes = notes, - controlVariables = { - ShowIcon = true, - ShowLabelText = true, - ShowColoredText = true, - DisplayOnRightSide = true, - }, - savedVariables = { - ShowUsedSlots = 1, - ShowDetailedInfo = false, - CountProfBagSlots = false, - ShowIcon = 1, - ShowLabelText = 1, - ShowColoredText = 1, - DisplayOnRightSide = false, - OpenBags = false, - OpenBagsClassic = "new_install", - } - }; - if TITAN_ID == "Titan" then -- 10.* / Retail - -- for taint issue - self.registry.savedVariables.OpenBags = false - else - -- does not taint so default to open bags on click - self.registry.savedVariables.OpenBags = true - end - - self:RegisterEvent("PLAYER_ENTERING_WORLD"); - - if trace then - TitanDebug("TS OnLoad" - .." complete" - ) - end -end - -local function OnEvent(self, event, a1, a2, ...) - if trace then - TitanDebug("TS event" - .." "..tostring(event).."" - .." "..tostring(a1).."" - ) - end - - if event == "PLAYER_ENTERING_WORLD" then - if a1 == true and TITAN_ID == "Titan" then -- 10.* / Retail - -- initial login - - TitanPrint(L["TITAN_BAG_TAINT_TEXT"], "warning") - else -- either Classic version - local open = TitanGetVar(TITAN_PLUGIN, "OpenBagsClassic") - if open == "new_install" then -- - -- set to default behavior of opening bag on left click - TitanSetVar(TITAN_PLUGIN, "OpenBags", true) - TitanSetVar(TITAN_PLUGIN, "OpenBagsClassic", "processed") -- don't do again - else - -- already processed... - end - end - end - - if event == "BAG_UPDATE" then - -- update the plugin text - TitanPanelButton_UpdateButton(TITAN_PLUGIN); - end -end - -local function OnClick(self, button) - if trace then - TitanDebug("TS click" - .." "..tostring(button).."" - ) - end - - if (button == "LeftButton") then - ToggleBags(); - end -end - -local function OnShow(self) - if trace then - TitanDebug("TS OnShow" - .." register" - ) - end - -- Register for bag updates and update the plugin text - self:RegisterEvent("BAG_UPDATE") - TitanPanelButton_UpdateButton(TITAN_PLUGIN); -end - -local function OnHide(self) - if trace then - TitanDebug("TS OnShow" - .." unregister" - ) - end - self:UnregisterEvent("BAG_UPDATE") -end - --- ====== Create needed frames -local function Create_Frames() - if _G[TITAN_BUTTON] then - return -- if already created - end - - if trace then - TitanDebug("TS frames" - .." '"..tostring(TITAN_BUTTON).."'" - ) - end - - -- general container frame - local f = CreateFrame("Frame", nil, UIParent) --- f:Hide() - - -- Titan plugin button - --[[ - The plugin frame is created here. The typical plugin is a 'combo' which includes - - an icon (can be shown or hidden) - - label - value pair where the label can be turned off - There can be multiple label - value pairs; TitanPerformance uses this scheme. - - The frame is 'forever' as are most of WoW game frames. - --]] - local window = CreateFrame("Button", TITAN_BUTTON, f, "TitanPanelComboTemplate") - window:SetFrameStrata("FULLSCREEN") - -- Using SetScript to set "OnLoad" does not work - -- - -- This routine sets the guts of the plugin - the .registry - OnLoad(window); - - --[[ - Below are the frame 'events' that need to be processed. - A couple have Titan routines that ensure the plugin is properly on / off a Titan bar. - - The combined Titan changed design to register for events when the user places the plugin - on the bar (OnShow) and unregister events when the user hids the plugin (OnHide). - This reduces cycles the plugin uses when the user does not want the plugin. - - NOTE: If a Titan bar is hidden, the plugins on it will still run. - NOTE: Titan plugins are NOT child frames!! Meaning plugins are not automatically hidden when the - bar they visible on is hidden! - --]] - window:SetScript("OnShow", function(self) - OnShow(self) - -- This routine ensures the plugin is put where the user requested it. - -- Titan saves the bar the plugin was on. It does not save the relative order. - TitanPanelButton_OnShow(self); - end) - window:SetScript("OnHide", function(self) - OnHide(self) - -- We use the Blizzard frame hide to visually remove the frame - end) - window:SetScript("OnEvent", function(self, event, ...) - -- Handle any events the plugin is interested in - OnEvent(self, event, ...) - end) - window:SetScript("OnClick", function(self, button) - -- Typically this routine handles actions on left click - OnClick(self, button); - -- Typically this routine handles the menu creation on right click - TitanPanelButton_OnClick(self, button); - end) -end - -Create_Frames() -- do the work - --- ====== 3 routines required to be in the global namespace - --- ====== diff --git a/TitanExamplePlugin/TitanStarter.tga b/TitanExamplePlugin/TitanStarter.tga deleted file mode 100644 index 6a7ddda..0000000 Binary files a/TitanExamplePlugin/TitanStarter.tga and /dev/null differ