Thread Tools Display Modes
04-25-14, 12:50 PM   #1
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Module Namespace

This was brought to my attention by Phanx when she was helping me fix on of my modules for my addon:
Code:
-- You should fix your DB to use module namespaces properly:
So I have searched Google and the WoWInterface forums and could not come up with a explanation on how this should be done correctly.

So this is my attempt at trying to fix this.

This was the old db for modules (I think):
Lua Code:
  1. ModuleEnabledState = {
  2.             ["*"] = true
  3.         },

So I went thru and changed this to:
Lua Code:
  1. ModuleEnabledState = {
  2.             Actionbars = true,
  3.             Buffs = true,
  4.             Castbars = true,
  5.             Chat = true,
  6.             Cooldown = true,
  7.             Datapanel = true,
  8.             FlashGatherNodes = true,
  9.             Fonts = true,
  10.             Merchant = true,
  11.             Minimap = true,
  12.             Nameplates = true,
  13.             Powerbar = true,
  14.             Quest = true,
  15.             Quicky = true,
  16.             Skinning = true,
  17.             Tooltip = true,
  18.             Unitframes = true,
  19.             Velluminous = true,
  20.         },

Now the following I seen in Postal to enable all the modules so I figured it was the correct way to do it (this is in my main Core:OnInitialize):
Lua Code:
  1. for name, module in self:IterateModules() do
  2.         module:SetEnabledState(self.db.profile.ModuleEnabledState[name] or false)
  3.     end

then this is the OnProfileChanged
Lua Code:
  1. function Core:OnProfileChanged(event, database, newProfileKey)
  2.     for name, module in self:IterateModules() do
  3.         if self.db.profile.ModuleEnabledState[name] then
  4.             module:Enable()
  5.         else
  6.             module:Disable()
  7.         end
  8.     end
  9. end

Am I looking at this correctly or am I totally off base with my guess?

Thanks
Coke
  Reply With Quote
04-25-14, 05:41 PM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Those look fine -- though you don't need to explicitly list all the modules; "*" is just fine -- but they have nothing to do with DB namespacing. I'd suggest copying from Mapster, as it's well-written, and its small size means it's easier to find the relevant parts of code.

Code:
local Addon = LibStub("AceAddon-3.0"):NewAddon("MyTestAddon")

local db
local defaults = {
	profile = {
		scale = 1.25,
		alpha = 1,
		showTheThing = true,
		showTheOtherThing = false,
		modules = {
			["*"] = true,
		}
	}
}

function Addon:OnInitialize()
	self.db = LibStub("AceDB-3.0"):New("MyTestAddonDB", defaults, true) -- true is important!
	db = self.db.profile

	self.db.RegisterCallback(self, "OnProfileChanged", "Refresh")
	self.db.RegisterCallback(self, "OnProfileCopied", "Refresh")
	self.db.RegisterCallback(self, "OnProfileReset", "Refresh")

	local Dialog = LibStub("AceConfigDialog-3.0")

	local options = self:GetOptions()
	LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable("MyTestAddon", options)
	Dialog:AddToBlizOptions("MyTestAddon", nil, nil, "general")

	for k, v in self:IterateModules() do
		if type(v.GetOptions) == "function" then
			options.args[k] = v:GetOptions()
			Dialog:AddToBlizOptions("MyTestAddon", nil, "MyTestAddon", k)
		end
	end

	options.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
	options.args.profile.order = -1
	Dialog:AddToBlizOptions("MyTestAddon", nil, "MyTestAddon", "profile")	
end

function Addon:OnEnable()
	-- set up stuff here
end

function Addon:Refresh()
	db = self.db.profile -- update the upvalue to point to the new profile

	-- change stuff here

	for k, v in self:IterateModules() do
		local isEnabled, shouldEnable = v:IsEnabled(), self:GetModuleEnabled(k)
		if shouldEnable and not isEnabled then then
			self:EnableModule(k)
		elseif isEnabled and not shouldEnable then
			self:DisableModule(k)
		end
		if type(v.Refresh) == "function" then
			v:Refresh()
		end
	end
end

function Addon:GetModuleEnabled(moduleName)
	return db.modules[moduleName]
end

