You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

825 lines
25 KiB

--[=[ This addon provides options for all modules.
Options are preferrably defined as "BetterOptions" tables, which functionally resemble AceOptionsTables but are much more concise.
The point of this abstraction layer is that I (Xuerian) wanted to use AceDB/AceConfig to present a more standard configuration dialog to users. I am, however, not satisfied with the conventions and limitations of it, so this is a attempt to provide both a more concise format (BetterOptions), and a more featureful intermediate options format (Finalize(...)) to support it.
Methods:
Finalize(module_data, option_table)
- Compiles a AceOptionTable with extra features to a validating AceOptionTable by migrating extra data/metadata into option_metadata[current_option_table] so AceConfig doesn't brit a shick.
> module_data expects a table where t.name == "ModuleName" and t.addon = AddonTable
> option_table expects a "BetterOptions" option table
BetterOptions.Compile(better_option_table)
- Compiles BetterOptions tables to intermediate option tables which must be provided
to either a supporting option system or Finalize() for use as a validating AceOptionsTable
> better_option_table expects a "BetterOptions" option table
Start by defining your module options here in addon:OnEnable below other module options with the call XLootOptions:RegisterOptions("ModuleName", table), inside a if XLoot:GetModule(ModuleName, true) block.
XLootOptions:RegisterOptions(module_data, better_option_table)
- Registers a BetterOptions table with XLootOptions
> module_data and better_option_table follow BetterOptions.Compile and Finalize()
XLootOptions:RegisterAceOptionTable("ModuleName", ace_option_table)
- Registers a "normal" ace option table with no additional steps.
- Must provide get and set methods at least in the root group(s), as default get and set rely on Finalize()
Features/Finalize:
- Fill missing localization from XLootOptions.L[module_data.name][key|key_desc]
- Generate .values from {{ "key", "value" }, ...} .item tables and set them appropriately
- Get/Set from db key/subkey instead of key via .subtable[, .subkey]
- Propagate .defaults to child nodes
- Default type "toggle"
- "alpha" and "scale" types with automatic localization
- .requires = key and .requires_inverse = key
Features/BetterOptions:
- Nested tables with implied ordering and table values:
-- Basic structure: { "key", "type"[, arg1[, ...]] [, key = value[, ...]] }
-- Examples:
-- { "key", "toggle" }
-- { "key", option = "blah" } -> { "key", "toggle", option = "blah" }
-- { "key", "group", inline } -> key = { type = "group", inline = true }
-- { "key", "execute", func } -> key = { type = "execute", func = func }
-- { "key", "select", items }
-- { "key", "color", hasAlpha (defaults to true) }
-- { "key", "range", min, max, step, softMin, softMax, bigStep }
-- Automatic types:
-- Entry is just a "key": "toggle"
-- "key"
-- t[2] is unset: "toggle"
-- { "key" }
-- t[2] is a table: "select"
-- { "key", {k, v} }
Please note that inline and non-inline groups do not mix well for AceConfigDialog. -]=]
-- Create module
local addon, L = XLoot:NewModule("Options")
addon.modules = {}
-- Global
_G.XLootOptions = addon
-- Locals
local print = print
local function trigger(target, method, ...)
local func = target[method]
if type(func) == 'function' then
func(target, ...)
end
end
local function sizeof(t)
local i = 0
for k,v in pairs(t) do
i=i+1
end
return i
end
-- Provide throttled updates
local update_throttle, elapsed = CreateFrame("Frame"), 0
update_throttle:Hide()
update_throttle:SetScript("OnUpdate", function(self, delta)
if elapsed > .1 then
XLoot:ApplyOptions(true)
elapsed = 0
self:Hide()
else
elapsed = elapsed + delta
end
end)
-------------------------------------------------------------------------------
-- Module init
function addon:OnEnable() -- Construct addon option tables here
local option_metadata = {} -- Stores metadata for option entries outside of library-specific compiled option structure
addon.option_metadata = option_metadata -- Until resulting AceOptionsTable can have .values upated, this is the only way to store a new .items table
-------------------------------------------------------------------------------
-- General config methods
-- Find module options and requested key from AceConfigDialog info table
-- returns:
-- db -- Current settings table for option (May be a subtable)
-- k -- Current settings key for option
-- meta -- Config metatable for option
-- full_db -- Full settings table for module
local function path(info)
local meta = option_metadata[info.option]
local db = meta.module_data.addon.db.profile
return meta.subtable and db[meta.subtable] or db, meta.subkey or info[#info], meta, db
end
-- Generic option getter
local function get(info)
local db, k, meta = path(info)
if info.option.type == "color" then
return unpack(db[k])
elseif info.option.type == "select" and meta.items then
for i,v in ipairs(meta.items) do
if db[k] == v[1] then
return i
end
end
else
return db[k]
end
end
-- Generic option setter
local function set(info, v, v2, v3, v4, ...)
update_throttle:Show()
local db, k, meta = path(info)
if info.option.type == "color" then
db[k][1] = v
db[k][2] = v2
db[k][3] = v3
db[k][4] = v4
elseif info.option.type == "select" and meta.items then
db[k] = meta.items[v][1]
else
db[k] = v
end
if meta.module_data.OnChanged then
meta.module_data.OnChanged(k, v, v2, v3, v4, ...)
end
if meta.must_reload_ui then
print((L.message_reloadui_warning):format(meta.module_data.name, info.option.name))
end
end
-- Anchor toggles
local function set_anchor(...)
set(...)
local db, k, meta = path(...)
trigger(meta.module_data.addon, "UpdateAnchors")
end
-- Select value generator
local function values_from_items(info)
local db, k, meta = path(info)
local values = meta.values
wipe(values)
for i,v in ipairs(meta.items) do
values[i] = v[2]
end
return values
end
-- Dependencies
-- TODO: Recursive dependencies
local function requires(info)
local db, k, meta, full_db = path(info)
return ((meta.requires and (not full_db[meta.requires]) or false)
or (meta.requires_inverse and full_db[meta.requires_inverse] or false))
end
-------------------------------------------------------------------------------
-- Streamlined options tables
local BetterOptions = {}
local table_remove = table.remove
function BetterOptions.Compile(set)
for i,v in ipairs(set) do
local t, key = BetterOptions.any_type(v)
t.order = i
set[key] = t
set[i] = nil
end
return set
end
local BetterOptionsTypes = {}
BetterOptions.types = BetterOptionsTypes
function BetterOptions.any_type(t)
-- Simple
if type(t) == 'string' then
t = { t }
end
-- Shift required elements
local key = table.remove(t, 1)
t.type = table.remove(t, 1)
-- Infer toggle by default
if not t.type then
t.type = "toggle"
-- Infer select from table
elseif type(t.type) == "table" then
t.items, t.type = t.type, "select"
-- Other positional arguments may be present
table.insert(t, 1, "select")
end
-- Handle specific option types
if BetterOptionsTypes[t.type] then
BetterOptionsTypes[t.type](t)
end
-- Cleanup
for i,v in ipairs(t) do
t[i] = nil
end
return t, key
end
-- Many options are short enough that t[n] and t[n+1] can comfortably represent t.subtable and t.subkey
function BetterOptions.infer_db_path(t, offset)
offset = offset or 0
t.subtable = t.subtable or t[1+offset]
t.subkey = t.subkey or t[2+offset]
end
function BetterOptionsTypes.group(t)
t.args = t.args or t[1]
if t.inline == nil then
t.inline = (t[2] == nil and true or t[2])
end
if t.args then
BetterOptions.Compile(t.args)
end
end
function BetterOptionsTypes.toggle(t)
BetterOptions.infer_db_path(t)
end
function BetterOptionsTypes.select(t)
t.items = t.items or t[1]
BetterOptions.infer_db_path(t, 1)
end
function BetterOptionsTypes.alpha(t)
t.min = 0.0
t.max = 1.0
t.step = 0.1
BetterOptions.infer_db_path(t)
end
function BetterOptionsTypes.scale(t)
t.min = 0.1
t.max = 2.0
t.step = 0.1
BetterOptions.infer_db_path(t)
end
function BetterOptionsTypes.color(t)
if t.hasAlpha == nil and t[1] ~= nil then
t.hasAlpha = t[1]
else
t.hasAlpha = true
end
end
function BetterOptionsTypes.range(t)
t.min = t.min or t[1]
t.max = t.max or t[2]
t.step = t.step or t[3]
t.softMin = t.softMin or t[4]
t.softMax = t.softMax or t[5]
t.bigStep = t.bigStep or t[6]
end
function BetterOptionsTypes.execute(t)
t.func = t.func or t[1]
end
function BetterOptionsTypes.description(t)
t.width = t.width or "full"
t.fontSize = t.fontSize or "medium"
end
addon.BetterOptions = BetterOptions
addon.BetterOptionsTypes = BetterOptionsTypes
-------------------------------------------------------------------------------
-- AceOptionsTable extension
-- Flesh out AceOptionsTables for a given module
-- Add features not directly supported
local function Finalize(module_data, opts, key)
local meta = option_metadata[opts]
if not meta then
meta = { module_data = module_data }
option_metadata[opts] = meta
end
-- First call
if not key then
for k,v in pairs(opts) do
Finalize(module_data, v, k)
end
-- Recursion
else
-- Automatically localized selects
if opts.type == "alpha" or opts.type == "scale" then
opts.name = opts.name or L[module_data.name][key] or L[key] or L[opts.type]
opts.type = "range"
end
-- Fill in localized name/description
opts.name = opts.name or L[module_data.name][key] or L[key] or key
opts.desc = opts.desc or L[module_data.name][key.."_desc"]
meta.subtable, meta.subkey = opts.subtable, opts.subkey
opts.subtable, opts.subkey = nil, nil
-- Dependencies
if opts.requires or opts.requires_inverse then
meta.requires, meta.requires_inverse = opts.requires, opts.requires_inverse
opts.disabled = requires
opts.requires, opts.requires_inverse = nil, nil
end
-- Reload UI warning
if opts.must_reload_ui then
meta.must_reload_ui = true
opts.must_reload_ui = nil
end
-- Sorted select
-- TODO: Set metatable on option table to update meta.items?
if opts.type == "select" and opts.items then
opts.values = values_from_items
meta.values = {}
meta.items = opts.items
opts.items = nil
end
-- Traverse subgroup
if opts.args then
-- Apply subgroup defaults
if opts.defaults then
for argk, argv in pairs(opts.args) do
for defk, defv in pairs(opts.defaults) do
if argv[defk] == nil then
argv[defk] = defv
end
end
end
opts.defaults = nil
end
-- Finalize subgroups
for k,v in pairs(opts.args) do
Finalize(module_data, v, k)
end
-- Default type "toggle"
elseif not opts.type then
opts.type = "toggle"
end
end
return opts
end
-------------------------------------------------------------------------------
-- Module config registration
-- Global config header
self.config = {
type = "group",
name = "XLoot",
get = get,
set = set,
childGroups = "tab"
}
local function OnCoreChanged(k, v)
if k == 'skin' then
XLoot:ApplyOptions(true)
end
end
local skins = {}
local options = Finalize({ name = "Core", addon = XLoot, OnChanged = OnCoreChanged }, BetterOptions.Compile({
{ "details", "description" },
{ "skin", "select", values = function()
wipe(skins)
for k,v in pairs(XLoot.Skin.skins) do
skins[k] = v.name
end
return skins
end},
{ "skin_anchors", "toggle" },
-- { "module_header", "header" },
}))
self.config.args = options
function addon:RegisterAceOptionTable(module_name, option_table)
-- Insert into options
options[module_name] = {
type = "group",
name = L[module_name].panel_title,
desc = L[module_name].panel_desc,
args = option_table,
order = sizeof(options) + 1,
inline = false
}
end
function addon:RegisterOptions(module_data, option_table)
-- Have to finalize here because Finalize needs to know what module we're in
-- There's probably a better way to do this.
addon.modules[module_data.name] = module_data
Finalize(module_data, BetterOptions.Compile(option_table))
self:RegisterAceOptionTable(module_data.name, option_table)
end
-------------------------------------------------------------------------------
-- Generic select values
local item_qualities = {}
do
for i=0, #ITEM_QUALITY_COLORS do
local hex = select(4, GetItemQualityColor(i))
table.insert(item_qualities, { i, ("|c%s%s"):format(hex, _G["ITEM_QUALITY"..tostring(i).."_DESC"]) })
end
end
local directions = {
{ "up", L.up },
{ "down", L.down }
}
local leftright = {
{ "left", L.left },
{ "right", L.right },
}
-- Shared Media
local LSM = LibStub and LibStub("LibSharedMedia-3.0",1)
local fonts
if LSM then
fonts = {}
for name, ttf in pairs(LSM:HashTable("font")) do
table.insert(fonts, {ttf, name})
end
else
fonts = {
{ STANDARD_TEXT_FONT, "Friz Quadrata TT" },
{ [[Fonts\MORPHEUS.ttf]], "Morpheus" },
{ [[Fonts\ARIALN.ttf]], "Arial Narrow" },
{ [[Fonts\SKURRI.ttf]], "Skurri" },
}
end
local font_flag = {
{ "", "NONE" },
{ "OUTLINE", "OUTLINE" },
{ "THICKOUTLINE", "THICKOUTLINE" },
{ "MONOCHROME", "MONOCHROME" }
}
-------------------------------------------------------------------------------
-- Module configs
-- XLoot Frame
if XLoot:GetModule("Frame", true) then
local when_group = {
{ "never", L.when_never },
{ "solo", L.when_solo },
{ "always", L.when_always },
{ "group", L.when_group },
{ "party", L.when_party },
{ "raid", L.when_raid }
}
addon:RegisterOptions({ name = "Frame", addon = XLootFrame.addon }, {
{ "frame_options", "group", {
{ "frame_width_automatic", width = "double" },
{ "old_close_button" },
{ "frame_width", "range", 75, 300, 5, requires_inverse = "frame_width_automatic" },
{ "frame_scale", "scale" },
{ "frame_alpha", "alpha" },
{ "frame_snap" },
{ "frame_snap_offset_x", "range", -2000, 2000, 1, -250, 250, 10, requires = "frame_snap" },
{ "frame_snap_offset_y", "range", -2000, 2000, 1, -250, 250, 10, requires = "frame_snap" },
{ "frame_draggable" },
{ "frame_grow_upwards" },
{ "show_slot_errors" },
}},
{ "slot_options", "group", {
{ "loot_texts_info", width = "double" },
{ "loot_texts_bind" },
{ "loot_highlight", width = "double", },
{ "loot_collapse" },
{ "loot_texts_lock", width = "double" },
{ "loot_buttons_auto" },
{ "loot_alpha", "alpha" },
{ "loot_icon_size", "range", 16, 64, 1, name = L.icon_size },
{ "loot_row_height", "range", 14, 64, 1 },
{ "loot_padding", "header", name = L.padding },
{ "loot_padding_top", "range", 0, 25, 1, name = L.top },
{ "loot_padding_left", "range", 0, 25, 1, name = L.left },
{ "loot_padding_right", "range", 0, 25, 1, name = L.right },
{ "loot_padding_bottom", "range", 0, 25, 1, name = L.bottom },
}},
{ "link_button", "group", {
{ "linkall_show", when_group },
{ "linkall_threshold", item_qualities },
{ "linkall_channel", {
{ "SAY", CHAT_MSG_SAY },
{ "PARTY", CHAT_MSG_PARTY },
{ "GUILD", CHAT_MSG_GUILD },
{ "OFFICER", CHAT_MSG_OFFICER },
{ "RAID", CHAT_MSG_RAID },
{ "RAID_WARNING", RAID_WARNING },
{ 'INSTANCE_CHAT', INSTANCE_CHAT},
}},
{ "linkall_channel_secondary", {
{ "SAY", CHAT_MSG_SAY },
{ "PARTY", CHAT_MSG_PARTY },
{ "GUILD", CHAT_MSG_GUILD },
{ "OFFICER", CHAT_MSG_OFFICER },
{ "RAID", CHAT_MSG_RAID },
{ "RAID_WARNING", RAID_WARNING },
{ 'INSTANCE_CHAT', INSTANCE_CHAT},
{ 'NONE', NONE },
}},
{ "linkall_first_only" }
}},
{ "autolooting", "group", {
{ "autolooting_text", "description" },
{ "autoloot_currency", when_group, "autoloots", "currency" },
{ "autoloot_quest", when_group, "autoloots", "quest" },
{ "autoloot_tradegoods", when_group, "autoloots", "tradegoods" },
{ "autoloot_all", when_group, "autoloots", "all" },
{ "autolooting_list", "description" },
{ "autoloot_list", when_group, "autoloots", "list" },
{ "autoloot_item_list", "input", width = "double" },
{ "autolooting_details", "description" },
}},
{ "font", "group", {
{ "font", fonts },
{ "font_flag", font_flag },
{ "font_sizes", "header" },
{ "font_size_loot", "range", 4, 26, 1 },
{ "font_size_info", "range", 4, 26, 1 },
{ "font_size_quantity", "range", 4, 26, 1 },
{ "font_size_bottombuttons", "range", 4, 26, 1 },
{ "font_size_button_auto", "range", 4, 26, 1, requires = "loot_buttons_auto", name = L.Frame.loot_buttons_auto },
}},
{ "colors", "group", {
{ "quality_color_frame", width = "full" },
{ "quality_color_slot", width = "full" },
{ "frame_color_border", "color", width = "double", requires_inverse = "quality_color_frame" },
{ "loot_color_border", "color", requires_inverse = "quality_color_slot" },
{ "frame_color_backdrop", "color", width = "double" },
{ "loot_color_backdrop", "color" },
{ "frame_color_gradient", "color", width = "double" },
{ "loot_color_gradient", "color" },
{ "loot_color_info", "color", width = "double", requires = "loot_texts_info" },
{ "loot_color_button_auto", "color", requires = "loot_buttons_auto", name = L.Frame.loot_buttons_auto},
}}
})
end
-- XLoot Group
if XLoot:GetModule("Group", true) then
addon:RegisterOptions({ name = "Group", addon = XLootGroup }, {
{ "anchors", "group", {
{ "roll_anchor_visible", "toggle", "roll_anchor", "visible", set = set_anchor },
}},
{ "rolls", "group", {
{ "roll_direction", directions, "roll_anchor", "direction" , name = L.growth_direction },
{ "roll_scale", "scale", "roll_anchor", "scale" },
{ "roll_width", "range", 150, 700, 1, 150, 400, 10, name = L.width },
{ "roll_spacing", "range", -25, 25, 1, name = L.spacing, subtable = "roll_anchor", subkey = "spacing" },
{ "roll_offset", "range", -25, 25, 1, name = L.offset, subtable = "roll_anchor", subkey = "offset" },
{ "roll_button_size", "range", 16, 48, 1 },
}},
{ "extra_info", "group", {
{ "equip_prefix" },
{ "prefix_equippable", "input", requires = "equip_prefix" },
{ "prefix_upgrade", "input" },
{ "show_time_remaining", name = L.Group.text_time },
{ "show_undecided" },
{ "role_icon" },
{ "win_icon" },
{ "text_ilvl" },
}},
{ "font", "group", {
{ "font", fonts },
{ "font_flag", font_flag },
}},
{ "roll_tracking", "group", {
{ "track_all", width = "double" },
{ "track_player_roll", requires_inverse = "track_all" },
{ "track_by_threshold", requires_inverse = "track_all", width = "double" },
{ "track_threshold", item_qualities, requires = "track_by_threshold", name = L.minimum_quality },
{ "expiration", "header" },
{ "expire_won", "range", 5, 30, 1 },
{ "expire_lost", "range", 5, 30, 1 },
}},
})
end
-- XLoot Monitor
if XLoot:GetModule("Monitor", true) then
addon:RegisterOptions({ name = "Monitor", addon = XLootMonitor.addon }, {
{ "testing", "group", {
{ "test_settings", "execute", func = XLootMonitor.TestSettings }
}},
{ "anchor", "group", {
{ "visible", set = set_anchor, width = "double" },
{ "scale", "scale" },
{ "direction", directions, name = L.growth_direction },
{ "alignment", leftright, name = L.alignment },
{ "offsets", "header", name = '' },
{ "spacing", "range", -25, 25, 1, name = L.spacing, subtable = "anchor" },
{ "offset", "range", -25, 25, 1, name = L.offset, subtable = "anchor" },
}, defaults = { subtable = "anchor" } },
{ "thresholds", "group", {
{ "threshold_own", item_qualities, name = L.items_own },
{ "threshold_other", item_qualities, name = L.items_others },
}},
{ "filters", "group", {
{ "show_coin", name = MONEY },
{ "show_currency", name = CURRENCY },
{ "show_crafted" },
}, name = FILTERS },
{ "fading", "group", {
{ "fade_own", "range", 1, 30, 1, name = L.items_own },
{ "fade_other", "range", 1, 30, 1, name = L.items_others },
}},
{ "details", "group", {
{ "show_totals", width = "double" },
{ "use_altoholic", requires = "show_totals" },
{ "totals_delay", "range", 0.1, 1.0, 0.1 },
{ "name_width", "range", 25, 200, 5 },
{ "show_ilvl", name = L.Group.text_ilvl },
}},
{ "font", "group", {
{ "font", fonts },
{ "font_flag", font_flag },
{ "font_sizes", "header" },
{ "font_size_loot", "range", 4, 26, 1 },
{ "font_size_quantity", "range", 4, 26, 1 },
{ "font_size_ilvl", "range", 4, 26, 1 },
}},
{ "colors", "group", {
{ "gradients", must_reload_ui = true },
}, name = L.Frame.colors },
})
end
-- XLoot Master
if XLoot:GetModule("Master", true) then
-- Item quality dropdown generator
local item_qualities = {}
do
for i, v in ipairs({ "ITEM_QUALITY2_DESC", "ITEM_QUALITY3_DESC", "ITEM_QUALITY4_DESC", "CANCEL" }) do -- we only care for the qualities available as ML filters
local quality = tonumber(strmatch(v,"%d+"))
if quality then
local hex = select(4, GetItemQualityColor(quality))
item_qualities[i] = { quality, ('|c%s%s'):format(hex, _G[v]) }
end
end
end
table.insert(item_qualities, 1, { -1, ALWAYS })
table.insert(item_qualities, { 10, NEVER })
local channels = {
{ 'AUTO', L.desc_channel_auto },
{ 'SAY', CHAT_MSG_SAY },
{ 'PARTY', CHAT_MSG_PARTY },
{ 'RAID', CHAT_MSG_RAID },
{ 'INSTANCE_CHAT', INSTANCE_CHAT},
{ 'RAID_WARNING', RAID_WARNING },
{ 'OFFICER', CHAT_MSG_OFFICER },
{ 'NONE', NONE },
}
addon:RegisterOptions({ name = "Master", addon = XLootMaster }, {
{ "confirm_qualitythreshold", item_qualities },
{ "specialrecipients", "group", {
{ "menu_self" },
{ "menu_disenchant" },
{ "menu_disenchanters", "input", requires="menu_disenchant" },
{ "menu_bank" },
{ "menu_bankers", "input", requires="menu_bank" },
}},
{ "raidroll", "group", {
{ "menu_roll" },
}},
{ "awardannounce", "group", {
{ "award_qualitythreshold", item_qualities },
{ "award_channel", channels },
{ "award_channel_secondary", channels },
{ "award_guildannounce" },
{ "award_special" },
}},
})
end
--[=[ -- Generate reset staticpopup
if not StaticPopupDialogs['XLOOT_RESETPROFILE'] then
StaticPopupDialogs['XLOOT_RESETPROFILE'] = {
preferredIndex = 3,
text = L.confirm_reset_profile,
button1 = ACCEPT,
button2 = CANCEL,
OnAccept = function() addon:ResetProfile() end,
exclusive = true,
timeout = 0,
whileDead = true,
hideOnEscape = true,
}
end--]=]
if Settings then
addon:Init()
end
end
function addon:OnInitialize()
end
-------------------------------------------------------------------------------
-- Panel methods
local function PanelDefault(self)
-- StaticPopup_Show("XLOOT_RESETPROFILE")
addon:ResetProfile()
end
local function PanelOkay(self)
end
local function PanelCancel(self)
-- Restore old options?
end
function addon:ResetProfile()
XLoot.db:ResetProfile()
LibStub("AceConfigRegistry-3.0"):NotifyChange("XLoot")
end
local init = false
local AceConfigDialog, AceConfigRegistry = LibStub("AceConfigDialog-3.0"), LibStub("AceConfigRegistry-3.0")
function addon:Init()
-- One-time init
if not init then
init = true
if not Settings then
-- Remove bootstrap
for i,frame in ipairs(INTERFACEOPTIONS_ADDONCATEGORIES) do
if frame.name == "XLoot" then
table.remove(INTERFACEOPTIONS_ADDONCATEGORIES, i)
end
end
end
-- Generate new panel
AceConfigRegistry:RegisterOptionsTable("XLoot", self.config)
local panel = AceConfigDialog:AddToBlizOptions("XLoot")
XLoot.option_panel = panel
panel.default = PanelDefault
-- panel.okay = PanelOkay
-- panel.cancel = PanelCancel
local _OnShow = panel:GetScript("OnShow")
local _OnHide = panel:GetScript("OnHide")
panel:SetScript("OnShow", function(...)
_OnShow(...)
for name, module_data in pairs(self.modules) do
trigger(module_data.addon, "OnOptionsShow", panel)
end
end)
panel:SetScript("OnHide", function(...)
_OnHide(...)
for name, module_data in pairs(self.modules) do
trigger(module_data.addon, "OnOptionsHide", panel)
end
end)
-- Create profile panel
AceConfigRegistry:RegisterOptionsTable("XLootProfile", LibStub("AceDBOptions-3.0"):GetOptionsTable(XLoot.db))
XLoot.profile_panel = AceConfigDialog:AddToBlizOptions("XLootProfile", L.profile, "XLoot")
XLoot.profile_panel.default = PanelDefault
-- Force list to expand
if not Settings then
InterfaceAddOnsList_Update()
end
end
end
function addon:OpenPanel(module)
addon:Init()
-- Open panel
if Settings then
Settings.OpenToCategory("XLoot")
else
InterfaceOptionsFrame_OpenToCategory(XLoot.option_panel)
end
end