farmbuyer@1: local addon = select(2,...) farmbuyer@67: if addon.NOLOAD then return end farmbuyer@1: farmbuyer@1: --[[ farmbuyer@1: Purely the AceGUI-related routines, and the subroutines needed for support. farmbuyer@1: ------ Constants farmbuyer@6: ------ Globals farmbuyer@1: ------ Behind the scenes routines farmbuyer@1: ------ Main GUI Window farmbuyer@1: ------ Popup dialogs farmbuyer@1: ]] farmbuyer@1: farmbuyer@1: ------ Constants farmbuyer@1: local eoi_st_rowheight = 20 farmbuyer@83: local eoi_st_displayed_rows = math.floor(416/eoi_st_rowheight) farmbuyer@1: local eoi_st_textured_item_format = "|T%s:"..(eoi_st_rowheight-2).."|t %s[%s]|r%s" farmbuyer@84: -- This can get indexed by kind/reason/etc, and will default to lib-st's farmbuyer@84: -- default "blank" background at runtime. farmbuyer@1: local eoi_st_otherrow_bgcolortable = { farmbuyer@1: wipe = { ["r"] = 0.3, ["g"] = 0.3, ["b"] = 0.3}, farmbuyer@1: kill = { ["r"] = 0.2, ["g"] = 0.2, ["b"] = 0.2}, farmbuyer@1: time = { ["r"] = 0x0/255, ["g"] = 0x0/255, ["b"] = 1, ["a"] = 0.3}, farmbuyer@1: } farmbuyer@1: eoi_st_otherrow_bgcolortable[""] = eoi_st_otherrow_bgcolortable["kill"] farmbuyer@1: local eoi_st_otherrow_bgcolortable_default farmbuyer@1: local eoi_st_lootrow_col3_colortable = { farmbuyer@73: normal = { text = "", r = "ff", g = "ff", b = "ff" }, farmbuyer@73: shard = { text = "shard", r = "a3", g = "35", b = "ee" }, farmbuyer@73: offspec = { text = "offspec", r = "c6", g = "9b", b = "6d" }, farmbuyer@73: gvault = { text = "guild vault", r = "33", g = "ff", b = "99" }, farmbuyer@1: } farmbuyer@73: for k,v in pairs(eoi_st_lootrow_col3_colortable) do farmbuyer@73: -- for chat output by core code farmbuyer@73: v.hex = "|cff" .. v.r .. v.g .. v.b farmbuyer@73: -- for lib-st farmbuyer@73: v.r = tonumber(v.r,16)/255 farmbuyer@73: v.g = tonumber(v.g,16)/255 farmbuyer@73: v.b = tonumber(v.b,16)/255 farmbuyer@73: v.a = 1 farmbuyer@73: end farmbuyer@73: addon.disposition_colors = eoi_st_lootrow_col3_colortable farmbuyer@73: local function eoi_st_lootrow_col3_colortable_func (data, _, realrow) farmbuyer@1: local disp = data[realrow].disposition farmbuyer@73: return eoi_st_lootrow_col3_colortable[disp or 'normal'] farmbuyer@1: end farmbuyer@1: addon.time_column1_used_mt = { __index = { farmbuyer@1: [2] = {value=""}, farmbuyer@1: [3] = {value=""}, farmbuyer@1: } } farmbuyer@1: local time_column1_used_mt = addon.time_column1_used_mt farmbuyer@1: farmbuyer@1: farmbuyer@6: ------ Globals farmbuyer@1: local GUI = LibStub("AceGUI-3.0") farmbuyer@1: local flib = LibStub("LibFarmbuyer") farmbuyer@1: farmbuyer@1: local g_loot = nil farmbuyer@79: local g_uniques = nil farmbuyer@1: local g_generated = nil farmbuyer@17: local window_title = "Ouro Loot" farmbuyer@47: local dirty_tabs = nil farmbuyer@1: farmbuyer@76: local error = addon.error farmbuyer@76: local assert = addon.assert farmbuyer@76: farmbuyer@56: local pairs, ipairs, tinsert, tremove, tostring, tonumber = farmbuyer@56: pairs, ipairs, table.insert, table.remove, tostring, tonumber farmbuyer@1: farmbuyer@1: local pprint, tabledump = addon.pprint, flib.tabledump farmbuyer@11: local GetItemInfo, ITEM_QUALITY_COLORS = GetItemInfo, ITEM_QUALITY_COLORS farmbuyer@78: local GetNumRaidMembers = GetNumRaidMembers farmbuyer@1: farmbuyer@1: -- En masse forward decls of symbols defined inside local blocks farmbuyer@83: local _generate_text, _populate_text_specials, _markup farmbuyer@78: local eoi_dropdownfuncs, _tabtexts, _taborder -- filled out in gui block scope farmbuyer@72: local _do_debugging_tooltip, _hide_debugging_tooltip, _build_debugging_tooltip farmbuyer@78: local _new_rebroadcast_hyperlink farmbuyer@1: farmbuyer@49: --[[ farmbuyer@49: This is a table of callback functions, each responsible for drawing a tab farmbuyer@49: into the container passed in the first argument. Special-purpose buttons farmbuyer@49: can optionally be created (mkbutton) and added to the container in the second farmbuyer@49: argument. farmbuyer@49: ]] farmbuyer@49: local tabs_OnGroupSelected = {} farmbuyer@49: local mkbutton farmbuyer@49: local tabs_OnGroupSelected_func, tabs_generated_text_OGS farmbuyer@83: -- Similarly for the popup tips on the right side of the window. farmbuyer@83: local noob_tips = {} farmbuyer@49: farmbuyer@73: -- Class color support farmbuyer@73: local class_colors-- = {} farmbuyer@73: do farmbuyer@73: local function fill_out_class_colors() farmbuyer@73: class_colors = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS farmbuyer@73: -- If we were dependant on lib-st calling this function (via a farmbuyer@73: -- 'color' field in eoi_st_cols[2]), then this would have to be deep farmbuyer@73: -- copied and an "a=1" field added to each. But as we have to use farmbuyer@73: -- this ourselves via DoCellUpdate, we can just share tables and farmbuyer@73: -- pass an alpha value manually during cell update. farmbuyer@73: --for class,color in pairs(CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS) do farmbuyer@73: -- class_colors[class] = { r = color.r, g = color.g, b = color.b, a = 1 } farmbuyer@73: --end farmbuyer@73: end farmbuyer@73: fill_out_class_colors() farmbuyer@73: if CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS.RegisterCallback then farmbuyer@73: CUSTOM_CLASS_COLORS:RegisterCallback(fill_out_class_colors) farmbuyer@73: end farmbuyer@73: addon.class_colors = class_colors farmbuyer@73: end farmbuyer@73: farmbuyer@83: do farmbuyer@83: local replacement_colors = { farmbuyer@83: ["+"]="|cffffffff", -- white farmbuyer@83: ["<"]="|cff00ff00", -- light green farmbuyer@83: [">"]="|r" } farmbuyer@83: function _markup (t) farmbuyer@83: -- wonder if it would be worth memoizing this also farmbuyer@83: return t:gsub("[%+<>]",replacement_colors) farmbuyer@83: :gsub("([^\n])\n([^\n])", "%1 %2") farmbuyer@83: :gsub("|r\n\n", "|r\n") farmbuyer@83: end farmbuyer@83: end farmbuyer@83: farmbuyer@1: -- Working around this bug: farmbuyer@1: -- http://forums.wowace.com/showpost.php?p=295202&postcount=31 farmbuyer@1: do farmbuyer@37: local function fix_frame_level (level, ...) farmbuyer@1: for i = 1, select("#", ...) do farmbuyer@1: local button = select(i, ...) farmbuyer@1: button:SetFrameLevel(level) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@37: local function fix_menu_frame_levels() farmbuyer@37: local f = _G.DropDownList1 farmbuyer@1: local i = 1 farmbuyer@1: while f do farmbuyer@37: fix_frame_level (f:GetFrameLevel() + 2, f:GetChildren()) farmbuyer@1: i = i + 1 farmbuyer@1: f = _G["DropDownList"..i] farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- To fix Blizzard's bug caused by the new "self:SetFrameLevel(2);" farmbuyer@37: hooksecurefunc("UIDropDownMenu_CreateFrames", fix_menu_frame_levels) farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: ------ Behind the scenes routines farmbuyer@1: -- Text generation farmbuyer@1: do farmbuyer@1: local text_gen_funcs, specials_gen_funcs = {}, {} farmbuyer@1: local accumulator = {} farmbuyer@1: farmbuyer@1: -- Can do clever things by passing other halting points as zero farmbuyer@84: function addon:zero_printed_fenceposts (zero) farmbuyer@1: for t in pairs(text_gen_funcs) do farmbuyer@1: g_loot.printed[t] = zero or g_loot.printed[t] or 0 farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@10: function addon:registered_textgen_iter() farmbuyer@10: return pairs(text_gen_funcs) farmbuyer@10: end farmbuyer@10: farmbuyer@1: -- This function is called during load, so be careful! farmbuyer@1: function addon:register_text_generator (text_type, title, description, generator, opt_specgen) farmbuyer@1: if type(generator) ~= 'function' then farmbuyer@1: error(("Generator for text type '%s' must be a function!"):format(text_type)) farmbuyer@1: end farmbuyer@1: _tabtexts[text_type] = { title=title, desc=description } farmbuyer@57: self:tabposition_insert (text_type) farmbuyer@1: text_gen_funcs[text_type] = generator farmbuyer@1: specials_gen_funcs[text_type] = opt_specgen farmbuyer@47: dirty_tabs = true farmbuyer@1: end farmbuyer@1: farmbuyer@84: -- These two called by tabs_generated_text_OGS farmbuyer@84: -- tabs_OnGroupSelected_func will catch propagated errors farmbuyer@1: function _generate_text (text_type) farmbuyer@1: local f = text_gen_funcs[text_type] farmbuyer@1: if not f then farmbuyer@1: error(("Generator called for unregistered text type '%s'."):format(text_type)) farmbuyer@1: end farmbuyer@1: g_generated = g_generated or {} farmbuyer@1: g_loot[text_type] = g_loot[text_type] or "" farmbuyer@1: farmbuyer@1: if g_loot.printed[text_type] >= #g_loot then return false end farmbuyer@76: assert (addon.loot_clean == #g_loot, farmbuyer@76: tostring(addon.loot_clean) .. " ~= " .. #g_loot) farmbuyer@1: -- if glc is nil, #==0 test already returned farmbuyer@1: farmbuyer@1: local ok,ret = pcall (f, text_type, g_loot, g_loot.printed[text_type], g_generated, accumulator) farmbuyer@1: if not ok then farmbuyer@1: error(("ERROR: text generator '%s' failed: %s"):format(text_type, ret)) farmbuyer@1: end farmbuyer@1: if ret then farmbuyer@1: g_loot.printed[text_type] = #g_loot farmbuyer@1: g_generated[text_type] = (g_generated[text_type] or "") .. table.concat(accumulator,'\n') .. '\n' farmbuyer@1: end farmbuyer@1: wipe(accumulator) farmbuyer@1: return ret farmbuyer@1: end farmbuyer@1: function _populate_text_specials (editbox, specials, mkb, text_type) farmbuyer@1: local f = specials_gen_funcs[text_type] farmbuyer@1: if not f then return end farmbuyer@84: local ok,ret = pcall (f, text_type, editbox, specials, mkb) farmbuyer@84: if not ok then farmbuyer@84: error(("ERROR: special widget creation for '%s' failed: %s"):format(text_type, ret)) farmbuyer@84: end farmbuyer@1: end farmbuyer@49: farmbuyer@49: -- LOD tab has been clicked on. farmbuyer@49: local function _handle_LOD (tabs_container,specials,tabtitle) farmbuyer@51: -- "tabtitle" here is the name in _taborder, not the colorized string farmbuyer@49: local what = _tabtexts[tabtitle] farmbuyer@49: local addon_index = what.LOD farmbuyer@49: local function LOAD() farmbuyer@49: _tabtexts[tabtitle] = nil farmbuyer@57: addon:tabposition_remove_and_remember (tabtitle) farmbuyer@49: local loaded, whynot = LoadAddOn(addon_index) farmbuyer@57: local tabdelta = addon:tabposition_restore() farmbuyer@49: if loaded then farmbuyer@57: addon:Print("%s loaded, %d |4tab:tabs; added.", tabtitle, tabdelta) farmbuyer@49: else farmbuyer@49: what.disabled = true farmbuyer@49: _tabtexts[tabtitle] = what -- restore this for mouseovers farmbuyer@49: addon:Print("%s could not load (game client reason was '%s').", tabtitle, whynot) farmbuyer@49: DisableAddOn(addon_index) farmbuyer@49: end farmbuyer@49: dirty_tabs = true farmbuyer@51: return addon:OpenMainDisplayToTab(tabtitle) or addon:BuildMainDisplay() farmbuyer@49: end farmbuyer@49: addon.display:Hide() farmbuyer@49: if what.LOD_enabled then farmbuyer@49: -- totally loadable, go for it farmbuyer@49: LOAD() farmbuyer@49: else farmbuyer@49: -- was disabled at addons menu farmbuyer@49: StaticPopupDialogs["OUROL_LOD_DISABLED"] = flib.StaticPopup{ farmbuyer@57: text = tabtitle.." was disabled at the character selection screen. Do you want to enable it?", farmbuyer@49: button1 = YES, farmbuyer@49: button2 = NO, farmbuyer@49: OnAccept = function() farmbuyer@49: EnableAddOn(addon_index) farmbuyer@49: LOAD() farmbuyer@49: end, farmbuyer@49: OnCancel = function() farmbuyer@49: addon:BuildMainDisplay() farmbuyer@49: end, farmbuyer@49: OnHide = function() farmbuyer@49: StaticPopupDialogs["OUROL_LOD_DISABLED"] = nil farmbuyer@49: end, farmbuyer@49: } farmbuyer@49: StaticPopup_Show("OUROL_LOD_DISABLED") farmbuyer@49: end farmbuyer@49: end farmbuyer@49: farmbuyer@49: -- Add a clickable tab that brings the real module in. Since gui_init has farmbuyer@49: -- already been called, we flag the dirty bit and let the main building farmbuyer@49: -- routine handle it like any other plugin. farmbuyer@49: function addon:_gui_add_LOD_tab (tabtitle, folder, addon_index, enabled_p, why_not) farmbuyer@49: _tabtexts[tabtitle] = { farmbuyer@51: title = ("|cffff0000(%s)|r"):format(tabtitle), farmbuyer@57: desc = ("Plugin '|cffff0000%s|r' is not loaded yet. Click the tab to load it now."):format(folder), farmbuyer@49: LOD = addon_index, farmbuyer@49: LOD_enabled = enabled_p, farmbuyer@49: LOD_why_not = why_not, farmbuyer@49: } farmbuyer@49: tabs_OnGroupSelected[tabtitle] = _handle_LOD farmbuyer@57: self:tabposition_insert (tabtitle) farmbuyer@49: dirty_tabs = true farmbuyer@49: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: --[[ farmbuyer@1: The g_loot table is populated only with "behavior-relevant" data (names, farmbuyer@1: links, etc). This function runs through it and fills out the "display- farmbuyer@1: relevant" bits (icons, user-friendly labels, etc). Everything from the farmbuyer@1: loot_clean index to the end of the table is filled out, loot_clean is farmbuyer@1: updated. Override the starting point with the argument. farmbuyer@1: farmbuyer@1: XXX blizzard's scrolling update and lib-st keep finding some way of displaying farmbuyer@1: the grid without ever calling the hooked refresh, thereby skipping this farmbuyer@1: function and erroring on missing columnar data. fuckit. from now on farmbuyer@1: this function gets called everywhere, all the time, and loops over the farmbuyer@1: entire goddamn table each time. If we can't find blizz's scrollframe bugs, farmbuyer@1: we'll just work around them. Sorry for your smoking CPU. farmbuyer@1: farmbuyer@1: FIXME just move this functionality to a per-entry function and call it once farmbuyer@1: in _addlootentry. --actually no, then the columnar data won't be updated once farmbuyer@1: the backend data is changed on the fly. farmbuyer@1: ]] farmbuyer@1: do farmbuyer@1: function addon:_fill_out_eoi_data (opt_starting_index) farmbuyer@1: if #g_loot < 1 then farmbuyer@1: --pprint('_f_o_e_d', "#g_loot<1") farmbuyer@1: self.loot_clean = nil farmbuyer@1: opt_starting_index = nil farmbuyer@1: end farmbuyer@1: for i = (opt_starting_index or self.loot_clean or 1), #g_loot do farmbuyer@1: local e = g_loot[i] farmbuyer@1: if e == nil then farmbuyer@1: self.loot_clean = nil farmbuyer@1: pprint('_f_o_e_d', "index",i,"somehow still in loop past",#g_loot,"bailing") farmbuyer@1: return farmbuyer@1: end farmbuyer@1: farmbuyer@65: local display_bcast_from = OuroLootSV_opts.display_bcast_from farmbuyer@1: -- XXX FIXME a major weakness here is that we're constantly replacing farmbuyer@1: -- what's already been created. Lots of garbage. Trying to detect what farmbuyer@1: -- actually needs to be replaced is even worse. We'll live with farmbuyer@1: -- garbage for now. farmbuyer@1: if e.kind == 'loot' then farmbuyer@11: local textured = eoi_st_textured_item_format:format (e.itexture, ITEM_QUALITY_COLORS[e.quality].hex, e.itemname, e.count or "") farmbuyer@1: e.cols = { farmbuyer@1: {value = textured}, farmbuyer@1: {value = e.person}, farmbuyer@73: {} farmbuyer@1: } farmbuyer@1: -- This is horrible. Must do better. farmbuyer@1: if e.extratext then for k,v in pairs(eoi_st_lootrow_col3_colortable) do farmbuyer@1: if v.text == e.extratext then farmbuyer@73: e.disposition = k ~= 'normal' and k or nil farmbuyer@1: --e.extratext = nil, not feasible farmbuyer@1: break farmbuyer@1: end farmbuyer@1: end end farmbuyer@73: local ex = eoi_st_lootrow_col3_colortable[e.disposition or 'normal'].text farmbuyer@65: if e.bcast_from and display_bcast_from and e.extratext then farmbuyer@1: ex = e.extratext .. " (from " .. e.bcast_from .. ")" farmbuyer@65: elseif e.bcast_from and display_bcast_from then farmbuyer@73: ex = ex .. (e.disposition and " " or "") farmbuyer@73: .. "(from " .. e.bcast_from .. ")" farmbuyer@1: elseif e.extratext then farmbuyer@1: ex = e.extratext farmbuyer@1: end farmbuyer@1: e.cols[3].value = ex farmbuyer@1: farmbuyer@1: elseif e.kind == 'boss' then farmbuyer@1: local v farmbuyer@52: e.duration = e.duration or 0 -- can occasionally miss getting set farmbuyer@1: if e.reason == 'kill' then farmbuyer@1: if e.attempts == 1 then farmbuyer@1: v = "one-shot" farmbuyer@1: else farmbuyer@84: v = ("kill on %d%s attempt"):format(e.attempts or 0, farmbuyer@84: e.attempts==2 and "nd" or e.attempts==3 and "rd" or "th") farmbuyer@1: end farmbuyer@1: v = ("%s (%d:%.2d)"):format(v, math.floor(e.duration/60), math.floor(e.duration%60)) farmbuyer@1: elseif e.reason == 'wipe' then farmbuyer@1: v = ("wipe (%d:%.2d)"):format(math.floor(e.duration/60), math.floor(e.duration%60)) farmbuyer@1: end farmbuyer@1: e.cols = { farmbuyer@55: {value = e.bossname}, farmbuyer@1: {value = e.instance}, farmbuyer@1: {value = v or ""}, farmbuyer@1: } farmbuyer@1: farmbuyer@1: elseif e.kind == 'time' then farmbuyer@1: e.cols = setmetatable({ farmbuyer@1: {value=e.startday.text}, farmbuyer@1: }, time_column1_used_mt) farmbuyer@1: --[[e.cols = { farmbuyer@1: {value=e.startday.text}, farmbuyer@1: {value=""}, farmbuyer@1: {value=""}, farmbuyer@1: }]] farmbuyer@1: farmbuyer@1: end farmbuyer@1: end farmbuyer@1: self.loot_clean = #g_loot farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: do farmbuyer@1: function addon:_fill_out_hist_data (opt_starting_index) farmbuyer@6: local new, del = flib.new, flib.del farmbuyer@6: farmbuyer@1: -- Clearing history finishes this function with #hist==0 and hist_clean==0. farmbuyer@1: -- The next call typically detects this (#<1) and handles it. If loot is farmbuyer@1: -- recorded before then, it results in hist_clean==0 and #hist==1, which farmbuyer@1: -- breaks the first iteration of the loop. Thus, the "extra" test here: farmbuyer@1: if #self.history < 1 or self.hist_clean == 0 then farmbuyer@1: self.hist_clean = nil farmbuyer@1: opt_starting_index = nil farmbuyer@1: end farmbuyer@1: if not self.history.st then farmbuyer@6: --print"creating ST!" farmbuyer@1: self.history.st = { farmbuyer@4: --[[{ kind = "realm", farmbuyer@1: cols = setmetatable({ farmbuyer@1: { value = self.history.realm }, farmbuyer@1: }, time_column1_used_mt) farmbuyer@4: }]] farmbuyer@1: } farmbuyer@1: end farmbuyer@6: farmbuyer@6: -- for now farmbuyer@6: if self.hist_clean == #self.history then return end farmbuyer@6: farmbuyer@1: local st = self.history.st farmbuyer@6: --print("starting history loop, #st ==", #st, "#history ==", #self.history) farmbuyer@6: for i,t in ipairs(st) do farmbuyer@6: del(t.cols[1]) farmbuyer@6: del(t.cols[2]) farmbuyer@6: del(t.cols[3]) farmbuyer@6: del(t.cols) farmbuyer@6: del(t) farmbuyer@6: st[i] = nil farmbuyer@6: end farmbuyer@1: farmbuyer@6: --for i = (opt_starting_index or self.hist_clean or 1), #self.history do farmbuyer@6: local cache_okay = true farmbuyer@6: for pi,player in ipairs(self.history) do farmbuyer@6: local col1 = new() farmbuyer@6: col1.OLi = pi farmbuyer@6: col1.OLn = #player farmbuyer@6: col1.value = player.name -- may spiffy this up in future farmbuyer@1: farmbuyer@73: for li,unique in ipairs(player.unique) do farmbuyer@6: local col2 = new() farmbuyer@6: col2.OLi = li farmbuyer@84: col2.OLu = unique farmbuyer@6: local col3 = new() farmbuyer@73: col3.value = player.when[unique] farmbuyer@6: farmbuyer@73: local id = player.id[unique] farmbuyer@73: local itexture = GetItemIcon(id) farmbuyer@73: local iname, ilink, iquality = GetItemInfo(id) farmbuyer@4: local textured farmbuyer@4: if itexture and iname then farmbuyer@6: textured = eoi_st_textured_item_format:format (itexture, farmbuyer@73: ITEM_QUALITY_COLORS[iquality].hex, iname, player.count[unique] or "") farmbuyer@4: else farmbuyer@6: textured = eoi_st_textured_item_format:format ([[ICONS\INV_Misc_QuestionMark]], farmbuyer@19: ITEM_QUALITY_COLORS[ITEM_QUALITY_COMMON].hex, 'UNKNOWN - REDISPLAY LATER', "") farmbuyer@6: cache_okay = false farmbuyer@4: end farmbuyer@6: col2.value = textured farmbuyer@6: farmbuyer@84: -- To facilitate sharing lib-st routines between EOI and this farmbuyer@84: -- one, we do some of the same fields: 'kind' and 'itemlink'. farmbuyer@84: -- These aren't used outside of the GUI. These become our data farmbuyer@84: -- table arguments to the lib-st routines (thus 'e' locals). farmbuyer@6: local dotcols = new (col1, col2, col3) farmbuyer@6: local st_entry = new() farmbuyer@84: st_entry.kind = 'hist' farmbuyer@6: st_entry.OLwho = player.name farmbuyer@6: st_entry.cols = dotcols farmbuyer@16: st_entry.itemlink = ilink -- for onenter and onclick farmbuyer@6: tinsert (st, st_entry) farmbuyer@1: end farmbuyer@6: end farmbuyer@1: farmbuyer@6: --print("finished history loop, #st ==", #st) farmbuyer@6: self.hist_clean = cache_okay and #self.history or nil farmbuyer@1: end farmbuyer@72: end farmbuyer@6: farmbuyer@74: -- Debugging tooltip (unfortunately managed by global and semi-global state farmbuyer@74: -- rather than passing around stack parameters) farmbuyer@74: do farmbuyer@74: local debug_tt farmbuyer@74: farmbuyer@74: local _creators, _builders = {}, {} farmbuyer@73: local function _create_tooltip() farmbuyer@74: local which = assert(tonumber(_do_debugging_tooltip)) farmbuyer@74: if type(_creators[which]) == 'function' then farmbuyer@74: _creators[which]() farmbuyer@74: end farmbuyer@74: debug_tt = _creators[which] farmbuyer@74: end farmbuyer@74: function _build_debugging_tooltip (parent, index) farmbuyer@74: local which = assert(tonumber(_do_debugging_tooltip)) farmbuyer@74: if type(_builders[which]) == 'function' then farmbuyer@74: _builders[which](parent,index) farmbuyer@74: end farmbuyer@74: end farmbuyer@74: function _hide_debugging_tooltip() farmbuyer@74: if debug_tt then debug_tt:Hide() end farmbuyer@74: end farmbuyer@74: farmbuyer@74: -- 2 == /dump farmbuyer@74: _creators[2] = function() farmbuyer@74: local tt = CreateFrame("GameTooltip") farmbuyer@73: UIParentLoadAddOn("Blizzard_DebugTools") farmbuyer@73: farmbuyer@73: tt:SetBackdrop{ farmbuyer@73: bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], farmbuyer@73: edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], farmbuyer@73: tile = true, farmbuyer@73: tileSize = 8, farmbuyer@73: edgeSize = 12, farmbuyer@73: insets = { left = 2, right = 2, top = 2, bottom = 2 } farmbuyer@73: } farmbuyer@73: tt:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, farmbuyer@73: TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b) farmbuyer@73: tt:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, farmbuyer@73: TOOLTIP_DEFAULT_COLOR.b) farmbuyer@73: tt:SetMovable(false) farmbuyer@73: tt:EnableMouse(false) farmbuyer@73: tt:SetFrameStrata("TOOLTIP") farmbuyer@73: tt:SetToplevel(true) farmbuyer@73: tt:SetClampedToScreen(true) farmbuyer@73: farmbuyer@73: local font = CreateFont("OuroLootDebugFont") farmbuyer@73: font:CopyFontObject(GameTooltipTextSmall) farmbuyer@73: if IsAddOnLoaded"tekticles" then -- maybe check for one of the sharedmedia things? farmbuyer@73: font:SetFont([[Interface\AddOns\tekticles\Calibri.ttf]], 9) farmbuyer@73: else farmbuyer@73: font:SetFont([[Fonts\FRIZQT__.TTF]], 9) farmbuyer@73: end farmbuyer@73: farmbuyer@73: local left, right, prevleft farmbuyer@73: -- Only create as many lines as we might need (the auto growth farmbuyer@73: -- by Add*Line does odd things sometimes). farmbuyer@73: for i = 1, math.max(DEVTOOLS_MAX_ENTRY_CUTOFF,15)+5 do farmbuyer@73: prevleft = left farmbuyer@73: left = tt:CreateFontString(nil,"ARTWORK") farmbuyer@73: right = tt:CreateFontString(nil,"ARTWORK") farmbuyer@73: left:SetFontObject(font) farmbuyer@73: right:SetFontObject(font) farmbuyer@73: tt:AddFontStrings(left,right) farmbuyer@73: if prevleft then farmbuyer@73: left:SetPoint("TOPLEFT",prevleft,"BOTTOMLEFT",0,-2) farmbuyer@73: else farmbuyer@73: left:SetPoint("TOPLEFT",10,-10) -- top line farmbuyer@73: end farmbuyer@73: right:SetPoint("RIGHT",left,"LEFT") farmbuyer@73: end farmbuyer@73: tt.AddMessage = tt.AddLine farmbuyer@73: farmbuyer@74: _creators[2] = tt farmbuyer@73: end farmbuyer@73: farmbuyer@74: _builders[2] = function (parent, index) farmbuyer@73: local e = g_loot[index]; assert(type(e)=='table') farmbuyer@74: _create_tooltip() farmbuyer@74: debug_tt:SetOwner (parent, "ANCHOR_LEFT", -15, -5) farmbuyer@74: debug_tt:ClearLines() farmbuyer@73: farmbuyer@73: local real = DEFAULT_CHAT_FRAME farmbuyer@74: DEFAULT_CHAT_FRAME = debug_tt farmbuyer@73: DevTools_Dump{ [index] = e } farmbuyer@73: DEFAULT_CHAT_FRAME = real farmbuyer@73: farmbuyer@74: debug_tt:Show() farmbuyer@73: end farmbuyer@73: farmbuyer@72: -- Now here's a thing unheard-of. A tooltip not inheriting from the big farmbuyer@72: -- memory-wasteful template, but also not intended merely for scanning farmbuyer@72: -- invisible tooltips. farmbuyer@72: -- (If this ever grows beyond a text dump, then replace it with libqtip.) farmbuyer@74: -- farmbuyer@74: -- Fields to put in the fixed-fields tooltip (maybe move these into the farmbuyer@74: -- options window if I spend too much time fiddling). farmbuyer@74: local loot = {'person', 'id', 'unique', 'disposition', 'count', 'variant'} farmbuyer@74: local boss = {'bossname', 'reason', 'instance', 'maxsize', 'duration', 'raidersnap'} farmbuyer@74: farmbuyer@74: -- 3 == fixed fields farmbuyer@74: _creators[3] = function() farmbuyer@74: local tt = CreateFrame("GameTooltip") farmbuyer@72: farmbuyer@72: tt:SetBackdrop{ farmbuyer@72: bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], farmbuyer@72: edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], farmbuyer@72: tile = true, farmbuyer@72: tileSize = 8, farmbuyer@72: edgeSize = 12, farmbuyer@72: insets = { left = 2, right = 2, top = 2, bottom = 2 } farmbuyer@72: } farmbuyer@72: tt:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, farmbuyer@72: TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b) farmbuyer@72: tt:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, farmbuyer@72: TOOLTIP_DEFAULT_COLOR.b) farmbuyer@72: tt:SetMovable(false) farmbuyer@72: tt:EnableMouse(false) farmbuyer@72: tt:SetFrameStrata("TOOLTIP") farmbuyer@72: tt:SetToplevel(true) farmbuyer@72: tt:SetClampedToScreen(true) farmbuyer@72: farmbuyer@72: local font = GameTooltipTextSmall farmbuyer@72: local left, right, prevleft farmbuyer@72: -- Only create as many lines as we might need (the auto growth farmbuyer@72: -- by Add*Line does odd things sometimes). farmbuyer@72: for i = 1, math.max(#loot,#boss)+2 do farmbuyer@72: prevleft = left farmbuyer@72: left = tt:CreateFontString(nil,"ARTWORK") farmbuyer@72: right = tt:CreateFontString(nil,"ARTWORK") farmbuyer@72: left:SetFontObject(font) farmbuyer@72: right:SetFontObject(font) farmbuyer@72: tt:AddFontStrings(left,right) farmbuyer@72: if prevleft then farmbuyer@72: left:SetPoint("TOPLEFT",prevleft,"BOTTOMLEFT",0,-2) farmbuyer@72: else farmbuyer@72: left:SetPoint("TOPLEFT",10,-10) -- top line farmbuyer@72: end farmbuyer@72: right:SetPoint("RIGHT",left,"LEFT") farmbuyer@72: end farmbuyer@72: farmbuyer@74: _creators[3] = tt farmbuyer@72: end farmbuyer@72: farmbuyer@74: _builders[3] = function (parent, index) farmbuyer@72: local e = g_loot[index]; assert(type(e)=='table') farmbuyer@74: _create_tooltip() farmbuyer@74: debug_tt:SetOwner (parent, "ANCHOR_LEFT", -15, -5) farmbuyer@74: debug_tt:ClearLines() farmbuyer@72: farmbuyer@72: -- change these, change the +2 above farmbuyer@74: debug_tt:AddDoubleLine (tostring(index), tostring(e), 1,1,1) farmbuyer@74: debug_tt:AddDoubleLine ('kind', e.kind, 1,1,1) farmbuyer@72: farmbuyer@72: local source = (e.kind == 'loot' and loot) or (e.kind == 'boss' and boss) farmbuyer@72: if source then farmbuyer@72: for _,field in ipairs(source) do farmbuyer@74: debug_tt:AddDoubleLine (field, tostring(e[field]), 1,1,1, 0,156/255,1) farmbuyer@72: end farmbuyer@72: end farmbuyer@74: debug_tt:Show() farmbuyer@72: end farmbuyer@1: end farmbuyer@1: farmbuyer@78: do farmbuyer@78: local rebroadcast_map -- XXX weaken this somehow? farmbuyer@78: farmbuyer@78: local function onclick (self, ident) farmbuyer@79: -- Since an arbitrary number of insert/delete ops can happen between farmbuyer@79: -- now and (potentially) clicking on the hyperlink, we can't depend on farmbuyer@79: -- the row index. Force the uniques cache to re-search (research?) it. farmbuyer@79: local u = assert(rebroadcast_map[ident]) farmbuyer@79: local cache = g_uniques:SEARCH(u) farmbuyer@79: -- A missing history entry isn't necessarily an error here, but we farmbuyer@79: -- need a loot entry to go further. farmbuyer@79: if cache.loot then farmbuyer@79: eoi_dropdownfuncs["Rebroadcast this loot entry"](cache.loot) farmbuyer@79: else farmbuyer@79: addon:Print("...guh? Entry was recorded with tag <%s> but cannot now be found!", u) farmbuyer@79: end farmbuyer@79: -- delete the entry maybe? farmbuyer@78: end farmbuyer@78: farmbuyer@79: function _new_rebroadcast_hyperlink (u) farmbuyer@78: rebroadcast_map = rebroadcast_map or flib.new() farmbuyer@78: local clicky, ident = addon.format_hypertext( farmbuyer@78: -- same color sequence as what DBM uses to announce pizza timers, farmbuyer@78: -- which looks reasonably pleasing farmbuyer@78: [[Broadcast this entry]], "|cff3588ff", onclick) farmbuyer@79: rebroadcast_map[ident] = u farmbuyer@78: return clicky farmbuyer@78: end farmbuyer@78: end farmbuyer@78: farmbuyer@83: -- UI tips window farmbuyer@83: local hide_noobtips_frame = flib.nullfunc farmbuyer@83: local function get_noobtips_frame() farmbuyer@83: local f = CreateFrame("Frame") farmbuyer@83: f:SetBackdrop{ farmbuyer@83: bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], farmbuyer@83: --bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]], farmbuyer@83: edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], farmbuyer@83: --edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]], farmbuyer@83: tile = true, farmbuyer@83: tileSize = 8, farmbuyer@83: --tileSize = 32, farmbuyer@83: edgeSize = 12, farmbuyer@83: --edgeSize = 32, farmbuyer@83: insets = { left = 2, right = 2, top = 2, bottom = 2 } farmbuyer@83: --insets = { left = 11, right = 12, top = 12, bottom = 11 } farmbuyer@83: } farmbuyer@83: f:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, farmbuyer@83: TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b) farmbuyer@83: f:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, farmbuyer@83: TOOLTIP_DEFAULT_COLOR.b) farmbuyer@83: f:SetMovable(false) farmbuyer@83: f:EnableMouse(false) farmbuyer@83: f:SetFrameStrata("TOOLTIP") farmbuyer@83: f:SetToplevel(true) farmbuyer@83: f:SetClampedToScreen(true) farmbuyer@83: f:SetWidth(220) farmbuyer@83: local t = f:CreateFontString (nil, "ARTWORK", "GameFontHighlightSmall") farmbuyer@83: --t:SetPoint ("TOPLEFT", f, "TOPLEFT", 14, -15) farmbuyer@83: t:SetPoint ("TOPLEFT", f, "TOPLEFT", 10, -10) farmbuyer@83: t:SetJustifyH("LEFT") farmbuyer@83: farmbuyer@83: f.text = t farmbuyer@83: f.DoTextWork = function (self, text) farmbuyer@83: self.text:SetText(text) farmbuyer@83: self.text:SetWidth (self:GetWidth() - 20) farmbuyer@83: self:SetHeight (self.text:GetHeight() + 20) farmbuyer@83: end farmbuyer@83: farmbuyer@83: get_noobtips_frame = function() return f end farmbuyer@83: hide_noobtips_frame = function() f:Hide() end farmbuyer@83: return f farmbuyer@83: end farmbuyer@83: farmbuyer@1: farmbuyer@1: ------ Main GUI Window farmbuyer@37: local _d -- display when it's open, eoiST when it's not farmbuyer@1: local function setstatus(txt) _d:SetStatusText(txt) end farmbuyer@1: local function statusy_OnLeave() setstatus("") end farmbuyer@1: local tabgroup_tabs farmbuyer@1: farmbuyer@1: --[[ farmbuyer@1: Controls for the tabs on the left side of the main display. farmbuyer@1: ]] farmbuyer@57: farmbuyer@57: -- The _tabtexts and _taborder tables have distressingly wide visibility. farmbuyer@57: -- They are used to build the tabgroup_tabs array fed to TabGroup, and for the farmbuyer@57: -- official source of mouseover tab titles, etc. Not completely encapsulated farmbuyer@57: -- because we need to reach in and fiddle too often to be worth it. farmbuyer@1: _tabtexts = { farmbuyer@1: ["eoi"] = {title=[[Loot]], desc=[[Observed loot, plus boss kills and other events of interest]]}, farmbuyer@1: ["hist"] = {title=[[History]], desc=[[A short semi-permanent record]]}, farmbuyer@1: ["help"] = {title=[[Help]], desc=[[Instructions, reminders, and tips for non-obvious features]]}, farmbuyer@1: ["opt"] = {title=[[Options]], desc=[[Options for fine-tuning behavior]]}, farmbuyer@1: } farmbuyer@1: _taborder = { "eoi", "hist", "help", "opt" } farmbuyer@1: farmbuyer@57: do farmbuyer@57: local next_insertion_position = 2 -- position in _taborder farmbuyer@57: local removed, saved_offset farmbuyer@57: farmbuyer@57: function addon:tabposition_insert (tabcode) farmbuyer@57: tinsert (_taborder, next_insertion_position, tabcode) farmbuyer@57: next_insertion_position = next_insertion_position + 1 farmbuyer@57: end farmbuyer@57: farmbuyer@57: -- These two functions are push/pop pairs, sort of. The first removes farmbuyer@57: -- a tab and prepares to insert more tab(s) in its place. The second farmbuyer@57: -- returns the "next tab goes here" marker back to the proper end. (And farmbuyer@57: -- doing all 3 adjustments below at once is amazingly hard to read.) farmbuyer@57: function addon:tabposition_remove_and_remember (tabcode) farmbuyer@57: assert(not removed) -- enforce stack-ish discipline farmbuyer@57: for i = 2, #_taborder do farmbuyer@57: if _taborder[i] == tabcode then farmbuyer@57: tremove (_taborder, i) farmbuyer@57: saved_offset = next_insertion_position - i - 1 farmbuyer@57: removed, next_insertion_position = i, i farmbuyer@57: return farmbuyer@57: end farmbuyer@57: end farmbuyer@57: error(("'%s' not used as a tab-text code"):format(tabcode)) farmbuyer@57: end farmbuyer@57: function addon:tabposition_restore() farmbuyer@57: assert(removed) farmbuyer@57: local count = next_insertion_position - removed farmbuyer@57: next_insertion_position = next_insertion_position + saved_offset farmbuyer@57: removed, saved_offset = nil, nil farmbuyer@57: return count farmbuyer@57: end farmbuyer@57: end farmbuyer@57: farmbuyer@57: -- Done at startup, and whenever we've changed the population of tabs. farmbuyer@79: function addon:gui_init (loot_pointer, uniques_pointer) farmbuyer@71: g_loot = assert(loot_pointer, "something went wrong at startup") farmbuyer@79: g_uniques = assert(uniques_pointer, "something went wrong at startup") farmbuyer@1: g_generated = nil farmbuyer@1: tabgroup_tabs = {} farmbuyer@17: window_title = "Ouro Loot " .. self.revision farmbuyer@46: -- TabGroup stretches out the tabs to fill the row but only if >75% of the farmbuyer@46: -- row is already full. It turns out that not doing this looks like ass. farmbuyer@46: -- If we won't have enough tabs to trigger this on its own, pad out the tab farmbuyer@46: -- titles (not looking quite as nice, ah well) to force it to trigger. farmbuyer@46: local fmtstr = #_taborder > 6 and "%s" or " %s " farmbuyer@49: for i,name in ipairs(_taborder) do farmbuyer@49: tabgroup_tabs[i] = { farmbuyer@49: value = name, farmbuyer@49: text = fmtstr:format(_tabtexts[name].title), farmbuyer@49: disabled = _tabtexts[name].disabled, farmbuyer@49: } farmbuyer@1: -- By default, tabs are editboxes with generated text farmbuyer@49: if not tabs_OnGroupSelected[name] then farmbuyer@49: tabs_OnGroupSelected[name] = tabs_generated_text_OGS farmbuyer@1: end farmbuyer@1: end farmbuyer@47: dirty_tabs = nil farmbuyer@1: end farmbuyer@1: farmbuyer@37: --[[ farmbuyer@84: Dropdown menu handling; this has grown in ungainly directions. farmbuyer@37: ]] farmbuyer@37: -- forward decls farmbuyer@1: local eoi_editcell farmbuyer@1: farmbuyer@37: local dropdownfuncs farmbuyer@37: do farmbuyer@37: local ddf_mt = { farmbuyer@37: __index = { farmbuyer@37: -- more stuff should be moved into this table farmbuyer@37: [CLOSE] = function() CloseDropDownMenus() end, farmbuyer@37: } farmbuyer@37: } farmbuyer@37: dropdownfuncs = function(t) farmbuyer@37: return setmetatable(t, ddf_mt) farmbuyer@37: end farmbuyer@37: end farmbuyer@37: farmbuyer@1: local function dropdownmenu_handler (ddbutton, subfunc, arg) farmbuyer@84: local i = _d and _d.GetUserData and _d:GetUserData("DD index") farmbuyer@26: if i then farmbuyer@26: subfunc(i,arg) farmbuyer@84: _d:GetUserData("which ST"):OuroLoot_Refresh(i) farmbuyer@26: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: local function gen_easymenu_table (initial, list, funcs) farmbuyer@1: for _,tag in ipairs(list) do farmbuyer@1: local name, arg, tiptext farmbuyer@1: name, tiptext = strsplit('|',tag) farmbuyer@1: name, arg = strsplit('%',name) farmbuyer@1: if name == "--" then farmbuyer@1: tinsert (initial, { farmbuyer@6: disabled = true, notCheckable = true, text = "", farmbuyer@1: }) farmbuyer@1: else farmbuyer@1: if not funcs[name] then farmbuyer@1: error(("'%s' not defined as a dropdown function"):format(name)) farmbuyer@1: end farmbuyer@1: tinsert (initial, { farmbuyer@1: text = name, farmbuyer@1: func = dropdownmenu_handler, farmbuyer@1: arg1 = funcs[name], farmbuyer@1: arg2 = arg, farmbuyer@1: notCheckable = true, farmbuyer@25: tooltipOnButton = true, farmbuyer@25: tooltipWhileDisabled = true, farmbuyer@1: tooltipTitle = tiptext and name or nil, farmbuyer@1: tooltipText = tiptext, farmbuyer@1: }) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: return initial farmbuyer@1: end farmbuyer@1: farmbuyer@1: local dropdownmenuframe = CreateFrame("Frame", "OuroLootDropDownMenu", nil, "UIDropDownMenuTemplate") farmbuyer@1: farmbuyer@37: farmbuyer@37: -- Tab 1: Events Of Interest farmbuyer@37: -- This actually takes up quite a bit of the file. farmbuyer@37: eoi_dropdownfuncs = dropdownfuncs{ farmbuyer@1: df_INSERT = function(rowi,text) farmbuyer@1: local which = (text == 'loot') and "OUROL_EOI_INSERT_LOOT" or "OUROL_EOI_INSERT" farmbuyer@1: local dialog = StaticPopup_Show(which,text) farmbuyer@16: dialog.editBox:SetScript("OnTextChanged",StaticPopup_EditBoxOnTextChanged) farmbuyer@1: dialog.data = {rowindex=rowi, display=_d, kind=text} farmbuyer@1: end, farmbuyer@1: farmbuyer@1: df_DELETE = function(rowi) farmbuyer@84: local gone = tremove (g_loot, rowi) farmbuyer@1: addon:Print("Removed %s.", farmbuyer@55: gone.itemlink or gone.bossname or gone.startday.text) farmbuyer@36: if gone.kind == 'loot' and IsShiftKeyDown() then farmbuyer@84: local okay,err = addon:_delHistoryEntry (gone) farmbuyer@84: if okay then farmbuyer@84: addon:Print("Removed history entry %s from '%s'.", farmbuyer@84: gone.itemlink, gone.person) farmbuyer@84: else farmbuyer@84: addon:Print(err) farmbuyer@84: end farmbuyer@36: end farmbuyer@1: end, farmbuyer@1: farmbuyer@1: ["Delete remaining entries for this day"] = function(rowi,kind) farmbuyer@28: -- if kind is boss, also need to stop at new timestamp farmbuyer@28: local fencepost = addon._find_timeboss_fencepost (kind, rowi) farmbuyer@1: local count = fencepost and (fencepost-rowi) or (#g_loot-rowi+1) farmbuyer@1: repeat farmbuyer@37: eoi_dropdownfuncs.df_DELETE(rowi) farmbuyer@1: count = count - 1 farmbuyer@1: until count < 1 farmbuyer@1: end, farmbuyer@1: farmbuyer@1: ["Rebroadcast this loot entry"] = function(rowi) farmbuyer@1: local e = g_loot[rowi] farmbuyer@1: -- This only works because GetItemInfo accepts multiple argument formats farmbuyer@71: addon:vbroadcast('loot', e.person, e.unique, e.itemlink, e.count, e.cols[3].value) farmbuyer@28: addon:Print("Rebroadcast entry", rowi, e.itemlink) farmbuyer@1: end, farmbuyer@1: farmbuyer@1: ["Rebroadcast this boss"] = function(rowi,kind) farmbuyer@28: -- if kind is boss, also need to stop at new timestamp farmbuyer@28: local fencepost = addon._find_timeboss_fencepost (kind, rowi) or #g_loot farmbuyer@28: -- this could be a lot of traffic, but frankly it's counterproductive farmbuyer@28: -- to try to micromanage when ChatThrottleLib is already doing so farmbuyer@28: repeat farmbuyer@28: local e = g_loot[rowi] farmbuyer@28: if e.kind == 'boss' then farmbuyer@56: addon:vbroadcast('boss', e.reason, e.bossname, e.instance) farmbuyer@28: elseif e.kind == 'loot' then farmbuyer@28: -- This only works because GetItemInfo accepts multiple argument formats farmbuyer@71: addon:vbroadcast('loot', e.person, e.unique, e.itemlink, e.count, e.cols[3].value) farmbuyer@28: end farmbuyer@55: addon:Print("Rebroadcast entry", rowi, e.itemlink or e.bossname or UNKNOWN) farmbuyer@28: rowi = rowi + 1 farmbuyer@28: until rowi >= fencepost farmbuyer@1: end, farmbuyer@1: farmbuyer@73: ["Mark as normal"] = function(rowi,disp) farmbuyer@73: addon:loot_mark_disposition ("local", rowi, disp) farmbuyer@1: end, farmbuyer@1: farmbuyer@1: ["Show only this player"] = function(rowi) farmbuyer@1: local st = _d:GetUserData("eoiST") farmbuyer@1: _d:SetUserData("player filter name", g_loot[rowi].person) farmbuyer@1: st:SetFilter(_d:GetUserData("player filter by name")) farmbuyer@1: _d:GetUserData("eoi_filter_reset"):SetDisabled(false) farmbuyer@81: -- it'd be more futureproof to get the button and call some kind farmbuyer@81: -- of :GetText() on it, but no such function is provided by acegui farmbuyer@81: setstatus[[Use the "Reset Player Filter" button in the lower-right to return to normal.]] farmbuyer@1: end, farmbuyer@1: farmbuyer@1: ["Change from 'wipe' to 'kill'"] = function(rowi) farmbuyer@1: addon:_mark_boss_kill(rowi) farmbuyer@1: -- the fillout function called automatically will start too far down the list farmbuyer@1: _d:GetUserData("eoiST"):OuroLoot_Refresh() farmbuyer@1: end, farmbuyer@1: farmbuyer@1: ["Edit note"] = function(rowi) farmbuyer@84: eoi_editcell (rowi, _d:GetUserData("DD cell")) farmbuyer@1: end, farmbuyer@1: farmbuyer@1: df_REASSIGN = function(rowi,to_whom) farmbuyer@81: addon:reassign_loot ("local", rowi, to_whom) farmbuyer@1: CloseDropDownMenus() -- also need to close parent menu farmbuyer@1: end, farmbuyer@1: ["Enter name..."] = function(rowi) farmbuyer@25: CloseDropDownMenus() -- also need to close parent menu farmbuyer@1: local dialog = StaticPopup_Show "OUROL_REASSIGN_ENTER" farmbuyer@1: dialog.data = {index=rowi, display=_d} farmbuyer@1: end, farmbuyer@1: } farmbuyer@1: -- Would be better to move the %arg to this list rather than below, but farmbuyer@1: -- that's a lot of extra effort that doesn't buy much in return. farmbuyer@37: eoi_dropdownfuncs["Delete this loot event"] = eoi_dropdownfuncs.df_DELETE farmbuyer@37: eoi_dropdownfuncs["Delete this boss event"] = eoi_dropdownfuncs.df_DELETE farmbuyer@37: eoi_dropdownfuncs["Insert new loot entry"] = eoi_dropdownfuncs.df_INSERT farmbuyer@37: eoi_dropdownfuncs["Insert new boss kill event"] = eoi_dropdownfuncs.df_INSERT farmbuyer@37: eoi_dropdownfuncs["Mark as disenchanted"] = eoi_dropdownfuncs["Mark as normal"] farmbuyer@37: eoi_dropdownfuncs["Mark as guild vault"] = eoi_dropdownfuncs["Mark as normal"] farmbuyer@37: eoi_dropdownfuncs["Mark as offspec"] = eoi_dropdownfuncs["Mark as normal"] farmbuyer@37: eoi_dropdownfuncs["Delete remaining entries for this boss"] = farmbuyer@37: eoi_dropdownfuncs["Delete remaining entries for this day"] farmbuyer@37: eoi_dropdownfuncs["Rebroadcast this day"] = eoi_dropdownfuncs["Rebroadcast this boss"] farmbuyer@1: local eoi_time_dropdown = gen_easymenu_table( farmbuyer@1: {{ farmbuyer@1: -- this is the dropdown title, text filled in on the fly farmbuyer@1: isTitle = true, farmbuyer@1: notClickable = true, farmbuyer@1: notCheckable = true, farmbuyer@1: }}, farmbuyer@1: { farmbuyer@25: "Rebroadcast this day%time|Broadcasts everything from here down until a new day.", farmbuyer@84: "Delete remaining entries for this day%time|Erases everything from here down until a new day.\n\nHold down the Shift key to also delete the corresponding entries from player History.", farmbuyer@25: "Insert new loot entry%loot|Inserts new loot above this one, prompting you for information.", farmbuyer@25: "Insert new boss kill event%boss|Inserts new event above this one, prompting you for information.", farmbuyer@1: CLOSE farmbuyer@37: }, eoi_dropdownfuncs) farmbuyer@1: local eoi_loot_dropdown = gen_easymenu_table( farmbuyer@1: {{ farmbuyer@1: -- this is the dropdown title, text filled in on the fly farmbuyer@1: notClickable = true, farmbuyer@1: notCheckable = true, farmbuyer@1: }}, farmbuyer@1: { farmbuyer@1: "Mark as disenchanted%shard", farmbuyer@1: "Mark as offspec%offspec", farmbuyer@1: "Mark as guild vault%gvault", farmbuyer@25: "Mark as normal|This is the default. Selecting any 'Mark as ' action blanks out extra notes about who broadcast this entry, etc.", farmbuyer@1: "--", farmbuyer@1: "Rebroadcast this loot entry|Sends this loot event, including special notes, as if it just happened.", farmbuyer@84: "Delete this loot event|Permanent, no going back!\n\nHold down the Shift key to also delete the corresponding entry from player's History.", farmbuyer@84: "Delete remaining entries for this boss%boss|Erases everything from here down until a new boss/day.\n\nHold down the Shift key to also delete the corresponding entries from player History.", farmbuyer@25: "Insert new loot entry%loot|Inserts new loot above this one, prompting you for information.", farmbuyer@25: "Insert new boss kill event%boss|Inserts new event above this one, prompting you for information.", farmbuyer@25: "Edit note|Same as double-clicking in the notes column.", farmbuyer@1: "--", farmbuyer@1: CLOSE farmbuyer@37: }, eoi_dropdownfuncs) farmbuyer@1: local eoi_player_dropdown = gen_easymenu_table( farmbuyer@1: { farmbuyer@1: { farmbuyer@1: -- this is the dropdown title, text filled in on the fly farmbuyer@1: isTitle = true, farmbuyer@1: notClickable = true, farmbuyer@1: notCheckable = true, farmbuyer@1: }, farmbuyer@1: { farmbuyer@1: text = "Reassign to...", farmbuyer@1: hasArrow = true, farmbuyer@1: --menuList = filled in in the fly, farmbuyer@25: tooltipOnButton = true, farmbuyer@25: tooltipWhileDisabled = true, farmbuyer@1: }, farmbuyer@1: }, farmbuyer@1: { farmbuyer@1: "Show only this player", farmbuyer@1: CLOSE farmbuyer@37: }, eoi_dropdownfuncs) farmbuyer@1: local eoi_boss_dropdown = gen_easymenu_table( farmbuyer@1: {{ farmbuyer@1: -- this is the dropdown title, text filled in on the fly farmbuyer@1: isTitle = true, farmbuyer@1: notClickable = true, farmbuyer@1: notCheckable = true, farmbuyer@1: }}, farmbuyer@1: { farmbuyer@83: "Change from 'wipe' to 'kill'|Also collapses previous wipe entries.", -- KILLWIPE farmbuyer@28: "Rebroadcast this boss%boss|Broadcasts the kill event and all subsequent loot until next boss.", farmbuyer@1: "Delete this boss event|Permanent, no going back!", farmbuyer@84: "Delete remaining entries for this boss%boss|Erases everything from here down until a new boss/day.\n\nHold down the Shift key to also delete the corresponding entries from player History.", farmbuyer@25: "Insert new loot entry%loot|Inserts new loot above this one, prompting you for information.", farmbuyer@25: "Insert new boss kill event%boss|Inserts new event above this one, prompting you for information.", farmbuyer@1: "--", farmbuyer@1: CLOSE farmbuyer@37: }, eoi_dropdownfuncs) farmbuyer@1: farmbuyer@84: --[[ quoted verbatim from lib-st docs (table->stable for obvious reasons): farmbuyer@1: rowFrame This is the UI Frame table for the row. farmbuyer@1: cellFrame This is the UI Frame table for the cell in the row. farmbuyer@1: data This is the data table supplied to the scrolling table (in case you lost it :) ) farmbuyer@1: cols This is the cols table supplied to the scrolling table (again, in case you lost it :) ) farmbuyer@1: row This is the number of the UI row that the event was triggered for.
ex. If your scrolling table only shows ten rows, this number will be a number between 1 and 10. farmbuyer@1: realrow This is the exact row index (after sorting and filtering) in the data table of what data is displayed in the row you triggered the event in. (NOT the UI row!) farmbuyer@1: column This is the index of which column the event was triggered in. farmbuyer@84: stable This is a reference to the scrollingtable table. farmbuyer@1: ... Any arguments generated by the '''NORMAL''' Blizzard event triggered by the frame are passed as is. farmbuyer@1: ]] farmbuyer@84: local function eoi_st_OnEnter (rowFrame, cellFrame, data, cols, row, realrow, column, stable, motion) farmbuyer@1: if (row == nil) or (realrow == nil) then return end -- mouseover column header farmbuyer@1: local e = data[realrow] farmbuyer@1: local kind = e.kind farmbuyer@72: local tt = GameTooltip -- can this be hoisted? does GT ever get securely replaced? farmbuyer@1: farmbuyer@84: if _do_debugging_tooltip and column == 1 and kind ~= 'hist' then farmbuyer@72: _build_debugging_tooltip (cellFrame, realrow) farmbuyer@72: end farmbuyer@84: if (kind == 'loot' and column == 1) or (kind == 'hist' and column == 2) then farmbuyer@72: tt:SetOwner (cellFrame, "ANCHOR_RIGHT", -20, 0) farmbuyer@19: if e.cache_miss then farmbuyer@72: tt:ClearLines() farmbuyer@72: tt:AddLine("Missing Cache Data") farmbuyer@72: tt:AddLine([[Wait a few seconds, then type]], 0.8, 0.8, 0.8, 1) farmbuyer@81: tt:AddLine([[/ouroloot fix cache]], 0, 1, 64/255, nil) farmbuyer@72: tt:AddLine([[and redisplay this window.]], 0.8, 0.8, 0.8, 1) farmbuyer@72: tt:Show() farmbuyer@19: elseif e.itemlink then farmbuyer@72: tt:SetHyperlink (e.itemlink) farmbuyer@16: end farmbuyer@1: farmbuyer@1: elseif kind == 'loot' and column == 2 then farmbuyer@72: tt:SetOwner (cellFrame, "ANCHOR_BOTTOMRIGHT", -50, 5) farmbuyer@72: tt:ClearLines() farmbuyer@72: tt:AddLine(e.person.." Loot:") farmbuyer@1: local counter = 0 farmbuyer@1: for i,e2 in ipairs(data) do farmbuyer@1: if e2.person == e.person then -- would be awesome to test for alts farmbuyer@1: if counter > 10 then farmbuyer@72: tt:AddLine("...") farmbuyer@1: break farmbuyer@1: else farmbuyer@1: -- textures screw up too badly, strip them farmbuyer@1: local textured = e2.cols[1].value farmbuyer@1: local space = textured:find(" ") farmbuyer@72: tt:AddLine(textured:sub(space+1)) farmbuyer@1: counter = counter + 1 farmbuyer@1: end farmbuyer@1: end farmbuyer@1: end farmbuyer@72: tt:Show() farmbuyer@1: farmbuyer@1: elseif kind == 'loot' and column == 3 then farmbuyer@1: setstatus(e.cols[column].value) farmbuyer@1: farmbuyer@1: end farmbuyer@1: farmbuyer@1: return false -- continue with default highlighting behavior farmbuyer@1: end farmbuyer@84: local function eoi_st_OnLeave (rowFrame, cellFrame, data, cols, row, realrow, column, stable, motion) farmbuyer@1: GameTooltip:Hide() farmbuyer@72: _hide_debugging_tooltip() farmbuyer@1: if row and realrow and data[realrow].kind ~= 'loot' then farmbuyer@84: stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[data[realrow].reason or data[realrow].kind]) farmbuyer@1: return true -- do not do anything further farmbuyer@1: else farmbuyer@1: --setstatus("") farmbuyer@1: return false -- continue with default un-highlighting behavior farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@84: local function eoi_st_OnClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, down) farmbuyer@1: if (row == nil) or (realrow == nil) then return true end -- click column header, suppress reordering farmbuyer@1: local e = data[realrow] farmbuyer@1: local kind = e.kind farmbuyer@1: farmbuyer@1: -- Check for shift-clicking a loot line farmbuyer@84: if IsModifiedClick("CHATLINK") and kind == 'loot' and column == 1 farmbuyer@16: then farmbuyer@1: ChatEdit_InsertLink (e.itemlink) farmbuyer@1: return true -- do not do anything further farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- Remaining actions are all right-click farmbuyer@1: if button ~= "RightButton" then return true end farmbuyer@84: _d:SetUserData("DD index", realrow) farmbuyer@1: farmbuyer@1: if kind == 'loot' and (column == 1 or column == 3) then farmbuyer@84: _d:SetUserData("DD cell", cellFrame) farmbuyer@1: eoi_loot_dropdown[1].text = e.itemlink farmbuyer@1: EasyMenu (eoi_loot_dropdown, dropdownmenuframe, cellFrame, 0, 0, "MENU") farmbuyer@1: farmbuyer@1: elseif kind == 'loot' and column == 2 then farmbuyer@1: eoi_player_dropdown[1].text = e.person farmbuyer@1: local raiders = {} farmbuyer@1: for i = 1, GetNumRaidMembers() do farmbuyer@1: tinsert (raiders, (GetRaidRosterInfo(i))) farmbuyer@1: end farmbuyer@1: table.sort(raiders) farmbuyer@1: for i = 1, #raiders do farmbuyer@1: local name = raiders[i] farmbuyer@1: raiders[i] = { farmbuyer@1: text = name, farmbuyer@1: func = dropdownmenu_handler, farmbuyer@37: arg1 = eoi_dropdownfuncs.df_REASSIGN, farmbuyer@1: arg2 = name, farmbuyer@1: notCheckable = true, farmbuyer@1: } farmbuyer@1: end farmbuyer@1: eoi_player_dropdown[2].menuList = farmbuyer@37: gen_easymenu_table (raiders, {"Enter name...",CLOSE}, eoi_dropdownfuncs) farmbuyer@25: if e.disposition == 'shard' or e.disposition == 'gvault' then farmbuyer@25: eoi_player_dropdown[2].disabled = true farmbuyer@25: eoi_player_dropdown[2].tooltipTitle = "Cannot Reassign" farmbuyer@25: eoi_player_dropdown[2].tooltipText = "You must first mark this item as 'normal' or 'offspec' before reassignment." farmbuyer@25: else farmbuyer@25: eoi_player_dropdown[2].disabled = nil farmbuyer@25: eoi_player_dropdown[2].tooltipTitle = nil farmbuyer@25: eoi_player_dropdown[2].tooltipText = nil farmbuyer@25: end farmbuyer@1: EasyMenu (eoi_player_dropdown, dropdownmenuframe, cellFrame, 0, 0, "MENU") farmbuyer@1: farmbuyer@1: elseif kind == 'boss' then farmbuyer@55: eoi_boss_dropdown[1].text = e.bossname farmbuyer@83: -- KILLWIPE: update '2' if this is not the 2nd entry in eoi_boss_dropdown farmbuyer@83: eoi_boss_dropdown[2].tooltipWhileDisabled = nil farmbuyer@83: eoi_boss_dropdown[2].disabled = e.reason ~= 'wipe' and true or nil farmbuyer@1: EasyMenu (eoi_boss_dropdown, dropdownmenuframe, cellFrame, 0, 0, "MENU") farmbuyer@1: farmbuyer@1: elseif kind == 'time' then farmbuyer@1: eoi_time_dropdown[1].text = e.startday.text farmbuyer@1: EasyMenu (eoi_time_dropdown, dropdownmenuframe, cellFrame, 0, 0, "MENU") farmbuyer@1: farmbuyer@1: end farmbuyer@1: farmbuyer@1: return true -- do not do anything further farmbuyer@1: end farmbuyer@1: farmbuyer@1: function eoi_editcell (row_index, cell_frame) farmbuyer@1: local e = g_loot[row_index] farmbuyer@1: if not e then return end -- how the hell could we get this far? farmbuyer@1: local celldata = e.cols[3] farmbuyer@1: local box = GUI:Create("EditBox") farmbuyer@1: box:SetText(celldata.value) farmbuyer@1: box:SetUserData("old show", box.editbox:GetScript("OnShow")) farmbuyer@1: box:SetUserData("old escape", box.editbox:GetScript("OnEscapePressed")) farmbuyer@1: box.editbox:SetScript("OnShow", box.editbox.SetFocus) farmbuyer@1: box.editbox:SetScript("OnEscapePressed", function(_be) farmbuyer@1: _be:ClearFocus() farmbuyer@1: _be.obj:Release() farmbuyer@1: end) farmbuyer@1: box:SetCallback("OnEnterPressed", function(_b,event,value) farmbuyer@1: e.extratext = value farmbuyer@1: celldata.value = value farmbuyer@1: e.bcast_from = nil -- things get screwy if this field is still present. sigh. farmbuyer@1: e.extratext_byhand = true farmbuyer@1: value = value and value:match("^(x%d+)") farmbuyer@1: if value then e.count = value end farmbuyer@1: _b:Release() farmbuyer@1: return _d:GetUserData("eoiST"):OuroLoot_Refresh(row_index) farmbuyer@1: end) farmbuyer@1: box:SetCallback("OnRelease", function(_b) farmbuyer@1: _b.editbox:ClearFocus() farmbuyer@1: _b.editbox:SetScript("OnShow", _b:GetUserData("old show")) farmbuyer@1: _b.editbox:SetScript("OnEscapePressed", _b:GetUserData("old escape")) farmbuyer@1: setstatus("") farmbuyer@1: end) farmbuyer@1: box.frame:SetAllPoints(cell_frame) farmbuyer@1: box.frame:SetParent(cell_frame) farmbuyer@1: box.frame:SetFrameLevel(cell_frame:GetFrameLevel()+1) farmbuyer@1: box.frame:Show() farmbuyer@1: setstatus("Press Enter or click Okay to accept changes, or press Escape to cancel them.") farmbuyer@1: end farmbuyer@1: farmbuyer@84: local function eoi_st_OnDoubleClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button) farmbuyer@1: if (row == nil) or (realrow == nil) then return true end -- they clicked on column header, suppress reordering farmbuyer@1: local e = data[realrow] farmbuyer@1: local kind = e.kind farmbuyer@1: farmbuyer@84: --_d:SetUserData("DD index", realrow) farmbuyer@1: if kind == 'loot' and column == 3 and button == "LeftButton" then farmbuyer@1: eoi_editcell (realrow, cellFrame) farmbuyer@1: end farmbuyer@1: farmbuyer@1: return true -- do not do anything further farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- Used for EOI column 2 and Hist column 1. Both are player name columns. farmbuyer@84: local function eoi_st_col2_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable) farmbuyer@1: if not fShow then farmbuyer@1: cellFrame.text:SetText("") farmbuyer@1: if cellFrame.icontexture then farmbuyer@1: cellFrame.icontexture:Hide() farmbuyer@1: end farmbuyer@1: return farmbuyer@1: end farmbuyer@1: farmbuyer@1: local e = data[realrow] farmbuyer@1: local cell = e.cols[column] farmbuyer@1: farmbuyer@1: cellFrame.text:SetText(cell.value) farmbuyer@1: farmbuyer@1: if e.person_class then farmbuyer@1: local icon farmbuyer@1: if cellFrame.icontexture then farmbuyer@1: icon = cellFrame.icontexture farmbuyer@1: else farmbuyer@1: icon = cellFrame:CreateTexture(nil,"BACKGROUND") farmbuyer@1: icon:SetPoint("LEFT", cellFrame, "LEFT") farmbuyer@1: icon:SetHeight(eoi_st_rowheight-4) farmbuyer@1: icon:SetWidth(eoi_st_rowheight-4) farmbuyer@1: icon:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes") farmbuyer@1: cellFrame.icontexture = icon farmbuyer@1: end farmbuyer@1: icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[e.person_class])) farmbuyer@1: icon:Show() farmbuyer@1: cellFrame.text:SetPoint("LEFT", icon, "RIGHT", 1, 0) farmbuyer@73: local color = class_colors[e.person_class] farmbuyer@73: cellFrame.text:SetTextColor(color.r,color.g,color.b,1) farmbuyer@1: else farmbuyer@1: if cellFrame.icontexture then farmbuyer@1: cellFrame.icontexture:Hide() farmbuyer@1: cellFrame.text:SetPoint("LEFT", cellFrame, "LEFT") farmbuyer@1: end farmbuyer@73: cellFrame.text:SetTextColor(1,1,1,1) farmbuyer@1: end farmbuyer@1: farmbuyer@1: --if e.kind ~= 'loot' then farmbuyer@1: stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[e.reason or e.kind or ""]) farmbuyer@1: --else farmbuyer@84: -- stable:SetHighLightColor (rowFrame, table:GetDefaultHighlightBlank()) farmbuyer@1: --end farmbuyer@1: end farmbuyer@1: farmbuyer@1: local eoi_st_cols = { farmbuyer@1: { -- col 1 farmbuyer@1: name = "Item", farmbuyer@1: width = 250, farmbuyer@1: }, farmbuyer@1: { -- col 2 farmbuyer@1: name = "Player", farmbuyer@1: width = 130, farmbuyer@1: DoCellUpdate = eoi_st_col2_DoCellUpdate, farmbuyer@1: }, farmbuyer@1: { -- col 3 farmbuyer@1: name = "Notes", farmbuyer@3: width = 250, farmbuyer@73: color = eoi_st_lootrow_col3_colortable_func, farmbuyer@1: }, farmbuyer@1: } farmbuyer@1: farmbuyer@6: local player_filter_all farmbuyer@6: local player_filter_by_name = function (st, e) farmbuyer@1: if e.kind ~= 'loot' then return true end farmbuyer@1: return e.person == _d:GetUserData("player filter name") farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- Tab 1: Events Of Interest (implementation) farmbuyer@1: tabs_OnGroupSelected["eoi"] = function(ocontainer,specials) farmbuyer@1: if (not addon.rebroadcast) and (not addon.enabled) and (#g_loot < 1) then farmbuyer@40: addon.dprint('flow', "Nothing to show in first tab, skipping creation") farmbuyer@40: return farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- The first time this function is called, we set up a persistent ST farmbuyer@1: -- object and store it. Any other delayed setup work is done, and then farmbuyer@1: -- this function replaces itself with a smaller, sleeker, sexier one. farmbuyer@1: -- This function will later be garbage collected. farmbuyer@1: local ST = LibStub("ScrollingTable"):CreateST(eoi_st_cols,eoi_st_displayed_rows,eoi_st_rowheight) farmbuyer@1: _d:SetUserData("eoiST",ST) farmbuyer@1: if addon.author_debug then farmbuyer@1: _G.OLST = ST farmbuyer@1: end farmbuyer@1: farmbuyer@1: if not eoi_st_otherrow_bgcolortable_default then farmbuyer@1: eoi_st_otherrow_bgcolortable_default = ST:GetDefaultHighlightBlank() farmbuyer@1: setmetatable(eoi_st_otherrow_bgcolortable, {__index = function (bg, key) farmbuyer@1: return eoi_st_otherrow_bgcolortable_default farmbuyer@1: end}) farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- Calling SetData breaks (trying to call Refresh) if g_loot hasn't gone farmbuyer@1: -- through this loop. farmbuyer@1: addon:_fill_out_eoi_data(1) farmbuyer@1: -- safety check begin farmbuyer@1: for i,e in ipairs(g_loot) do farmbuyer@1: if type(e.cols) ~= 'table' then farmbuyer@1: addon:Print("ARGH, index",i,"bad in eoi_OGS, type",type(e.cols), farmbuyer@55: "entry kind", e.kind, "data", e.itemname or e.bossname or e.startday.text, farmbuyer@55: "-- please take a screenshot and send to Farmbuyer@US-Kilrogg.") farmbuyer@1: tabledump(e) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: -- safety check end farmbuyer@1: ST:SetData(g_loot) farmbuyer@1: ST:RegisterEvents{ farmbuyer@1: OnEnter = eoi_st_OnEnter, farmbuyer@1: OnLeave = eoi_st_OnLeave, farmbuyer@1: OnClick = eoi_st_OnClick, farmbuyer@1: OnDoubleClick = eoi_st_OnDoubleClick, farmbuyer@1: } farmbuyer@1: farmbuyer@1: -- We want a single "update and redraw" function for the ST. Also, the farmbuyer@1: -- given refresh function is badly named and does nothing; the actual farmbuyer@1: -- function is SortData (also badly named when no sorting is being done), farmbuyer@1: -- which unconditionally calls the *hooked* Refresh. farmbuyer@1: local oldrefresh = ST.Refresh farmbuyer@1: ST.Refresh = function (self, opt_index) farmbuyer@1: addon:_fill_out_eoi_data(opt_index) farmbuyer@1: return oldrefresh(self) farmbuyer@1: end farmbuyer@1: ST.OuroLoot_Refresh = function (self, opt_index) farmbuyer@1: addon:_fill_out_eoi_data(opt_index) farmbuyer@1: -- safety check begin farmbuyer@1: for i,e in ipairs(g_loot) do farmbuyer@1: if type(e.cols) ~= 'table' then farmbuyer@4: addon:Print("ARGH, index",i,"bad in eoi refresh, refreshed at", opt_index, "type",type(e.cols), farmbuyer@55: "entry kind", e.kind, "data", e.itemname or e.bossname or e.startday.text, farmbuyer@55: "-- please take a screenshot and send to Farmbuyer@US-Kilrogg.") farmbuyer@1: tabledump(e) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: -- safety check end farmbuyer@1: self:SortData() -- calls hooked refresh farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- No need to keep creating function closures that all just "return true", farmbuyer@1: -- instead we grab the one made inside lib-st. There's no "get filter" API farmbuyer@1: -- so we just reach inside. farmbuyer@6: player_filter_all = ST.Filter farmbuyer@1: farmbuyer@1: -- Now set up the future drawing function... farmbuyer@1: tabs_OnGroupSelected["eoi"] = function(container,specials) farmbuyer@1: local st_widget = GUI:Create("lib-st") farmbuyer@1: local st = _d:GetUserData("eoiST") farmbuyer@1: farmbuyer@84: _d:SetUserData("which ST",st) farmbuyer@84: farmbuyer@1: -- This is actually required each time farmbuyer@6: _d:SetUserData ("player filter clear", player_filter_all) farmbuyer@6: _d:SetUserData ("player filter by name", player_filter_by_name) farmbuyer@1: farmbuyer@1: st:OuroLoot_Refresh() farmbuyer@1: st_widget:WrapST(st) farmbuyer@3: st_widget.head_offset = 15 farmbuyer@3: st_widget.tail_offset = 0 farmbuyer@1: farmbuyer@1: if OuroLootSV_opts.scroll_to_bottom then farmbuyer@1: local scrollbar = _G[st.scrollframe:GetName().."ScrollBar"] farmbuyer@1: if scrollbar then farmbuyer@1: local _,max = scrollbar:GetMinMaxValues() farmbuyer@1: scrollbar:SetValue(max) -- also calls hooked Refresh farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: container:SetLayout("Fill") farmbuyer@1: container:AddChild(st_widget) farmbuyer@1: farmbuyer@42: local b farmbuyer@42: --[===[ b = mkbutton("Generate Header", farmbuyer@42: [[]]) farmbuyer@42: b:SetFullWidth(true) farmbuyer@42: b:SetCallback("OnClick", function (_b) farmbuyer@42: end) farmbuyer@42: specials:AddChild(b) ]===] farmbuyer@42: farmbuyer@42: b = mkbutton('eoi_filter_reset', "Reset Player Filter", farmbuyer@1: [[Return to showing complete loot information.]]) farmbuyer@1: b:SetFullWidth(true) farmbuyer@1: b:SetCallback("OnClick", function (_b) farmbuyer@1: local st = _d:GetUserData("eoiST") farmbuyer@6: st:SetFilter(player_filter_all) farmbuyer@1: _b:SetDisabled(true) farmbuyer@1: end) farmbuyer@6: b:SetDisabled(st.Filter == player_filter_all) farmbuyer@1: specials:AddChild(b) farmbuyer@1: farmbuyer@1: local people = { "" } farmbuyer@1: for i=1,GetNumRaidMembers() do farmbuyer@1: tinsert(people,(GetRaidRosterInfo(i))) farmbuyer@1: end farmbuyer@1: table.sort(people) farmbuyer@1: local initial farmbuyer@1: for i,n in ipairs(people) do farmbuyer@1: if n == addon.sharder then initial = i end farmbuyer@1: end farmbuyer@1: b = mkbutton("Dropdown", nil, "", farmbuyer@1: [[If set, items received by this person will be automatically marked as disenchanted.]]) farmbuyer@1: b:SetFullWidth(true) farmbuyer@1: b:SetLabel("Auto-mark as shard:") farmbuyer@1: b:SetList(people) farmbuyer@1: b:SetValue(initial or 1) farmbuyer@1: b:SetCallback("OnValueChanged", function(_dd,event,choice) farmbuyer@1: addon.sharder = (choice ~= 1) and people[choice] or nil farmbuyer@1: end) farmbuyer@1: specials:AddChild(b) farmbuyer@1: farmbuyer@42: b = mkbutton('eoi_bcast_req', "Request B'casters", farmbuyer@1: [[Sends out a request for others to enable loot rebroadcasting if they have not already done so.]]) farmbuyer@1: b:SetFullWidth(true) farmbuyer@1: b:SetCallback("OnClick", function () farmbuyer@1: addon:Print("Sending request!") farmbuyer@1: addon.requesting = true farmbuyer@1: addon:broadcast('bcast_req') farmbuyer@1: end) farmbuyer@1: b:SetDisabled(not addon.enabled) farmbuyer@1: specials:AddChild(b) farmbuyer@1: end farmbuyer@1: -- ...and call it. farmbuyer@1: return tabs_OnGroupSelected["eoi"](ocontainer,specials) farmbuyer@1: end farmbuyer@83: noob_tips["eoi"] = _markup[[ farmbuyer@83: while over an item link to paste it into chat. farmbuyer@83: farmbuyer@83: -click any row to display a dropdown menu. The menu is different for farmbuyer@83: the Player column than it is for the Item/Notes columns, and different for farmbuyer@83: loot entries than it is for other rows.]] farmbuyer@1: farmbuyer@37: farmbuyer@1: -- Tab 2/3 (generated text) farmbuyer@1: function tabs_generated_text_OGS (container, specials, text_kind) farmbuyer@1: container:SetLayout("Fill") farmbuyer@1: local box = GUI:Create("MultiLineEditBox") farmbuyer@1: box:SetFullWidth(true) farmbuyer@1: box:SetFullHeight(true) farmbuyer@1: box:SetLabel("Pressing the Escape key while typing will return keystroke control to the usual chat window.") farmbuyer@1: box:DisableButton(true) farmbuyer@1: addon:_fill_out_eoi_data(1) farmbuyer@1: farmbuyer@1: -- Update the savedvar copy of the text before presenting it for editing, farmbuyer@1: -- then save it again when editing finishes. This way if the user goes farmbuyer@1: -- offline while editing, at least the unedited version is saved instead farmbuyer@1: -- of all the new text being lost entirely. (Yes, it's happened.) farmbuyer@1: -- farmbuyer@1: -- No good local-ish place to store the cursor position that will also farmbuyer@1: -- survive the entire display being released. Abuse the generated text farmbuyer@1: -- cache for this purpose. farmbuyer@1: local pos = text_kind.."_pos" farmbuyer@1: if _generate_text(text_kind) then farmbuyer@1: g_loot[text_kind] = g_loot[text_kind] .. g_generated[text_kind] farmbuyer@1: g_generated[text_kind] = nil farmbuyer@1: end farmbuyer@1: box:SetText(g_loot[text_kind]) farmbuyer@1: box.editBox:SetCursorPosition(g_generated[pos] or 0) farmbuyer@1: box.editBox:SetScript("OnShow", box.editBox.SetFocus) farmbuyer@1: box:SetCallback("OnRelease", function(_box) farmbuyer@1: box.editBox:ClearFocus() farmbuyer@1: g_loot[text_kind] = _box:GetText() farmbuyer@1: g_generated[pos] = _box.editBox:GetCursorPosition() farmbuyer@1: end) farmbuyer@1: container:AddChild(box) farmbuyer@1: farmbuyer@1: local w = mkbutton("Regenerate", farmbuyer@1: [[+DISCARD> all text in this tab, and regenerate it from the current loot information.]]) farmbuyer@1: w:SetFullWidth(true) farmbuyer@1: w:SetDisabled ((#g_loot == 0) and (box:GetText() == "")) farmbuyer@1: w:SetCallback("OnClick", function(_w) farmbuyer@1: box:SetText("") farmbuyer@1: g_loot[text_kind] = "" farmbuyer@1: g_loot.printed[text_kind] = 0 farmbuyer@1: g_generated.last_instance = nil farmbuyer@1: g_generated[pos] = nil farmbuyer@1: addon:Print("'%s' has been regenerated.", _tabtexts[text_kind].title) farmbuyer@1: return addon:redisplay() farmbuyer@1: end) farmbuyer@1: specials:AddChild(w) farmbuyer@58: if addon:is_plugin(text_kind) then farmbuyer@58: local pname = addon:is_plugin(text_kind):GetName() farmbuyer@58: w = mkbutton("Reset SVs & ReloadUI", farmbuyer@59: ([[ Reset savedvariables for %s plugin back to defaults, and trigger a UI reload.]]):format(pname)) farmbuyer@58: w:SetFullWidth(true) farmbuyer@58: w:SetCallback("OnClick", function(_w) farmbuyer@58: _G['OuroLoot'..pname..'_opts'] = nil farmbuyer@58: ReloadUI() farmbuyer@58: end) farmbuyer@58: specials:AddChild(w) farmbuyer@58: end farmbuyer@1: _populate_text_specials (box, specials, mkbutton, text_kind) farmbuyer@1: end farmbuyer@1: farmbuyer@37: farmbuyer@1: -- Tab 4: History farmbuyer@1: -- Much of the implementation here follows a similar desgin for the first farmbuyer@4: -- tab's handling of ST objects. We will even reuse its controlling tables farmbuyer@4: -- when feasible. farmbuyer@37: local histST, hist_dropdownfuncs farmbuyer@84: local hist_normal_status = farmbuyer@84: [[Click on a row to view all history for that player only. (Click column headers to re-sort.)]] farmbuyer@84: local hist_name_status = farmbuyer@84: [[Right-click on any row to return to normal history display.]] farmbuyer@84: farmbuyer@84: local history_filter_by_recent = function (st, e) farmbuyer@84: if e.kind ~= 'hist' then return true end farmbuyer@84: return e.cols[2].OLi == 1 farmbuyer@84: end farmbuyer@84: farmbuyer@84: local history_filter_who farmbuyer@84: local history_filter_by_name = function (st, e) farmbuyer@84: if e.kind ~= 'hist' then return true end farmbuyer@84: return e.OLwho == history_filter_who farmbuyer@84: end farmbuyer@1: farmbuyer@37: hist_dropdownfuncs = dropdownfuncs{ farmbuyer@84: ["Delete this loot event from history"] = function(rowi) farmbuyer@84: local h = _d:GetUserData("DD history entry") farmbuyer@84: local okay,err = addon:_delHistoryEntry (h.cols[2].OLu, h.itemlink) farmbuyer@84: if okay then farmbuyer@84: addon:Print("Removed history entry %s from '%s'.", farmbuyer@84: h.itemlink, h.OLwho) farmbuyer@84: else farmbuyer@84: addon:Print(err) farmbuyer@84: end farmbuyer@84: end, farmbuyer@84: farmbuyer@84: ["Delete this player's entire loot history"] = function(rowi) farmbuyer@84: local h = _d:GetUserData("DD history entry") farmbuyer@84: local name = h.OLwho farmbuyer@84: local player_i = addon.history.byname[name] farmbuyer@84: local gone = tremove (addon.history, player_i) farmbuyer@84: assert(gone.name == name) farmbuyer@84: addon:_build_history_names() farmbuyer@84: addon:Print("Removed player '%s' from history (%d total entries).", farmbuyer@84: name, #gone.unique) farmbuyer@37: end, farmbuyer@37: } farmbuyer@84: local hist_general_dropdown = gen_easymenu_table( farmbuyer@84: {{ farmbuyer@84: -- this is the dropdown title, text filled in on the fly farmbuyer@84: isTitle = true, farmbuyer@84: notClickable = true, farmbuyer@84: notCheckable = true, farmbuyer@84: }}, farmbuyer@84: { farmbuyer@84: "Delete this player's entire loot history|Permanent, no going back!", farmbuyer@84: "--", farmbuyer@84: CLOSE farmbuyer@84: }, hist_dropdownfuncs) farmbuyer@84: local hist_specific_dropdown = gen_easymenu_table( farmbuyer@37: {{ farmbuyer@37: -- this is the dropdown title, text filled in on the fly farmbuyer@37: notClickable = true, farmbuyer@37: notCheckable = true, farmbuyer@37: }}, farmbuyer@37: { farmbuyer@84: "Delete this loot event from history|Permanent, no going back!", farmbuyer@37: "--", farmbuyer@37: CLOSE farmbuyer@37: }, hist_dropdownfuncs) farmbuyer@6: farmbuyer@84: -- Loot column farmbuyer@84: --[[ farmbuyer@84: local function hist_st_col2_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable) farmbuyer@84: end]] farmbuyer@84: farmbuyer@84: -- Formatted timestamp column farmbuyer@84: local function hist_st_col3_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable) farmbuyer@84: if not fShow then farmbuyer@84: cellFrame.text:SetText("") farmbuyer@84: return farmbuyer@84: end farmbuyer@84: farmbuyer@84: local h = data[realrow] farmbuyer@84: local cell = h.cols[column] farmbuyer@84: farmbuyer@84: cellFrame.text:SetText(cell.value) farmbuyer@84: cellFrame.text:SetTextColor(1,1,1,1) farmbuyer@84: farmbuyer@84: --stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[h.kind]) farmbuyer@84: stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable_default) farmbuyer@84: end farmbuyer@84: farmbuyer@84: local function hist_st_OnClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, down) farmbuyer@84: if (row == nil) or (realrow == nil) then return false end -- click column header, do default resorting farmbuyer@84: local h = data[realrow] farmbuyer@84: assert(h.kind=='hist') farmbuyer@84: farmbuyer@84: -- Four button combinations we need to care about: farmbuyer@84: farmbuyer@84: -- Shift-left pastes loot farmbuyer@84: if IsModifiedClick("CHATLINK") and column == 2 then farmbuyer@84: ChatEdit_InsertLink (h.itemlink) farmbuyer@84: return true -- do not do anything further farmbuyer@84: end farmbuyer@84: farmbuyer@84: _d:SetUserData("DD index", realrow) farmbuyer@84: _d:SetUserData("DD history entry", h) farmbuyer@84: farmbuyer@84: -- The rest depends on whether we're filtering (focused in on a specific farmbuyer@84: -- player) or not. farmbuyer@84: if history_filter_who then farmbuyer@84: -- Shift-right opens a menu farmbuyer@84: if IsShiftKeyDown() and button == "RightButton" then farmbuyer@84: hist_specific_dropdown[1].text = h.itemlink farmbuyer@84: EasyMenu (hist_specific_dropdown, dropdownmenuframe, cellFrame, 0, 0, "MENU") farmbuyer@84: farmbuyer@84: -- Right goes back to normal mode farmbuyer@84: elseif button == "RightButton" then farmbuyer@84: history_filter_who = nil farmbuyer@84: stable:SetFilter(history_filter_by_recent) farmbuyer@84: setstatus(hist_normal_status) farmbuyer@84: end farmbuyer@84: farmbuyer@84: else -- not focused farmbuyer@84: -- Shift-right opens a menu farmbuyer@84: if IsShiftKeyDown() and button == "RightButton" then farmbuyer@84: hist_general_dropdown[1].text = h.OLwho farmbuyer@84: EasyMenu (hist_general_dropdown, dropdownmenuframe, cellFrame, 0, 0, "MENU") farmbuyer@84: farmbuyer@84: -- Left focuses on a specific player farmbuyer@84: elseif button == "LeftButton" then farmbuyer@84: history_filter_who = h.OLwho farmbuyer@84: stable:SetFilter(history_filter_by_name) farmbuyer@84: setstatus(hist_name_status) farmbuyer@84: end farmbuyer@84: end farmbuyer@84: farmbuyer@84: return true -- do not do anything further farmbuyer@84: end farmbuyer@84: farmbuyer@84: --[[ farmbuyer@84: local function hist_st_OnDoubleClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button) farmbuyer@84: if (row == nil) or (realrow == nil) then return true end -- they clicked on column header, suppress reordering farmbuyer@84: local h = data[realrow] farmbuyer@84: assert(h.kind=='hist') farmbuyer@84: farmbuyer@84: return true -- do not do anything further farmbuyer@84: end]] farmbuyer@84: farmbuyer@37: local hist_st_cols = { farmbuyer@37: { -- col 1 farmbuyer@37: name = "Player", farmbuyer@37: width = 130, farmbuyer@37: DoCellUpdate = eoi_st_col2_DoCellUpdate, farmbuyer@37: }, farmbuyer@37: { -- col 2 farmbuyer@37: name = "Most Recent Loot", farmbuyer@37: width = 250, farmbuyer@84: --DoCellUpdate = hist_st_col2_DoCellUpdate, farmbuyer@37: }, farmbuyer@37: { -- col 3 farmbuyer@37: name = "When", farmbuyer@37: width = 250, farmbuyer@37: DoCellUpdate = hist_st_col3_DoCellUpdate, farmbuyer@37: defaultsort = "asc", farmbuyer@37: sort = "asc", farmbuyer@37: sortnext = 1, farmbuyer@37: }, farmbuyer@37: } farmbuyer@37: farmbuyer@37: -- Tab 4: History (implementation) farmbuyer@37: tabs_OnGroupSelected["hist"] = function(container,specials) farmbuyer@37: histST = LibStub("ScrollingTable"):CreateST(hist_st_cols,eoi_st_displayed_rows,eoi_st_rowheight) farmbuyer@37: _d:SetUserData("histST",histST) farmbuyer@37: if addon.author_debug then farmbuyer@37: _G.OLHST = histST farmbuyer@1: end farmbuyer@1: farmbuyer@37: if not eoi_st_otherrow_bgcolortable_default then farmbuyer@37: eoi_st_otherrow_bgcolortable_default = histST:GetDefaultHighlightBlank() farmbuyer@37: setmetatable(eoi_st_otherrow_bgcolortable, {__index = function (bg, key) farmbuyer@37: return eoi_st_otherrow_bgcolortable_default farmbuyer@37: end}) farmbuyer@1: end farmbuyer@1: farmbuyer@37: addon:_build_history_names() farmbuyer@37: addon:_fill_out_hist_data(1) farmbuyer@37: histST:SetData(addon.history.st) farmbuyer@37: histST:RegisterEvents{ farmbuyer@37: OnEnter = eoi_st_OnEnter, farmbuyer@37: OnLeave = eoi_st_OnLeave, farmbuyer@37: OnClick = hist_st_OnClick, farmbuyer@37: --OnDoubleClick = hist_st_OnDoubleClick, farmbuyer@37: } farmbuyer@37: local oldrefresh = histST.Refresh farmbuyer@37: histST.Refresh = function (self, opt_index) farmbuyer@37: addon:_fill_out_hist_data(opt_index) farmbuyer@37: return oldrefresh(self) farmbuyer@37: end farmbuyer@37: histST.OuroLoot_Refresh = function (self, opt_index) farmbuyer@37: addon:_fill_out_hist_data(opt_index) farmbuyer@37: self:SortData() -- calls hooked refresh farmbuyer@6: end farmbuyer@6: farmbuyer@37: histST:SetFilter(history_filter_by_recent) farmbuyer@6: farmbuyer@37: -- Zaps history for the given realm, or the current (current-playing farmbuyer@37: -- realm, not currently-displayed realm) one if not specified. farmbuyer@37: local function reset_current_realm (opt_realmname) farmbuyer@37: local r = assert(opt_realmname or GetRealmName()) farmbuyer@37: -- new .history table: farmbuyer@37: addon.history_all[r] = addon:_prep_new_history_category (nil, r) farmbuyer@37: addon.history = addon.history_all[r] farmbuyer@37: addon.hist_clean = nil farmbuyer@37: -- new .history.st table: farmbuyer@37: histST:OuroLoot_Refresh() farmbuyer@37: histST:SetData(addon.history.st) farmbuyer@37: end farmbuyer@6: farmbuyer@1: tabs_OnGroupSelected["hist"] = function(container,specials) farmbuyer@37: local st_widget = GUI:Create("lib-st") farmbuyer@37: -- don't need _d:GetUserData("histST") here, as it's already a local farmbuyer@84: _d:SetUserData("which ST",histST) farmbuyer@37: histST:OuroLoot_Refresh() farmbuyer@37: st_widget:WrapST(histST) farmbuyer@37: st_widget.head_offset = 15 farmbuyer@37: st_widget.tail_offset = 0 farmbuyer@37: container:SetLayout("Fill") farmbuyer@37: container:AddChild(st_widget) farmbuyer@37: setstatus(hist_normal_status) farmbuyer@1: farmbuyer@37: local b farmbuyer@37: do farmbuyer@37: local realms,current = {},1 farmbuyer@37: for realmname,histtable in pairs(addon.history_all) do farmbuyer@37: if type(histtable) == 'table' then farmbuyer@37: tinsert(realms,realmname) farmbuyer@37: if addon.history == histtable then current = #realms end farmbuyer@4: end farmbuyer@4: end farmbuyer@37: b = mkbutton("Dropdown", nil, "", [[Which realm to display]]) farmbuyer@1: b:SetFullWidth(true) farmbuyer@37: b:SetLabel() -- required even when empty, see ace3 ticket #234 farmbuyer@37: b:SetList(realms) farmbuyer@37: b:SetValue(current) farmbuyer@37: b:SetCallback("OnValueChanged", function(_dd,event,choice) farmbuyer@37: local r = realms[choice] farmbuyer@37: addon.history = addon:_prep_new_history_category (addon.history_all[r], r) farmbuyer@37: addon.hist_clean = nil farmbuyer@6: histST:OuroLoot_Refresh() farmbuyer@6: histST:SetData(addon.history.st) farmbuyer@37: -- Reset filters to normal farmbuyer@37: history_filter_who = nil farmbuyer@37: histST:SetFilter(history_filter_by_recent) farmbuyer@37: setstatus(hist_normal_status) farmbuyer@1: return addon:redisplay() farmbuyer@1: end) farmbuyer@1: specials:AddChild(b) farmbuyer@37: end farmbuyer@1: farmbuyer@37: --[[ b = GUI:Create("Spacer") b:SetFullWidth(true) b:SetHeight(10) specials:AddChild(b) ]] farmbuyer@4: farmbuyer@37: b = mkbutton("Regenerate", farmbuyer@37: [[Erases all history entries from the displayed realm, and regenerates it from current loot information.]]) farmbuyer@37: b:SetFullWidth(true) farmbuyer@37: b:SetDisabled (#addon.history == 0) farmbuyer@37: b:SetCallback("OnClick", function(_b) farmbuyer@37: local dialog = StaticPopup_Show("OUROL_HIST_REGEN", addon.history.realm) farmbuyer@37: dialog.data = addon farmbuyer@37: dialog.data2 = function(_addon) farmbuyer@37: _addon:rewrite_history (_addon.history.realm) farmbuyer@37: histST:OuroLoot_Refresh() farmbuyer@37: histST:SetData(_addon.history.st) farmbuyer@37: end farmbuyer@37: end) farmbuyer@37: specials:AddChild(b) farmbuyer@1: farmbuyer@37: b = mkbutton('hist_clear', "Clear Realm History", farmbuyer@37: [[|cffff1010Erases absolutely all> history entries from the displayed realm.]]) farmbuyer@37: b:SetFullWidth(true) farmbuyer@37: b:SetCallback("OnClick", function (_b) farmbuyer@37: local dialog = StaticPopup_Show("OUROL_HIST_CLEAR", addon.history.realm) farmbuyer@37: dialog.data = addon farmbuyer@37: dialog.data2 = function(_addon) farmbuyer@37: reset_current_realm(_addon.history.realm) farmbuyer@37: end farmbuyer@37: end) farmbuyer@37: specials:AddChild(b) farmbuyer@37: farmbuyer@37: b = mkbutton('hist_clear_all', "Clear All History", farmbuyer@37: [[|cffff1010Erases absolutely all> history entries from ALL realms.]]) farmbuyer@37: b:SetFullWidth(true) farmbuyer@37: b:SetCallback("OnClick", function (_b) farmbuyer@37: local dialog = StaticPopup_Show("OUROL_HIST_CLEAR", "ALL realms") farmbuyer@37: dialog.data = addon farmbuyer@37: dialog.data2 = function(_addon) farmbuyer@37: _addon.history_all = {} farmbuyer@37: reset_current_realm() farmbuyer@37: end farmbuyer@37: end) farmbuyer@37: specials:AddChild(b) farmbuyer@37: farmbuyer@37: b = mkbutton('hist_clear_old', "Clear Older", farmbuyer@75: [[Preserves only the latest loot entries for players on the displayed realm, removing all earlier ones.]]) farmbuyer@37: b:SetFullWidth(true) farmbuyer@37: b:SetCallback("OnClick", function (_b) farmbuyer@75: local dialog = StaticPopup_Show("OUROL_HIST_PREEN", '', addon.history.realm, addon) farmbuyer@37: dialog.data = addon farmbuyer@75: dialog.data2 = function (_addon, howmany) farmbuyer@75: _addon:preen_history (_addon.history.realm, howmany) farmbuyer@37: _addon.hist_clean = nil farmbuyer@37: histST:OuroLoot_Refresh() farmbuyer@37: end farmbuyer@37: end) farmbuyer@37: specials:AddChild(b) farmbuyer@1: end farmbuyer@37: return tabs_OnGroupSelected["hist"](container,specials) farmbuyer@1: end farmbuyer@83: noob_tips["hist"] = _markup[[ farmbuyer@83: -click a row to see all history for that player. -click any row farmbuyer@83: to return to showing all players. farmbuyer@83: farmbuyer@83: while over an item link to paste it into chat. farmbuyer@83: any row to display a dropdown menu.]] farmbuyer@1: farmbuyer@37: farmbuyer@6: -- Tab 5: Help (content in verbage.lua) farmbuyer@1: do farmbuyer@1: local tabs_help_OnGroupSelected_func = function (treeg,event,category) farmbuyer@1: treeg:ReleaseChildren() farmbuyer@1: local txt = GUI:Create("Label") farmbuyer@1: txt:SetFullWidth(true) farmbuyer@1: txt:SetFontObject(GameFontNormal)--Highlight) farmbuyer@1: txt:SetText(addon.helptext[category]) farmbuyer@1: local sf = GUI:Create("ScrollFrame") farmbuyer@1: local sfstat = _d:GetUserData("help tab scroll status") or {} farmbuyer@1: sf:SetStatusTable(sfstat) farmbuyer@1: _d:SetUserData("help tab scroll status",sfstat) farmbuyer@1: sf:SetLayout("Fill") farmbuyer@1: -- This forces the scrolling area to be bigger than the visible area; else farmbuyer@1: -- some of the text gets cut off. farmbuyer@1: sf.content:SetHeight(700) farmbuyer@1: sf:AddChild(txt) farmbuyer@1: treeg:AddChild(sf) farmbuyer@1: if treeg:GetUserData("help restore scroll") then farmbuyer@1: sfstat = sfstat.scrollvalue farmbuyer@1: if sfstat then sf:SetScroll(sfstat) end farmbuyer@1: treeg:SetUserData("help restore scroll", false) farmbuyer@1: else farmbuyer@1: sf:SetScroll(0) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: tabs_OnGroupSelected["help"] = function(container,specials) farmbuyer@1: container:SetLayout("Fill") farmbuyer@1: local left = GUI:Create("TreeGroup") farmbuyer@1: local leftstat = _d:GetUserData("help tab select status") farmbuyer@1: or {treewidth=145} farmbuyer@1: left:SetStatusTable(leftstat) farmbuyer@1: _d:SetUserData("help tab select status",leftstat) farmbuyer@1: left:SetLayout("Fill") farmbuyer@1: left:SetFullWidth(true) farmbuyer@1: left:SetFullHeight(true) farmbuyer@1: left:EnableButtonTooltips(false) farmbuyer@1: left:SetTree(addon.helptree) farmbuyer@1: left:SetCallback("OnGroupSelected", tabs_help_OnGroupSelected_func) farmbuyer@1: container:AddChild(left) farmbuyer@1: leftstat = leftstat.selected farmbuyer@1: if leftstat then farmbuyer@1: left:SetUserData("help restore scroll", true) farmbuyer@1: left:SelectByValue(leftstat) farmbuyer@1: else farmbuyer@1: left:SelectByValue("basic") farmbuyer@1: end farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@37: farmbuyer@1: -- Tab 6: Options / Advanced farmbuyer@1: do farmbuyer@65: -- Local ref to OuroLootSV_opts, which may be reassigned after load. farmbuyer@65: -- So instead this is updated when the tab is displayed. farmbuyer@65: local opts farmbuyer@1: local function mkoption (opt, label, width, desc, opt_func) farmbuyer@1: local w = mkbutton("CheckBoxSmallLabel", nil, "", desc) farmbuyer@1: w:SetRelativeWidth(width) farmbuyer@1: w:SetType("checkbox") farmbuyer@1: w:SetLabel(label) farmbuyer@1: if opt then farmbuyer@65: w:SetValue(opts[opt]) farmbuyer@1: w:SetCallback("OnValueChanged", opt_func or (function(_w,event,value) farmbuyer@65: opts[opt] = value farmbuyer@1: end)) farmbuyer@1: end farmbuyer@1: return w farmbuyer@1: end farmbuyer@1: farmbuyer@1: local function adv_careful_OnTextChanged (ebox,event,value) farmbuyer@1: -- The EditBox widget's code will call an internal ShowButton routine farmbuyer@1: -- after this callback returns. ShowButton will test for this flag: farmbuyer@1: ebox:DisableButton (value == "") farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- Like the first tab, we use a pair of functions; first and repeating. farmbuyer@1: local function adv_real (container, specials) farmbuyer@1: local grp, w farmbuyer@1: farmbuyer@1: grp = GUI:Create("InlineGroup") farmbuyer@1: grp:SetLayout("Flow") farmbuyer@1: grp:PauseLayout() farmbuyer@1: grp:SetFullWidth(true) farmbuyer@1: grp:SetTitle("Debugging/Testing Options [not saved across sessions]") farmbuyer@1: farmbuyer@1: w = mkbutton("EditBox", 'comm_ident', addon.ident, farmbuyer@73: [[Set tracking to 'Disabled' in the top-right dropdown, then change this field (click Okay or press Enter).]]) farmbuyer@1: w:SetRelativeWidth(0.2) farmbuyer@1: w:SetLabel("Addon channel ID") farmbuyer@1: w:SetCallback("OnTextChanged", adv_careful_OnTextChanged) farmbuyer@1: w:SetCallback("OnEnterPressed", function(_w,event,value) farmbuyer@1: -- if they set it to blank spaces, they're boned. oh well. farmbuyer@1: -- Re-enabling will take care of propogating this new value. farmbuyer@1: addon.ident = (value == "") and "OuroLoot2" or value farmbuyer@1: _w:SetText(addon.ident) farmbuyer@1: addon:Print("Addon channel ID set to '".. addon.ident.. "' for rebroadcasting and listening.") farmbuyer@1: end) farmbuyer@1: w:SetDisabled(addon.enabled or addon.rebroadcast) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@40: w = mkbutton("EditBox", nil, addon.recent_messages.ttl, [[comm cache TTL]]) farmbuyer@1: w:SetRelativeWidth(0.05) farmbuyer@1: w:SetLabel("ttl") farmbuyer@1: w:SetCallback("OnTextChanged", adv_careful_OnTextChanged) farmbuyer@1: w:SetCallback("OnEnterPressed", function(_w,event,value) farmbuyer@1: value = tonumber(value) or addon.recent_messages.ttl farmbuyer@1: addon.recent_messages.ttl = value farmbuyer@1: _w:SetText(tostring(value)) farmbuyer@1: end) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@1: w = mkbutton("load nsaab1548", [[Cursed Darkhound]]) farmbuyer@1: w:SetRelativeWidth(0.25) farmbuyer@1: w:SetCallback("OnClick", function() farmbuyer@1: for i, v in ipairs(DBM.AddOns) do farmbuyer@1: if v.modId == "DBM-NotScaryAtAll" then farmbuyer@1: DBM:LoadMod(v) farmbuyer@1: break farmbuyer@1: end farmbuyer@1: end farmbuyer@1: local mod = DBM:GetModByName("NotScaryAtAll") farmbuyer@1: if mod then farmbuyer@1: mod:EnableMod() farmbuyer@1: addon:Print("Now tracking ID",mod.creatureId) farmbuyer@73: else farmbuyer@73: addon:Print("Can do nothing; DBM testing mod wasn't loaded.") farmbuyer@73: end farmbuyer@1: end) farmbuyer@5: w:SetDisabled(addon.bossmod_registered ~= 'DBM') farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@1: w = mkbutton("GC", [[full GC cycle]]) farmbuyer@1: w:SetRelativeWidth(0.1) farmbuyer@73: w:SetCallback("OnClick", function() farmbuyer@73: local before = collectgarbage('count') farmbuyer@73: collectgarbage('collect') farmbuyer@73: local after = collectgarbage('count') farmbuyer@73: addon:Print("Collected %d KB, %d KB still in use by Lua universe.", before-after, after) farmbuyer@73: end) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@20: w = GUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(1) grp:AddChild(w) farmbuyer@1: farmbuyer@1: local simple = GUI:Create("SimpleGroup") farmbuyer@1: simple:SetLayout("List") farmbuyer@1: simple:SetRelativeWidth(0.3) farmbuyer@74: w = mkbutton("Dropdown", nil, "", [[hovering over Item column only]]) farmbuyer@74: w:SetFullWidth(true) farmbuyer@74: w:SetLabel("loot debugging tooltip") farmbuyer@74: w:SetList{ farmbuyer@74: [1] = "Off", farmbuyer@74: [2] = "/dump into tooltip", farmbuyer@74: [3] = "small fixed fields", farmbuyer@74: } farmbuyer@74: w:SetValue(_do_debugging_tooltip or 1) farmbuyer@74: w:SetCallback("OnValueChanged", function(_w,event,choice) farmbuyer@74: _do_debugging_tooltip = choice > 1 and choice or nil farmbuyer@74: end) farmbuyer@74: simple:AddChild(w) farmbuyer@74: farmbuyer@74: w = GUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(10) simple:AddChild(w) farmbuyer@74: farmbuyer@1: w = GUI:Create("CheckBoxSmallLabel") farmbuyer@1: w:SetFullWidth(true) farmbuyer@1: w:SetType("checkbox") farmbuyer@74: w:SetLabel("debug toggle --->") farmbuyer@1: w:SetValue(addon.DEBUG_PRINT) farmbuyer@19: w:SetCallback("OnValueChanged", function(_w,event,value) farmbuyer@19: addon.DEBUG_PRINT = value farmbuyer@19: addon:redisplay() farmbuyer@19: end) farmbuyer@19: simple:AddChild(w) farmbuyer@19: w = GUI:Create("CheckBoxSmallLabel") farmbuyer@19: w:SetFullWidth(true) farmbuyer@19: w:SetType("checkbox") farmbuyer@19: w:SetLabel("GOP history mode") farmbuyer@73: w:SetValue(addon.history_suppress) farmbuyer@19: w:SetCallback("OnValueChanged", function(_w,event,value) addon.history_suppress = value end) farmbuyer@1: simple:AddChild(w) farmbuyer@1: w = mkbutton("Clear All & Reload", farmbuyer@1: [[No confirmation! |cffff1010Erases absolutely all> Ouro Loot saved variables and reloads the UI.]]) farmbuyer@1: w:SetFullWidth(true) farmbuyer@1: w:SetCallback("OnClick", function() farmbuyer@8: addon:_clear_SVs() -- reloads farmbuyer@1: end) farmbuyer@1: simple:AddChild(w) farmbuyer@1: grp:AddChild(simple) farmbuyer@1: farmbuyer@1: simple = GUI:Create("SimpleGroup") farmbuyer@1: simple:SetLayout("List") farmbuyer@1: simple:SetRelativeWidth(0.5) farmbuyer@1: for d,v in pairs(addon.debug) do farmbuyer@1: w = GUI:Create("CheckBoxSmallLabel") farmbuyer@1: w:SetFullWidth(true) farmbuyer@1: w:SetType("checkbox") farmbuyer@1: w:SetLabel(d) farmbuyer@1: if d == "notraid" then farmbuyer@39: w:SetDescription[[Tick this before enabling to make the addon work outside of raid groups]] farmbuyer@19: else farmbuyer@40: if d == "alsolog" then farmbuyer@40: w:SetDescription[[Also log all debug messages to disk. See print_log.lua in the addon folder for later viewing.]] farmbuyer@40: end farmbuyer@19: w:SetDisabled(not addon.DEBUG_PRINT) farmbuyer@1: end farmbuyer@1: w:SetValue(v) farmbuyer@1: w:SetCallback("OnValueChanged", function(_w,event,value) addon.debug[d] = value end) farmbuyer@1: simple:AddChild(w) farmbuyer@1: end farmbuyer@1: grp:AddChild(simple) farmbuyer@10: farmbuyer@10: simple = GUI:Create("SimpleGroup") farmbuyer@10: simple:SetLayout("Flow") farmbuyer@10: simple:SetRelativeWidth(0.85) farmbuyer@10: w = mkbutton("MidS-H", [[not exactly an Easter egg, with sound]]) farmbuyer@10: w:SetRelativeWidth(0.15) farmbuyer@10: w:SetCallback("OnClick", function() farmbuyer@77: PlaySoundFile ([[Sound\Music\WorldEvents\HordeFirepole.mp3]], "Master") farmbuyer@10: end) farmbuyer@10: simple:AddChild(w) farmbuyer@10: w = mkbutton("MidS-A", [[not exactly an Easter egg, with sound]]) farmbuyer@10: w:SetRelativeWidth(0.15) farmbuyer@10: w:SetCallback("OnClick", function() farmbuyer@77: PlaySoundFile ([[Sound\Music\WorldEvents\AllianceFirepole.mp3]], "Master") farmbuyer@77: end) farmbuyer@77: simple:AddChild(w) farmbuyer@77: w = mkbutton("SFRR", [[test]]) farmbuyer@77: w:SetRelativeWidth(0.15) farmbuyer@77: w:SetCallback("OnClick", function() farmbuyer@77: PlaySoundFile ([[Interface\AddOns\Ouro_Loot\sfrr.ogg]], "Master") farmbuyer@10: end) farmbuyer@10: simple:AddChild(w) farmbuyer@10: grp:AddChild(simple) farmbuyer@10: farmbuyer@1: grp:ResumeLayout() farmbuyer@1: container:AddChild(grp) farmbuyer@1: GUI:ClearFocus() farmbuyer@73: container:SetScroll(1000) -- scrollframe's max value farmbuyer@1: end farmbuyer@1: farmbuyer@76: -- Initial lower panel function (unless debug mode is on during load, which farmbuyer@76: -- means it was almost certainly hardcoded that way, which means it's farmbuyer@76: -- probably me testing). farmbuyer@76: local adv_lower farmbuyer@76: if addon.DEBUG_PRINT then farmbuyer@76: adv_lower = adv_real farmbuyer@76: else farmbuyer@76: function adv_lower (container, specials) farmbuyer@76: local spacer = GUI:Create("Spacer") farmbuyer@76: spacer:SetFullWidth(true) farmbuyer@76: spacer:SetHeight(5) farmbuyer@76: container:AddChild(spacer) farmbuyer@76: local speedbump = GUI:Create("InteractiveLabel") farmbuyer@76: speedbump:SetFullWidth(true) farmbuyer@76: speedbump:SetFontObject(GameFontHighlightLarge) farmbuyer@83: speedbump:SetImage[[Interface\DialogFrame\DialogAlertIcon]] farmbuyer@76: speedbump:SetImageSize(50,50) farmbuyer@76: 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.") farmbuyer@76: speedbump:SetCallback("OnClick", function (_sb) farmbuyer@76: adv_lower = adv_real farmbuyer@76: return addon:redisplay() farmbuyer@76: end) farmbuyer@76: container:AddChild(speedbump) farmbuyer@76: spacer = GUI:Create("Spacer") farmbuyer@76: spacer:SetFullWidth(true) farmbuyer@76: spacer:SetHeight(5) farmbuyer@76: container:AddChild(spacer) farmbuyer@76: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: tabs_OnGroupSelected["opt"] = function(container,specials) farmbuyer@65: opts = OuroLootSV_opts farmbuyer@65: farmbuyer@1: container:SetLayout("Fill") farmbuyer@1: local scroll, grp, w farmbuyer@1: farmbuyer@1: scroll = GUI:Create("ScrollFrame") farmbuyer@1: scroll:SetLayout("Flow") farmbuyer@1: farmbuyer@1: grp = GUI:Create("InlineGroup") farmbuyer@1: grp:SetLayout("Flow") farmbuyer@1: grp:SetFullWidth(true) farmbuyer@1: grp:SetTitle("User Options [these are saved across sessions]") farmbuyer@1: farmbuyer@83: -- The relative width fields used to be done to take up less vertical farmbuyer@83: -- space, but that turned out to look messy. Now they're just a farmbuyer@83: -- straight line for the most part. farmbuyer@83: farmbuyer@83: -- the nubtoggle! farmbuyer@83: w = mkoption('gui_noob', [[Show UI Tips]], 0.85, farmbuyer@83: [[Toggles display of the "helpful tips" box on the right side. Useful if you've just installed/upgraded.]]) farmbuyer@83: w:SetImage[[Interface\OptionsFrame\UI-OptionsFrame-NewFeatureIcon]] farmbuyer@83: grp:AddChild(w) farmbuyer@83: w = GUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(10) grp:AddChild(w) farmbuyer@10: farmbuyer@1: -- reminder popup farmbuyer@83: w = mkoption ('popup_on_join', "Show reminder popup on new raid", 0.49, farmbuyer@1: [[When joining a raid and not already tracking, display a dialog asking for instructions.]]) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@1: -- toggle scroll-to-bottom on first tab farmbuyer@16: w = mkoption('scroll_to_bottom', "Scroll to bottom when opening display", 0.49, farmbuyer@1: [[Scroll to the bottom of the loot window (most recent entries) when displaying the GUI.]]) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@1: -- /loot option farmbuyer@16: w = mkoption('register_slashloot', "Register /loot slash command on login", 0.49, farmbuyer@1: [[Register "/loot" as a slash command in addition to the normal "/ouroloot". Relog to take effect.]]) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@73: -- chatty boss mode farmbuyer@16: w = mkoption('chatty_on_kill', "Be chatty on boss kill", 0.49, farmbuyer@83: [[Print something to chat output when the boss mod tells Ouro Loot about a successful boss kill.]]) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@1: -- less noise in main panel farmbuyer@16: w = mkoption('no_tracking_wipes', "Do not track wipes", 0.49, farmbuyer@1: [[Do not add 'wipe' entries on the main loot grid, or generate any text for them.]]) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@1: -- cutesy abbrevs farmbuyer@16: w = mkoption('snarky_boss', "Use snarky boss names", 0.49, farmbuyer@83: [[Irreverent replacement names for boss events. See abbreviations.lua for details.]]) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@57: -- LOD plugins in all cases farmbuyer@57: w = mkoption('display_disabled_LODs', "Include disabled plugins", 0.49, farmbuyer@57: [[Show loadable plugins even if they've been disabled (and offer to enable them). Relog to take effect.]]) farmbuyer@57: grp:AddChild(w) farmbuyer@57: farmbuyer@65: -- showing the "(from Rebroadcasterdude)" in the notes column farmbuyer@65: w = mkoption('display_bcast_from', "Show rebroadcasting player", 0.49, farmbuyer@73: [[Include "from PlayerName" in the Notes column for loot that was broadcast to you. (Not included in forum output).]], farmbuyer@65: function(_w,_e,value) farmbuyer@65: opts.display_bcast_from = value farmbuyer@65: addon.loot_clean = nil farmbuyer@65: end) farmbuyer@65: grp:AddChild(w) farmbuyer@65: farmbuyer@73: -- prefilling g_uniques with history farmbuyer@73: w = mkoption('precache_history_uniques', "Prescan for faster handling", 0.49, farmbuyer@73: [[See description under +Help -- Handy Tips -- Prescanning> for instructions.]]) farmbuyer@73: grp:AddChild(w) farmbuyer@73: farmbuyer@73: w = GUI:Create("Spacer") w:SetFullWidth(true) w:SetHeight(1) grp:AddChild(w) farmbuyer@73: farmbuyer@1: -- possible keybindings farmbuyer@1: do farmbuyer@73: local pair = GUI:Create("InlineGroup") farmbuyer@73: pair:SetLayout("List") farmbuyer@73: pair:SetRelativeWidth(0.49) farmbuyer@1: local editbox, checkbox farmbuyer@65: editbox = mkbutton("EditBox", nil, opts.keybinding_text, farmbuyer@83: [[Keybinding text format is fragile (ALT then CTRL then SHIFT)! Relog to take effect.]]) farmbuyer@73: editbox:SetFullWidth(true) farmbuyer@1: editbox:SetLabel("Keybinding text") farmbuyer@1: editbox:SetCallback("OnEnterPressed", function(_w,event,value) farmbuyer@65: opts.keybinding_text = value farmbuyer@1: end) farmbuyer@65: editbox:SetDisabled(not opts.keybinding) farmbuyer@73: checkbox = mkoption('keybinding', "Register keybinding", 1, farmbuyer@1: [[Register a keybinding to toggle the loot display. Relog to take effect.]], farmbuyer@1: function (_w,_,value) farmbuyer@65: opts.keybinding = value farmbuyer@65: editbox:SetDisabled(not opts.keybinding) farmbuyer@1: end) farmbuyer@73: checkbox:SetFullWidth(true) farmbuyer@1: pair:AddChild(checkbox) farmbuyer@1: pair:AddChild(editbox) farmbuyer@1: grp:AddChild(pair) farmbuyer@1: end farmbuyer@1: farmbuyer@73: -- chatty disposition/assignment changes farmbuyer@73: do farmbuyer@73: local chatgroup = GUI:Create("InlineGroup") farmbuyer@73: chatgroup:SetLayout("List") farmbuyer@73: chatgroup:SetRelativeWidth(0.49) farmbuyer@73: chatgroup:SetTitle("Remote Changes Chat") farmbuyer@73: local toggle, editbox farmbuyer@73: toggle = mkoption('chatty_on_remote_changes', "Be chatty on remote changes", 1, farmbuyer@73: [[Print something to chat when other users change recorded loot.]], farmbuyer@73: function (_w,_,value) farmbuyer@73: opts.chatty_on_remote_changes = value farmbuyer@73: editbox:SetDisabled(not opts.chatty_on_remote_changes) farmbuyer@73: end) farmbuyer@73: toggle:SetFullWidth(true) farmbuyer@73: chatgroup:AddChild(toggle) farmbuyer@73: w = GUI:Create("Label") farmbuyer@73: w:SetFullWidth(true) farmbuyer@73: 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.") farmbuyer@73: chatgroup:AddChild(w) farmbuyer@73: editbox = mkbutton("EditBox", nil, opts.chatty_on_remote_changes_frame, farmbuyer@73: [[1 = default chat frame, 2 = combat log, etc]]) farmbuyer@73: editbox:SetFullWidth(true) farmbuyer@73: editbox:SetLabel("Output Chatframe") farmbuyer@73: editbox:SetCallback("OnTextChanged", adv_careful_OnTextChanged) farmbuyer@73: editbox:SetCallback("OnEnterPressed", function(_w,event,value) farmbuyer@73: local prev = opts.chatty_on_remote_changes_frame farmbuyer@73: value = value:trim() farmbuyer@73: value = tonumber(value) or value farmbuyer@73: if addon:_set_remote_change_chatframe (value) then farmbuyer@73: opts.chatty_on_remote_changes_frame = value farmbuyer@73: _w:SetText(tostring(value)) farmbuyer@73: _w.editbox:ClearFocus() farmbuyer@73: else farmbuyer@73: _w:SetText(tostring(prev)) farmbuyer@73: end farmbuyer@73: end) farmbuyer@73: editbox:SetDisabled(not opts.chatty_on_remote_changes) farmbuyer@73: chatgroup:AddChild(editbox) farmbuyer@73: w = mkbutton("Chat Frame Numbers", farmbuyer@73: [[Print each chat window number in its own frame, for easy reference in the editing field.]]) farmbuyer@73: w:SetFullWidth(true) farmbuyer@73: w:SetCallback("OnClick", function() farmbuyer@73: for i = 1, NUM_CHAT_WINDOWS do farmbuyer@73: local cf = _G['ChatFrame'..i] farmbuyer@73: if not cf then break end farmbuyer@73: addon:CFPrint (cf, "This is frame number |cffff0000%d|r.", i) farmbuyer@73: end farmbuyer@73: end) farmbuyer@73: chatgroup:AddChild(w) farmbuyer@73: grp:AddChild(chatgroup) farmbuyer@73: end farmbuyer@73: farmbuyer@3: -- boss mod selection farmbuyer@3: w = GUI:Create("Spacer") farmbuyer@3: w:SetFullWidth(true) farmbuyer@73: w:SetHeight(2) farmbuyer@3: grp:AddChild(w) farmbuyer@3: do farmbuyer@3: local list = {} farmbuyer@3: local current farmbuyer@3: for k,v in ipairs(addon.bossmods) do farmbuyer@3: list[k] = v.n farmbuyer@65: if v.n == opts.bossmod then farmbuyer@3: current = k farmbuyer@3: end farmbuyer@3: end farmbuyer@3: w = mkbutton("Dropdown", nil, "", [[Which 'boss mod' to use.]]) farmbuyer@3: w:SetRelativeWidth(0.2) farmbuyer@3: w:SetLabel("Boss Mod:") farmbuyer@3: w:SetList(list) farmbuyer@3: w:SetValue(current) farmbuyer@3: w:SetCallback("OnValueChanged", function(_w,event,choice) farmbuyer@65: opts.bossmod = list[choice] farmbuyer@3: end) farmbuyer@3: grp:AddChild(w) farmbuyer@3: end farmbuyer@3: farmbuyer@70: -- item filters farmbuyer@1: w = GUI:Create("Spacer") farmbuyer@1: w:SetFullWidth(true) farmbuyer@73: w:SetHeight(2) farmbuyer@1: grp:AddChild(w) farmbuyer@1: do farmbuyer@70: 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." farmbuyer@54: local cache_warn, cache_warned = false, false farmbuyer@70: local function do_warning() farmbuyer@70: if cache_warn and not cache_warned then farmbuyer@70: cache_warned = true farmbuyer@70: addon:Print(warntext) farmbuyer@70: end farmbuyer@70: end farmbuyer@70: farmbuyer@70: local filterlist, vaultlist = {}, {} farmbuyer@65: for id in pairs(opts.itemfilter) do farmbuyer@1: local iname, _, iquality = GetItemInfo(id) farmbuyer@2: if iname then farmbuyer@70: filterlist[id] = ITEM_QUALITY_COLORS[iquality].hex .. iname .. "|r" farmbuyer@54: else farmbuyer@54: cache_warn = true farmbuyer@2: end farmbuyer@1: end farmbuyer@70: for id in pairs(opts.itemvault) do farmbuyer@70: local iname, _, iquality = GetItemInfo(id) farmbuyer@70: if iname then farmbuyer@70: vaultlist[id] = ITEM_QUALITY_COLORS[iquality].hex .. iname .. "|r" farmbuyer@70: else farmbuyer@70: cache_warn = true farmbuyer@70: end farmbuyer@70: end farmbuyer@70: farmbuyer@1: w = GUI:Create("EditBoxDropDown") farmbuyer@1: w:SetRelativeWidth(0.4) farmbuyer@1: w:SetText("Item filter") farmbuyer@1: w:SetEditBoxTooltip("Link items which should no longer be tracked.") farmbuyer@70: w:SetList(filterlist) farmbuyer@1: w:SetCallback("OnTextEnterPressed", function(_w, _, text) farmbuyer@73: local iname, ilink, iquality = GetItemInfo(text:trim()) farmbuyer@1: if not iname then farmbuyer@1: return addon:Print("Error: %s is not a valid item name/link!", text) farmbuyer@1: end farmbuyer@1: local id = tonumber(ilink:match("item:(%d+)")) farmbuyer@70: filterlist[id] = ITEM_QUALITY_COLORS[iquality].hex .. iname .. "|r" farmbuyer@65: opts.itemfilter[id] = true farmbuyer@1: addon:Print("Now filtering out", ilink) farmbuyer@1: end) farmbuyer@1: w:SetCallback("OnListItemClicked", function(_w, _, key_id, val_name) farmbuyer@1: --local ilink = select(2,GetItemInfo(key_id)) farmbuyer@65: opts.itemfilter[tonumber(key_id)] = nil farmbuyer@1: --addon:Print("No longer filtering out", ilink) farmbuyer@1: addon:Print("No longer filtering out", val_name) farmbuyer@1: end) farmbuyer@70: w:SetCallback("OnDropdownShown",do_warning) farmbuyer@70: grp:AddChild(w) farmbuyer@70: farmbuyer@70: w = GUI:Create("Spacer") farmbuyer@70: w:SetRelativeWidth(0.1) farmbuyer@70: w:SetHeight(2) farmbuyer@70: grp:AddChild(w) farmbuyer@70: farmbuyer@70: w = GUI:Create("EditBoxDropDown") farmbuyer@70: w:SetRelativeWidth(0.4) farmbuyer@70: w:SetText("Vault items") farmbuyer@70: w:SetEditBoxTooltip("Link items which should be automatically marked as guild vault.") farmbuyer@70: w:SetList(vaultlist) farmbuyer@70: w:SetCallback("OnTextEnterPressed", function(_w, _, text) farmbuyer@73: local iname, ilink, iquality = GetItemInfo(text:trim()) farmbuyer@70: if not iname then farmbuyer@70: return addon:Print("Error: %s is not a valid item name/link!", text) farmbuyer@54: end farmbuyer@70: local id = tonumber(ilink:match("item:(%d+)")) farmbuyer@70: vaultlist[id] = ITEM_QUALITY_COLORS[iquality].hex .. iname .. "|r" farmbuyer@70: opts.itemvault[id] = true farmbuyer@70: addon:Print("Now auto-vaulting", ilink) farmbuyer@54: end) farmbuyer@70: w:SetCallback("OnListItemClicked", function(_w, _, key_id, val_name) farmbuyer@70: --local ilink = select(2,GetItemInfo(key_id)) farmbuyer@70: opts.itemfilter[tonumber(key_id)] = nil farmbuyer@70: --addon:Print("No longer filtering out", ilink) farmbuyer@70: addon:Print("No longer auto-vaulting", val_name) farmbuyer@70: end) farmbuyer@70: w:SetCallback("OnDropdownShown",do_warning) farmbuyer@1: grp:AddChild(w) farmbuyer@1: end farmbuyer@1: farmbuyer@1: addon.sender_list.sort() farmbuyer@1: if #addon.sender_list.namesI > 0 then farmbuyer@1: local senders = table.concat(addon.sender_list.namesI,'\n') -- sigh farmbuyer@1: -- If 39 other people in the raid are running this, the label will farmbuyer@1: -- explode... is it likely enough to care about? No. farmbuyer@1: w = GUI:Create("Spacer") farmbuyer@1: w:SetFullWidth(true) farmbuyer@1: w:SetHeight(20) farmbuyer@1: grp:AddChild(w) farmbuyer@1: w = GUI:Create("Label") farmbuyer@1: w:SetRelativeWidth(0.4) farmbuyer@11: w:SetText(ITEM_QUALITY_COLORS[3].hex .."Echo from latest ping:|r\n"..senders) farmbuyer@1: grp:AddChild(w) farmbuyer@1: end farmbuyer@1: farmbuyer@6: scroll:AddChild(grp) farmbuyer@6: farmbuyer@1: w = mkbutton("ReloadUI", [[Does what you think it does. Loot information is written out and restored.]]) farmbuyer@1: w:SetFullWidth(true) farmbuyer@1: w:SetCallback("OnClick", ReloadUI) farmbuyer@1: specials:AddChild(w) farmbuyer@1: farmbuyer@1: w = mkbutton("Ping!", farmbuyer@1: [[Asks other raid users for their addon version and current status. Results displayed on User Options panel.]]) farmbuyer@1: w:SetFullWidth(true) farmbuyer@1: w:SetCallback("OnClick", function(_w) farmbuyer@1: _w:SetText("5... 4... 3...") farmbuyer@1: _w:SetDisabled(true) farmbuyer@23: addon:DoPing() farmbuyer@1: addon:ScheduleTimer(function(b) farmbuyer@1: if b:IsVisible() then farmbuyer@1: return addon:redisplay() farmbuyer@1: end farmbuyer@1: end, 5, _w) farmbuyer@1: end) farmbuyer@1: specials:AddChild(w) farmbuyer@1: farmbuyer@1: -- Add appropriate lower panel farmbuyer@1: adv_lower (scroll, specials) farmbuyer@1: farmbuyer@1: -- Finish up farmbuyer@1: container:AddChild(scroll) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: -- Simply to avoid recreating the same function over and over farmbuyer@1: local tabs_OnGroupSelected_func_args = { [2] = "OnGroupSelected" } farmbuyer@1: tabs_OnGroupSelected_func = function (tabs,event,group) farmbuyer@1: tabs_OnGroupSelected_func_args[1] = tabs farmbuyer@1: tabs_OnGroupSelected_func_args[3] = group farmbuyer@83: hide_noobtips_frame() farmbuyer@1: tabs:ReleaseChildren() farmbuyer@1: local spec = tabs:GetUserData("special buttons group") farmbuyer@1: spec:ReleaseChildren() farmbuyer@1: local h = GUI:Create("Heading") farmbuyer@1: h:SetFullWidth(true) farmbuyer@1: h:SetText(_tabtexts[group].title) farmbuyer@1: spec:AddChild(h) farmbuyer@76: do farmbuyer@76: addon.sender_list.sort() farmbuyer@76: local fmt = "Received broadcast data from %d |4player:players;." farmbuyer@76: if addon.history_suppress then farmbuyer@76: -- this is the druid class color reworked into hex farmbuyer@76: fmt = fmt .. " |cffff7d0aHistory recording suppressed.|r" farmbuyer@76: end farmbuyer@76: tabs.titletext:SetFormattedText (fmt, addon.sender_list.activeI) farmbuyer@76: end farmbuyer@81: local status,err = pcall (tabs_OnGroupSelected[group], tabs, spec, group) farmbuyer@81: if not status then farmbuyer@81: addon:horrible_horrible_error(err) farmbuyer@81: end farmbuyer@83: if OuroLootSV_opts.gui_noob then farmbuyer@83: local tip = noob_tips[group] farmbuyer@83: if type(tip) == 'function' then farmbuyer@83: tip = tip() farmbuyer@83: end farmbuyer@83: if type(tip) == 'string' and tip ~= "" then farmbuyer@83: local w = get_noobtips_frame() farmbuyer@83: w:SetParent (_d.content) farmbuyer@83: w:ClearAllPoints() farmbuyer@83: w:SetPoint("BOTTOMLEFT", _d.frame, "BOTTOMRIGHT", 3, 3) farmbuyer@83: w:Show() farmbuyer@83: w:DoTextWork(tip) farmbuyer@83: end farmbuyer@83: end farmbuyer@1: --[====[ farmbuyer@1: Unfortunately, :GetHeight() called on anything useful out of a TabGroup farmbuyer@1: returns the static default size (about 50 pixels) until the refresh farmbuyer@1: cycle *after* all the frames are shown. Trying to fix it up after a farmbuyer@1: single OnUpdate doesn't work either. So for now it's all hardcoded. farmbuyer@1: farmbuyer@83: Using this to determine the actual height of the usable area. (Will farmbuyer@83: error until an ST is shown, which only happens if it's tracking, etc.) farmbuyer@83: 416 pixels farmbuyer@1: if group == "eoi" then farmbuyer@1: local stframe = tabs.children[1].frame farmbuyer@1: print(stframe:GetTop(),"-",stframe:GetBottom(),"=", farmbuyer@1: stframe:GetTop()-stframe:GetBottom()) farmbuyer@1: print(stframe:GetRight(),"-",stframe:GetLeft(),"=", farmbuyer@1: stframe:GetRight()-stframe:GetLeft()) farmbuyer@1: end farmbuyer@1: ]====] farmbuyer@1: end farmbuyer@1: farmbuyer@1: --[[ farmbuyer@1: mkbutton ("WidgetType", 'display key', "Text On Widget", "the mouseover display text") farmbuyer@1: mkbutton ( [Button] 'display key', "Text On Widget", "the mouseover display text") farmbuyer@1: mkbutton ( [Button] [text] "Text On Widget", "the mouseover display text") farmbuyer@1: ]] farmbuyer@83: function mkbutton (opt_widget_type, opt_key, label, status) farmbuyer@83: if not label then farmbuyer@83: opt_widget_type, opt_key, label, status = "Button", opt_widget_type, opt_widget_type, opt_key farmbuyer@83: elseif not status then farmbuyer@83: opt_widget_type, opt_key, label, status = "Button", opt_widget_type, opt_key, label farmbuyer@1: end farmbuyer@83: local button = assert(GUI:Create(opt_widget_type)) farmbuyer@83: if button.SetText then button:SetText(tostring(label)) end farmbuyer@83: status = _markup(status) farmbuyer@83: button:SetCallback("OnEnter", function() setstatus(status) end) -- maybe factor that closure out farmbuyer@83: button:SetCallback("OnLeave", statusy_OnLeave) farmbuyer@83: -- retrieval key may be specified as nil if all the parameters are given farmbuyer@83: if opt_key then _d:SetUserData (opt_key, button) end farmbuyer@83: return button farmbuyer@1: end farmbuyer@1: farmbuyer@1: --[[ farmbuyer@1: Creates the main window. farmbuyer@1: ]] farmbuyer@1: function addon:BuildMainDisplay (opt_tabselect) farmbuyer@1: if self.display then farmbuyer@1: -- try to get everything to update, rebuild, refresh... ugh, no farmbuyer@1: self.display:Hide() farmbuyer@1: end farmbuyer@67: if self.NOLOAD then return end -- don't even try farmbuyer@1: farmbuyer@25: -- This probably causes taint... hm. farmbuyer@25: local prev_fade_time = UIDROPDOWNMENU_SHOW_TIME farmbuyer@25: UIDROPDOWNMENU_SHOW_TIME = 4 farmbuyer@25: farmbuyer@47: if dirty_tabs then farmbuyer@84: -- pointers known to be good by now, pass them back in farmbuyer@84: self:gui_init (g_loot, g_uniques) farmbuyer@47: self:zero_printed_fenceposts() farmbuyer@47: end farmbuyer@47: farmbuyer@1: local display = GUI:Create("Frame") farmbuyer@1: if _d then farmbuyer@79: display:SetUserData("eoiST",_d) -- warning! warning! kludge detected! farmbuyer@1: end farmbuyer@1: _d = display farmbuyer@1: self.display = display farmbuyer@17: display:SetTitle(window_title) farmbuyer@1: display:SetStatusText(self.status_text) farmbuyer@1: display:SetLayout("Flow") farmbuyer@16: display:SetStatusTable{width=900,height=550} -- default height is 500 farmbuyer@47: display:EnableResize(false) farmbuyer@1: display:SetCallback("OnClose", function(_display) farmbuyer@25: UIDROPDOWNMENU_SHOW_TIME = prev_fade_time farmbuyer@83: hide_noobtips_frame() farmbuyer@1: _d = _display:GetUserData("eoiST") farmbuyer@1: self.display = nil farmbuyer@1: GUI:Release(_display) farmbuyer@6: flib.clear() farmbuyer@1: collectgarbage() farmbuyer@1: end) farmbuyer@1: farmbuyer@1: ----- Right-hand panel farmbuyer@1: local rhs_width = 0.20 farmbuyer@1: local control = GUI:Create("SimpleGroup") farmbuyer@1: control:SetLayout("Flow") farmbuyer@1: control:SetRelativeWidth(rhs_width) farmbuyer@1: control.alignoffset = 25 farmbuyer@1: control:PauseLayout() farmbuyer@1: local h,b farmbuyer@1: farmbuyer@1: --- Main --- farmbuyer@1: h = GUI:Create("Heading") farmbuyer@1: h:SetFullWidth(true) farmbuyer@1: h:SetText("Main") farmbuyer@1: control:AddChild(h) farmbuyer@1: farmbuyer@1: do farmbuyer@1: b = mkbutton("Dropdown", nil, "", farmbuyer@1: [[Enable full tracking, only rebroadcasting, or disable activity altogether.]]) farmbuyer@1: b:SetFullWidth(true) farmbuyer@1: b:SetLabel("On/Off:") farmbuyer@1: b:SetList{"Full Tracking", "Broadcasting", "Disabled"} farmbuyer@1: b:SetValue(self.enabled and 1 or (self.rebroadcast and 2 or 3)) farmbuyer@1: b:SetCallback("OnValueChanged", function(_w,event,choice) farmbuyer@1: if choice == 1 then self:Activate() farmbuyer@1: elseif choice == 2 then self:Activate(nil,true) farmbuyer@1: else self:Deactivate() farmbuyer@1: end farmbuyer@1: _w = display:GetUserData('comm_ident') farmbuyer@1: if _w and _w:IsVisible() then farmbuyer@1: _w:SetDisabled(self.enabled or self.rebroadcast) farmbuyer@1: end farmbuyer@1: _w = display:GetUserData('eoi_bcast_req') farmbuyer@1: if _w and _w:IsVisible() then farmbuyer@1: _w:SetDisabled(not self.enabled) farmbuyer@1: end farmbuyer@1: end) farmbuyer@1: control:AddChild(b) farmbuyer@1: end farmbuyer@1: farmbuyer@1: b = mkbutton("Dropdown", 'threshold', "", farmbuyer@1: [[Items greater than or equal to this quality will be tracked/rebroadcast.]]) farmbuyer@1: b:SetFullWidth(true) farmbuyer@1: b:SetLabel("Threshold:") farmbuyer@1: b:SetList(self.thresholds) farmbuyer@1: b:SetValue(self.threshold) farmbuyer@1: b:SetCallback("OnValueChanged", function(_dd,event,choice) farmbuyer@1: self:SetThreshold(choice) farmbuyer@1: end) farmbuyer@1: control:AddChild(b) farmbuyer@1: farmbuyer@4: b = mkbutton("Clear Loot", farmbuyer@1: [[+Erases> all current loot information and generated text (but not saved texts).]]) farmbuyer@1: b:SetFullWidth(true) farmbuyer@1: b:SetCallback("OnClick", function() farmbuyer@1: StaticPopup_Show("OUROL_CLEAR").data = self farmbuyer@1: end) farmbuyer@1: control:AddChild(b) farmbuyer@1: farmbuyer@1: b = GUI:Create("Spacer") farmbuyer@1: b:SetFullWidth(true) farmbuyer@16: b:SetHeight(10) farmbuyer@1: control:AddChild(b) farmbuyer@1: farmbuyer@1: --[[ farmbuyer@1: --- Saved Texts --- farmbuyer@1: [ Save Current As... ] farmbuyer@1: saved1 farmbuyer@1: saved2 farmbuyer@1: ... farmbuyer@1: [ Load ] [ Delete ] farmbuyer@1: ]] farmbuyer@1: h = GUI:Create("Heading") farmbuyer@1: h:SetFullWidth(true) farmbuyer@1: h:SetText("Saved Texts") farmbuyer@1: control:AddChild(h) farmbuyer@1: b = mkbutton("Save Current As...", farmbuyer@1: [[Save forum/attendance/etc texts for later retrieval. Main loot information not included.]]) farmbuyer@1: b:SetFullWidth(true) farmbuyer@1: b:SetCallback("OnClick", function() farmbuyer@1: StaticPopup_Show "OUROL_SAVE_SAVEAS" farmbuyer@1: _d:Hide() farmbuyer@1: end) farmbuyer@1: control:AddChild(b) farmbuyer@1: farmbuyer@16: do farmbuyer@16: local scontainer = GUI:Create("SimpleGroup") farmbuyer@16: scontainer:SetFullWidth(true) farmbuyer@16: scontainer:SetFullHeight(false) farmbuyer@16: scontainer:SetAutoAdjustHeight(false) farmbuyer@16: scontainer:SetHeight(40) -- no relative height available anymore farmbuyer@16: scontainer:SetLayout("Fill") farmbuyer@16: local scroll = GUI:Create("ScrollFrame") farmbuyer@16: scroll:SetLayout("List") farmbuyer@16: local saved = self:check_saved_table(--[[silent_on_empty=]]true) farmbuyer@16: if saved then for i,s in ipairs(saved) do farmbuyer@16: local il = GUI:Create("InteractiveLabel") farmbuyer@16: il:SetFullWidth(true) farmbuyer@16: il:SetText(s.name) farmbuyer@16: il:SetUserData("num",i) farmbuyer@16: il:SetHighlight(1,1,1,0.4) farmbuyer@16: local str = ("%s %d entries %s"):format(s.date,s.count,s.name) farmbuyer@16: il:SetCallback("OnEnter", function() setstatus(str) end) farmbuyer@16: il:SetCallback("OnLeave", statusy_OnLeave) farmbuyer@16: il:SetCallback("OnClick", function(_il) farmbuyer@16: local prev = _d:GetUserData("saved selection") farmbuyer@16: if prev then farmbuyer@16: prev.highlight:Hide() farmbuyer@16: prev:SetColor() farmbuyer@16: end farmbuyer@16: _il:SetColor(0,1,0) farmbuyer@16: _il.highlight:Show() farmbuyer@16: _d:SetUserData("saved selection",_il) farmbuyer@16: _d:GetUserData("Load"):SetDisabled(false) farmbuyer@16: _d:GetUserData("Delete"):SetDisabled(false) farmbuyer@16: end) farmbuyer@16: scroll:AddChild(il) farmbuyer@16: end end farmbuyer@16: scontainer:AddChild(scroll) farmbuyer@16: control:AddChild(scontainer) farmbuyer@16: end farmbuyer@1: farmbuyer@1: b = mkbutton("Load", farmbuyer@1: [[Load previously saved text. +REPLACES> all current loot information!]]) farmbuyer@1: b:SetRelativeWidth(0.5) farmbuyer@1: b:SetCallback("OnClick", function() farmbuyer@1: local num = _d:GetUserData("saved selection"):GetUserData("num") farmbuyer@1: self:save_restore(num) farmbuyer@1: self:BuildMainDisplay() farmbuyer@1: end) farmbuyer@1: b:SetDisabled(true) farmbuyer@1: control:AddChild(b) farmbuyer@1: b = mkbutton("Delete", farmbuyer@1: [[Delete previously saved text.]]) farmbuyer@1: b:SetRelativeWidth(0.5) farmbuyer@1: b:SetCallback("OnClick", function() farmbuyer@1: local num = _d:GetUserData("saved selection"):GetUserData("num") farmbuyer@1: self:save_delete(num) farmbuyer@1: self:BuildMainDisplay() farmbuyer@1: end) farmbuyer@1: b:SetDisabled(true) farmbuyer@1: control:AddChild(b) farmbuyer@1: farmbuyer@1: b = GUI:Create("Spacer") farmbuyer@1: b:SetFullWidth(true) farmbuyer@16: b:SetHeight(10) farmbuyer@1: control:AddChild(b) farmbuyer@1: farmbuyer@1: -- Other stuff on right-hand side farmbuyer@1: local tab_specials = GUI:Create("SimpleGroup") farmbuyer@1: tab_specials:SetLayout("Flow") farmbuyer@1: tab_specials:SetFullWidth(true) farmbuyer@1: control:AddChild(tab_specials) farmbuyer@1: control:ResumeLayout() farmbuyer@1: farmbuyer@1: ----- Left-hand group farmbuyer@1: local tabs = GUI:Create("TabGroup") farmbuyer@1: tabs:SetLayout("Flow") farmbuyer@1: tabs.alignoffset = 25 farmbuyer@49: local titletext_orig_fo = tabs.titletext:GetFontObject() farmbuyer@49: tabs.titletext:SetFontObject(GameFontNormalSmall) farmbuyer@49: tabs:SetCallback("OnRelease", function(_tabs) farmbuyer@49: tabs.titletext:SetFontObject(titletext_orig_fo) farmbuyer@49: end) farmbuyer@1: tabs:SetRelativeWidth(0.99-rhs_width) farmbuyer@1: tabs:SetFullHeight(true) farmbuyer@1: tabs:SetTabs(tabgroup_tabs) farmbuyer@1: tabs:SetCallback("OnGroupSelected", tabs_OnGroupSelected_func) farmbuyer@1: tabs:SetCallback("OnTabEnter", function(_tabs,event,value,tab) farmbuyer@1: setstatus(_tabtexts[value].desc) farmbuyer@1: end) farmbuyer@1: tabs:SetCallback("OnTabLeave", statusy_OnLeave) farmbuyer@1: tabs:SetUserData("special buttons group",tab_specials) farmbuyer@76: tabs:SelectTab((opt_tabselect and #opt_tabselect>0) farmbuyer@76: and opt_tabselect or "eoi") farmbuyer@1: farmbuyer@1: display:AddChildren (tabs, control) farmbuyer@1: display:ApplyStatus() farmbuyer@1: farmbuyer@1: display:Show() -- without this, only appears every *other* function call farmbuyer@1: return display farmbuyer@1: end farmbuyer@1: farmbuyer@1: function addon:OpenMainDisplayToTab (text) farmbuyer@44: text = '^'..text:lower() farmbuyer@1: for tab,v in pairs(_tabtexts) do farmbuyer@1: if v.title:lower():find(text) then farmbuyer@1: self:BuildMainDisplay(tab) farmbuyer@1: return true farmbuyer@1: end farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- Essentially a re-click on the current tab (if the current tab were clickable). farmbuyer@1: function addon:redisplay () farmbuyer@1: tabs_OnGroupSelected_func (unpack(tabs_OnGroupSelected_func_args)) farmbuyer@1: end farmbuyer@1: farmbuyer@1: farmbuyer@1: ------ Popup dialogs farmbuyer@75: local function build_my_slider_widget() farmbuyer@75: local s = CreateFrame("Slider", "OuroLootSlider", nil, "OptionsSliderTemplate") farmbuyer@75: s.text = OuroLootSliderText farmbuyer@75: s.low = OuroLootSliderLow farmbuyer@75: s.high = OuroLootSliderHigh farmbuyer@75: s:SetScript("OnValueChanged", function (_s, value) farmbuyer@75: _s.value = value -- conveniently, this is already of numeric type farmbuyer@75: --_s.text:SetText(tostring(value)) farmbuyer@75: if _s.DoOnValueChanged then farmbuyer@75: _s:DoOnValueChanged() farmbuyer@75: end farmbuyer@75: end) farmbuyer@75: build_my_slider_widget = nil farmbuyer@75: return s farmbuyer@75: end farmbuyer@75: farmbuyer@1: StaticPopupDialogs["OUROL_CLEAR"] = flib.StaticPopup{ farmbuyer@1: text = "Clear current loot information and text?", farmbuyer@16: button1 = YES, farmbuyer@16: button2 = NO, farmbuyer@1: OnAccept = function (dialog, addon) farmbuyer@1: addon:Clear(--[[verbose_p=]]true) farmbuyer@1: end, farmbuyer@1: } farmbuyer@1: farmbuyer@37: StaticPopupDialogs["OUROL_HIST_REGEN"] = flib.StaticPopup{ farmbuyer@37: -- Concatenate this once at load time. There is no ITEM_QUALITY_LEGENDARY constant. farmbuyer@75: text = "Erase all history entries from " .. ITEM_QUALITY_COLORS[5].hex farmbuyer@75: .. "%s|r, and generate it anew from current loot?", farmbuyer@37: button1 = YES, farmbuyer@37: button2 = NO, farmbuyer@37: OnAccept = function (dialog, addon, data2) farmbuyer@37: data2(addon) farmbuyer@37: addon:Print("%s history has been regenerated.", addon.history.realm) farmbuyer@37: addon:redisplay() farmbuyer@37: end, farmbuyer@37: } farmbuyer@37: farmbuyer@16: StaticPopupDialogs["OUROL_HIST_CLEAR"] = flib.StaticPopup{ farmbuyer@37: -- Concatenate this once at load time. There is no ITEM_QUALITY_LEGENDARY constant. farmbuyer@37: text = "Erase all history entries from " .. ITEM_QUALITY_COLORS[5].hex .. "%s|r?", farmbuyer@16: button1 = YES, farmbuyer@16: button2 = NO, farmbuyer@16: OnAccept = function (dialog, addon, data2) farmbuyer@16: data2(addon) farmbuyer@16: addon:Print("Stimpy, you eeediot, you've pushed the history erase button!") farmbuyer@16: addon:redisplay() farmbuyer@16: end, farmbuyer@16: } farmbuyer@16: farmbuyer@16: StaticPopupDialogs["OUROL_HIST_PREEN"] = flib.StaticPopup{ farmbuyer@37: -- Concatenate this once at load time. There is no ITEM_QUALITY_LEGENDARY constant. farmbuyer@75: text = "This will erase all but the latest " farmbuyer@75: .. ITEM_QUALITY_COLORS[ITEM_QUALITY_UNCOMMON].hex farmbuyer@75: .. "%s|r for each player on " farmbuyer@75: .. ITEM_QUALITY_COLORS[5].hex .. "%s|r. " .. CONTINUE .. "?", farmbuyer@16: button1 = YES, farmbuyer@16: button2 = NO, farmbuyer@75: OnShow = function (dialog, addon) farmbuyer@75: local thistable = StaticPopupDialogs[dialog.which] farmbuyer@75: -- StaticPopup_Resize does not take extraFrame into account, so we farmbuyer@75: -- hook the sizing method that _Resize calls at the end. farmbuyer@75: dialog.saved_setheight = dialog.SetHeight farmbuyer@75: dialog.SetHeight = function (d, h) farmbuyer@75: return d.saved_setheight(d,h+35) farmbuyer@75: end farmbuyer@75: dialog.extraFrame:ClearAllPoints() farmbuyer@75: dialog.extraFrame:SetPoint("TOP", dialog.text, "BOTTOM") farmbuyer@75: dialog.extraFrame:SetWidth(150) farmbuyer@75: dialog.extraFrame:SetHeight(35) farmbuyer@75: dialog.extraFrame:Show() farmbuyer@75: local slider = _G.OuroLootSlider or build_my_slider_widget() farmbuyer@75: slider.DoOnValueChanged = function(s) farmbuyer@75: dialog.text:SetFormattedText (thistable.text, farmbuyer@75: s.value == 1 and "single entry" or (s.value .. " entries"), farmbuyer@75: addon.history.realm) farmbuyer@75: StaticPopup_Resize (dialog, "OUROL_HIST_PREEN") farmbuyer@75: end farmbuyer@75: slider:SetOrientation('HORIZONTAL') farmbuyer@75: slider:SetMinMaxValues(1,30) farmbuyer@75: slider:SetValueStep(1) farmbuyer@75: slider.low:SetText("1") farmbuyer@75: slider.high:SetText("30") farmbuyer@75: --slider.tooltipText = ??? farmbuyer@75: slider:SetParent(dialog.extraFrame) farmbuyer@75: slider:ClearAllPoints() farmbuyer@75: slider:SetPoint("TOPLEFT",dialog.extraFrame,"TOPLEFT",0, -15) farmbuyer@75: slider:SetPoint("BOTTOMRIGHT",dialog.extraFrame,"BOTTOMRIGHT",0, 0) farmbuyer@75: slider:Show() farmbuyer@75: -- This causes OnValueChanged to fire, reformatting the text. Except farmbuyer@75: -- IF the slider has already been shown, and IF at the time it was hidden farmbuyer@75: -- it had the same value here, THEN there is technically no "change" farmbuyer@75: -- and no event is fired. We work around this clever optimization by farmbuyer@75: -- doing a pair of set's, forcing the last one to fire OVC. farmbuyer@75: slider:SetValue(1) farmbuyer@75: slider:SetValue(5) farmbuyer@75: end, farmbuyer@75: OnAccept = function (dialog, addon, callback) farmbuyer@75: local howmany = assert(tonumber(_G.OuroLootSlider.value)) farmbuyer@75: callback (addon, howmany) farmbuyer@75: addon:Print("All loot prior to the most recent %d |4entry:entries; has been erased.", howmany) farmbuyer@16: addon:redisplay() farmbuyer@16: end, farmbuyer@75: OnHide = function (dialog, addon) farmbuyer@75: dialog.SetHeight = nil farmbuyer@75: dialog.saved_setheight = nil farmbuyer@75: dialog.extraFrame:ClearAllPoints() farmbuyer@75: _G.OuroLootSlider:Hide() -- parent is hidden, why is this required? farmbuyer@75: _G.OuroLootSlider:ClearAllPoints() farmbuyer@75: _G.OuroLootSlider:SetParent(nil) farmbuyer@75: end, farmbuyer@16: } farmbuyer@16: farmbuyer@27: StaticPopupDialogs["OUROL_URL"] = { --flib.StaticPopup{ farmbuyer@27: text = "Use Control-C or equivalent to copy this URL to your system clipboard:", farmbuyer@27: button1 = OKAY, farmbuyer@27: timeout = 0, farmbuyer@27: whileDead = true, farmbuyer@27: hideOnEscape = true, farmbuyer@27: enterClicksFirstButton = true, farmbuyer@27: hasEditBox = true, farmbuyer@27: editBoxWidth = 350, farmbuyer@53: preferredIndex = 3, farmbuyer@27: OnShow = function (dialog, url) farmbuyer@27: dialog.editBox:SetText(url) farmbuyer@27: dialog.editBox:SetFocus() farmbuyer@27: dialog.editBox:HighlightText() farmbuyer@27: end, farmbuyer@27: } farmbuyer@27: farmbuyer@1: StaticPopupDialogs["OUROL_REMIND"] = flib.StaticPopup{ farmbuyer@77: text = "Do you wish to activate Ouro Loot?|n|n(Hit the Escape key to close this window without clicking; Enter is the same as Activate)", farmbuyer@1: button1 = "Activate recording", -- "accept", left farmbuyer@69: button2 = "Broadcast Only", -- "cancel", middle farmbuyer@69: button3 = HELP_LABEL, -- "alt", right farmbuyer@1: OnAccept = function (dialog, addon) farmbuyer@1: addon:Activate() farmbuyer@1: end, farmbuyer@69: noCancelOnEscape = true, farmbuyer@69: OnCancel = function (dialog, addon) farmbuyer@1: addon:Activate(nil,true) farmbuyer@1: end, farmbuyer@69: OnAlt = function (dialog, addon) farmbuyer@1: -- hitting escape also calls this, but the 3rd arg would be "clicked" farmbuyer@1: -- in both cases, not useful here. farmbuyer@1: local helpbutton = dialog.button2 farmbuyer@1: local ismousing = MouseIsOver(helpbutton) farmbuyer@1: if ismousing then farmbuyer@1: -- they actually clicked the button (or at least the mouse was over "Help" farmbuyer@1: -- when they hit escape... sigh) farmbuyer@1: addon:BuildMainDisplay('help') farmbuyer@1: else farmbuyer@1: addon.popped = true farmbuyer@1: end farmbuyer@1: end, farmbuyer@1: } farmbuyer@1: farmbuyer@69: -- Callback for each Next/Accept stage of inserting a new loot or boss row via farmbuyer@69: -- dropdown. Thanks to noCancelOnReuse, each Show done here will technically farmbuyer@69: -- Hide and redisplay the same dialog, passing along the same 'data' structure farmbuyer@69: -- each time. The topmost call to our OnAccept will then finish by hiding the farmbuyer@69: -- (very last) dialog. farmbuyer@69: -- farmbuyer@69: -- This is really, really hideous to read. farmbuyer@69: local function eoi_st_insert_OnAccept_boss (dialog, data, data2) farmbuyer@69: if data.all_done then farmbuyer@69: -- It'll probably be the final entry in the table, but there might have farmbuyer@73: -- been real loot happening while the user was clicking and typing. farmbuyer@69: local boss_index = addon._addBossEntry{ farmbuyer@69: kind = 'boss', farmbuyer@69: bossname = (OuroLootSV_opts.snarky_boss and addon.boss_abbrev[data.name] or data.name) or data.name, farmbuyer@69: reason = 'kill', farmbuyer@69: instance = data.instance, farmbuyer@69: duration = 0, farmbuyer@69: maxsize = data.max_raid_size, farmbuyer@69: raidersnap = data.yes_snap or {}, farmbuyer@69: } farmbuyer@69: local entry = tremove(g_loot,boss_index) farmbuyer@69: tinsert(g_loot,data.rowindex,entry) farmbuyer@69: addon:_mark_boss_kill(data.rowindex) farmbuyer@69: data.display:GetUserData("eoiST"):OuroLoot_Refresh(data.rowindex) farmbuyer@69: dialog.data = nil -- free up memory farmbuyer@78: addon:Print("Inserted %s %s at entry %d.", data.kind, data.name, data.rowindex) farmbuyer@69: return farmbuyer@69: end farmbuyer@69: farmbuyer@69: -- third click farmbuyer@69: if data.name and data.instance then farmbuyer@69: data.all_done = true farmbuyer@69: -- this is how we distinguish OnAccept from OnCancel ("clicked"); the farmbuyer@69: -- 3rd param is handled all in StaticPopup_OnClick farmbuyer@69: if data2 ~= 'clicked' then farmbuyer@69: data.yes_snap = data.maybe_snap farmbuyer@69: end farmbuyer@69: return eoi_st_insert_OnAccept_boss (dialog, data) farmbuyer@69: end farmbuyer@69: farmbuyer@69: local text = dialog.editBox:GetText():trim() farmbuyer@69: farmbuyer@69: -- second click farmbuyer@69: if data.name and text then farmbuyer@69: data.instance = text farmbuyer@69: -- not "resuing" this dialog in the same sense as with loot farmbuyer@69: dialog.data = nil farmbuyer@69: dialog:Hide() farmbuyer@69: local getsnap = StaticPopup_Show("OUROL_EOI_INSERT_INCLUDE_RAIDERSNAP") farmbuyer@69: getsnap.data = data farmbuyer@69: return true farmbuyer@69: end farmbuyer@69: farmbuyer@69: -- first click farmbuyer@69: if text then farmbuyer@69: data.name = text farmbuyer@69: local maybe_instance farmbuyer@69: data.maybe_snap, data.max_raid_size, maybe_instance = addon:snapshot_raid() farmbuyer@69: local getinstance = StaticPopup_Show("OUROL_EOI_INSERT","instance") farmbuyer@69: getinstance.data = data farmbuyer@69: getinstance.editBox:SetText(maybe_instance) farmbuyer@69: -- This suppresses auto-hide (which would cause the getinstance dialog farmbuyer@69: -- to go away), but only when mouse clicking. OnEnter is on its own. farmbuyer@69: return true farmbuyer@69: end farmbuyer@69: end farmbuyer@69: farmbuyer@69: local function eoi_st_insert_OnAccept_loot (dialog, data) farmbuyer@69: if data.all_done then farmbuyer@69: data.display:Hide() farmbuyer@73: local loot_index = assert(addon:CHAT_MSG_LOOT ("manual", data.recipient, data.name, data.notes)) farmbuyer@69: local entry = tremove(g_loot,loot_index) farmbuyer@69: tinsert(g_loot,data.rowindex,entry) farmbuyer@69: addon:_fill_out_eoi_data(data.rowindex) farmbuyer@69: addon:BuildMainDisplay() farmbuyer@79: local clicky = _new_rebroadcast_hyperlink (entry.unique) farmbuyer@69: dialog.data = nil farmbuyer@78: addon:Print ("Inserted %s %s at entry %d. %s", farmbuyer@78: data.kind, data.name, data.rowindex, tostring(clicky)) farmbuyer@69: return farmbuyer@69: end farmbuyer@69: farmbuyer@69: local text = dialog.editBox:GetText():trim() farmbuyer@69: farmbuyer@69: -- third click farmbuyer@69: if data.name and data.recipient and text then farmbuyer@69: data.notes = (text ~= "") and text or nil farmbuyer@69: data.all_done = true farmbuyer@69: return eoi_st_insert_OnAccept_loot (dialog, data) farmbuyer@69: end farmbuyer@69: farmbuyer@69: -- second click farmbuyer@69: if data.name and text then farmbuyer@69: data.recipient = text farmbuyer@69: local getnotes = StaticPopup_Show("OUROL_EOI_INSERT","notes") farmbuyer@69: getnotes.data = data farmbuyer@69: getnotes.editBox:SetText("") farmbuyer@69: getnotes.editBox:HighlightText() farmbuyer@69: return true farmbuyer@69: end farmbuyer@69: farmbuyer@69: -- first click farmbuyer@69: if text then farmbuyer@69: data.name = text farmbuyer@69: dialog:Hide() -- technically a "different" one about to be shown farmbuyer@78: StaticPopupDialogs["OUROL_EOI_INSERT"].autoCompleteParams = farmbuyer@78: AUTOCOMPLETE_LIST_TEMPLATES[GetNumRaidMembers() > 0 and "IN_GROUP" or "IN_GUILD"] farmbuyer@69: local getrecipient = StaticPopup_Show("OUROL_EOI_INSERT","recipient") farmbuyer@78: StaticPopupDialogs["OUROL_EOI_INSERT"].autoCompleteParams = nil farmbuyer@69: getrecipient.data = data farmbuyer@69: getrecipient.editBox:SetText("") farmbuyer@69: return true farmbuyer@69: end farmbuyer@69: end farmbuyer@69: farmbuyer@69: local function eoi_st_insert_OnAccept (dialog, data) farmbuyer@69: if data.kind == 'boss' then farmbuyer@69: return eoi_st_insert_OnAccept_boss (dialog, data) farmbuyer@69: elseif data.kind == 'loot' then farmbuyer@69: return eoi_st_insert_OnAccept_loot (dialog, data) farmbuyer@69: end farmbuyer@69: end farmbuyer@69: farmbuyer@1: -- The data member here is a table built with: farmbuyer@1: -- {rowindex=, display=_d, kind=} farmbuyer@1: do farmbuyer@1: local t = flib.StaticPopup{ farmbuyer@75: text = "Enter name of new %s, then click "..CONTINUE.." or press Enter:", farmbuyer@75: button1 = CONTINUE.." ->", farmbuyer@1: button2 = CANCEL, farmbuyer@1: hasEditBox = true, farmbuyer@16: editBoxWidth = 350, farmbuyer@1: maxLetters = 50, farmbuyer@1: noCancelOnReuse = true, farmbuyer@1: } farmbuyer@1: t.EditBoxOnEnterPressed = function(editbox) farmbuyer@39: if editbox:GetText() == "" then return end farmbuyer@1: local dialog = editbox:GetParent() farmbuyer@1: if not eoi_st_insert_OnAccept (dialog, dialog.data) then farmbuyer@1: dialog:Hide() -- replicate OnAccept click behavior farmbuyer@1: end farmbuyer@1: end farmbuyer@1: t.enterClicksFirstButton = nil -- no effect with editbox focused farmbuyer@1: t.OnAccept = eoi_st_insert_OnAccept farmbuyer@1: StaticPopupDialogs["OUROL_EOI_INSERT"] = t farmbuyer@1: farmbuyer@69: -- This seems to be gratuitous use of metatables, really. farmbuyer@1: local OEIL = { farmbuyer@75: text = "Paste the new item into here, then click "..CONTINUE.." or press Enter:", farmbuyer@1: __index = StaticPopupDialogs["OUROL_EOI_INSERT"] farmbuyer@1: } farmbuyer@1: StaticPopupDialogs["OUROL_EOI_INSERT_LOOT"] = setmetatable(OEIL,OEIL) farmbuyer@1: farmbuyer@1: hooksecurefunc("ChatEdit_InsertLink", function (link,...) farmbuyer@1: local dialogname = StaticPopup_Visible "OUROL_EOI_INSERT_LOOT" farmbuyer@1: if dialogname then farmbuyer@16: _G[dialogname.."EditBox"]:SetText(link) farmbuyer@1: return true farmbuyer@1: end farmbuyer@1: end) farmbuyer@69: farmbuyer@69: t = flib.StaticPopup{ farmbuyer@69: -- Concatenate this once at load time. There is no ITEM_QUALITY_LEGENDARY constant. farmbuyer@69: text = "Include a snapshot of the " .. ITEM_QUALITY_COLORS[5].hex farmbuyer@77: .. "CURRENT|r raid?|n|nClicking '" .. YES .. "' will allow this entry to " farmbuyer@69: .. "appear in attendance lists, but with the roster as it is NOW, not as it " farmbuyer@69: .. "was THEN. Clicking '" .. NO .."' means this kill cannot be included in " farmbuyer@77: .. "attendance.|n|n(Enter = '" .. YES .."', Escape = '" .. CANCEL .. "')", farmbuyer@69: button1 = YES, -- "accept", left farmbuyer@69: button2 = NO, -- "cancel", middle farmbuyer@69: button3 = CANCEL, -- "alt", right farmbuyer@69: } farmbuyer@69: -- Hitting Escape still hides the frame, but doesn't run OnCancel (which farmbuyer@69: -- is for the "No" button, not the "Cancel"/OnAlt button). Dizzy yet? farmbuyer@69: t.noCancelOnEscape = true farmbuyer@69: t.OnAccept = eoi_st_insert_OnAccept_boss farmbuyer@69: t.OnCancel = eoi_st_insert_OnAccept_boss farmbuyer@69: StaticPopupDialogs["OUROL_EOI_INSERT_INCLUDE_RAIDERSNAP"] = t farmbuyer@1: end farmbuyer@1: farmbuyer@1: StaticPopupDialogs["OUROL_REASSIGN_ENTER"] = flib.StaticPopup{ farmbuyer@1: text = "Enter the player name:", farmbuyer@1: button1 = ACCEPT, farmbuyer@1: button2 = CANCEL, farmbuyer@1: hasEditBox = true, farmbuyer@1: OnAccept = function(dialog, data) farmbuyer@1: local name = dialog.usertext --editBox:GetText() farmbuyer@81: addon:reassign_loot ("local", data.index, name) farmbuyer@1: data.display:GetUserData("eoiST"):OuroLoot_Refresh(data.index) farmbuyer@1: end, farmbuyer@1: } farmbuyer@1: farmbuyer@1: StaticPopupDialogs["OUROL_SAVE_SAVEAS"] = flib.StaticPopup{ farmbuyer@1: text = "Enter a name for the loot collection:", farmbuyer@1: button1 = ACCEPT, farmbuyer@1: button2 = CANCEL, farmbuyer@1: hasEditBox = true, farmbuyer@1: maxLetters = 30, farmbuyer@1: OnAccept = function(dialog)--, data) farmbuyer@1: local name = dialog.usertext --editBox:GetText() farmbuyer@1: addon:save_saveas(name) farmbuyer@1: addon:BuildMainDisplay() farmbuyer@1: end, farmbuyer@1: OnCancel = function(dialog)--, data, reason) farmbuyer@1: addon:BuildMainDisplay() farmbuyer@1: end, farmbuyer@1: } farmbuyer@1: farmbuyer@25: farmbuyer@25: -- Workaround this bug: http://us.battle.net/wow/en/forum/topic/3278901991 farmbuyer@25: if true then farmbuyer@25: -- Verbatim copy of UIDropDownMenuTemplates.xml:155 or so, except as farmbuyer@25: -- tagged with CHANGE. farmbuyer@25: local function onenter (self, motion) farmbuyer@25: if ( self.hasArrow ) then farmbuyer@25: local level = self:GetParent():GetID() + 1; farmbuyer@25: local listFrame = _G["DropDownList"..level]; farmbuyer@25: if ( not listFrame or not listFrame:IsShown() or select(2, listFrame:GetPoint()) ~= self ) then farmbuyer@25: ToggleDropDownMenu(self:GetParent():GetID() + 1, self.value, nil, nil, nil, nil, self.menuList, self); farmbuyer@25: end farmbuyer@25: else farmbuyer@25: CloseDropDownMenus(self:GetParent():GetID() + 1); farmbuyer@25: end farmbuyer@25: _G[self:GetName().."Highlight"]:Show(); farmbuyer@25: UIDropDownMenu_StopCounting(self:GetParent()); farmbuyer@25: if ( self.tooltipTitle ) then farmbuyer@25: if ( self.tooltipOnButton ) then farmbuyer@25: GameTooltip:SetOwner(self, "ANCHOR_RIGHT"); farmbuyer@25: GameTooltip:AddLine(self.tooltipTitle, 1.0, 1.0, 1.0); farmbuyer@25: GameTooltip:AddLine(self.tooltipText, nil,nil,nil,1); -- CHANGE added nil->1 arguments farmbuyer@25: GameTooltip:Show(); farmbuyer@25: else farmbuyer@25: GameTooltip_AddNewbieTip(self, self.tooltipTitle, 1.0, 1.0, 1.0, self.tooltipText, 1); farmbuyer@25: end farmbuyer@25: end farmbuyer@25: end farmbuyer@25: -- end verbatime copy farmbuyer@25: farmbuyer@25: for i = 1, UIDROPDOWNMENU_MAXLEVELS do farmbuyer@25: local list = _G["DropDownList"..i] farmbuyer@25: if list then farmbuyer@25: for j = 1, UIDROPDOWNMENU_MAXBUTTONS do farmbuyer@25: local button = _G["DropDownList"..i.."Button"..j] farmbuyer@25: if button then farmbuyer@25: --print("button fixup",i,j) farmbuyer@25: button:SetScript("OnEnter",onenter) farmbuyer@25: end farmbuyer@25: end farmbuyer@25: end farmbuyer@25: end farmbuyer@25: end farmbuyer@25: farmbuyer@1: -- vim:noet