function Addon:SetModuleEnabled(moduleName, newState)
	local oldState = db.modules[moduleName]
	if oldState == newState then return end
	if newState then
		self:EnableModule(moduleName)
	else
		self:DisableModule(moduleName)
	end
end

local options
function Addon:GetOptions()
	options = options or {
		type = "group",
		name = "MyTestAddon",
		args = {
			general = {
				order = 1,
				type = "group",
				name = "General Settings",
				args = {
					-- addon-wide settings here
				}
			}
		}
	}
	return options
end
Code:
local Addon = LibStub("AceAddon-3.0"):GetAddon("MyTestAddon")
local Module = Addon:NewModule("MyTestModule")

local db
local defaults = {
	profile = {
		cats = true,
		size = 20,
		color = {
			r = 1,
			g = 1,
			b = 0,
		},
	}
}

function Module:OnInitialize()
	self.db = Addon.db:RegisterNamespace("MyTestModule", defaults)
	db = self.db.profile

	self:SetEnabledState(Addon:GetModuleEnabled("MyTestModule")
end

function Module:OnEnable()
	-- set up stuff here
end

-- Leave this out if the module doesn't have any settings:
function Module:Refresh()
	db = self.db.profile -- update the upvalue

	-- change stuff here
end

-- Leave this out if the module doesn't have any options:
local options
function Module:GetOptions()
	options = options or {
		type = "group",
		name = "MyTestModule",
		args = {
			-- module-specific settings here
			-- use tabs or inline for subgroups
		}
	}
	return options
end
This moves the default settings and options table for each module into its own file, so it's self-contained.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 04-25-14 at 05:52 PM.
  Reply With Quote
04-25-14, 06:57 PM   #3
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
Those look fine -- though you don't need to explicitly list all the modules; "*" is just fine -- but they have nothing to do with DB namespacing. I'd suggest copying from Mapster, as it's well-written, and its small size means it's easier to find the relevant parts of code.

Code:
local Addon = LibStub("AceAddon-3.0"):NewAddon("MyTestAddon")

local db
local defaults = {
	profile = {
		scale = 1.25,
		alpha = 1,
		showTheThing = true,
		showTheOtherThing = false,
		modules = {
			["*"] = true,
		}
	}
}

function Addon:OnInitialize()
	self.db = LibStub("AceDB-3.0"):New("MyTestAddonDB", defaults, true) -- true is important!
	db = self.db.profile

	self.db.RegisterCallback(self, "OnProfileChanged", "Refresh")
	self.db.RegisterCallback(self, "OnProfileCopied", "Refresh")
	self.db.RegisterCallback(self, "OnProfileReset", "Refresh")

	local Dialog = LibStub("AceConfigDialog-3.0")

	local options = self:GetOptions()
	LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable("MyTestAddon", options)
	Dialog:AddToBlizOptions("MyTestAddon", nil, nil, "general")

	for k, v in self:IterateModules() do
		if type(v.GetOptions) == "function" then
			options.args[k] = v:GetOptions()
			Dialog:AddToBlizOptions("MyTestAddon", nil, "MyTestAddon", k)
		end
	end

	options.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
	options.args.profile.order = -1
	Dialog:AddToBlizOptions("MyTestAddon", nil, "MyTestAddon", "profile")	
end

function Addon:OnEnable()
	-- set up stuff here
end

function Addon:Refresh()
	db = self.db.profile -- update the upvalue to point to the new profile

	-- change stuff here

	for k, v in self:IterateModules() do
		local isEnabled, shouldEnable = v:IsEnabled(), self:GetModuleEnabled(k)
		if shouldEnable and not isEnabled then then
			self:EnableModule(k)
		elseif isEnabled and not shouldEnable then
			self:DisableModule(k)
		end
		if type(v.Refresh) == "function" then
			v:Refresh()
		end
	end
end

function Addon:GetModuleEnabled(moduleName)
	return db.modules[moduleName]
end

function Addon:SetModuleEnabled(moduleName, newState)
	local oldState = db.modules[moduleName]
	if oldState == newState then return end
	if newState then
		self:EnableModule(moduleName)
	else
		self:DisableModule(moduleName)
	end
end

local options
function Addon:GetOptions()
	options = options or {
		type = "group",
		name = "MyTestAddon",
		args = {
			general = {
				order = 1,
				type = "group",
				name = "General Settings",
				args = {
					-- addon-wide settings here
				}
			}
		}
	}
	return options
end
Code:
local Addon = LibStub("AceAddon-3.0"):GetAddon("MyTestAddon")
local Module = Addon:NewModule("MyTestModule")

local db
local defaults = {
	profile = {
		cats = true,
		size = 20,
		color = {
			r = 1,
			g = 1,
			b = 0,
		},
	}
}

function Module:OnInitialize()
	self.db = Addon.db:RegisterNamespace("MyTestModule", defaults)
	db = self.db.profile

	self:SetEnabledState(Addon:GetModuleEnabled("MyTestModule")
end

function Module:OnEnable()
	-- set up stuff here
end

-- Leave this out if the module doesn't have any settings:
function Module:Refresh()
	db = self.db.profile -- update the upvalue

	-- change stuff here
end

-- Leave this out if the module doesn't have any options:
local options
function Module:GetOptions()
	options = options or {
		type = "group",
		name = "MyTestModule",
		args = {
			-- module-specific settings here
			-- use tabs or inline for subgroups
		}
	}
	return options
end
This moves the default settings and options table for each module into its own file, so it's self-contained.
So in general I should not have one large db but individual db's for each module?

Does that mean I should have individual options for each module?

I've seen on ElvUI that he has his options selt like:
Lua Code:
  1. E.Options.args.datatexts = {}

so mine would be
Lua Code:
  1. Core.Options.args.unitframes = {}

Or am I looking to far into this?
  Reply With Quote
04-25-14, 10:06 PM   #4
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Ok slowly but surely moving along with this.

Here is what I currently have done:

BasicUI.lua the main part of the addon.
Actionbars.lua for some reason the UnregisterEvent in this throws an error.
Buffs.lua this one works.
Unitframes.lua this one also is throwing and error except it is the RegisterEvent.

Actionbar.lua error:
Code:
5x BasicUI-5.4.7\Modules\Actionbars.lua:44: attempt to call method "UnregisterEvent" (a nil value)
BasicUI-5.4.7\Modules\Actionbars.lua:44: in function <BasicUI\Modules\Actionbars.lua:37>
(tail call): ?
<in C code>
<string>:"safecall Dispatcher[1]":9: in function <string>:"safecall Dispatcher[1]":5
(tail call): ?
BasicUI-5.4.7\Libs\AceAddon-3.0\AceAddon-3.0-11.lua:543: in function "EnableAddon"
BasicUI-5.4.7\Libs\AceAddon-3.0\AceAddon-3.0-11.lua:556: in function "EnableAddon"
BasicUI-5.4.7\Libs\AceAddon-3.0\AceAddon-3.0-11.lua:636: in function <BasicUI\Libs\AceAddon-3.0\AceAddon-3.0.lua:621>
<in C code>
FrameXML\UIParent.lua:306: in function "UIParentLoadAddOn"
FrameXML\UIParent.lua:329: in function "CombatLog_LoadUI"
FrameXML\UIParent.lua:742: in function <FrameXML\UIParent.lua:705>

Locals:
Unitframes.lua error:
Code:
17x BasicUI-5.4.7\Modules\Unitframes.lua:221: attempt to call method "RegisterEvent" (a nil value)
BasicUI-5.4.7\Modules\Unitframes.lua:221: in function "ApplySettings"
BasicUI-5.4.7\Modules\Unitframes.lua:119: in function <BasicUI\Modules\Unitframes.lua:91>
(tail call): ?
<in C code>
<string>:"safecall Dispatcher[1]":9: in function <string>:"safecall Dispatcher[1]":5
(tail call): ?
BasicUI-5.4.7\Libs\AceAddon-3.0\AceAddon-3.0-11.lua:543: in function "EnableAddon"
BasicUI-5.4.7\Libs\AceAddon-3.0\AceAddon-3.0-11.lua:556: in function "EnableAddon"
BasicUI-5.4.7\Libs\AceAddon-3.0\AceAddon-3.0-11.lua:636: in function <BasicUI\Libs\AceAddon-3.0\AceAddon-3.0.lua:621>
<in C code>
FrameXML\UIParent.lua:306: in function "UIParentLoadAddOn"
FrameXML\UIParent.lua:329: in function "CombatLog_LoadUI"
FrameXML\UIParent.lua:742: in function <FrameXML\UIParent.lua:705>

Locals:
nil
Thanks
Coke
  Reply With Quote
04-25-14, 10:59 PM   #5
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Module is a table, not a WoW API Frame object. Lua tables have no notion of RegisterEvent or UnregisterEvent.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
04-26-14, 08:05 AM   #6
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
@Torhal:
AceAddon-3.0 module tables do have RegisterEvent and UnregisterEvent methods if you include AceEvent-3.0 as a mixin.

@cokedrivers:
You forgot to include AceEvent-3.0 when you declared your modules:
Code:
local Module = Addon:NewModule("Actionbars", "AceEvent-3.0")
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
04-26-14, 08:11 AM   #7
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by cokedrivers View Post
So in general I should not have one large db but individual db's for each module?
No, you still have one db (one saved variable) but each module gets its own self-managed section, rather than you manually splitting it up. This also makes it easier to keep each module self-contained -- eg. the file for each module contains the module code, the module's default db settings, and the module's options table, instead of your old method where the module file only contained the module code, and you were mixing all the module defaults and options together in other files.

Originally Posted by cokedrivers View Post
Does that mean I should have individual options for each module?
Yes and no. Look at the example in my last post. Each module's options are defined in its own file, but they all end up in a single AceConfig options table, and are all accessed as sub-panels of a single options panel in the Interface Options window.

Again, the primary benefit here is that your code is better organized and easier to maintain -- if you want to add a new setting to a module, you can add the default value, the option itself, and the code to apply it all in one file, instead of having to add code to the module file, add the default value to the addon core file, and add the option to yet another file.

I've seen on ElvUI that he has his options selt like:
Lua Code:
  1. E.Options.args.datatexts = {}

so mine would be
Lua Code:
  1. Core.Options.args.unitframes = {}
No. Look at the example I gave you. It's all taken care of. Your core does not need to hardcode anything for your module options, and your modules don't need to have any awareness of the core options table. It's all dynamic and automatic.

Also, while I haven't spent any time looking at it in great detail, from what I have seen, I don't really think you should be leaning too heavily on ElvUI as an example of good coding practices. Any addon that begins every file with calls to unpack and select should probably be nuked from orbit.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 04-26-14 at 08:15 AM.
  Reply With Quote
04-26-14, 08:49 AM   #8
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
@Torhal:
AceAddon-3.0 module tables do have RegisterEvent and UnregisterEvent methods if you include AceEvent-3.0 as a mixin.

@cokedrivers:
You forgot to include AceEvent-3.0 when you declared your modules:
Code:
local Module = Addon:NewModule("Actionbars", "AceEvent-3.0")
Originally Posted by Phanx View Post
No, you still have one db (one saved variable) but each module gets its own self-managed section, rather than you manually splitting it up. This also makes it easier to keep each module self-contained -- eg. the file for each module contains the module code, the module's default db settings, and the module's options table, instead of your old method where the module file only contained the module code, and you were mixing all the module defaults and options together in other files.



Yes and no. Look at the example in my last post. Each module's options are defined in its own file, but they all end up in a single AceConfig options table, and are all accessed as sub-panels of a single options panel in the Interface Options window.

Again, the primary benefit here is that your code is better organized and easier to maintain -- if you want to add a new setting to a module, you can add the default value, the option itself, and the code to apply it all in one file, instead of having to add code to the module file, add the default value to the addon core file, and add the option to yet another file.



No. Look at the example I gave you. It's all taken care of. Your core does not need to hardcode anything for your module options, and your modules don't need to have any awareness of the core options table. It's all dynamic and automatic.

Also, while I haven't spent any time looking at it in great detail, from what I have seen, I don't really think you should be leaning too heavily on ElvUI as an example of good coding practices. Any addon that begins every file with calls to unpack and select should probably be nuked from orbit.
Thank you for the incite.

Now all I have to do is figure out a sort for the new options layout. (You spoiled me with your help with the other options layout).

Coke
  Reply With Quote
04-27-14, 03:16 AM   #9
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by cokedrivers View Post
Now all I have to do is figure out a sort for the new options layout.
All you should need to do is copy the options sub-group from your old "all in one" options table into the module, and update the db paths.

Here's an example for the actionbar module:

http://pastebin.com/8rGBw4Yi
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
04-27-14, 08:37 AM   #10
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
All you should need to do is copy the options sub-group from your old "all in one" options table into the module, and update the db paths.

Here's an example for the actionbar module:

http://pastebin.com/8rGBw4Yi
Thank You for this, I guess I need to learn the terms of WoW. I ment the sorting of the Option in the Blizzard/Interface. You did this code for me:
Code:
function BasicUI:SetUpOptions()
	local options = GetOptions()

	-- @PHANX: add this to your options table instead of registering it separately:
	options.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)

	LibStub("AceConfig-3.0"):RegisterOptionsTable("BasicUI", options)

	-- @PHANX: You could write out each subkey but let's be lazy:
	local panels = {}
	for k in pairs(options.args) do -- this assumes all immediate children are groups
		if k ~= "welcome" and k ~= "profile" then -- skip these so we can add them manually as the first and last panels
			tinsert(panels, k)
		end
	end
	sort(panels) -- alphabetize so it looks nice and is easy to navigate

	local Dialog = LibStub("AceConfigDialog-3.0")

	-- Use the "welcome" panel as the main one:
	self.optionsFrame = Dialog:AddToBlizOptions("BasicUI", "BasicUI", nil, "welcome")

	-- Add all the rest as sub-panels:
	for i = 1, #panels do
		local k = panels[i]
		Dialog:AddToBlizOptions("BasicUI", options.args[k].name, "BasicUI", k)
	end

	-- Add the profile panel last:
	Dialog:AddToBlizOptions("BasicUI", options.args.profile.name, "BasicUI", "profile")

end
With the new way of all the options being in wach module I tried the "sort" as you did above and it didn't work. Here is the new way:
Code:
function Addon:OnInitialize()
	self.db = LibStub("AceDB-3.0"):New("BasicDB", defaults, true) -- true is important!
	db = self.db.profile

	self.db.RegisterCallback(self, "OnProfileChanged", "Refresh")
	self.db.RegisterCallback(self, "OnProfileCopied", "Refresh")
	self.db.RegisterCallback(self, "OnProfileReset", "Refresh")

	local Dialog = LibStub("AceConfigDialog-3.0")

	local options = self:GetOptions()
	LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable("BasicUI", options)
	Dialog:AddToBlizOptions("BasicUI", nil, nil, "media")

	for k, v in self:IterateModules() do
		if type(v.GetOptions) == "function" then
			options.args[k] = v:GetOptions()
			Dialog:AddToBlizOptions("BasicUI", options.args[k].name, "BasicUI", k)
		end
	end

	options.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
	options.args.profile.order = -1
	Dialog:AddToBlizOptions("BasicUI", options.args.profile.name, "BasicUI", "profile")	
end
Coke

EDIT: Added aPicture to show you what I mean.
Attached Thumbnails
Click image for larger version

Name:	Options Non-Sorted.png
Views:	434
Size:	677.8 KB
ID:	8068  

Last edited by cokedrivers : 04-27-14 at 06:37 PM.
  Reply With Quote
04-27-14, 04:54 PM   #11
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by Phanx View Post
@Torhal:
AceAddon-3.0 module tables do have RegisterEvent and UnregisterEvent methods if you include AceEvent-3.0 as a mixin.

@cokedrivers:
You forgot to include AceEvent-3.0 when you declared your modules:
Code:
local Module = Addon:NewModule("Actionbars", "AceEvent-3.0")
Ah, hadn't thought of that scenario.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
04-27-14, 06:59 PM   #12
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Ok I'm so excited after a long day of coding I finally have my whole BasicUI converted over to the way Phanx suggested. It's not perfect but it works and I think the code might be a little bit more understandable for those programmers out there.

So here are pastebins of the files:

BasicUI.lua the main core of the addon.
Actionbars.lua the Actionbars module.
Buffs.lua the Buffs module.
Castbars.lua the Castbar module.
Chat.lue the Chat module.
Datapanel.lua the Datapanel module.
Minimap.lua the Minimap module.
Miscellaneous.lua the Miscellaneous module. (with this I combined 11 files into 1 file)
Nameplates.lua the Nameplates module.
Powerbar.lua the Powerbar module.
Tooltip.lua the Tooltip module.
Unitframes.lua the Unitframes module.


Darn pastebin I had to create an account to post all these LOL, no biggie.

Well there they are in all there glory... well I feel proud but its all because of Phanx that I feel this way, they guided me along and I'm sure that not all the files are correct or all are the most efficient but they all work for now.

Thanks Again everyone for your help.

Coke
  Reply With Quote
04-28-14, 04:23 AM   #13
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
This should fix the sorting:
Code:
	local panels = {}
	for k, v in self:IterateModules() do
		if type(v.GetOptions) == "function" then
			options.args[k] = v:GetOptions()
			tinsert(panels, k)
		end
	end
	sort(panels)
	for i = 1, #panels do
		local k = panels[i]
		Dialog:AddToBlizOptions("BasicUI", options.args[k].name, "BasicUI", k)
	end
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
04-28-14, 09:38 AM   #14
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
This should fix the sorting:
Code:
	local panels = {}
	for k, v in self:IterateModules() do
		if type(v.GetOptions) == "function" then
			options.args[k] = v:GetOptions()
			tinsert(panels, k)
		end
	end
	sort(panels)
	for i = 1, #panels do
		local k = panels[i]
		Dialog:AddToBlizOptions("BasicUI", options.args[k].name, "BasicUI", k)
	end
Worked like a charm (see image below)... Thank You

I also was able to add back the SharedMedia support (see image below).

Now beings I have been told to try to make everything more efficient would the following be an efficient way to have a global table for media in my UI?
Code:
ADDON_NAME.media = {}

function ADDON_NAME:UpdateMedia()
	
	-- Fonts
	self.media.fontNormal 		= LSM:Fetch("font", db.general.fontNormal)
	self.media.fontBold 		= LSM:Fetch("font", db.general.fontBold)
	self.media.fontItalic 		= LSM:Fetch("font", db.general.fontItalic)
	self.media.fontBoldItalic	= LSM:Fetch("font", db.general.fontBoldItalic)
	self.media.fontNumber 		= LSM:Fetch("font", db.general.fontNumber)
	
	-- Background
	self.media.background 		= LSM:Fetch("background", db.general.background)
	
	-- Borders
	self.media.border 			= LSM:Fetch("border", db.general.border)
	self.media.panelborder 		= LSM:Fetch("border", db.general.panelborder)
	
	-- Statusbar
	self.media.statusbar 		= LSM:Fetch("statusbar", db.general.statusbar)
	
	-- Sound
	self.media.sound			= LSM:Fetch("sound", db.general.sound)
end
The media setting are now in my "general" db.

Then in the ADDON_NAME:OnInitialize() function I call self:UpdateMedia().

Is this the correct way to do it or is there a better way.

Also is there a way to adjust the timer size and format for buffs? the default has the space and when I have 2 buffs with timers next to each other they overlap.

Thanks Again
Coke
Attached Thumbnails
Click image for larger version

Name:	NewOptions.png
Views:	366
Size:	600.4 KB
ID:	8069  
  Reply With Quote
04-28-14, 02:28 PM   #15
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
The media thing looks fine, except that ADDON_NAME is (I assume) a string value, instead of your addon table, so you should probably change that... or change the variable name if it actually points to an object instead of a name string.

Code:
local ADDON_NAME, private_table = ...
-- ADDON_NAME is a string containing the name of your addon's folder and TOC file, eg. "BasicUI"
-- private_table is a table that exists only for the files in your addon
-- You can name these FLYING_BANANAS and cat_potato if you want, it doesn't matter.
Actually looking at your code, I see you're using ADDON_NAME to point to your core addon object... don't do that. Anyone looking at your code (or any code) is going to assume that a variable with "name" in its name contains the name of something, not an object, especially when the similarly named MODULE_NAME [i]does[i] contain a name. Also, at least in Lua programming, variable names in all-caps are generally reserved for constants (variables with simple values, like numbers or strings, that never change). I'd suggest sticking with "Addon" or "Core" or "BasicUI" for the core addon object, and "Module" or "Actionbars" for the module object.

Also, don't put that local L = setmetatable... block in every file. Put it in whichever file loads first, and add it to the addon object, eg.

Code:
local BasicUI = LibStub("AceAddon-3.0"):NewAddon("BasicUI")
BasicUI.L = L
... then refer to it in the other files:

Code:
local BasicUI = LibStub("AceAddon-3.0"):GetAddon("BasicUI")
local L = BasicUI.L
That way, when you actually add translations in the future, you can just plug them in system-wide, rather than each file having its own self-contained localization table.

--------------------------------------------------

Registering fonts with LSM as "BasicUI Normal" and "BasicUI Bold" is probably not the best practice... use the actual font name.

You should probably set width = "double" on those media dropdowns, especially the backdrop and border ones, so you can actually see the names.

--------------------------------------------------

As for the buff text, there's surely a way to adjust it... which file is doing that? All I see in the Buffs module file is a scale change.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
04-28-14, 02:33 PM   #16
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
As for the buff text, there's surely a way to adjust it... which file is doing that? All I see in the Buffs module file is a scale change.
I think its blizzard default. As you said I haven't changed anything except the font size and style. I would just like to get rid of the space ( Default = 60 m vs What i want = 60m ).
  Reply With Quote
04-28-14, 04:06 PM   #17
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Code:
DAY_ONELETTER_ABBR = gsub(DAY_ONELETTER_ABBR, "%s", "")
HOUR_ONELETTER_ABBR = gsub(HOUR_ONELETTER_ABBR, "%s", "")
MINUTE_ONELETTER_ABBR = gsub(MINUTE_ONELETTER_ABBR, "%s", "")
SECOND_ONELETTER_ABBR = gsub(SECOND_ONELETTER_ABBR, "%s", "")
However, note that this will affect all parts of the UI that also use these global strings, and your text will still overlap if you combine big enough text with small enough icons.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
04-29-14, 09:00 AM   #18
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
Code:
DAY_ONELETTER_ABBR = gsub(DAY_ONELETTER_ABBR, "%s", "")
HOUR_ONELETTER_ABBR = gsub(HOUR_ONELETTER_ABBR, "%s", "")
MINUTE_ONELETTER_ABBR = gsub(MINUTE_ONELETTER_ABBR, "%s", "")
SECOND_ONELETTER_ABBR = gsub(SECOND_ONELETTER_ABBR, "%s", "")
However, note that this will affect all parts of the UI that also use these global strings, and your text will still overlap if you combine big enough text with small enough icons.
Thank you this did what I wanted.

Kinda off topic but not should I move my post in the other section to here beings we are talking about libs and code?

Coke
  Reply With Quote
12-06-16, 11:06 PM   #19
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
Really late to the party, and sorry for thread necro, but Google and all that...

If you know you are going to need one or more embeddable libraries in each module, you can do the following. Just remember it only works on libraries that have a mixin, or are embed-capable, so it won't work on LibDataBroker-1.1 or LibWindow-1.1, as examples.
Lua Code:
  1. local MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceConsole-3.0", "AceEvent-3.0")
  2.  
  3. function MyAddOn:OnInitialize()
  4.     -- do all the DB stuff as normal
  5.  
  6.     -- embed AceConsole-3.0 and AceEvent-3.0
  7.     self:SetDefaultModuleLibraries("AceConsole-3.0", "AceEvent-3.0")
  8.  
  9.     -- remember, the list of libs could be any embeddable libs, not just Ace3 stuff
  10.     -- and you didn't care about those, don't list them, and list something else, like...
  11.     self:SetDefaultModuleLibraries("LibUtilities-1.0")
  12.  
  13.     -- of course, do NOT code exactly like the above example
  14.     -- the second command will overwrite the first
  15.     -- so list all your libs on one line, in one command
  16. end

Okay, question time. If I wanted a load on demand options AddOn that plugged into AceConfig-3.0 for the "core" AddOn, how would that be done?

Also, I see the magic ["*"] thing, which I more or less understand. Why not use ["**"] instead?

Then, in the AceConfig-Options docs, besides the ubiquitous "args", there is also a "plugins" type. Should that not be used instead of "modules"?
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Module Namespace


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off