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@16: local eoi_st_displayed_rows = math.floor(416/eoi_st_rowheight) --math.floor(366/eoi_st_rowheight) farmbuyer@1: local eoi_st_textured_item_format = "|T%s:"..(eoi_st_rowheight-2).."|t %s[%s]|r%s" 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@4: --eoi_st_otherrow_bgcolortable["realm"] = eoi_st_otherrow_bgcolortable["time"] farmbuyer@1: local eoi_st_otherrow_bgcolortable_default farmbuyer@1: local eoi_st_lootrow_col3_colortable = { farmbuyer@1: [""] = { text = "", r = 1.0, g = 1.0, b = 1.0, a = 1.0 }, farmbuyer@1: shard = { text = "shard", r = 0xa3/255, g = 0x35/255, b = 0xee/255, a = 1.0 }, farmbuyer@1: offspec = { text = "offspec", r = 0.78, g = 0.61, b = 0.43, a = 1.0 }, farmbuyer@1: gvault = { text = "guild vault", r = 0x33/255, g = 1.0, b = 0x99/255, a = 1.0 }, farmbuyer@1: } farmbuyer@1: local function eoi_st_lootrow_col3_colortable_func (data, cols, realrow, column, table) farmbuyer@1: local disp = data[realrow].disposition farmbuyer@1: return eoi_st_lootrow_col3_colortable[disp or ""] 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@1: local g_generated = nil farmbuyer@17: local window_title = "Ouro Loot" farmbuyer@47: local dirty_tabs = nil farmbuyer@1: 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@1: farmbuyer@1: -- En masse forward decls of symbols defined inside local blocks farmbuyer@1: local _generate_text, _populate_text_specials farmbuyer@1: local _tabtexts, _taborder -- filled out in gui block scope 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@49: 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@1: 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@1: -- Called by tabs_generated_text_OGS 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@1: assert(addon.loot_clean == #g_loot, 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: return false 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@1: pcall (f, text_type, editbox, specials, mkb) 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: local grammar = { -- not worth making a mt for this farmbuyer@1: [2] = "nd", farmbuyer@1: [3] = "rd", farmbuyer@1: } farmbuyer@1: 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@1: { color = eoi_st_lootrow_col3_colortable_func } 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@1: e.disposition = k farmbuyer@1: --e.extratext = nil, not feasible farmbuyer@1: break farmbuyer@1: end farmbuyer@1: end end farmbuyer@65: local ex = e.disposition or "" farmbuyer@65: ex = eoi_st_lootrow_col3_colortable[ex].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@65: ex = ex .. " (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@16: v = ("kill on %d%s attempt"):format(e.attempts or 0, grammar[e.attempts] 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@6: for li,loot in ipairs(player) do farmbuyer@6: local col2 = new() farmbuyer@6: col2.OLi = li farmbuyer@6: local col3 = new() farmbuyer@6: col3.value = loot.when farmbuyer@6: farmbuyer@6: local itexture = GetItemIcon(loot.id) farmbuyer@6: local iname, ilink, iquality = GetItemInfo(loot.id) farmbuyer@4: local textured farmbuyer@4: if itexture and iname then farmbuyer@6: textured = eoi_st_textured_item_format:format (itexture, farmbuyer@11: ITEM_QUALITY_COLORS[iquality].hex, iname, loot.count 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@6: local dotcols = new (col1, col2, col3) farmbuyer@6: local st_entry = new() farmbuyer@6: st_entry.kind = 'history' 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@6: farmbuyer@6: farmbuyer@1: end farmbuyer@1: 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: --["adv"] = {title=[[Advanced]], desc=[[Debugging and testing]]}, farmbuyer@1: } farmbuyer@6: --if addon.author_debug then farmbuyer@1: _taborder = { "eoi", "hist", "help", "opt" } farmbuyer@6: --else _taborder = { "eoi", "help", "opt" } end 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: farmbuyer@57: -- Done at startup, and whenever we've changed the population of tabs. farmbuyer@1: function addon:gui_init (loot_pointer) farmbuyer@1: g_loot = loot_pointer 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@37: Dropdown menu handling 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@26: local i = _d and _d.GetUserData and _d:GetUserData("DD loot index") farmbuyer@26: if i then farmbuyer@26: subfunc(i,arg) farmbuyer@26: _d:GetUserData("eoiST"):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: local eoi_dropdownfuncs 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@1: 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@36: addon:_delHistoryEntry (rowi, gone) 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@56: addon:vbroadcast('loot', e.person, 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@56: addon:vbroadcast('loot', e.person, 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@1: ["Mark as normal"] = function(rowi,disp) -- broadcast the change? ugh farmbuyer@25: local olddisp = g_loot[rowi].disposition farmbuyer@1: g_loot[rowi].disposition = disp farmbuyer@1: g_loot[rowi].bcast_from = nil farmbuyer@1: g_loot[rowi].extratext = nil farmbuyer@25: addon:history_handle_disposition (rowi, olddisp) 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@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@1: eoi_editcell (rowi, _d:GetUserData("DD loot cell")) farmbuyer@1: end, farmbuyer@1: farmbuyer@1: df_REASSIGN = function(rowi,to_whom) farmbuyer@24: addon:reassign_loot (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@43: "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 players' corresponding History entry.", 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@36: "Delete this loot event|Permanent, no going back!\n\nHold down the Shift key to also delete the player's corresponding History entry.", farmbuyer@43: "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 players' corresponding History entry.", 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@25: "Change from 'wipe' to 'kill'|Also collapses other wipe entries.", 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@43: "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 player's corresponding History entry.", 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@1: --[[ quoted verbatim from lib-st docs: 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@1: table 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@1: local function eoi_st_OnEnter (rowFrame, cellFrame, data, cols, row, realrow, column, table, button, ...) 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@1: farmbuyer@16: if (kind == 'loot' and column == 1) or (kind == 'history' and column == 2) then farmbuyer@19: GameTooltip:SetOwner (cellFrame, "ANCHOR_RIGHT", -20, 0) farmbuyer@19: if e.cache_miss then farmbuyer@19: GameTooltip:ClearLines() farmbuyer@19: GameTooltip:AddLine("Missing Cache Data") farmbuyer@19: GameTooltip:AddLine([[Wait a few seconds, then type]], 0.8, 0.8, 0.8, 1) farmbuyer@19: GameTooltip:AddLine([[/ouroloot fixcache]], 0, 1, 64/255, nil) farmbuyer@19: GameTooltip:AddLine([[and redisplay this window.]], 0.8, 0.8, 0.8, 1) farmbuyer@19: GameTooltip:Show() farmbuyer@19: elseif e.itemlink then farmbuyer@16: GameTooltip:SetHyperlink (e.itemlink) farmbuyer@16: end farmbuyer@1: farmbuyer@1: elseif kind == 'loot' and column == 2 then farmbuyer@1: GameTooltip:SetOwner (cellFrame, "ANCHOR_BOTTOMRIGHT", -50, 5) farmbuyer@1: GameTooltip:ClearLines() farmbuyer@1: GameTooltip: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@1: GameTooltip: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@1: GameTooltip:AddLine(textured:sub(space+1)) farmbuyer@1: counter = counter + 1 farmbuyer@1: end farmbuyer@1: end farmbuyer@1: end farmbuyer@1: GameTooltip: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@1: local function eoi_st_OnLeave (rowFrame, cellFrame, data, cols, row, realrow, column, table, button, ...) farmbuyer@1: GameTooltip:Hide() farmbuyer@1: if row and realrow and data[realrow].kind ~= 'loot' then farmbuyer@1: table: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@1: local function eoi_st_OnClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, ...) 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@16: if IsModifiedClick("CHATLINK") and farmbuyer@16: ((kind == 'loot' and column == 1) or (kind == 'history' and column == 2)) 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@1: _d:SetUserData("DD loot index", realrow) farmbuyer@1: farmbuyer@1: if kind == 'loot' and (column == 1 or column == 3) then farmbuyer@1: _d:SetUserData("DD loot 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@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@16: elseif kind == 'history' then -- XXX need to move this into new onclick handler farmbuyer@16: _d:SetUserData("DD loot cell", cellFrame) farmbuyer@16: hist_dropdown[1].text = e.itemlink farmbuyer@16: EasyMenu (hist_dropdown, dropdownmenuframe, cellFrame, 0, 0, "MENU") 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@1: 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@1: --_d:SetUserData("DD loot 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@6: 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: cellFrame.text:SetTextColor(1,1,1,1) 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@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@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@1: -- table: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@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@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@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: --return tabs_OnGroupSelected_func(container,"OnGroupSelected",text_kind) 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@1: farmbuyer@37: hist_dropdownfuncs = dropdownfuncs{ farmbuyer@37: ["Delete this loot history"] = function(rowi) farmbuyer@37: --local gone = tremove(g_loot,rowi) farmbuyer@37: --addon:Print("Removed %s.", farmbuyer@55: --gone.itemlink or gone.bossname or gone.startday.text) farmbuyer@37: end, farmbuyer@37: } farmbuyer@37: local hist_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@37: "Delete this loot history|Permanent, no going back!", farmbuyer@37: --"Delete remaining entries for this boss%boss|Erases everything from here down until a new boss/day", farmbuyer@37: "--", farmbuyer@37: CLOSE farmbuyer@37: }, hist_dropdownfuncs) farmbuyer@6: 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@37: 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: local hist_normal_status = farmbuyer@37: [[Click on a row to view all history for that player only. (Click column headers to re-sort.)]] farmbuyer@37: local hist_name_status = farmbuyer@37: [[Right-click on any row to return to normal history display.]] farmbuyer@37: farmbuyer@37: local history_filter_by_recent = function (st, e) farmbuyer@37: if e.kind ~= 'history' then return true end farmbuyer@37: return e.cols[2].OLi == 1 farmbuyer@37: end farmbuyer@37: farmbuyer@37: local history_filter_who farmbuyer@37: local history_filter_by_name = function (st, e) farmbuyer@37: if e.kind ~= 'history' then return true end farmbuyer@37: return e.OLwho == history_filter_who farmbuyer@37: end farmbuyer@37: farmbuyer@37: -- Loot column farmbuyer@37: local function hist_st_col2_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable, ...) farmbuyer@37: print("col2 DCU", realrow) farmbuyer@37: end farmbuyer@37: farmbuyer@37: -- Formatted timestamp column farmbuyer@37: local function hist_st_col3_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable, ...) farmbuyer@37: print("col3 DCU", realrow) farmbuyer@37: if not fShow then farmbuyer@37: cellFrame.text:SetText("") farmbuyer@37: return farmbuyer@6: end farmbuyer@6: farmbuyer@37: local d = data[realrow] farmbuyer@37: local cell = d.cols[column] farmbuyer@37: farmbuyer@37: cellFrame.text:SetText(cell.value) farmbuyer@37: cellFrame.text:SetTextColor(1,1,1,1) farmbuyer@37: farmbuyer@37: --if d.kind ~= 'loot' then farmbuyer@37: stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[d.kind]) farmbuyer@37: --else farmbuyer@37: -- table:SetHighLightColor (rowFrame, table:GetDefaultHighlightBlank()) farmbuyer@37: --end farmbuyer@37: end farmbuyer@37: farmbuyer@37: local function hist_st_OnClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, ...) farmbuyer@37: if (row == nil) or (realrow == nil) then return false end -- click column header, do default resorting farmbuyer@37: local h = data[realrow] farmbuyer@37: local kind = h.kind farmbuyer@37: farmbuyer@37: if history_filter_who and button == "RightButton" then -- now filtering and wanting not to farmbuyer@37: history_filter_who = nil farmbuyer@37: stable:SetFilter(history_filter_by_recent) farmbuyer@37: setstatus(hist_normal_status) farmbuyer@37: elseif (not history_filter_who) and button == "LeftButton" then -- not filtering and wanting to farmbuyer@37: history_filter_who = h.OLwho farmbuyer@37: stable:SetFilter(history_filter_by_name) farmbuyer@37: setstatus(hist_name_status) farmbuyer@6: end farmbuyer@6: farmbuyer@37: return true -- do not do anything further farmbuyer@37: end farmbuyer@37: farmbuyer@37: --[[ farmbuyer@37: local function hist_st_OnDoubleClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, ...) farmbuyer@37: if (row == nil) or (realrow == nil) then return true end -- they clicked on column header, suppress reordering farmbuyer@37: local h = data[realrow] farmbuyer@37: local kind = h.kind farmbuyer@37: farmbuyer@37: return true -- do not do anything further farmbuyer@37: end]] 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@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@37: [[Preserves only the latest loot entry for each player on the displayed realm, removing all earlier ones.]]) farmbuyer@37: b:SetFullWidth(true) farmbuyer@37: b:SetCallback("OnClick", function (_b) farmbuyer@37: local dialog = StaticPopup_Show("OUROL_HIST_PREEN", addon.history.realm) farmbuyer@37: dialog.data = addon farmbuyer@37: dialog.data2 = function(_addon) farmbuyer@37: _addon:preen_history(_addon.history.realm) 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@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@1: [[Disable the addon, change this field (click Okay or press Enter), then re-enable the addon.]]) 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@1: else addon:Print("Can do nothing; DBM testing mod wasn't loaded.") 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@1: w:SetCallback("OnClick", function() collectgarbage() end) farmbuyer@1: grp:AddChild(w) farmbuyer@1: farmbuyer@20: --[==[ this has been well and truly debugged by now farmbuyer@1: w = mkbutton("EditBox", nil, addon.loot_pattern:sub(17), [[]]) farmbuyer@1: w:SetRelativeWidth(0.35) farmbuyer@1: w:SetLabel("CML pattern suffix") farmbuyer@1: w:SetCallback("OnEnterPressed", function(_w,event,value) farmbuyer@1: addon.loot_pattern = addon.loot_pattern:sub(1,16) .. value farmbuyer@1: end) farmbuyer@20: grp:AddChild(w) ]==] farmbuyer@20: 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@1: w = GUI:Create("CheckBoxSmallLabel") farmbuyer@1: w:SetFullWidth(true) farmbuyer@1: w:SetType("checkbox") farmbuyer@19: 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@19: w:SetValue(false) 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@10: PlaySoundFile[[Sound\Music\WorldEvents\HordeFirepole.mp3]] 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@10: PlaySoundFile[[Sound\Music\WorldEvents\AllianceFirepole.mp3]] 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@1: end farmbuyer@1: farmbuyer@1: -- Initial lower panel function farmbuyer@1: local function adv_lower (container, specials) farmbuyer@1: local speedbump = GUI:Create("InteractiveLabel") farmbuyer@1: speedbump:SetFullWidth(true) farmbuyer@1: speedbump:SetFontObject(GameFontHighlightLarge) farmbuyer@1: speedbump:SetImage("Interface\\DialogFrame\\DialogAlertIcon") farmbuyer@1: speedbump:SetImageSize(50,50) farmbuyer@1: speedbump:SetText("The debugging/testing settings on the rest of this panel can" farmbuyer@1: .." seriously bork up the addon if you make a mistake. If you're okay" farmbuyer@1: .." with the possibility of losing data, click this warning to load the panel.") farmbuyer@1: speedbump:SetCallback("OnClick", function (_sb) farmbuyer@1: adv_lower = adv_real farmbuyer@1: return addon:redisplay() farmbuyer@1: --return tabs_OnGroupSelected_func(container.parent,"OnGroupSelected","opt") farmbuyer@1: end) farmbuyer@1: container:AddChild(speedbump) farmbuyer@1: end farmbuyer@1: farmbuyer@1: tabs_OnGroupSelected["opt"] = function(container,specials) farmbuyer@65: opts = OuroLootSV_opts farmbuyer@65: farmbuyer@1: --container:SetLayout("List") 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@10: -- The relative width fields used to be done to take up less vertical space, but farmbuyer@10: -- that turned out to look messy. Now they're just a straight line for the most part. farmbuyer@10: farmbuyer@1: -- reminder popup farmbuyer@16: w = mkoption ('popup_on_join', "Show reminder popup", 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@1: -- chatty mode farmbuyer@16: w = mkoption('chatty_on_kill', "Be chatty on boss kill", 0.49, farmbuyer@1: [[Print something to chat output when DBM 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@1: [[Irreverent replacement names for boss events.]]) 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@65: [[Include "(from Player_Name)" in the Notes column for loot that was broadcast to you.]], 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@1: -- possible keybindings farmbuyer@1: do farmbuyer@1: local pair = GUI:Create("SimpleGroup") farmbuyer@1: pair:SetLayout("Flow") farmbuyer@10: pair:SetRelativeWidth(0.95) farmbuyer@1: local editbox, checkbox farmbuyer@65: editbox = mkbutton("EditBox", nil, opts.keybinding_text, farmbuyer@1: [[Keybinding text format is fragile! Relog to take effect.]]) farmbuyer@1: editbox:SetRelativeWidth(0.5) 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@1: checkbox = mkoption('keybinding', "Register keybinding", 0.5, 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@1: pair:AddChild(checkbox) farmbuyer@1: pair:AddChild(editbox) farmbuyer@1: grp:AddChild(pair) farmbuyer@1: end farmbuyer@1: farmbuyer@3: -- boss mod selection farmbuyer@3: w = GUI:Create("Spacer") farmbuyer@3: w:SetFullWidth(true) farmbuyer@3: w:SetHeight(20) 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@1: -- item filter farmbuyer@1: w = GUI:Create("Spacer") farmbuyer@1: w:SetFullWidth(true) farmbuyer@1: w:SetHeight(20) farmbuyer@1: grp:AddChild(w) farmbuyer@1: do farmbuyer@1: local list = {} farmbuyer@54: local cache_warn, cache_warned = false, false farmbuyer@65: for id in pairs(opts.itemfilter) do farmbuyer@1: local iname, _, iquality = GetItemInfo(id) farmbuyer@2: if iname then farmbuyer@11: list[id] = ITEM_QUALITY_COLORS[iquality].hex .. iname .. "|r" farmbuyer@54: else farmbuyer@54: cache_warn = true farmbuyer@2: end farmbuyer@1: end 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@1: w:SetList(list) farmbuyer@1: w:SetCallback("OnTextEnterPressed", function(_w, _, text) farmbuyer@1: local iname, ilink, iquality = GetItemInfo(strtrim(text)) 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@11: list[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@54: w:SetCallback("OnDropdownShown", function() farmbuyer@54: if cache_warn and not cache_warned then farmbuyer@54: cache_warned = true farmbuyer@54: addon:Print("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: end farmbuyer@54: end) 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: --return tabs_OnGroupSelected_func(container,"OnGroupSelected","opt") 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@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@1: return tabs_OnGroupSelected[group](tabs,spec,group) 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@1: Using this to determine the actual height of the usable area. farmbuyer@1: 366 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@1: do farmbuyer@1: local replacement_colors = { ["+"]="|cffffffff", ["<"]="|cff00ff00", [">"]="|r" } farmbuyer@1: function mkbutton (opt_widget_type, opt_key, label, status) farmbuyer@1: if not label then farmbuyer@1: opt_widget_type, opt_key, label, status = "Button", opt_widget_type, opt_widget_type, opt_key farmbuyer@1: elseif not status then farmbuyer@1: opt_widget_type, opt_key, label, status = "Button", opt_widget_type, opt_key, label farmbuyer@1: end farmbuyer@47: local button = assert(GUI:Create(opt_widget_type)) farmbuyer@1: if button.SetText then button:SetText(tostring(label)) end farmbuyer@1: status = status:gsub("[%+<>]",replacement_colors) farmbuyer@1: button:SetCallback("OnEnter", function() setstatus(status) end) -- maybe factor that closure out farmbuyer@1: button:SetCallback("OnLeave", statusy_OnLeave) farmbuyer@1: -- retrieval key may be specified as nil if all the parameters are given farmbuyer@1: if opt_key then _d:SetUserData (opt_key, button) end farmbuyer@1: return button farmbuyer@1: end 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@47: self:gui_init(g_loot) -- pointer known to be good by now farmbuyer@47: self:zero_printed_fenceposts() farmbuyer@47: end farmbuyer@47: farmbuyer@1: local display = GUI:Create("Frame") farmbuyer@1: if _d then farmbuyer@1: 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@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: do farmbuyer@1: self.sender_list.sort() farmbuyer@1: tabs.titletext:SetFormattedText("Received broadcast data from %d |4player:players;.", farmbuyer@1: self.sender_list.activeI) farmbuyer@1: 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@1: tabs:SelectTab(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@1: -- Callback for each Next/Accept stage of inserting a new loot row via dropdown farmbuyer@1: local function eoi_st_insert_OnAccept_boss (dialog, data) farmbuyer@1: if data.all_done then farmbuyer@1: -- It'll probably be the final entry in the table, but there might have farmbuyer@1: -- been real loot happening at the same time. farmbuyer@1: local boss_index = addon._addLootEntry{ farmbuyer@1: kind = 'boss', farmbuyer@55: bossname = (OuroLootSV_opts.snarky_boss and addon.boss_abbrev[data.name] or data.name) or data.name, farmbuyer@1: reason = 'kill', farmbuyer@1: instance = data.instance, farmbuyer@1: duration = 0, farmbuyer@1: } farmbuyer@1: local entry = tremove(g_loot,boss_index) farmbuyer@1: tinsert(g_loot,data.rowindex,entry) farmbuyer@1: addon:_mark_boss_kill(data.rowindex) farmbuyer@1: data.display:GetUserData("eoiST"):OuroLoot_Refresh(data.rowindex) farmbuyer@1: dialog.data = nil -- free up memory farmbuyer@1: addon:Print("Inserted %s %s (entry %d).", data.kind, data.name, data.rowindex) farmbuyer@1: return farmbuyer@1: end farmbuyer@1: farmbuyer@16: local text = dialog.editBox:GetText() farmbuyer@1: farmbuyer@1: -- second click farmbuyer@1: if data.name and text then farmbuyer@1: data.instance = text farmbuyer@1: data.all_done = true farmbuyer@1: -- in future do one more thing, for now just jump to the check farmbuyer@1: return eoi_st_insert_OnAccept_boss (dialog, data) farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- first click farmbuyer@1: if text then farmbuyer@1: data.name = text farmbuyer@1: local getinstance = StaticPopup_Show("OUROL_EOI_INSERT","instance") farmbuyer@1: getinstance.data = data farmbuyer@56: getinstance.editBox:SetText((addon.instance_tag())) farmbuyer@1: -- This suppresses auto-hide (which would case the getinstance dialog farmbuyer@1: -- to go away), but only when mouse clicking. OnEnter is on its own. farmbuyer@1: return true farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: local function eoi_st_insert_OnAccept_loot (dialog, data) farmbuyer@1: if data.all_done then farmbuyer@1: --local real_rebroadcast, real_enabled = addon.rebroadcast, addon.enabled farmbuyer@1: --g_rebroadcast, g_enabled = false, true farmbuyer@1: data.display:Hide() farmbuyer@1: local loot_index = addon:CHAT_MSG_LOOT ("manual", data.recipient, data.name, data.notes) farmbuyer@1: --g_rebroadcast, g_enabled = real_g_rebroadcast, real_g_enabled farmbuyer@1: local entry = tremove(g_loot,loot_index) farmbuyer@1: tinsert(g_loot,data.rowindex,entry) farmbuyer@1: --data.display:GetUserData("eoiST"):OuroLoot_Refresh(data.rowindex) farmbuyer@1: addon:_fill_out_eoi_data(data.rowindex) farmbuyer@1: addon:BuildMainDisplay() farmbuyer@1: dialog.data = nil farmbuyer@1: addon:Print("Inserted %s %s (entry %d).", data.kind, data.name, data.rowindex) farmbuyer@1: return farmbuyer@1: end farmbuyer@1: farmbuyer@16: local text = dialog.editBox:GetText():trim() farmbuyer@1: farmbuyer@1: -- third click farmbuyer@1: if data.name and data.recipient and text then farmbuyer@1: data.notes = (text ~= "") and text or nil farmbuyer@1: data.all_done = true farmbuyer@1: return eoi_st_insert_OnAccept_loot (dialog, data) farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- second click farmbuyer@1: if data.name and text then farmbuyer@1: data.recipient = text farmbuyer@1: local getnotes = StaticPopup_Show("OUROL_EOI_INSERT","notes") farmbuyer@1: getnotes.data = data farmbuyer@16: getnotes.editBox:SetText("") farmbuyer@16: getnotes.editBox:HighlightText() farmbuyer@1: return true farmbuyer@1: end farmbuyer@1: farmbuyer@1: -- first click farmbuyer@1: if text then farmbuyer@1: data.name = text farmbuyer@1: dialog:Hide() -- technically a "different" one about to be shown farmbuyer@1: local getrecipient = StaticPopup_Show("OUROL_EOI_INSERT","recipient") farmbuyer@1: getrecipient.data = data farmbuyer@16: getrecipient.editBox:SetText("") farmbuyer@1: return true farmbuyer@1: end farmbuyer@1: end farmbuyer@1: farmbuyer@1: local function eoi_st_insert_OnAccept (dialog, data) farmbuyer@1: if data.kind == 'boss' then farmbuyer@1: return eoi_st_insert_OnAccept_boss (dialog, data) farmbuyer@1: elseif data.kind == 'loot' then farmbuyer@1: return eoi_st_insert_OnAccept_loot (dialog, data) farmbuyer@1: end farmbuyer@1: end farmbuyer@1: 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@37: text = "Erase all history entries from " .. ITEM_QUALITY_COLORS[5].hex .. "%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@37: text = "Erase all but the latest entry for players on " .. 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("All loot prior to the most recent entries has been erased.") farmbuyer@16: addon:redisplay() farmbuyer@16: 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@1: text = "Do you wish to activate Ouro Loot?\n\n(Hit the Escape key to close this window without clicking)", farmbuyer@1: button1 = "Activate recording", -- "accept", left farmbuyer@1: button3 = "Broadcast only", -- "alt", middle farmbuyer@1: button2 = "Help", -- "cancel", right farmbuyer@1: OnAccept = function (dialog, addon) farmbuyer@1: addon:Activate() farmbuyer@1: end, farmbuyer@1: OnAlt = function (dialog, addon) farmbuyer@1: addon:Activate(nil,true) farmbuyer@1: end, farmbuyer@1: OnCancel = 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@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@1: text = "Enter name of new %s, then click Next or press Enter:", farmbuyer@1: button1 = "Next >", farmbuyer@1: button2 = CANCEL, farmbuyer@1: hasEditBox = true, farmbuyer@16: editBoxWidth = 350, farmbuyer@1: maxLetters = 50, farmbuyer@1: noCancelOnReuse = true, farmbuyer@1: --[[ XXX still needed? farmbuyer@1: OnShow = function(dialog) farmbuyer@1: dialog.wideEditBox:SetText("") farmbuyer@1: dialog.wideEditBox:SetFocus() farmbuyer@1: end,]] 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: end farmbuyer@1: farmbuyer@1: -- This seems to be gratuitous use of metatables, really. farmbuyer@1: do farmbuyer@1: local OEIL = { farmbuyer@1: text = "Paste the new item into here, then click Next 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@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: --[[ XXX needed? farmbuyer@1: OnShow = function(dialog) farmbuyer@1: dialog.editBox:SetText("") farmbuyer@1: dialog.editBox:SetFocus() farmbuyer@1: end,]] farmbuyer@1: OnAccept = function(dialog, data) farmbuyer@1: local name = dialog.usertext --editBox:GetText() farmbuyer@24: addon:reassign_loot (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: --[[ XXX farmbuyer@1: OnShow = function(dialog) farmbuyer@1: dialog.editBox:SetText("") farmbuyer@1: dialog.editBox:SetFocus() farmbuyer@1: end,]] 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: --[[XXX farmbuyer@1: EditBoxOnEnterPressed = function(editbox) farmbuyer@1: local dialog = editbox:GetParent() farmbuyer@1: StaticPopupDialogs["OUROL_SAVE_SAVEAS"].OnAccept (dialog, dialog.data) farmbuyer@1: dialog:Hide() 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