diff gui.lua @ 96:780b7e0eeeeb

Break the options panel out of gui.lua into new options.lua. Move default item lists from verbage.lua there also. Redo options panel as a tree instead of a massive scrolling thing, and prepare data structures to let plugins/etc add their own options code.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Thu, 26 Jul 2012 20:46:00 +0000
parents 3546c7b55986
children ba5ff82dcf19
line wrap: on
line diff
--- a/gui.lua	Thu Jul 26 03:34:56 2012 +0000
+++ b/gui.lua	Thu Jul 26 20:46:00 2012 +0000
@@ -60,7 +60,6 @@
 	tabtexts = {
 		["eoi"] = {title=[[Loot]], desc=[[Observed loot, plus boss kills and other events of interest]]},
 		["hist"] = {title=[[History]], desc=[[A short semi-permanent record]]},
-		["opt"] = {title=[[Options]], desc=[[Options for fine-tuning behavior]]},
 	},
 	taborder        = { "eoi"                        },
 	taborder_APPEND = {        "hist", "help", "opt" },
@@ -90,7 +89,7 @@
 -- En masse forward decls of symbols defined inside local blocks
 local _generate_text, _populate_text_specials, _markup
 local eoi_dropdownfuncs -- filled out in gui block scope
-local _do_debugging_tooltip, _hide_debugging_tooltip, _build_debugging_tooltip
+local _hide_debugging_tooltip, _build_debugging_tooltip
 local _new_rebroadcast_hyperlink
 
 --[[
@@ -515,14 +514,14 @@
 
 	local _creators, _builders = {}, {}
 	local function _create_tooltip()
-		local which = assert(tonumber(_do_debugging_tooltip))
+		local which = assert(tonumber(gui._do_debugging_tooltip))
 		if type(_creators[which]) == 'function' then
 			_creators[which]()
 		end
 		debug_tt = _creators[which]
 	end
 	function _build_debugging_tooltip (parent, index)
-		local which = assert(tonumber(_do_debugging_tooltip))
+		local which = assert(tonumber(gui._do_debugging_tooltip))
 		if type(_builders[which]) == 'function' then
 			_builders[which](parent,index)
 		end
@@ -1083,7 +1082,7 @@
 	local kind = e.kind
 	local tt = GameTooltip   -- can this be hoisted? does GT ever get securely replaced?
 
-	if _do_debugging_tooltip and column == 1 and kind ~= 'hist' then
+	if gui._do_debugging_tooltip and column == 1 and kind ~= 'hist' then
 		_build_debugging_tooltip (cellFrame, realrow)
 	end
 	if (kind == 'loot' and column == 1) or (kind == 'hist' and column == 2) then
@@ -1896,562 +1895,7 @@
 -- Tab 5:  Help (content in verbage.lua)
 
 
--- Tab 6:  Options / Advanced
-do
-	-- Local ref to OuroLootSV_opts, which may be reassigned after load.
-	-- So instead this is updated when the tab is displayed.
-	local opts
-	local function mkoption (opt, label, width, desc, opt_func)
-		local w = mkbutton("CheckBoxSmallLabel", nil, "", desc)
-		w:SetRelativeWidth(width)
-		w:SetType("checkbox")
-		w:SetLabel(label)
-		if opt then
-			w:SetValue(opts[opt])
-			w:SetCallback("OnValueChanged", opt_func or (function(_w,event,value)
-				opts[opt] = value
-			end))
-		end
-		return w
-	end
-
-	local function adv_careful_OnTextChanged (ebox,event,value)
-		-- The EditBox widget's code will call an internal ShowButton routine
-		-- after this callback returns.  ShowButton will test for this flag:
-		ebox:DisableButton (value == "")
-	end
-
-	-- Like the first tab, we use a pair of functions; first and repeating.
-	local function adv_real (container, specials)
-		local grp, w
-
-		grp = AceGUI:Create("InlineGroup")
-		grp:SetLayout("Flow")
-		grp:PauseLayout()
-		grp:SetFullWidth(true)
-		grp:SetTitle("Debugging/Testing Options      [not saved across sessions]")
-
-		w = mkbutton("EditBox", 'comm_ident', addon.ident,
-			[[Set tracking to 'Disabled' in the top-right dropdown, then change this field (click Okay or press Enter).]])
-		w:SetRelativeWidth(0.2)
-		w:SetLabel("Addon channel ID")
-		w:SetCallback("OnTextChanged", adv_careful_OnTextChanged)
-		w:SetCallback("OnEnterPressed", function(_w,event,value)
-			-- if they set it to blank spaces, they're boned.  oh well.
-			-- Re-enabling will take care of propogating this new value.
-			addon.ident = (value == "") and "OuroLoot2" or value
-			_w:SetText(addon.ident)
-			addon:Print("Addon channel ID set to '".. addon.ident.. "' for rebroadcasting and listening.")
-		end)
-		w:SetDisabled(addon.enabled or addon.rebroadcast)
-		grp:AddChild(w)
-
-		w = mkbutton("EditBox", nil, addon.recent_messages.ttl, [[comm cache TTL]])
-		w:SetRelativeWidth(0.05)
-		w:SetLabel("ttl")
-		w:SetCallback("OnTextChanged", adv_careful_OnTextChanged)
-		w:SetCallback("OnEnterPressed", function(_w,event,value)
-			value = tonumber(value) or addon.recent_messages.ttl
-			addon.recent_messages.ttl = value
-			_w:SetText(tostring(value))
-		end)
-		grp:AddChild(w)
-
-		w = mkbutton("load nsaab1548", [[Cursed Darkhound]])
-		w:SetRelativeWidth(0.25)
-		w:SetCallback("OnClick", function()
-			for i, v in ipairs(DBM.AddOns) do
-				if v.modId == "DBM-NotScaryAtAll" then
-					DBM:LoadMod(v)
-					break
-				end
-			end
-			local mod = DBM:GetModByName("NotScaryAtAll")
-			if mod then
-				mod:EnableMod()
-				addon:Print("Now tracking ID",mod.creatureId)
-			else
-				addon:Print("Can do nothing; DBM testing mod wasn't loaded.")
-			end
-		end)
-		w:SetDisabled(addon.bossmod_registered ~= 'DBM')
-		grp:AddChild(w)
-
-		w = mkbutton("GC", [[full GC cycle]])
-		w:SetRelativeWidth(0.1)
-		w:SetCallback("OnClick", function()
-			local before = collectgarbage('count')
-			collectgarbage('collect')
-			local after = collectgarbage('count')
-			addon:Print("Collected %d KB, %d KB still in use by Lua universe.", before-after, after)
-		end)
-		grp:AddChild(w)
-
-		w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(1) grp:AddChild(w)
-
-		local simple = AceGUI:Create("SimpleGroup")
-		simple:SetLayout("List")
-		simple:SetRelativeWidth(0.3)
-		w = mkbutton("Dropdown", nil, "", [[hovering over Item column only]])
-		w:SetFullWidth(true)
-		w:SetLabel("loot debugging tooltip")
-		w:SetList{
-			[1] = "Off",
-			[2] = "/dump into tooltip",
-			[3] = "small fixed fields",
-		}
-		w:SetValue(_do_debugging_tooltip or 1)
-		w:SetCallback("OnValueChanged", function(_w,event,choice)
-			_do_debugging_tooltip = choice > 1 and choice or nil
-		end)
-		simple:AddChild(w)
-
-		w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(10) simple:AddChild(w)
-
-		w = AceGUI:Create("CheckBoxSmallLabel")
-		w:SetFullWidth(true)
-		w:SetType("checkbox")
-		w:SetLabel("debug toggle  --->")
-		w:SetValue(addon.DEBUG_PRINT)
-		w:SetCallback("OnValueChanged", function(_w,event,value)
-			addon.DEBUG_PRINT = value
-			addon:redisplay()
-		end)
-		simple:AddChild(w)
-		w = AceGUI:Create("CheckBoxSmallLabel")
-		w:SetFullWidth(true)
-		w:SetType("checkbox")
-		w:SetLabel("GOP history mode")
-		w:SetValue(addon.history_suppress)
-		w:SetCallback("OnValueChanged", function(_w,event,value) addon.history_suppress = value end)
-		simple:AddChild(w)
-		w = mkbutton("Clear All & Reload",
-			[[No confirmation!  |cffff1010Erases absolutely all> Ouro Loot saved variables and reloads the UI.]])
-		w:SetFullWidth(true)
-		w:SetCallback("OnClick", function()
-			addon:_clear_SVs()  -- reloads
-		end)
-		simple:AddChild(w)
-		grp:AddChild(simple)
-
-		simple = AceGUI:Create("SimpleGroup")
-		simple:SetLayout("List")
-		simple:SetRelativeWidth(0.5)
-		for d,v in pairs(addon.debug) do
-			w = AceGUI:Create("CheckBoxSmallLabel")
-			w:SetFullWidth(true)
-			w:SetType("checkbox")
-			w:SetLabel(d)
-			if d == "notraid" then
-				w:SetDescription[[Tick this before enabling to make the addon work outside of raid groups]]
-			else
-				if d == "alsolog" then
-					w:SetDescription[[Also log all debug messages to disk. See print_log.lua in the addon folder for later viewing.]]
-				end
-				w:SetDisabled(not addon.DEBUG_PRINT)
-			end
-			w:SetValue(v)
-			w:SetCallback("OnValueChanged", function(_w,event,value) addon.debug[d] = value end)
-			simple:AddChild(w)
-		end
-		grp:AddChild(simple)
-
-		simple = AceGUI:Create("SimpleGroup")
-		simple:SetLayout("Flow")
-		simple:SetRelativeWidth(0.85)
-		w = mkbutton("MidS-H", [[not exactly an Easter egg, with sound]])
-		w:SetRelativeWidth(0.15)
-		w:SetCallback("OnClick", function() 
-			PlaySoundFile ([[Sound\Music\WorldEvents\HordeFirepole.mp3]], "Master")
-		end)
-		simple:AddChild(w)
-		w = mkbutton("MidS-A", [[not exactly an Easter egg, with sound]])
-		w:SetRelativeWidth(0.15)
-		w:SetCallback("OnClick", function() 
-			PlaySoundFile ([[Sound\Music\WorldEvents\AllianceFirepole.mp3]], "Master")
-		end)
-		simple:AddChild(w)
-		w = mkbutton("SFRR", [[test]])
-		w:SetRelativeWidth(0.15)
-		w:SetCallback("OnClick", function() 
-			PlaySoundFile ([[Interface\AddOns\Ouro_Loot\sfrr.ogg]], "Master")
-		end)
-		simple:AddChild(w)
-		grp:AddChild(simple)
-
-		grp:ResumeLayout()
-		container:AddChild(grp)
-		AceGUI:ClearFocus()
-		container:SetScroll(1000)  -- scrollframe's max value
-	end
-
-	-- Initial lower panel function (unless debug mode is on during load, which
-	-- means it was almost certainly hardcoded that way, which means it's
-	-- probably me testing).
-	local adv_lower
-	if addon.DEBUG_PRINT then
-		adv_lower = adv_real
-	else
-		function adv_lower (container, specials)
-			local spacer = AceGUI:Create("Spacer")
-			spacer:SetFullWidth(true)
-			spacer:SetHeight(5)
-			container:AddChild(spacer)
-			local speedbump = AceGUI:Create("InteractiveLabel")
-			speedbump:SetFullWidth(true)
-			speedbump:SetFontObject(GameFontHighlightLarge)
-			speedbump:SetImage[[Interface\DialogFrame\DialogAlertIcon]]
-			speedbump:SetImageSize(50,50)
-			speedbump:SetText("The debugging/testing settings on the rest of this panel can seriously bork up the addon if you make a mistake.  If you're okay with the possibility of losing data, click this warning to load the panel.")
-			speedbump:SetCallback("OnClick", function (_sb)
-				adv_lower = adv_real
-				return addon:redisplay()
-			end)
-			container:AddChild(speedbump)
-			spacer = AceGUI:Create("Spacer")
-			spacer:SetFullWidth(true)
-			spacer:SetHeight(5)
-			container:AddChild(spacer)
-		end
-	end
-
-	tabs_OnGroupSelected["opt"] = function(container,specials)
-		opts = OuroLootSV_opts
-
-		container:SetLayout("Fill")
-		local scroll, grp, w
-
-		scroll = AceGUI:Create("ScrollFrame")
-		scroll:SetLayout("Flow")
-
-		grp = AceGUI:Create("InlineGroup")
-		grp:SetLayout("Flow")
-		grp:SetFullWidth(true)
-		grp:SetTitle("User Options     [these are saved across sessions]")
-
-		-- The relative width fields used to be done to take up less vertical
-		-- space, but that turned out to look messy.  Now they're just a
-		-- straight line for the most part.
-
-		-- the nubtoggle!
-		w = mkoption('gui_noob', [[Show UI Tips]], 0.85,
-			[[Toggles display of the "helpful tips" box on the right side.  Useful if you've just installed/upgraded.]])
-		grp:AddChild(w)
-
-		-- reminder popup
-		w = mkoption ('popup_on_join', "Show reminder popup on new raid", 0.49,
-			[[When joining a raid and not already tracking, display a dialog asking for instructions.]])
-		grp:AddChild(w)
-
-		-- toggle scroll-to-bottom on first tab
-		w = mkoption('scroll_to_bottom', "Scroll to bottom when opening display", 0.49,
-			[[Scroll to the bottom of the loot window (most recent entries) when displaying the GUI.]])
-		grp:AddChild(w)
-
-		-- chatty boss mode
-		w = mkoption('chatty_on_kill', "Be chatty on boss kill", 0.49,
-			[[Print something to chat output when the boss mod tells Ouro Loot about a successful boss kill.]])
-		grp:AddChild(w)
-
-		-- less noise in main panel
-		w = mkoption('no_tracking_wipes', "Do not track wipes", 0.49,
-			[[Do not add 'wipe' entries on the main loot grid, or generate any text for them.]])
-		grp:AddChild(w)
-
-		-- cutesy abbrevs
-		w = mkoption('snarky_boss', "Use snarky boss names", 0.49,
-			[[Irreverent replacement names for boss events.  See abbreviations.lua for details.]])
-		grp:AddChild(w)
-
-		-- LOD plugins in all cases
-		w = mkoption('display_disabled_LODs', "Include disabled plugins", 0.49,
-			[[Show loadable plugins even if they've been disabled (and offer to enable them).  Relog to take effect.]])
-		grp:AddChild(w)
-
-		-- showing the "(from Rebroadcasterdude)" in the notes column
-		w = mkoption('display_bcast_from', "Show rebroadcasting player", 0.49,
-			[[Include "from PlayerName" in the Notes column for loot that was broadcast to you.  (Not included in forum output).]],
-			function(_w,_e,value)
-				opts.display_bcast_from = value
-				addon.loot_clean = nil
-			end)
-		grp:AddChild(w)
-
-		-- prefilling g_uniques with history
-		w = mkoption('precache_history_uniques', "Prescan for faster handling", 0.49,
-			[[See description under +Help -- Handy Tips -- Prescanning> for instructions.]])
-		grp:AddChild(w)
-
-		w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(5) grp:AddChild(w)
-
-		-- possible keybindings
-		do
-			local pair = AceGUI:Create("InlineGroup")
-			pair:SetLayout("List")
-			pair:SetRelativeWidth(0.49)
-			pair:SetTitle("Keybinding for '/ouroloot'")
-			local editbox, checkbox
-			editbox = mkbutton("EditBox", nil, opts.keybinding_text,
-				[[Keybinding text format is fragile (ALT then CTRL then SHIFT)!  Relog to take effect.]])
-			editbox:SetFullWidth(true)
-			editbox:SetLabel("Keybinding text")
-			editbox:SetCallback("OnEnterPressed", function(_w,event,value)
-				opts.keybinding_text = value
-			end)
-			editbox:SetDisabled(not opts.keybinding)
-			checkbox = mkoption('keybinding', "Register keybinding", 1,
-				[[Register a keybinding to toggle the loot display.  Relog to take effect.]],
-				function (_w,_,value)
-					opts.keybinding = value
-					editbox:SetDisabled(not opts.keybinding)
-				end)
-			checkbox:SetFullWidth(true)
-			pair:AddChild(checkbox)
-			pair:AddChild(editbox)
-			grp:AddChild(pair)
-		end
-
-		-- replacement for slashloot
-		do
-			local pair = AceGUI:Create("InlineGroup")
-			pair:SetLayout("List")
-			pair:SetRelativeWidth(0.49)
-			pair:SetTitle('Synonyms for "/ouroloot"')
-			local editbox, checkbox
-			editbox = mkbutton("EditBox", nil, opts.slash_synonyms,
-				[[Separate multiple synonyms with a comma.  Relog to take effect.]])
-			editbox:SetFullWidth(true)
-			editbox:SetLabel("Slash commands")
-			editbox:SetCallback("OnEnterPressed", function(_e,event,value)
-				-- Do the sanity checking here rather than at each login.
-				-- This is not foolproof.  That's okay.
-				local t = { strsplit(',', tostring(value)) }
-				for k,v in ipairs(t) do
-					v = v:trim()
-					if v:sub(1,1) ~= "/" then
-						v = "/" .. v
-					end
-					t[k] = v
-				end
-				value = table.concat(t,',')
-				_e:SetText(value)
-				opts.slash_synonyms = value
-			end)
-			editbox:SetDisabled(not opts.register_slash_synonyms)
-			checkbox = mkoption('register_slash_synonyms', "Register slash commands", 1,
-				[[Register these slash commands as synonyms for "/ouroloot".  Relog to take effect.]],
-				function (_w,_,value)
-					opts.register_slash_synonyms = value
-					editbox:SetDisabled(not opts.register_slash_synonyms)
-				end)
-			checkbox:SetFullWidth(true)
-			pair:AddChild(checkbox)
-			pair:AddChild(editbox)
-			grp:AddChild(pair)
-		end
-
-		-- chatty disposition/assignment changes
-		do
-			local chatgroup = AceGUI:Create("InlineGroup")
-			chatgroup:SetLayout("List")
-			chatgroup:SetRelativeWidth(0.49)
-			chatgroup:SetTitle("Remote Changes Chat")
-			local toggle, editbox
-			toggle = mkoption('chatty_on_remote_changes', "Be chatty on remote changes", 1,
-				[[Print something to chat when other users change recorded loot.]],
-				function (_w,_,value)
-					opts.chatty_on_remote_changes = value
-					editbox:SetDisabled(not opts.chatty_on_remote_changes)
-				end)
-			toggle:SetFullWidth(true)
-			chatgroup:AddChild(toggle)
-			w = AceGUI:Create("Label")
-			w:SetFullWidth(true)
-			w:SetText("This controls the output of the |cff00ffff'Be chatty on remote changes'|r option.  If this field is a number, it designates which chat frame to use.  Otherwise it is the Lua variable name of a frame with AddMessage capability.")
-			chatgroup:AddChild(w)
-			editbox = mkbutton("EditBox", nil, opts.chatty_on_remote_changes_frame,
-				[[1 = default chat frame, 2 = combat log, etc]])
-			editbox:SetFullWidth(true)
-			editbox:SetLabel("Output Chatframe")
-			editbox:SetCallback("OnTextChanged", adv_careful_OnTextChanged)
-			editbox:SetCallback("OnEnterPressed", function(_w,event,value)
-				local prev = opts.chatty_on_remote_changes_frame
-				value = value:trim()
-				value = tonumber(value) or value
-				if addon:_set_remote_change_chatframe (value) then
-					opts.chatty_on_remote_changes_frame = value
-					_w:SetText(tostring(value))
-					_w.editbox:ClearFocus()
-				else
-					_w:SetText(tostring(prev))
-				end
-			end)
-			editbox:SetDisabled(not opts.chatty_on_remote_changes)
-			chatgroup:AddChild(editbox)
-			w = mkbutton("Chat Frame Numbers",
-				[[Print each chat window number in its own frame, for easy reference in the editing field.]])
-			w:SetFullWidth(true)
-			w:SetCallback("OnClick", function()
-				for i = 1, NUM_CHAT_WINDOWS do
-					local cf = _G['ChatFrame'..i]
-					if not cf then break end
-					addon:CFPrint (cf, "This is frame number |cffff0000%d|r.", i)
-				end
-			end)
-			chatgroup:AddChild(w)
-			grp:AddChild(chatgroup)
-		end
-
-		-- boss mod selection
-		w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(2) grp:AddChild(w)
-		do
-			local list = {}
-			local current
-			for k,v in ipairs(addon.bossmods) do
-				list[k] = v.n
-				if v.n == opts.bossmod then
-					current = k
-				end
-			end
-			w = mkbutton("Dropdown", nil, "", [[Which 'boss mod' to use.]])
-			w:SetRelativeWidth(0.2)
-			w:SetLabel("Boss Mod:")
-			w:SetList(list)
-			w:SetValue(current)
-			w:SetCallback("OnValueChanged", function(_w,event,choice)
-				opts.bossmod = list[choice]
-			end)
-			grp:AddChild(w)
-		end
-
-		-- item filters
-		w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(2) grp:AddChild(w)
-		do
-			local warntext = "At least one of the items in the filter list was not in your game client's cache.  This is okay.  Just wait a few seconds, display some other Ouro Loot tab, and then display Options again."
-			local cache_warn, cache_warned = false, false
-			local function do_warning()
-				if cache_warn and not cache_warned then
-					cache_warned = true
-					addon:Print(warntext)
-				end
-			end
-
-			local filterlist, vaultlist = {}, {}
-			for id in pairs(opts.itemfilter) do
-				local iname, _, iquality = GetItemInfo(id)
-				if iname then
-					filterlist[id] = ITEM_QUALITY_COLORS[iquality].hex .. iname .. "|r"
-				else
-					cache_warn = true
-				end
-			end
-			for id in pairs(opts.itemvault) do
-				local iname, _, iquality = GetItemInfo(id)
-				if iname then
-					vaultlist[id] = ITEM_QUALITY_COLORS[iquality].hex .. iname .. "|r"
-				else
-					cache_warn = true
-				end
-			end
-
-			w = AceGUI:Create("EditBoxDropDown")
-			w:SetRelativeWidth(0.4)
-			w:SetText("Item filter")
-			w:SetEditBoxTooltip("Link items which should no longer be tracked.")
-			w:SetList(filterlist)
-			w:SetCallback("OnTextEnterPressed", function(_w, _, text)
-				local iname, ilink, iquality = GetItemInfo(text:trim())
-				if not iname then
-					return addon:Print("Error:  %s is not a valid item name/link!", text)
-				end
-				local id = tonumber(ilink:match("item:(%d+)"))
-				filterlist[id] = ITEM_QUALITY_COLORS[iquality].hex .. iname .. "|r"
-				opts.itemfilter[id] = true
-				addon:Print("Now filtering out", ilink)
-			end)
-			w:SetCallback("OnListItemClicked", function(_w, _, key_id, val_name)
-				--local ilink = select(2,GetItemInfo(key_id))
-				opts.itemfilter[tonumber(key_id)] = nil
-				--addon:Print("No longer filtering out", ilink)
-				addon:Print("No longer filtering out", val_name)
-			end)
-			w:SetCallback("OnDropdownShown",do_warning)
-			grp:AddChild(w)
-
-			w = AceGUI:Create("Spacer")
-			w:SetRelativeWidth(0.1)
-			w:SetHeight(2)
-			grp:AddChild(w)
-
-			w = AceGUI:Create("EditBoxDropDown")
-			w:SetRelativeWidth(0.4)
-			w:SetText("Vault items")
-			w:SetEditBoxTooltip("Link items which should be automatically marked as guild vault.")
-			w:SetList(vaultlist)
-			w:SetCallback("OnTextEnterPressed", function(_w, _, text)
-				local iname, ilink, iquality = GetItemInfo(text:trim())
-				if not iname then
-					return addon:Print("Error:  %s is not a valid item name/link!", text)
-				end
-				local id = tonumber(ilink:match("item:(%d+)"))
-				vaultlist[id] = ITEM_QUALITY_COLORS[iquality].hex .. iname .. "|r"
-				opts.itemvault[id] = true
-				addon:Print("Now auto-vaulting", ilink)
-			end)
-			w:SetCallback("OnListItemClicked", function(_w, _, key_id, val_name)
-				--local ilink = select(2,GetItemInfo(key_id))
-				opts.itemfilter[tonumber(key_id)] = nil
-				--addon:Print("No longer filtering out", ilink)
-				addon:Print("No longer auto-vaulting", val_name)
-			end)
-			w:SetCallback("OnDropdownShown",do_warning)
-			grp:AddChild(w)
-		end
-
-		addon.sender_list.sort()
-		if #addon.sender_list.namesI > 0 then
-			local senders = table.concat(addon.sender_list.namesI,'\n')   -- sigh
-			-- If 39 other people in the raid are running this, the label will
-			-- explode... is it likely enough to care about?  No.
-			w = AceGUI:Create("Spacer")
-			w:SetFullWidth(true)
-			w:SetHeight(20)
-			grp:AddChild(w)
-			w = AceGUI:Create("Label")
-			w:SetRelativeWidth(0.4)
-			w:SetText(ITEM_QUALITY_COLORS[3].hex .."Echo from latest ping:|r\n"..senders)
-			grp:AddChild(w)
-		end
-
-		scroll:AddChild(grp)
-
-		w = mkbutton("ReloadUI", [[Does what you think it does.  Loot information is written out and restored.]])
-		w:SetFullWidth(true)
-		w:SetCallback("OnClick", ReloadUI)
-		specials:AddChild(w)
-
-		w = mkbutton("Ping!",
-			[[Asks other raid users for their addon version and current status.  Results displayed on User Options panel.]])
-		w:SetFullWidth(true)
-		w:SetCallback("OnClick", function(_w)
-			_w:SetText("5... 4... 3...")
-			_w:SetDisabled(true)
-			addon:DoPing()
-			addon:ScheduleTimer(function(b)
-				if b:IsVisible() then
-					return addon:redisplay()
-				end
-			end, 5, _w)
-		end)
-		specials:AddChild(w)
-
-		-- Add appropriate lower panel
-		adv_lower (scroll, specials)
-
-		-- Finish up
-		container:AddChild(scroll)
-	end
-end
+-- Tab 6:  Options (content in options.lua)
 
 
 -- Simply to avoid recreating the same function over and over
@@ -2533,6 +1977,7 @@
 	if opt_key then _d:SetUserData (opt_key, button) end
 	return button
 end
+gui.mkbutton = mkbutton
 
 --[[
 Creates the main window.
@@ -2565,6 +2010,7 @@
 	display:SetLayout("Flow")
 	display:SetStatusTable{width=900,height=550}   -- default height is 500
 	display:EnableResize(false)
+	display:SetUserData("GUI state",gui)
 	display:SetCallback("OnClose", function(_display)
 		UIDROPDOWNMENU_SHOW_TIME = prev_fade_time 
 		hide_noobtips_frame()