Mercurial > wow > ouroloot
diff options.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 | |
children | ba5ff82dcf19 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/options.lua Thu Jul 26 20:46:00 2012 +0000 @@ -0,0 +1,695 @@ +local addon = select(2,...) +if addon.NOLOAD then return end + +-- Don't bother recording any of this loot: +addon.default_itemfilter = { + -- could probably remove most of this now +-- [29434] = true, -- Badge of Justice +-- [40752] = true, -- Emblem of Heroism +-- [40753] = true, -- Emblem of Valor +-- [45624] = true, -- Emblem of Conquest +-- [43228] = true, -- Stone Keeper's Shard +-- [47241] = true, -- Emblem of Triumph +-- [49426] = true, -- Emblem of Frost +} + +-- Mark these as straight to guild vault: +addon.default_itemvault = { + [52078] = true, -- Chaos Orb + [69237] = true, -- Living Ember + [71998] = true, -- Essence of Destruction +} + +local options_tree = { + { + value = "pong", + text = "Pongs", + }, + { + value = "basic", + text = "Options", + children = { + { + value = "filter", + text = "Item Filters", + }, + }, + }, + { + value = "adv", + text = "Advanced/Debugging", + }, +} + + +--[[ +mkbutton ("WidgetType", 'display key', "Text On Widget", "mouseover status text") +mkbutton ( [Button] 'display key', "Text On Widget", "mouseover status text") +mkbutton ( [Button] [text] "Text On Widget", "mouseover status text") +]] +local mkbutton = addon.gui_state_pointer.mkbutton +local gui = addon.gui_state_pointer +local AceGUI = LibStub("AceGUI-3.0") +local flib = LibStub("LibFarmbuyer") +-- 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 mktoggle (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 mktitle (txt) + local t = AceGUI:Create("Label") + t:SetFullWidth(true) + t:SetColor (0.19, 0.68, 1) -- cff30adff + t:SetFontObject(GameFontHighlightLarge) + t:SetText(txt) + local s = AceGUI:Create("Spacer") + s:SetFullWidth(true) + s:SetHeight(20) + return t, s +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 + + +--------------- +-- All controls take a scrollframe container set to Flow layout. +local controls = {} +controls.pong = function (container) + container:AddChildren(mktitle[[Echoes from latest ping:]]) + addon.sender_list.sort() + if #addon.sender_list.namesI > 0 then + local w = AceGUI:Create("Label") + w:SetFullWidth(true) + w:SetText(table.concat(addon.sender_list.namesI,'\n')) -- sigh + container:AddChild(w) + end +end + + +--------------- +controls.basic = function (container) + container:AddChildren(mktitle[[Account Options (saved across sessions)]]) + + container:PauseLayout() + local w + local stdw = 0.99 -- standard width + + -- the nubtoggle! + w = mktoggle('gui_noob', [[Show UI Tips]], stdw, + [[Toggles display of the "helpful tips" box hanging off the right side. Useful if you've just installed/upgraded.]]) + container:AddChild(w) + + -- reminder popup + w = mktoggle('popup_on_join', "Show reminder popup on new raid", stdw, + [[When joining a raid and not already tracking, display a dialog asking for instructions.]]) + container:AddChild(w) + + -- toggle scroll-to-bottom on first tab + w = mktoggle('scroll_to_bottom', "Scroll to bottom when opening display", stdw, + [[Scroll to the bottom of the loot window (most recent entries) when displaying the GUI.]]) + container:AddChild(w) + + -- chatty boss mode + w = mktoggle('chatty_on_kill', "Be chatty on boss kill", stdw, + [[Print something to chat output when the boss mod tells Ouro Loot about a successful boss kill.]]) + container:AddChild(w) + + -- less noise in main panel + w = mktoggle('no_tracking_wipes', "Do not track wipes", stdw, + [[Do not add 'wipe' entries on the main loot grid, or generate any text for them.]]) + container:AddChild(w) + + -- cutesy abbrevs + w = mktoggle('snarky_boss', "Use snarky boss names", stdw, + [[Irreverent replacement names for boss events. See abbreviations.lua for details.]]) + container:AddChild(w) + + -- LOD plugins in all cases + w = mktoggle('display_disabled_LODs', "Include disabled plugins", stdw, + [[Show loadable plugins even if they've been disabled (and offer to enable them). Relog to take effect.]]) + container:AddChild(w) + + -- showing the "(from Rebroadcasterdude)" in the notes column + w = mktoggle('display_bcast_from', "Show rebroadcasting player", stdw, + [[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) + container:AddChild(w) + + -- prefilling g_uniques with history + w = mktoggle('precache_history_uniques', "Prescan for faster handling", stdw, + [[See description under +Help -- Handy Tips -- Prescanning> for instructions.]]) + container:AddChild(w) + + w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(10) container: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! (All caps, 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 = mktoggle('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) + container: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 = mktoggle('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) + container:AddChild(pair) + end + + -- chatty disposition/assignment changes + w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(10) container:AddChild(w) + do + local chatgroup = AceGUI:Create("InlineGroup") + chatgroup:SetLayout("List") + chatgroup:SetRelativeWidth(0.75) + chatgroup:SetTitle("Remote Changes Chat") + local toggle, editbox + toggle = mktoggle('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) + container:AddChild(chatgroup) + end + + -- boss mod selection + w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(2) container: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.3) + w:SetLabel("Boss Mod:") + w:SetList(list) + w:SetValue(current) + w:SetCallback("OnValueChanged", function(_w,event,choice) + opts.bossmod = list[choice] + end) + container:AddChild(w) + end + + container:ResumeLayout() + container:DoLayout() + AceGUI:ClearFocus() +end + + +--------------- +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 or panel, and then display the Item Filters again.]] + local cache_warn, cache_warned = false, false + local function do_warning (cnt) + if cache_warn and not cache_warned then + cache_warned = true + addon:Print(warntext) + local t = AceGUI:Create("Label") + t:SetFullWidth(true) + t:SetText(warntext) + cnt:AddChild(t) + end + end + + controls.basic_filter = function (container) + container:AddChildren(mktitle[[Item-Specific Special Handling]]) + + cache_warn, cache_warned = false, false + 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 + filterlist[id] = id + 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 + vaultlist[id] = id + cache_warn = true + end + end + + local 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) + w:SetCallback("OnDropdownShown", function() + do_warning(container) + end) + container:AddChild(w) + + w = AceGUI:Create("Spacer") + w:SetRelativeWidth(0.1) + w:SetHeight(2) + container: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) + container:AddChild(w) + end +end + + +--------------- +local adv_real = function (container) + container:AddChildren(mktitle[[Debugging Options (not saved across sessions)]]) + + container:PauseLayout() + local w + + do + local grp = AceGUI:Create("InlineGroup") + grp:SetLayout("List") + grp:SetRelativeWidth(0.60) + grp:SetTitle("Output of debugging messages") + + w = AceGUI:Create("CheckBoxSmallLabel") + w:SetFullWidth(true) + w:SetType("checkbox") + w:SetLabel("master toggle") + w:SetValue(addon.DEBUG_PRINT) + w:SetCallback("OnValueChanged", function(_w,event,value) + addon.DEBUG_PRINT = value + addon:redisplay() + end) + grp:AddChild(w) + 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) + grp:AddChild(w) + end + container:AddChild(grp) + end + + do + local simple = AceGUI:Create("SimpleGroup") + simple:SetLayout("List") + simple:SetRelativeWidth(0.35) + w = AceGUI:Create("CheckBoxSmallLabel") + --w:SetRelativeWidth(0.35) + 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("Dropdown", nil, "", + [[if active, tooltip shown when hovering over Item column only]]) + --w:SetRelativeWidth(0.4) + w:SetFullWidth(true) + w:SetLabel("loot debugging tooltip") + w:SetList{ + [1] = "Off", + [2] = "/dump into tooltip", + [3] = "small fixed fields", + } + w:SetValue(gui._do_debugging_tooltip or 1) + w:SetCallback("OnValueChanged", function(_w,event,choice) + gui._do_debugging_tooltip = choice > 1 and choice or nil + end) + simple:AddChild(w) + container:AddChild(simple) + end + + w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(10) container:AddChild(w) + + 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.25) + 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) + container:AddChild(w) + + w = mkbutton("EditBox", nil, addon.recent_messages.ttl, [[comm cache TTL]]) + w:SetRelativeWidth(0.1) + 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) + container: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') + container:AddChild(w) + + w = mkbutton("GC", [[full GC cycle]]) + w:SetRelativeWidth(0.2) + 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) + container:AddChild(w) + + w = AceGUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(3) container:AddChild(w) + do + local simple = AceGUI:Create("SimpleGroup") + simple:SetLayout("Flow") + --simple:SetRelativeWidth(0.95) + simple:SetFullWidth(true) + w = mkbutton("MidS-H", [[not exactly an Easter egg, with sound]]) + w:SetRelativeWidth(0.2) + 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.2) + 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) + + container:AddChild(simple) + end + + w = AceGUI:Create("Spacer") w:SetRelativeWidth(0.65) w:SetHeight(15) container:AddChild(w) + w = mkbutton("Clear All & Reload", + [[No confirmation! |cffff1010Erases absolutely all> Ouro Loot saved variables and reloads the UI.]]) + w:SetRelativeWidth(0.3) + w:SetCallback("OnClick", function() + addon:_clear_SVs() -- reloads + end) + container:AddChild(w) + + container:ResumeLayout() + container:DoLayout() + AceGUI:ClearFocus() + --container:SetScroll(1000) -- scrollframe widget's max value +end + +-- Initial advanced 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). +if false and addon.DEBUG_PRINT then + controls.adv = adv_real +else + controls.adv = function (container) + 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 advanced 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) + controls.adv = { adv_real } + return addon:redisplay() + end) + container:AddChild(speedbump) + end +end + + +--------------- +-- Tab 6: Options +do + local funkified = {} + for key,f in pairs(controls) do + -- this is how TreeGroup makes unique keys + local funkykey = key:gsub('_','\001') + funkified[funkykey] = { f } + end + controls = funkified +end + +-- widget container status tables (will have things magically appear +-- inside them that we wish to preserve) +local status_for_scroll = {} +local status_for_select = { treewidth = 160 } + +-- Clicking an entry on the left tree column. +local opt_OnGroupSelected_func = function (treeg,event,category) + local catfuncs = controls[category] + if not catfuncs then + addon:horrible_horrible_error(("Category '%s' has no handler function!"):format(category:gsub('\001','_'))) + end + treeg:ReleaseChildren() + local sf = AceGUI:Create("ScrollFrame") + sf:SetStatusTable(status_for_scroll) + sf:SetLayout("Flow") + -- This forces the scrolling area to be bigger than the visible area; else + -- some of the text gets cut off without ever triggering the scrollbar. + sf.content:SetHeight(700) + for _,func in ipairs(catfuncs) do + if func(sf) then break end + end + treeg:AddChild(sf) + if treeg:GetUserData("options restore scroll") then + if status_for_scroll.scrollvalue then + sf:SetScroll(status_for_scroll.scrollvalue) + end + treeg:SetUserData("options restore scroll", false) + else + sf:SetScroll(0) + end +end + +-- Clicking the Options tab as a whole (tabs_OnGroupSelected["opt"]). +local tabs_OGS = function (container, specials) + opts = OuroLootSV_opts + + container:SetLayout("Fill") + local left = AceGUI:Create("TreeGroup") + left:SetStatusTable(status_for_select) + left:SetLayout("Fill") + left:SetFullWidth(true) + left:SetFullHeight(true) + left:EnableButtonTooltips(false) + left:SetTree(options_tree) + left:SetCallback("OnGroupSelected", opt_OnGroupSelected_func) + container:AddChild(left) + if status_for_select.selected then + left:SetUserData("options restore scroll", true) + left:SelectByValue(status_for_select.selected) + else + left:SelectByValue("basic") + end + + local 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!", + [[Queries other raid users for their addon version and current status. Results displayed on Pongs panel after five seconds.]]) + 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) +end + +addon:register_tab_control_AT_END ("opt", [[Options]], + [[Options for fine-tuning behavior]], tabs_OGS) + +-- vim:noet