--[[ Example This example is intended to introduce Titan plugin essentials by using a Titan addon plugin loosely based on Titan Bag. Titan is REQUIRED for this addon to run without throwing errors. NOTE: The terms addon and plugin are essentially the same. Here plugin is used when the addon is displayed by Titan. NOTE: This example uses AceLocale. Titan locale strings were left in the code so it will run as is. Please use your own strings - localized or not. NOTE: Titan includes several libraries which have not changed in quite a while. You are free to use these. If you require additional libraries, please include them in your addon. NOTE: Timers are outside the scope of this example. See other Titan built-in plugins for timers (AceTimer). --]] --[[ 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 TOC file 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 .tocExample files - one .lua file - your great idea - one .tga file - the icon used by the plugin There are sites (wowhead or wow wiki as examples) that have deeper explainations on addon development. Please use these sites for more 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 as the folder name. The name after that (postfix) has meaning to WoW addon loader. 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 higher or lower, WoW will complain that you are running 'out of date' addons. === .lua This is the code for the plugin. === .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. === LDB Titan includes the LDB lib. It is not needed in the Titan plugin folder. === icons and artwork 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. --]] --[[ File Structure The plugin starts with local constants used throughout. Then local variables; then functions. NOTE: Titan locale strings were left in the code so it will run as is. Please use your own strings - localized or not. The design uses local functions. 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 <block comment start> API can be used by a plugin. Titan API routines will be maintained and the functionality expected to remain stable. Any parameter or functionality changes to API will be 'broadcast' on delivery sites and our sites (Discord, our web page). Of course feel free to reach out on our Discord site with any questions or suggestions! --]] --[[ Editting As noted above, remove the 'Example' from the TOC file name that cooresponds to the version of WoW you are developing for. It is not required to change all TOC files at the same time. Then start or reload WoW. This example may seem daunting at first. We decided to leave Bag as is (as of Jan 2024) to give plenty of coding examples. Routines: GetBagData will be replaced by your code. It uses local function IsProfessionBagID. ToggleBags is called from OnClick. This will be replaced by your code that handles mouse clicks. CreateMenu will need to be changed to implement your right click menu, if any. The other routines will be modified to implement 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 after Titan is loaded. 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 stated in TITAN_BUTTON. Then calls local OnLoad. Then sets the frame scripts for the addon. See Frame Scripts NOTE: The frame is created using a Titan template. A Titan 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 saved variable data is ready / loaded 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 frame OnEvent. When processing PLAYER_ENTERING_WORLD, only register for events and access local data. Do not assume saved variables from registry or server data is ready. Titan also receives the PLAYER_ENTERING_WORLD event. It is best to assume there is NO guarantee this plugin receives the event before or after Titan! Titan then processes its own data, creates Titan bars, registers Titan plugins and LDB addons, and syncs plugin saved variables. Titan will process and set any saved variables specified in the .registry of this plugin! Next: ==== Still waiting for WoW Titan shows the user requested bars with the user requested plugins. OnShow is called by Titan when placing this plugin on a bar or the user requests the plugin to be shown. NOTE: It is best to assume any saved variables in .registry are NOT ready until OnShow! OnShow now does all processing to set up this plugin properly. Once set up, this addon needs to call TitanPanelButton_UpdateButton to update the plugin text. The plugin is now ready for the user. Next: ==== Ready to play WoW, Yeah! The plugin is 'idle' until : - Titan calls TitanPanelButton_UpdateButton(TITAN_PLUGIN) to (re)display this plugin - User selects show this plugin (Config or menu) - User changes a plugin option using the plugin menu - User clicks on this plugin - OnClick - Any registered event is received - OnEvent - User mouses over plugin - OnEnter - User mouse leaves plugin - OnLeave - A timer or callback calls a plugin routine Next: ==== The above step continues until: - User hides the plugin - The user logs out the character or exits WoW or reloads UI Then OnHide to be eventually called. On logout or exit the saved variables are saved to the local system. NOTE: Any saved variables specified in .registry - savedVariables - are saved by WoW on logout or exit. No additional actions are required. ==== Using OnShow to set up this addon is good practice : It should: - Register any events the plugin will react to - Process any saved variable data now - Create any timers - Set the initial plugin - icon, label, text This ensures: - All saved variable data is set - Less processing if the user never selects the plugin or clicks Hide ==== Using OnHide to clean up is good practice : It should: - Unregister any events the pluginhad registered - Remove any timers - Cleanup any plugin specifc data or objects This ensures: - Less processing when the user clicks Hide ==== TitanPanelButton_UpdateButton(TITAN_PLUGIN) should be called by this plugin whenever the plugin text could change; usually when events are received or on user action. NOTE: This routine expects label - value pairs (up to 4). Titan uses 'show label' to control showing the label or not. Titan Performance uses and shows multiple label - value pairs based on user selection. ==== OnEnter and OnLeave NOTE: The Titan template handles OnEnter and OnLeave to show or hide the tooltip. Titan calls the specified .registry routine to show the tooltip - tooltipTextFunction. ==== Additional saved variables specific to this addon must be handled by this addon and are outside the scope of this example. See Titan Gold for an example of a Titan plugin that has its own saved variables. --]] --[[ Frame Scripts The frame scripts are how WoW and Titan interact with this addon. OnShow script : This is triggered when this plugin (frame) is shown - init; reload; user selected show (Titan menu or config). OnShow handles any plugin specific code. It is suggested events this plugin are interested in be registered here to minimize processing. Then call TitanPanelButton_UpdateButton(TITAN_PLUGIN) to get the text updated. Titan will use the routine specified in the .registry - buttonTextFunction TitanPanelButton_OnShow ensures the plugin is placed on the selected bar - from user or saved variables. Technically : - Titan calls the now registered plugin frame - TITAN_BUTTON:Show() - Which first calls the frame script :OnShow() as set by the Titan template - Eventually calling OnShow() in this addon as set in Create_Frames OnClick script : Right click is handled by the Titan template chosen and is assumed to be a create menu request.should be procssed by this plugin. Any other mouse click combination should be handled by the plugin code. Right click: TitanPanelButton_OnClick is called to handle right click which invokes the plugin menu. The routine can be known in one of two ways: 1) Specified in the registry - preferred - menuTextFunction 2) Create the expected routine - TitanPanelRightClickMenu_Prepare<id>Menu Titan will use the registry over the created routine. It will not use both. OnEnter script : OnEnter is handled by the Titan template to show the tool tip. It calls the routine specified in registry - tooltipTextFunction . OnLeave script : OnLeave is handled by the Titan template to hide the tool tip. OnHide script : 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. OnEvent script : All events registered for should be handled here. --]] --[[ Events Titan Bag uses PLAYER_ENTERING_WORLD to handle a difference between retail and Classic versions when opening bags via the addon. BAG_UPDATE just updates the text (count) whenever this event is fired. NOTE: The event also fires when moving items within the bag... --]] --[[ .registry attributes This is the GUTS of a Titan plugin. The .registry on the frame contains all the information to register the plugin for display. Every plugin registry with an id should appear in Titan > Configuration > Attempts. Information about the plugin is shown there along with pass / fail. If the plugin failed to register, the error is shown there. NOTE: Titan looks for 3 routines. See .registry Routines. Attributes: .id : Required : must be unique across plugins. If there are duplicates, the first one 'wins'. .category : The general grouping this plugin is in. The complete category list is in TITAN_PANEL_BUTTONS_PLUGIN_CATEGORY (TitanGlobal.lua) "Built-ins" is reserved for plugins that Titan releases. .version : plugin version shown in menus and config. .menuText : Used by as the title for the right click menu. .menuTextFunction : See .registry Routines. .buttonTextFunction : See .registry Routines. .tooltipTitle : Used as the title for the tool tip .tooltipTextFunction : See .registry Routines. .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. --]] --[[ .registry Routines Titan looks for 3 routines: - Routine that updates the plugin text : .buttonTextFunction - Routine that creates the tool tip : .tooltipTextFunction - Routine that creates the options (right click) : .menuTextFunction OR "TitanPanelRightClickMenu_Prepare"<id>"Menu" .menuTextFunction : This is the routine called by Titan on right click. This is the newer, prefered method which makes the options menu routine explicit. 2024 Feb The older method is still supported! Titan builds the expected routine name as "TitanPanelRightClickMenu_Prepare"<id>"Menu". In this example TitanPanelRightClickMenu_PrepareStarterMenu .buttonTextFunction : This is called whenever the button is to be updated. This is called from within the plugin and from Titan by calling TitanPanelButton_UpdateButton(TITAN_PLUGIN) . Titan will usually show "<?>" if the routine dies. If you need to see the error, search for this attribute in Titan folder and uncomment the print of the error message. This may generate a LOT of messages! .tooltipTextFunction : This is called when OnEnter of the plugin frame is triggered. The Titan templates set the OnEnter script for the plugin frame. On a tooltip error, Titan will usually show part of the error in the tool tip. If you need to see the error, search for this attribute in Titan folder and uncomment the print of the error message. NOTE: The specified routine is called securely (pcall) to protect Titan. NOTE: These routines are expected to have NO parameters. Handling parameters was not implemented in any version of Titan. NOTE: Routine can be specified (changed as of 2024 Feb) - - As a string, it MUST be in the global namespace. Strings were the only way for a long time. - As a function, it may be in the global namespace but could be local. This example usees uses a local routine. --]]