Mercurial > wow > ouroloot
diff gui.lua @ 116:fc2ff128835a
- Reset the 'clean' markers on all default-function option toggles.
- Fix a long-standing FIXME: Move all lib-scrollingtable and other
"display-only" data out of g_loot entries and into their own subclass-
style table; feed that to ST's SetData instead. No more 'cols'.
author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
---|---|
date | Thu, 16 Aug 2012 17:11:57 -0400 |
parents | 67bf97136273 |
children | ec5174529e0f |
line wrap: on
line diff
--- a/gui.lua Tue Aug 14 20:37:12 2012 -0400 +++ b/gui.lua Thu Aug 16 17:11:57 2012 -0400 @@ -14,6 +14,7 @@ local eoi_st_rowheight = 20 local eoi_st_displayed_rows = math.floor(416/eoi_st_rowheight) local eoi_st_textured_item_format = "|T%s:"..(eoi_st_rowheight-2).."|t %s[%s]|r%s" +local eoi_st_cols -- defined below -- This can get indexed by kind/reason/etc, and will default to lib-st's -- default "blank" background at runtime. local eoi_st_otherrow_bgcolortable = { @@ -27,10 +28,6 @@ local function eoi_st_lootrow_col3_colortable_func (data, _, realrow) return eoi_st_lootrow_col3_colortable[data[realrow].disposition] end -local time_column1_used_mt = { __index = { - [2] = {value=""}, - [3] = {value=""}, -} } ------ Globals @@ -57,6 +54,7 @@ end local g_loot = nil +local g_dloot = nil -- GUI-related "child" of the main table local g_uniques = nil local g_generated = nil local window_title = "Ouro Loot" @@ -132,6 +130,58 @@ end +local do_g_loot_wrap +do + local FOREIGN_SERVER_LABEL = FOREIGN_SERVER_LABEL + local wrappers = { + -- WTB Lua 5.2 instead of this + ["LEN"] = function() + return #g_loot + end, + -- returns the display's entry and the core entry + ["remove"] = function (dt, i) + local reale = tremove (g_loot, i) + return tremove (dt, i), reale + end, + -- counterpart + --[[ + ["insert"] = function (dt, i, displaye, reale) + tinsert (g_loot, i, reale) + tinsert (dt, i, displaye) + end,]] + } + local function wrap_e (t,index) + local real = g_loot[index] + if not real then return nil end + + local e = { + __index = real, + __newindex = real, + cols = {}, + } + if real.kind == 'loot' then + e.dperson = real.person_realm and + (real.person .. FOREIGN_SERVER_LABEL) or real.person + end + setmetatable(e,e) + rawset(t,index,e) + return e + end + function do_g_loot_wrap (g) + local dl = {} + for k,v in pairs(wrappers) do + dl[k] = v + end + for i,e in ipairs(g) do + wrap_e (dl, i) + end + return setmetatable(dl, { + __index = wrap_e, + }) + end +end + + ------ Behind the scenes routines -- Text generation do @@ -313,105 +363,90 @@ --[[ The g_loot table is populated only with "behavior-relevant" data (names, links, etc). This function runs through it and fills out the "display- -relevant" bits (icons, user-friendly labels, etc). Everything from the -loot_clean index to the end of the table is filled out, loot_clean is -updated. Override the starting point with the argument. +relevant" bits (icons, user-friendly labels, etc) in the g_dloot table, +which inherits (so to speak) the corresponding row entries. -XXX blizzard's scrolling update and lib-st keep finding some way of displaying -the grid without ever calling the hooked refresh, thereby skipping this -function and erroring on missing columnar data. fuckit. from now on -this function gets called everywhere, all the time, and loops over the -entire goddamn table each time. If we can't find blizz's scrollframe bugs, -we'll just work around them. Sorry for your smoking CPU. +Everything from the loot_clean index to the end of the table is filled out; +loot_clean is updated. Override this starting point with the function arg. +]] +function addon:_fill_out_eoi_data (opt_starting_index) + if #g_loot < 1 then + --pprint('_f_o_e_d', "#g_loot<1") + self.loot_clean = nil + opt_starting_index = nil + end -FIXME just move this functionality to a per-entry function and call it once -in _addlootentry. --actually no, then the columnar data won't be updated once -the backend data is changed on the fly. -]] -do - function addon:_fill_out_eoi_data (opt_starting_index) - if #g_loot < 1 then - --pprint('_f_o_e_d', "#g_loot<1") + local display_bcast_from = self.db.profile.display_bcast_from + local colcount = #eoi_st_cols + + -- 'while true' so that we can use (inner) break as (outer) continue + for i = (opt_starting_index or self.loot_clean or 1), #g_loot do while true do + local e = g_dloot[i] + if e == nil then self.loot_clean = nil - opt_starting_index = nil + pprint('_f_o_e_d', "index",i,"somehow still in loop past",#g_loot,"bailing") + -- hmm. used to bail here. does restarting instead cause problems? + return self:_fill_out_eoi_data(1) end - for i = (opt_starting_index or self.loot_clean or 1), #g_loot do - local e = g_loot[i] - if e == nil then - self.loot_clean = nil - pprint('_f_o_e_d', "index",i,"somehow still in loop past",#g_loot,"bailing") - -- hmm. used to bail here. does restarting cause problems? - return self:_fill_out_eoi_data(1) - end - local display_bcast_from = self.db.profile.display_bcast_from - -- XXX FIXME a major weakness here is that we're constantly replacing - -- what's already been created. Lots of garbage. Trying to detect what - -- actually needs to be replaced is even worse. We'll live with - -- garbage for now. - if e.kind == 'loot' then - local textured = eoi_st_textured_item_format:format (e.itexture, ITEM_QUALITY_COLORS[e.quality].hex, e.itemname, e.count or "") - local pdisplay = e.person_realm - and (e.person .. FOREIGN_SERVER_LABEL) or e.person - e.cols = { - {value = textured}, - {value = pdisplay}, - {} - } - -- This is horrible. Must do better. - if e.extratext then - for disp,text in self:_iter_dispositions('from_notes_text') do - if text == e.extratext then - e.disposition = disp - break - end + assert(type(rawget(e,'cols'))=='table') + + while #e.cols < colcount do + e.cols[#e.cols+1] = {} + end + + if e.kind == 'loot' then + local textured = eoi_st_textured_item_format:format (e.itexture, + ITEM_QUALITY_COLORS[e.quality].hex, e.itemname, e.count or "") + e.cols[1].value = textured + e.cols[2].value = e.dperson + -- This is horrible. Must do better. + if e.extratext then + for disp,text in self:_iter_dispositions('from_notes_text') do + if text == e.extratext then + e.disposition = disp + break end end - local ex = eoi_st_lootrow_col3_colortable[e.disposition].text - if e.bcast_from and display_bcast_from and e.extratext then - ex = e.extratext .. " (from " .. e.bcast_from .. ")" - elseif e.bcast_from and display_bcast_from then - ex = ex .. (e.disposition and " " or "") - .. "(from " .. e.bcast_from .. ")" - elseif e.extratext then - ex = e.extratext + end + local ex = eoi_st_lootrow_col3_colortable[e.disposition].text + if e.bcast_from and display_bcast_from and e.extratext then + ex = e.extratext .. " (from " .. e.bcast_from .. ")" + elseif e.bcast_from and display_bcast_from then + ex = ex .. (e.disposition and " " or "") + .. "(from " .. e.bcast_from .. ")" + elseif e.extratext then + ex = e.extratext + end + e.cols[3].value = ex + + elseif e.kind == 'boss' then + local v + e.duration = e.duration or 0 -- can occasionally miss getting set + if e.reason == 'kill' then + if e.attempts == 1 then + v = "one-shot" + else + v = ("kill on %d%s attempt"):format(e.attempts or 0, + e.attempts==2 and "nd" or e.attempts==3 and "rd" or "th") end - e.cols[3].value = ex + v = ("%s (%d:%.2d)"):format(v, math.floor(e.duration/60), math.floor(e.duration%60)) + elseif e.reason == 'wipe' then + v = ("wipe (%d:%.2d)"):format(math.floor(e.duration/60), math.floor(e.duration%60)) + end + e.cols[1].value = e.bossname + e.cols[2].value = e.instance + e.cols[3].value = v or "" - elseif e.kind == 'boss' then - local v - e.duration = e.duration or 0 -- can occasionally miss getting set - if e.reason == 'kill' then - if e.attempts == 1 then - v = "one-shot" - else - v = ("kill on %d%s attempt"):format(e.attempts or 0, - e.attempts==2 and "nd" or e.attempts==3 and "rd" or "th") - end - v = ("%s (%d:%.2d)"):format(v, math.floor(e.duration/60), math.floor(e.duration%60)) - elseif e.reason == 'wipe' then - v = ("wipe (%d:%.2d)"):format(math.floor(e.duration/60), math.floor(e.duration%60)) - end - e.cols = { - {value = e.bossname}, - {value = e.instance}, - {value = v or ""}, - } + elseif e.kind == 'time' then + e.cols[1].value = e.startday.text + e.cols[2].value = "" + e.cols[3].value = "" - elseif e.kind == 'time' then - e.cols = setmetatable({ - {value=e.startday.text}, - }, time_column1_used_mt) - --[[e.cols = { - {value=e.startday.text}, - {value=""}, - {value=""}, - }]] - - end end - self.loot_clean = #g_loot - end + break + end end + self.loot_clean = #g_loot end do @@ -803,6 +838,7 @@ function addon:gui_init (loot_pointer, uniques_pointer) g_loot = assert(loot_pointer, "something went wrong at startup") g_uniques = assert(uniques_pointer, "something went wrong at startup") + g_dloot = do_g_loot_wrap(g_loot) g_generated = nil tabgroup_tabs = {} window_title = "Ouro Loot " .. self.version @@ -823,6 +859,7 @@ end end dirty_tabs = nil + return g_dloot end --[[ @@ -889,7 +926,7 @@ end, df_DELETE = function(rowi) - local gone = tremove (g_loot, rowi) + local dgone, gone = g_dloot:remove(rowi) addon:Fire ('DelEOIEntry', gone) addon:Print("Removed %s.", gone.itemlink or gone.bossname or gone.startday.text) @@ -914,7 +951,7 @@ ["Delete remaining entries for this day"] = function(rowi,kind) -- if kind is boss, also need to stop at new timestamp local fencepost = addon._find_timeboss_fencepost (kind, rowi) - local count = fencepost and (fencepost-rowi) or (#g_loot-rowi+1) + local count = fencepost and (fencepost-rowi) or (#g_dloot-rowi+1) repeat eoi_dropdownfuncs.df_DELETE(rowi) count = count - 1 @@ -922,7 +959,7 @@ end, ["Rebroadcast this loot entry"] = function(rowi) - local e = g_loot[rowi] + local e = g_dloot[rowi] -- This only works because GetItemInfo accepts multiple argument formats addon:vbroadcast('loot', e.person, e.unique, e.itemlink, e.count, e.cols[3].value) addon:Print("Rebroadcast entry", rowi, e.itemlink) @@ -930,11 +967,11 @@ ["Rebroadcast this boss"] = function(rowi,kind) -- if kind is boss, also need to stop at new timestamp - local fencepost = addon._find_timeboss_fencepost (kind, rowi) or #g_loot + local fencepost = addon._find_timeboss_fencepost (kind, rowi) or #g_dloot -- this could be a lot of traffic, but frankly it's counterproductive -- to try to micromanage when ChatThrottleLib is already doing so repeat - local e = g_loot[rowi] + local e = g_dloot[rowi] if e.kind == 'boss' then addon:vbroadcast('boss', e.reason, e.bossname, e.instance) elseif e.kind == 'loot' then @@ -1205,7 +1242,7 @@ end function eoi_editcell (row_index, cell_frame) - local e = g_loot[row_index] + local e = g_dloot[row_index] if not e then return end -- how the hell could we get this far? local celldata = e.cols[3] local box = AceGUI:Create("EditBox") @@ -1329,7 +1366,7 @@ end end -local eoi_st_cols = { +eoi_st_cols = { { -- col 1 name = "Item", width = 250, @@ -1381,7 +1418,7 @@ -- through this loop. addon:_fill_out_eoi_data(1) -- safety check begin - for i,e in ipairs(g_loot) do + for i,e in ipairs(g_dloot) do if type(e.cols) ~= 'table' then addon:Print("ARGH, index",i,"bad in eoi_OGS, type",type(e.cols), "entry kind", e.kind, "data", e.itemname or e.bossname or e.startday.text, @@ -1390,7 +1427,7 @@ end end -- safety check end - ST:SetData(g_loot) + ST:SetData(g_dloot) ST:EnableSelection(true) ST:RegisterEvents{ OnEnter = eoi_st_OnEnter, @@ -1411,7 +1448,7 @@ ST.OuroLoot_Refresh = function (self, opt_index) addon:_fill_out_eoi_data(opt_index) -- safety check begin - for i,e in ipairs(g_loot) do + for i,e in ipairs(g_dloot) do if type(e.cols) ~= 'table' then addon:Print("ARGH, index",i,"bad in eoi refresh, refreshed at", opt_index, "type",type(e.cols), "entry kind", e.kind, "data", e.itemname or e.bossname or e.startday.text, @@ -1521,7 +1558,7 @@ if type(name_or_lineno) == 'string' then -- uh elseif type(name_or_lineno) == 'number' then - if name_or_lineno < 1 or name_or_lineno > #g_loot then + if name_or_lineno < 1 or name_or_lineno > #g_dloot then return end local scrollhere = -9 @@ -2485,11 +2522,13 @@ -- each time. The topmost call to our OnAccept will then finish by hiding the -- (very last) dialog. -- --- This is really, really hideous to read. +-- This is really, really hideous to read. Maybe increment a 'stage' counter +-- so the code flows top-down, rather than testing for missing data and going +-- backwards. local function eoi_st_insert_OnAccept_boss (dialog, data, data2) if data.all_done then - -- It'll probably be the final entry in the table, but there might have - -- been real loot happening while the user was clicking and typing. + -- boss_index will probably be the final entry in the table, but there + -- might have been real loot happening while the user was typing. local boss_index = addon._addBossEntry{ kind = 'boss', bossname = (gui.opts.snarky_boss and addon.boss_abbrev[data.name] or data.name) or data.name,