Mercurial > wow > ouroloot
view 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 source
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