annotate gui.lua @ 112:ccf90050cdc1 beta-mhg-1

Work around acegui bugs, revert when tickets fixed.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Thu, 09 Aug 2012 23:58:30 -0400
parents cfbaf001fd52
children 67bf97136273
rev   line source
farmbuyer@1 1 local addon = select(2,...)
farmbuyer@67 2 if addon.NOLOAD then return end
farmbuyer@1 3
farmbuyer@1 4 --[[
farmbuyer@1 5 Purely the AceGUI-related routines, and the subroutines needed for support.
farmbuyer@1 6 ------ Constants
farmbuyer@6 7 ------ Globals
farmbuyer@1 8 ------ Behind the scenes routines
farmbuyer@1 9 ------ Main GUI Window
farmbuyer@1 10 ------ Popup dialogs
farmbuyer@1 11 ]]
farmbuyer@1 12
farmbuyer@1 13 ------ Constants
farmbuyer@1 14 local eoi_st_rowheight = 20
farmbuyer@83 15 local eoi_st_displayed_rows = math.floor(416/eoi_st_rowheight)
farmbuyer@1 16 local eoi_st_textured_item_format = "|T%s:"..(eoi_st_rowheight-2).."|t %s[%s]|r%s"
farmbuyer@84 17 -- This can get indexed by kind/reason/etc, and will default to lib-st's
farmbuyer@84 18 -- default "blank" background at runtime.
farmbuyer@1 19 local eoi_st_otherrow_bgcolortable = {
farmbuyer@1 20 wipe = { ["r"] = 0.3, ["g"] = 0.3, ["b"] = 0.3},
farmbuyer@1 21 kill = { ["r"] = 0.2, ["g"] = 0.2, ["b"] = 0.2},
farmbuyer@1 22 time = { ["r"] = 0x0/255, ["g"] = 0x0/255, ["b"] = 1, ["a"] = 0.3},
farmbuyer@1 23 }
farmbuyer@1 24 eoi_st_otherrow_bgcolortable[""] = eoi_st_otherrow_bgcolortable["kill"]
farmbuyer@1 25 local eoi_st_otherrow_bgcolortable_default
farmbuyer@109 26 local eoi_st_lootrow_col3_colortable = addon.disposition_colors
farmbuyer@73 27 local function eoi_st_lootrow_col3_colortable_func (data, _, realrow)
farmbuyer@109 28 return eoi_st_lootrow_col3_colortable[data[realrow].disposition]
farmbuyer@1 29 end
farmbuyer@95 30 local time_column1_used_mt = { __index = {
farmbuyer@1 31 [2] = {value=""},
farmbuyer@1 32 [3] = {value=""},
farmbuyer@1 33 } }
farmbuyer@1 34
farmbuyer@1 35
farmbuyer@6 36 ------ Globals
farmbuyer@95 37 local AceGUI = LibStub("AceGUI-3.0")
farmbuyer@1 38 local flib = LibStub("LibFarmbuyer")
farmbuyer@1 39
farmbuyer@95 40 local gui = {
farmbuyer@95 41 -- These are used to build the tabgroup_tabs array fed to TabGroup, and
farmbuyer@95 42 -- for the official source of mouseover tab titles, etc. Not completely
farmbuyer@95 43 -- hidden because we need to reach in and fiddle too often to be worth it.
farmbuyer@95 44 tabtexts = {
farmbuyer@95 45 ["eoi"] = {title=[[Loot]], desc=[[Observed loot, plus boss kills and other events of interest]]},
farmbuyer@95 46 ["hist"] = {title=[[History]], desc=[[A short semi-permanent record]]},
farmbuyer@95 47 },
farmbuyer@95 48 taborder = { "eoi" },
farmbuyer@95 49 taborder_APPEND = { "hist", "help", "opt" },
farmbuyer@110 50
farmbuyer@110 51 -- Tables for feeding to EasyMenu
farmbuyer@110 52 dropdown = {},
farmbuyer@95 53 }
farmbuyer@95 54 addon.gui_state_pointer = gui -- only during loading, then cleaned out
farmbuyer@95 55 if addon.author_debug then
farmbuyer@95 56 _G.OLgui = gui
farmbuyer@95 57 end
farmbuyer@95 58
farmbuyer@1 59 local g_loot = nil
farmbuyer@79 60 local g_uniques = nil
farmbuyer@1 61 local g_generated = nil
farmbuyer@17 62 local window_title = "Ouro Loot"
farmbuyer@47 63 local dirty_tabs = nil
farmbuyer@1 64
farmbuyer@76 65 local error = addon.error
farmbuyer@76 66 local assert = addon.assert
farmbuyer@76 67
farmbuyer@56 68 local pairs, ipairs, tinsert, tremove, tostring, tonumber =
farmbuyer@56 69 pairs, ipairs, table.insert, table.remove, tostring, tonumber
farmbuyer@1 70
farmbuyer@1 71 local pprint, tabledump = addon.pprint, flib.tabledump
farmbuyer@11 72 local GetItemInfo, ITEM_QUALITY_COLORS = GetItemInfo, ITEM_QUALITY_COLORS
farmbuyer@90 73 local GetNumRaidMembers = GetNumGroupMembers or GetNumRaidMembers
farmbuyer@93 74 local IsInRaid = IsInRaid or (function() return GetNumRaidMembers() > 0 end)
farmbuyer@1 75
farmbuyer@1 76 -- En masse forward decls of symbols defined inside local blocks
farmbuyer@83 77 local _generate_text, _populate_text_specials, _markup
farmbuyer@95 78 local eoi_dropdownfuncs -- filled out in gui block scope
farmbuyer@96 79 local _hide_debugging_tooltip, _build_debugging_tooltip
farmbuyer@78 80 local _new_rebroadcast_hyperlink
farmbuyer@1 81
farmbuyer@49 82 --[[
farmbuyer@49 83 This is a table of callback functions, each responsible for drawing a tab
farmbuyer@49 84 into the container passed in the first argument. Special-purpose buttons
farmbuyer@49 85 can optionally be created (mkbutton) and added to the container in the second
farmbuyer@49 86 argument.
farmbuyer@49 87 ]]
farmbuyer@49 88 local tabs_OnGroupSelected = {}
farmbuyer@49 89 local mkbutton
farmbuyer@49 90 local tabs_OnGroupSelected_func, tabs_generated_text_OGS
farmbuyer@83 91 -- Similarly for the popup tips on the right side of the window.
farmbuyer@83 92 local noob_tips = {}
farmbuyer@88 93 -- And any special handling for additional CLI arguments.
farmbuyer@88 94 local tabs_CLI_special = {}
farmbuyer@49 95
farmbuyer@83 96 do
farmbuyer@83 97 local replacement_colors = {
farmbuyer@83 98 ["+"]="|cffffffff", -- white
farmbuyer@83 99 ["<"]="|cff00ff00", -- light green
farmbuyer@83 100 [">"]="|r" }
farmbuyer@83 101 function _markup (t)
farmbuyer@83 102 -- wonder if it would be worth memoizing this also
farmbuyer@83 103 return t:gsub("[%+<>]",replacement_colors)
farmbuyer@83 104 :gsub("([^\n])\n([^\n])", "%1 %2")
farmbuyer@83 105 :gsub("|r\n\n", "|r\n")
farmbuyer@83 106 end
farmbuyer@104 107 gui.markup = _markup -- too useful to keep local
farmbuyer@83 108 end
farmbuyer@83 109
farmbuyer@1 110 -- Working around this bug:
farmbuyer@1 111 -- http://forums.wowace.com/showpost.php?p=295202&postcount=31
farmbuyer@109 112 if false then -- XXX no longer needed? test on mop beta
farmbuyer@37 113 local function fix_frame_level (level, ...)
farmbuyer@1 114 for i = 1, select("#", ...) do
farmbuyer@1 115 local button = select(i, ...)
farmbuyer@1 116 button:SetFrameLevel(level)
farmbuyer@1 117 end
farmbuyer@1 118 end
farmbuyer@1 119
farmbuyer@37 120 local function fix_menu_frame_levels()
farmbuyer@37 121 local f = _G.DropDownList1
farmbuyer@1 122 local i = 1
farmbuyer@1 123 while f do
farmbuyer@37 124 fix_frame_level (f:GetFrameLevel() + 2, f:GetChildren())
farmbuyer@1 125 i = i + 1
farmbuyer@1 126 f = _G["DropDownList"..i]
farmbuyer@1 127 end
farmbuyer@1 128 end
farmbuyer@1 129
farmbuyer@1 130 -- To fix Blizzard's bug caused by the new "self:SetFrameLevel(2);"
farmbuyer@37 131 hooksecurefunc("UIDropDownMenu_CreateFrames", fix_menu_frame_levels)
farmbuyer@1 132 end
farmbuyer@1 133
farmbuyer@1 134
farmbuyer@1 135 ------ Behind the scenes routines
farmbuyer@1 136 -- Text generation
farmbuyer@1 137 do
farmbuyer@1 138 local text_gen_funcs, specials_gen_funcs = {}, {}
farmbuyer@1 139 local accumulator = {}
farmbuyer@1 140
farmbuyer@95 141 local function _reg (tab_code, title, description, --[[unused]]generator,
farmbuyer@95 142 opt_specgen, opt_noobtip, opt_cli
farmbuyer@95 143 )
farmbuyer@95 144 assert(type(tab_code)=='string')
farmbuyer@95 145 assert(type(title)=='string')
farmbuyer@95 146 assert(type(description)=='string')
farmbuyer@95 147 gui.tabtexts[tab_code] = { title=title, desc=description }
farmbuyer@95 148 if not gui.suppress_taborder then
farmbuyer@95 149 gui:tabposition_insert (tab_code)
farmbuyer@95 150 end
farmbuyer@95 151 if opt_specgen then
farmbuyer@95 152 assert(type(opt_specgen)=='function')
farmbuyer@95 153 specials_gen_funcs[tab_code] = opt_specgen
farmbuyer@95 154 end
farmbuyer@95 155 if opt_noobtip then
farmbuyer@95 156 if type(opt_noobtip) == 'string' then
farmbuyer@95 157 noob_tips[tab_code] = _markup(opt_noobtip)
farmbuyer@95 158 elseif type(opt_noobtip) == 'function' then
farmbuyer@95 159 noob_tips[tab_code] = opt_noobtip
farmbuyer@95 160 else
farmbuyer@95 161 error(("Optional new user tip argument for '%s' must be a string or function!"):format(tab_code))
farmbuyer@95 162 end
farmbuyer@95 163 end
farmbuyer@95 164 if opt_cli then
farmbuyer@95 165 assert(type(opt_cli)=='function')
farmbuyer@95 166 tabs_CLI_special[tab_code] = opt_cli
farmbuyer@95 167 end
farmbuyer@95 168 dirty_tabs = true
farmbuyer@95 169 end
farmbuyer@95 170
farmbuyer@1 171 -- Can do clever things by passing other halting points as zero
farmbuyer@84 172 function addon:zero_printed_fenceposts (zero)
farmbuyer@1 173 for t in pairs(text_gen_funcs) do
farmbuyer@1 174 g_loot.printed[t] = zero or g_loot.printed[t] or 0
farmbuyer@1 175 end
farmbuyer@1 176 end
farmbuyer@1 177
farmbuyer@10 178 function addon:registered_textgen_iter()
farmbuyer@10 179 return pairs(text_gen_funcs)
farmbuyer@10 180 end
farmbuyer@10 181
farmbuyer@1 182 -- This function is called during load, so be careful!
farmbuyer@95 183 function addon:register_text_generator (text_type, title, description,
farmbuyer@95 184 generator, opt_specgen, opt_noobtip, opt_cli
farmbuyer@95 185 )
farmbuyer@95 186 if self.NOLOAD then return end
farmbuyer@1 187 if type(generator) ~= 'function' then
farmbuyer@1 188 error(("Generator for text type '%s' must be a function!"):format(text_type))
farmbuyer@1 189 end
farmbuyer@95 190 _reg (text_type, title, description, generator, opt_specgen, opt_noobtip, opt_cli)
farmbuyer@1 191 text_gen_funcs[text_type] = generator
farmbuyer@1 192 end
farmbuyer@1 193
farmbuyer@84 194 -- These two called by tabs_generated_text_OGS
farmbuyer@84 195 -- tabs_OnGroupSelected_func will catch propagated errors
farmbuyer@1 196 function _generate_text (text_type)
farmbuyer@1 197 local f = text_gen_funcs[text_type]
farmbuyer@1 198 if not f then
farmbuyer@1 199 error(("Generator called for unregistered text type '%s'."):format(text_type))
farmbuyer@1 200 end
farmbuyer@1 201 g_generated = g_generated or {}
farmbuyer@1 202 g_loot[text_type] = g_loot[text_type] or ""
farmbuyer@1 203
farmbuyer@1 204 if g_loot.printed[text_type] >= #g_loot then return false end
farmbuyer@76 205 assert (addon.loot_clean == #g_loot,
farmbuyer@76 206 tostring(addon.loot_clean) .. " ~= " .. #g_loot)
farmbuyer@1 207 -- if glc is nil, #==0 test already returned
farmbuyer@1 208
farmbuyer@1 209 local ok,ret = pcall (f, text_type, g_loot, g_loot.printed[text_type], g_generated, accumulator)
farmbuyer@1 210 if not ok then
farmbuyer@1 211 error(("ERROR: text generator '%s' failed: %s"):format(text_type, ret))
farmbuyer@1 212 end
farmbuyer@1 213 if ret then
farmbuyer@1 214 g_loot.printed[text_type] = #g_loot
farmbuyer@1 215 g_generated[text_type] = (g_generated[text_type] or "") .. table.concat(accumulator,'\n') .. '\n'
farmbuyer@1 216 end
farmbuyer@1 217 wipe(accumulator)
farmbuyer@1 218 return ret
farmbuyer@1 219 end
farmbuyer@1 220 function _populate_text_specials (editbox, specials, mkb, text_type)
farmbuyer@1 221 local f = specials_gen_funcs[text_type]
farmbuyer@1 222 if not f then return end
farmbuyer@84 223 local ok,ret = pcall (f, text_type, editbox, specials, mkb)
farmbuyer@84 224 if not ok then
farmbuyer@84 225 error(("ERROR: special widget creation for '%s' failed: %s"):format(text_type, ret))
farmbuyer@84 226 end
farmbuyer@1 227 end
farmbuyer@49 228
farmbuyer@49 229 -- LOD tab has been clicked on.
farmbuyer@49 230 local function _handle_LOD (tabs_container,specials,tabtitle)
farmbuyer@95 231 -- "tabtitle" here is the name in taborder, not the colorized string
farmbuyer@95 232 local what = gui.tabtexts[tabtitle]
farmbuyer@49 233 local addon_index = what.LOD
farmbuyer@49 234 local function LOAD()
farmbuyer@95 235 gui.tabtexts[tabtitle] = nil
farmbuyer@95 236 gui:tabposition_remove_and_remember (tabtitle)
farmbuyer@49 237 local loaded, whynot = LoadAddOn(addon_index)
farmbuyer@95 238 local tabdelta = gui:tabposition_restore()
farmbuyer@49 239 if loaded then
farmbuyer@57 240 addon:Print("%s loaded, %d |4tab:tabs; added.", tabtitle, tabdelta)
farmbuyer@49 241 else
farmbuyer@49 242 what.disabled = true
farmbuyer@95 243 gui.tabtexts[tabtitle] = what -- restore this for mouseovers
farmbuyer@49 244 addon:Print("%s could not load (game client reason was '%s').", tabtitle, whynot)
farmbuyer@49 245 DisableAddOn(addon_index)
farmbuyer@49 246 end
farmbuyer@49 247 dirty_tabs = true
farmbuyer@51 248 return addon:OpenMainDisplayToTab(tabtitle) or addon:BuildMainDisplay()
farmbuyer@49 249 end
farmbuyer@49 250 addon.display:Hide()
farmbuyer@49 251 if what.LOD_enabled then
farmbuyer@49 252 -- totally loadable, go for it
farmbuyer@49 253 LOAD()
farmbuyer@49 254 else
farmbuyer@49 255 -- was disabled at addons menu
farmbuyer@49 256 StaticPopupDialogs["OUROL_LOD_DISABLED"] = flib.StaticPopup{
farmbuyer@57 257 text = tabtitle.." was disabled at the character selection screen. Do you want to enable it?",
farmbuyer@49 258 button1 = YES,
farmbuyer@49 259 button2 = NO,
farmbuyer@49 260 OnAccept = function()
farmbuyer@49 261 EnableAddOn(addon_index)
farmbuyer@49 262 LOAD()
farmbuyer@49 263 end,
farmbuyer@49 264 OnCancel = function()
farmbuyer@49 265 addon:BuildMainDisplay()
farmbuyer@49 266 end,
farmbuyer@49 267 OnHide = function()
farmbuyer@49 268 StaticPopupDialogs["OUROL_LOD_DISABLED"] = nil
farmbuyer@49 269 end,
farmbuyer@49 270 }
farmbuyer@49 271 StaticPopup_Show("OUROL_LOD_DISABLED")
farmbuyer@49 272 end
farmbuyer@49 273 end
farmbuyer@49 274
farmbuyer@49 275 -- Add a clickable tab that brings the real module in. Since gui_init has
farmbuyer@49 276 -- already been called, we flag the dirty bit and let the main building
farmbuyer@49 277 -- routine handle it like any other plugin.
farmbuyer@49 278 function addon:_gui_add_LOD_tab (tabtitle, folder, addon_index, enabled_p, why_not)
farmbuyer@95 279 gui.tabtexts[tabtitle] = {
farmbuyer@51 280 title = ("|cffff0000(%s)|r"):format(tabtitle),
farmbuyer@57 281 desc = ("Plugin '|cffff0000%s|r' is not loaded yet. Click the tab to load it now."):format(folder),
farmbuyer@49 282 LOD = addon_index,
farmbuyer@49 283 LOD_enabled = enabled_p,
farmbuyer@49 284 LOD_why_not = why_not,
farmbuyer@49 285 }
farmbuyer@49 286 tabs_OnGroupSelected[tabtitle] = _handle_LOD
farmbuyer@95 287 gui:tabposition_insert (tabtitle)
farmbuyer@49 288 dirty_tabs = true
farmbuyer@49 289 end
farmbuyer@95 290
farmbuyer@95 291 -- Registering truly arbitrary tab controls, not just text generators.
farmbuyer@95 292 -- (This is slightly out of place, but no more so than the LOD stuff.)
farmbuyer@95 293 -- The arguments are nearly the same as those of :register_text_generator
farmbuyer@95 294 -- but the "generator" function is the full-blown callback and there is
farmbuyer@95 295 -- no "specgen" (since it's handled in the main generator).
farmbuyer@95 296 function addon:register_tab_control (tab_code, title, description,
farmbuyer@95 297 generator, opt_noobtip, opt_cli
farmbuyer@95 298 )
farmbuyer@95 299 if self.NOLOAD then return end
farmbuyer@95 300 if type(generator) ~= 'function' then
farmbuyer@95 301 error(("Generator for tab code '%s' must be a function!"):format(tab_code))
farmbuyer@95 302 end
farmbuyer@95 303 _reg (tab_code, title, description, generator, --[[opt_specgen=]]nil, opt_noobtip, opt_cli)
farmbuyer@95 304 tabs_OnGroupSelected[tab_code] = generator
farmbuyer@95 305 end
farmbuyer@95 306 function addon:register_tab_control_AT_END (...)
farmbuyer@95 307 gui.suppress_taborder = true
farmbuyer@95 308 self:register_tab_control(...)
farmbuyer@95 309 gui.suppress_taborder = nil
farmbuyer@95 310 end
farmbuyer@1 311 end
farmbuyer@1 312
farmbuyer@1 313 --[[
farmbuyer@1 314 The g_loot table is populated only with "behavior-relevant" data (names,
farmbuyer@1 315 links, etc). This function runs through it and fills out the "display-
farmbuyer@1 316 relevant" bits (icons, user-friendly labels, etc). Everything from the
farmbuyer@1 317 loot_clean index to the end of the table is filled out, loot_clean is
farmbuyer@1 318 updated. Override the starting point with the argument.
farmbuyer@1 319
farmbuyer@1 320 XXX blizzard's scrolling update and lib-st keep finding some way of displaying
farmbuyer@1 321 the grid without ever calling the hooked refresh, thereby skipping this
farmbuyer@1 322 function and erroring on missing columnar data. fuckit. from now on
farmbuyer@1 323 this function gets called everywhere, all the time, and loops over the
farmbuyer@1 324 entire goddamn table each time. If we can't find blizz's scrollframe bugs,
farmbuyer@1 325 we'll just work around them. Sorry for your smoking CPU.
farmbuyer@1 326
farmbuyer@1 327 FIXME just move this functionality to a per-entry function and call it once
farmbuyer@1 328 in _addlootentry. --actually no, then the columnar data won't be updated once
farmbuyer@1 329 the backend data is changed on the fly.
farmbuyer@1 330 ]]
farmbuyer@1 331 do
farmbuyer@1 332 function addon:_fill_out_eoi_data (opt_starting_index)
farmbuyer@1 333 if #g_loot < 1 then
farmbuyer@1 334 --pprint('_f_o_e_d', "#g_loot<1")
farmbuyer@1 335 self.loot_clean = nil
farmbuyer@1 336 opt_starting_index = nil
farmbuyer@1 337 end
farmbuyer@1 338 for i = (opt_starting_index or self.loot_clean or 1), #g_loot do
farmbuyer@1 339 local e = g_loot[i]
farmbuyer@1 340 if e == nil then
farmbuyer@1 341 self.loot_clean = nil
farmbuyer@1 342 pprint('_f_o_e_d', "index",i,"somehow still in loop past",#g_loot,"bailing")
farmbuyer@1 343 return
farmbuyer@1 344 end
farmbuyer@1 345
farmbuyer@97 346 local display_bcast_from = self.db.profile.display_bcast_from
farmbuyer@1 347 -- XXX FIXME a major weakness here is that we're constantly replacing
farmbuyer@1 348 -- what's already been created. Lots of garbage. Trying to detect what
farmbuyer@1 349 -- actually needs to be replaced is even worse. We'll live with
farmbuyer@1 350 -- garbage for now.
farmbuyer@1 351 if e.kind == 'loot' then
farmbuyer@11 352 local textured = eoi_st_textured_item_format:format (e.itexture, ITEM_QUALITY_COLORS[e.quality].hex, e.itemname, e.count or "")
farmbuyer@1 353 e.cols = {
farmbuyer@1 354 {value = textured},
farmbuyer@1 355 {value = e.person},
farmbuyer@73 356 {}
farmbuyer@1 357 }
farmbuyer@1 358 -- This is horrible. Must do better.
farmbuyer@109 359 if e.extratext then
farmbuyer@109 360 for disp,text in self:_iter_dispositions('from_notes_text') do
farmbuyer@109 361 if text == e.extratext then
farmbuyer@109 362 e.disposition = disp
farmbuyer@109 363 break
farmbuyer@109 364 end
farmbuyer@1 365 end
farmbuyer@109 366 end
farmbuyer@109 367 local ex = eoi_st_lootrow_col3_colortable[e.disposition].text
farmbuyer@65 368 if e.bcast_from and display_bcast_from and e.extratext then
farmbuyer@1 369 ex = e.extratext .. " (from " .. e.bcast_from .. ")"
farmbuyer@65 370 elseif e.bcast_from and display_bcast_from then
farmbuyer@73 371 ex = ex .. (e.disposition and " " or "")
farmbuyer@73 372 .. "(from " .. e.bcast_from .. ")"
farmbuyer@1 373 elseif e.extratext then
farmbuyer@1 374 ex = e.extratext
farmbuyer@1 375 end
farmbuyer@1 376 e.cols[3].value = ex
farmbuyer@1 377
farmbuyer@1 378 elseif e.kind == 'boss' then
farmbuyer@1 379 local v
farmbuyer@52 380 e.duration = e.duration or 0 -- can occasionally miss getting set
farmbuyer@1 381 if e.reason == 'kill' then
farmbuyer@1 382 if e.attempts == 1 then
farmbuyer@1 383 v = "one-shot"
farmbuyer@1 384 else
farmbuyer@84 385 v = ("kill on %d%s attempt"):format(e.attempts or 0,
farmbuyer@84 386 e.attempts==2 and "nd" or e.attempts==3 and "rd" or "th")
farmbuyer@1 387 end
farmbuyer@1 388 v = ("%s (%d:%.2d)"):format(v, math.floor(e.duration/60), math.floor(e.duration%60))
farmbuyer@1 389 elseif e.reason == 'wipe' then
farmbuyer@1 390 v = ("wipe (%d:%.2d)"):format(math.floor(e.duration/60), math.floor(e.duration%60))
farmbuyer@1 391 end
farmbuyer@1 392 e.cols = {
farmbuyer@55 393 {value = e.bossname},
farmbuyer@1 394 {value = e.instance},
farmbuyer@1 395 {value = v or ""},
farmbuyer@1 396 }
farmbuyer@1 397
farmbuyer@1 398 elseif e.kind == 'time' then
farmbuyer@1 399 e.cols = setmetatable({
farmbuyer@1 400 {value=e.startday.text},
farmbuyer@1 401 }, time_column1_used_mt)
farmbuyer@1 402 --[[e.cols = {
farmbuyer@1 403 {value=e.startday.text},
farmbuyer@1 404 {value=""},
farmbuyer@1 405 {value=""},
farmbuyer@1 406 }]]
farmbuyer@1 407
farmbuyer@1 408 end
farmbuyer@1 409 end
farmbuyer@1 410 self.loot_clean = #g_loot
farmbuyer@1 411 end
farmbuyer@1 412 end
farmbuyer@1 413
farmbuyer@1 414 do
farmbuyer@1 415 function addon:_fill_out_hist_data (opt_starting_index)
farmbuyer@6 416 local new, del = flib.new, flib.del
farmbuyer@6 417
farmbuyer@1 418 -- Clearing history finishes this function with #hist==0 and hist_clean==0.
farmbuyer@1 419 -- The next call typically detects this (#<1) and handles it. If loot is
farmbuyer@1 420 -- recorded before then, it results in hist_clean==0 and #hist==1, which
farmbuyer@1 421 -- breaks the first iteration of the loop. Thus, the "extra" test here:
farmbuyer@1 422 if #self.history < 1 or self.hist_clean == 0 then
farmbuyer@1 423 self.hist_clean = nil
farmbuyer@1 424 opt_starting_index = nil
farmbuyer@1 425 end
farmbuyer@1 426 if not self.history.st then
farmbuyer@6 427 --print"creating ST!"
farmbuyer@1 428 self.history.st = {
farmbuyer@4 429 --[[{ kind = "realm",
farmbuyer@1 430 cols = setmetatable({
farmbuyer@1 431 { value = self.history.realm },
farmbuyer@1 432 }, time_column1_used_mt)
farmbuyer@4 433 }]]
farmbuyer@1 434 }
farmbuyer@1 435 end
farmbuyer@6 436
farmbuyer@6 437 -- for now
farmbuyer@6 438 if self.hist_clean == #self.history then return end
farmbuyer@6 439
farmbuyer@1 440 local st = self.history.st
farmbuyer@6 441 --print("starting history loop, #st ==", #st, "#history ==", #self.history)
farmbuyer@6 442 for i,t in ipairs(st) do
farmbuyer@6 443 del(t.cols[1])
farmbuyer@6 444 del(t.cols[2])
farmbuyer@6 445 del(t.cols[3])
farmbuyer@6 446 del(t.cols)
farmbuyer@6 447 del(t)
farmbuyer@6 448 st[i] = nil
farmbuyer@6 449 end
farmbuyer@1 450
farmbuyer@6 451 --for i = (opt_starting_index or self.hist_clean or 1), #self.history do
farmbuyer@6 452 local cache_okay = true
farmbuyer@6 453 for pi,player in ipairs(self.history) do
farmbuyer@6 454 local col1 = new()
farmbuyer@6 455 col1.OLi = pi
farmbuyer@6 456 col1.value = player.name -- may spiffy this up in future
farmbuyer@1 457
farmbuyer@73 458 for li,unique in ipairs(player.unique) do
farmbuyer@6 459 local col2 = new()
farmbuyer@6 460 col2.OLi = li
farmbuyer@84 461 col2.OLu = unique
farmbuyer@6 462 local col3 = new()
farmbuyer@103 463 col3.value = assert(player.when[unique])
farmbuyer@6 464
farmbuyer@103 465 local id = assert(player.id[unique])
farmbuyer@73 466 local itexture = GetItemIcon(id)
farmbuyer@73 467 local iname, ilink, iquality = GetItemInfo(id)
farmbuyer@4 468 local textured
farmbuyer@4 469 if itexture and iname then
farmbuyer@6 470 textured = eoi_st_textured_item_format:format (itexture,
farmbuyer@73 471 ITEM_QUALITY_COLORS[iquality].hex, iname, player.count[unique] or "")
farmbuyer@4 472 else
farmbuyer@6 473 textured = eoi_st_textured_item_format:format ([[ICONS\INV_Misc_QuestionMark]],
farmbuyer@19 474 ITEM_QUALITY_COLORS[ITEM_QUALITY_COMMON].hex, 'UNKNOWN - REDISPLAY LATER', "")
farmbuyer@6 475 cache_okay = false
farmbuyer@4 476 end
farmbuyer@6 477 col2.value = textured
farmbuyer@6 478
farmbuyer@84 479 -- To facilitate sharing lib-st routines between EOI and this
farmbuyer@84 480 -- one, we do some of the same fields: 'kind' and 'itemlink'.
farmbuyer@84 481 -- These aren't used outside of the GUI. These become our data
farmbuyer@84 482 -- table arguments to the lib-st routines (thus 'e' locals).
farmbuyer@6 483 local dotcols = new (col1, col2, col3)
farmbuyer@6 484 local st_entry = new()
farmbuyer@84 485 st_entry.kind = 'hist'
farmbuyer@6 486 st_entry.OLwho = player.name
farmbuyer@86 487 st_entry.OLclass = player.person_class
farmbuyer@6 488 st_entry.cols = dotcols
farmbuyer@16 489 st_entry.itemlink = ilink -- for onenter and onclick
farmbuyer@6 490 tinsert (st, st_entry)
farmbuyer@1 491 end
farmbuyer@6 492 end
farmbuyer@1 493
farmbuyer@6 494 --print("finished history loop, #st ==", #st)
farmbuyer@6 495 self.hist_clean = cache_okay and #self.history or nil
farmbuyer@1 496 end
farmbuyer@72 497 end
farmbuyer@6 498
farmbuyer@74 499 -- Debugging tooltip (unfortunately managed by global and semi-global state
farmbuyer@74 500 -- rather than passing around stack parameters)
farmbuyer@74 501 do
farmbuyer@74 502 local debug_tt
farmbuyer@74 503
farmbuyer@74 504 local _creators, _builders = {}, {}
farmbuyer@73 505 local function _create_tooltip()
farmbuyer@96 506 local which = assert(tonumber(gui._do_debugging_tooltip))
farmbuyer@74 507 if type(_creators[which]) == 'function' then
farmbuyer@74 508 _creators[which]()
farmbuyer@74 509 end
farmbuyer@74 510 debug_tt = _creators[which]
farmbuyer@74 511 end
farmbuyer@74 512 function _build_debugging_tooltip (parent, index)
farmbuyer@96 513 local which = assert(tonumber(gui._do_debugging_tooltip))
farmbuyer@74 514 if type(_builders[which]) == 'function' then
farmbuyer@74 515 _builders[which](parent,index)
farmbuyer@74 516 end
farmbuyer@74 517 end
farmbuyer@74 518 function _hide_debugging_tooltip()
farmbuyer@74 519 if debug_tt then debug_tt:Hide() end
farmbuyer@74 520 end
farmbuyer@74 521
farmbuyer@74 522 -- 2 == /dump
farmbuyer@74 523 _creators[2] = function()
farmbuyer@74 524 local tt = CreateFrame("GameTooltip")
farmbuyer@73 525 UIParentLoadAddOn("Blizzard_DebugTools")
farmbuyer@73 526
farmbuyer@73 527 tt:SetBackdrop{
farmbuyer@73 528 bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
farmbuyer@73 529 edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
farmbuyer@73 530 tile = true,
farmbuyer@73 531 tileSize = 8,
farmbuyer@73 532 edgeSize = 12,
farmbuyer@73 533 insets = { left = 2, right = 2, top = 2, bottom = 2 }
farmbuyer@73 534 }
farmbuyer@73 535 tt:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r,
farmbuyer@73 536 TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
farmbuyer@73 537 tt:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g,
farmbuyer@73 538 TOOLTIP_DEFAULT_COLOR.b)
farmbuyer@73 539 tt:SetMovable(false)
farmbuyer@73 540 tt:EnableMouse(false)
farmbuyer@73 541 tt:SetFrameStrata("TOOLTIP")
farmbuyer@73 542 tt:SetToplevel(true)
farmbuyer@73 543 tt:SetClampedToScreen(true)
farmbuyer@73 544
farmbuyer@73 545 local font = CreateFont("OuroLootDebugFont")
farmbuyer@73 546 font:CopyFontObject(GameTooltipTextSmall)
farmbuyer@73 547 if IsAddOnLoaded"tekticles" then -- maybe check for one of the sharedmedia things?
farmbuyer@73 548 font:SetFont([[Interface\AddOns\tekticles\Calibri.ttf]], 9)
farmbuyer@73 549 else
farmbuyer@73 550 font:SetFont([[Fonts\FRIZQT__.TTF]], 9)
farmbuyer@73 551 end
farmbuyer@73 552
farmbuyer@73 553 local left, right, prevleft
farmbuyer@73 554 -- Only create as many lines as we might need (the auto growth
farmbuyer@73 555 -- by Add*Line does odd things sometimes).
farmbuyer@73 556 for i = 1, math.max(DEVTOOLS_MAX_ENTRY_CUTOFF,15)+5 do
farmbuyer@73 557 prevleft = left
farmbuyer@73 558 left = tt:CreateFontString(nil,"ARTWORK")
farmbuyer@73 559 right = tt:CreateFontString(nil,"ARTWORK")
farmbuyer@73 560 left:SetFontObject(font)
farmbuyer@73 561 right:SetFontObject(font)
farmbuyer@73 562 tt:AddFontStrings(left,right)
farmbuyer@73 563 if prevleft then
farmbuyer@73 564 left:SetPoint("TOPLEFT",prevleft,"BOTTOMLEFT",0,-2)
farmbuyer@73 565 else
farmbuyer@73 566 left:SetPoint("TOPLEFT",10,-10) -- top line
farmbuyer@73 567 end
farmbuyer@73 568 right:SetPoint("RIGHT",left,"LEFT")
farmbuyer@73 569 end
farmbuyer@73 570 tt.AddMessage = tt.AddLine
farmbuyer@73 571
farmbuyer@74 572 _creators[2] = tt
farmbuyer@73 573 end
farmbuyer@73 574
farmbuyer@74 575 _builders[2] = function (parent, index)
farmbuyer@73 576 local e = g_loot[index]; assert(type(e)=='table')
farmbuyer@74 577 _create_tooltip()
farmbuyer@74 578 debug_tt:SetOwner (parent, "ANCHOR_LEFT", -15, -5)
farmbuyer@74 579 debug_tt:ClearLines()
farmbuyer@73 580
farmbuyer@73 581 local real = DEFAULT_CHAT_FRAME
farmbuyer@74 582 DEFAULT_CHAT_FRAME = debug_tt
farmbuyer@73 583 DevTools_Dump{ [index] = e }
farmbuyer@73 584 DEFAULT_CHAT_FRAME = real
farmbuyer@73 585
farmbuyer@74 586 debug_tt:Show()
farmbuyer@73 587 end
farmbuyer@73 588
farmbuyer@72 589 -- Now here's a thing unheard-of. A tooltip not inheriting from the big
farmbuyer@72 590 -- memory-wasteful template, but also not intended merely for scanning
farmbuyer@72 591 -- invisible tooltips.
farmbuyer@72 592 -- (If this ever grows beyond a text dump, then replace it with libqtip.)
farmbuyer@74 593 --
farmbuyer@74 594 -- Fields to put in the fixed-fields tooltip (maybe move these into the
farmbuyer@74 595 -- options window if I spend too much time fiddling).
farmbuyer@74 596 local loot = {'person', 'id', 'unique', 'disposition', 'count', 'variant'}
farmbuyer@74 597 local boss = {'bossname', 'reason', 'instance', 'maxsize', 'duration', 'raidersnap'}
farmbuyer@74 598
farmbuyer@74 599 -- 3 == fixed fields
farmbuyer@74 600 _creators[3] = function()
farmbuyer@74 601 local tt = CreateFrame("GameTooltip")
farmbuyer@72 602
farmbuyer@72 603 tt:SetBackdrop{
farmbuyer@72 604 bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
farmbuyer@72 605 edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
farmbuyer@72 606 tile = true,
farmbuyer@72 607 tileSize = 8,
farmbuyer@72 608 edgeSize = 12,
farmbuyer@72 609 insets = { left = 2, right = 2, top = 2, bottom = 2 }
farmbuyer@72 610 }
farmbuyer@72 611 tt:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r,
farmbuyer@72 612 TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
farmbuyer@72 613 tt:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g,
farmbuyer@72 614 TOOLTIP_DEFAULT_COLOR.b)
farmbuyer@72 615 tt:SetMovable(false)
farmbuyer@72 616 tt:EnableMouse(false)
farmbuyer@72 617 tt:SetFrameStrata("TOOLTIP")
farmbuyer@72 618 tt:SetToplevel(true)
farmbuyer@72 619 tt:SetClampedToScreen(true)
farmbuyer@72 620
farmbuyer@72 621 local font = GameTooltipTextSmall
farmbuyer@72 622 local left, right, prevleft
farmbuyer@72 623 -- Only create as many lines as we might need (the auto growth
farmbuyer@72 624 -- by Add*Line does odd things sometimes).
farmbuyer@72 625 for i = 1, math.max(#loot,#boss)+2 do
farmbuyer@72 626 prevleft = left
farmbuyer@72 627 left = tt:CreateFontString(nil,"ARTWORK")
farmbuyer@72 628 right = tt:CreateFontString(nil,"ARTWORK")
farmbuyer@72 629 left:SetFontObject(font)
farmbuyer@72 630 right:SetFontObject(font)
farmbuyer@72 631 tt:AddFontStrings(left,right)
farmbuyer@72 632 if prevleft then
farmbuyer@72 633 left:SetPoint("TOPLEFT",prevleft,"BOTTOMLEFT",0,-2)
farmbuyer@72 634 else
farmbuyer@72 635 left:SetPoint("TOPLEFT",10,-10) -- top line
farmbuyer@72 636 end
farmbuyer@72 637 right:SetPoint("RIGHT",left,"LEFT")
farmbuyer@72 638 end
farmbuyer@72 639
farmbuyer@74 640 _creators[3] = tt
farmbuyer@72 641 end
farmbuyer@72 642
farmbuyer@74 643 _builders[3] = function (parent, index)
farmbuyer@72 644 local e = g_loot[index]; assert(type(e)=='table')
farmbuyer@74 645 _create_tooltip()
farmbuyer@74 646 debug_tt:SetOwner (parent, "ANCHOR_LEFT", -15, -5)
farmbuyer@74 647 debug_tt:ClearLines()
farmbuyer@72 648
farmbuyer@72 649 -- change these, change the +2 above
farmbuyer@74 650 debug_tt:AddDoubleLine (tostring(index), tostring(e), 1,1,1)
farmbuyer@74 651 debug_tt:AddDoubleLine ('kind', e.kind, 1,1,1)
farmbuyer@72 652
farmbuyer@72 653 local source = (e.kind == 'loot' and loot) or (e.kind == 'boss' and boss)
farmbuyer@72 654 if source then
farmbuyer@72 655 for _,field in ipairs(source) do
farmbuyer@74 656 debug_tt:AddDoubleLine (field, tostring(e[field]), 1,1,1, 0,156/255,1)
farmbuyer@72 657 end
farmbuyer@72 658 end
farmbuyer@74 659 debug_tt:Show()
farmbuyer@72 660 end
farmbuyer@1 661 end
farmbuyer@1 662
farmbuyer@78 663 do
farmbuyer@78 664 local rebroadcast_map -- XXX weaken this somehow?
farmbuyer@78 665
farmbuyer@78 666 local function onclick (self, ident)
farmbuyer@79 667 -- Since an arbitrary number of insert/delete ops can happen between
farmbuyer@79 668 -- now and (potentially) clicking on the hyperlink, we can't depend on
farmbuyer@79 669 -- the row index. Force the uniques cache to re-search (research?) it.
farmbuyer@79 670 local u = assert(rebroadcast_map[ident])
farmbuyer@79 671 local cache = g_uniques:SEARCH(u)
farmbuyer@79 672 -- A missing history entry isn't necessarily an error here, but we
farmbuyer@79 673 -- need a loot entry to go further.
farmbuyer@79 674 if cache.loot then
farmbuyer@79 675 eoi_dropdownfuncs["Rebroadcast this loot entry"](cache.loot)
farmbuyer@79 676 else
farmbuyer@79 677 addon:Print("...guh? Entry was recorded with tag <%s> but cannot now be found!", u)
farmbuyer@79 678 end
farmbuyer@79 679 -- delete the entry maybe?
farmbuyer@78 680 end
farmbuyer@78 681
farmbuyer@79 682 function _new_rebroadcast_hyperlink (u)
farmbuyer@78 683 rebroadcast_map = rebroadcast_map or flib.new()
farmbuyer@78 684 local clicky, ident = addon.format_hypertext(
farmbuyer@78 685 -- same color sequence as what DBM uses to announce pizza timers,
farmbuyer@78 686 -- which looks reasonably pleasing
farmbuyer@78 687 [[Broadcast this entry]], "|cff3588ff", onclick)
farmbuyer@79 688 rebroadcast_map[ident] = u
farmbuyer@78 689 return clicky
farmbuyer@78 690 end
farmbuyer@78 691 end
farmbuyer@78 692
farmbuyer@83 693 -- UI tips window
farmbuyer@83 694 local hide_noobtips_frame = flib.nullfunc
farmbuyer@83 695 local function get_noobtips_frame()
farmbuyer@83 696 local f = CreateFrame("Frame")
farmbuyer@83 697 f:SetBackdrop{
farmbuyer@83 698 bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
farmbuyer@83 699 --bgFile = [[Interface\DialogFrame\UI-DialogBox-Background]],
farmbuyer@83 700 edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
farmbuyer@83 701 --edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]],
farmbuyer@83 702 tile = true,
farmbuyer@83 703 tileSize = 8,
farmbuyer@83 704 --tileSize = 32,
farmbuyer@83 705 edgeSize = 12,
farmbuyer@83 706 --edgeSize = 32,
farmbuyer@83 707 insets = { left = 2, right = 2, top = 2, bottom = 2 }
farmbuyer@83 708 --insets = { left = 11, right = 12, top = 12, bottom = 11 }
farmbuyer@83 709 }
farmbuyer@83 710 f:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r,
farmbuyer@83 711 TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
farmbuyer@83 712 f:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g,
farmbuyer@83 713 TOOLTIP_DEFAULT_COLOR.b)
farmbuyer@83 714 f:SetMovable(false)
farmbuyer@83 715 f:EnableMouse(false)
farmbuyer@83 716 f:SetFrameStrata("TOOLTIP")
farmbuyer@83 717 f:SetToplevel(true)
farmbuyer@83 718 f:SetClampedToScreen(true)
farmbuyer@83 719 f:SetWidth(220)
farmbuyer@83 720 local t = f:CreateFontString (nil, "ARTWORK", "GameFontHighlightSmall")
farmbuyer@83 721 --t:SetPoint ("TOPLEFT", f, "TOPLEFT", 14, -15)
farmbuyer@83 722 t:SetPoint ("TOPLEFT", f, "TOPLEFT", 10, -10)
farmbuyer@83 723 t:SetJustifyH("LEFT")
farmbuyer@83 724
farmbuyer@83 725 f.text = t
farmbuyer@83 726 f.DoTextWork = function (self, text)
farmbuyer@83 727 self.text:SetText(text)
farmbuyer@83 728 self.text:SetWidth (self:GetWidth() - 20)
farmbuyer@83 729 self:SetHeight (self.text:GetHeight() + 20)
farmbuyer@83 730 end
farmbuyer@83 731
farmbuyer@83 732 get_noobtips_frame = function() return f end
farmbuyer@83 733 hide_noobtips_frame = function() f:Hide() end
farmbuyer@83 734 return f
farmbuyer@83 735 end
farmbuyer@83 736
farmbuyer@1 737
farmbuyer@1 738 ------ Main GUI Window
farmbuyer@95 739 local _d -- display when it's open, nil when it's not
farmbuyer@1 740 local function setstatus(txt) _d:SetStatusText(txt) end
farmbuyer@1 741 local function statusy_OnLeave() setstatus("") end
farmbuyer@1 742 local tabgroup_tabs
farmbuyer@104 743 gui.setstatus = setstatus
farmbuyer@1 744
farmbuyer@1 745 --[[
farmbuyer@1 746 Controls for the tabs on the left side of the main display.
farmbuyer@1 747 ]]
farmbuyer@57 748
farmbuyer@57 749 do
farmbuyer@95 750 --local next_insertion_position = 2 -- position in taborder
farmbuyer@95 751 local next_insertion_position = #gui.taborder + 1
farmbuyer@57 752 local removed, saved_offset
farmbuyer@57 753
farmbuyer@95 754 function gui:tabposition_insert (tabcode)
farmbuyer@95 755 tinsert (gui.taborder, next_insertion_position, tabcode)
farmbuyer@57 756 next_insertion_position = next_insertion_position + 1
farmbuyer@57 757 end
farmbuyer@57 758
farmbuyer@57 759 -- These two functions are push/pop pairs, sort of. The first removes
farmbuyer@57 760 -- a tab and prepares to insert more tab(s) in its place. The second
farmbuyer@57 761 -- returns the "next tab goes here" marker back to the proper end. (And
farmbuyer@57 762 -- doing all 3 adjustments below at once is amazingly hard to read.)
farmbuyer@95 763 function gui:tabposition_remove_and_remember (tabcode)
farmbuyer@57 764 assert(not removed) -- enforce stack-ish discipline
farmbuyer@95 765 for i = 2, #gui.taborder do
farmbuyer@95 766 if gui.taborder[i] == tabcode then
farmbuyer@95 767 tremove (gui.taborder, i)
farmbuyer@57 768 saved_offset = next_insertion_position - i - 1
farmbuyer@57 769 removed, next_insertion_position = i, i
farmbuyer@57 770 return
farmbuyer@57 771 end
farmbuyer@57 772 end
farmbuyer@57 773 error(("'%s' not used as a tab-text code"):format(tabcode))
farmbuyer@57 774 end
farmbuyer@95 775 function gui:tabposition_restore()
farmbuyer@57 776 assert(removed)
farmbuyer@57 777 local count = next_insertion_position - removed
farmbuyer@57 778 next_insertion_position = next_insertion_position + saved_offset
farmbuyer@57 779 removed, saved_offset = nil, nil
farmbuyer@57 780 return count
farmbuyer@57 781 end
farmbuyer@95 782
farmbuyer@95 783 function addon:FINISH_SPECIAL_TABS()
farmbuyer@95 784 -- very carefully not touching next_insertion_position
farmbuyer@95 785 for i,v in ipairs(gui.taborder_APPEND) do
farmbuyer@95 786 gui.taborder[#gui.taborder+1] = v
farmbuyer@95 787 end
farmbuyer@95 788 gui.taborder_APPEND = nil
farmbuyer@95 789 self.register_tab_control_AT_END = nil
farmbuyer@95 790 self.FINISH_SPECIAL_TABS = nil
farmbuyer@95 791 end
farmbuyer@57 792 end
farmbuyer@57 793
farmbuyer@57 794 -- Done at startup, and whenever we've changed the population of tabs.
farmbuyer@79 795 function addon:gui_init (loot_pointer, uniques_pointer)
farmbuyer@71 796 g_loot = assert(loot_pointer, "something went wrong at startup")
farmbuyer@79 797 g_uniques = assert(uniques_pointer, "something went wrong at startup")
farmbuyer@1 798 g_generated = nil
farmbuyer@1 799 tabgroup_tabs = {}
farmbuyer@89 800 window_title = "Ouro Loot " .. self.version
farmbuyer@46 801 -- TabGroup stretches out the tabs to fill the row but only if >75% of the
farmbuyer@46 802 -- row is already full. It turns out that not doing this looks like ass.
farmbuyer@46 803 -- If we won't have enough tabs to trigger this on its own, pad out the tab
farmbuyer@46 804 -- titles (not looking quite as nice, ah well) to force it to trigger.
farmbuyer@95 805 local fmtstr = #gui.taborder > 6 and "%s" or " %s "
farmbuyer@95 806 for i,name in ipairs(gui.taborder) do
farmbuyer@49 807 tabgroup_tabs[i] = {
farmbuyer@49 808 value = name,
farmbuyer@95 809 text = fmtstr:format(gui.tabtexts[name].title),
farmbuyer@95 810 disabled = gui.tabtexts[name].disabled,
farmbuyer@49 811 }
farmbuyer@1 812 -- By default, tabs are editboxes with generated text
farmbuyer@49 813 if not tabs_OnGroupSelected[name] then
farmbuyer@49 814 tabs_OnGroupSelected[name] = tabs_generated_text_OGS
farmbuyer@1 815 end
farmbuyer@1 816 end
farmbuyer@47 817 dirty_tabs = nil
farmbuyer@1 818 end
farmbuyer@1 819
farmbuyer@37 820 --[[
farmbuyer@84 821 Dropdown menu handling; this has grown in ungainly directions.
farmbuyer@37 822 ]]
farmbuyer@37 823 -- forward decls
farmbuyer@1 824 local eoi_editcell
farmbuyer@1 825
farmbuyer@110 826 local dropdownmenuframe = CreateFrame("Frame", "OuroLootDropDownMenu", nil, "UIDropDownMenuTemplate")
farmbuyer@37 827 local dropdownfuncs
farmbuyer@37 828 do
farmbuyer@37 829 local ddf_mt = {
farmbuyer@37 830 __index = {
farmbuyer@37 831 -- more stuff should be moved into this table
farmbuyer@37 832 [CLOSE] = function() CloseDropDownMenus() end,
farmbuyer@37 833 }
farmbuyer@37 834 }
farmbuyer@37 835 dropdownfuncs = function(t)
farmbuyer@37 836 return setmetatable(t, ddf_mt)
farmbuyer@37 837 end
farmbuyer@37 838 end
farmbuyer@37 839
farmbuyer@1 840 local function dropdownmenu_handler (ddbutton, subfunc, arg)
farmbuyer@84 841 local i = _d and _d.GetUserData and _d:GetUserData("DD index")
farmbuyer@26 842 if i then
farmbuyer@26 843 subfunc(i,arg)
farmbuyer@95 844 gui.which_ST:OuroLoot_Refresh(i)
farmbuyer@26 845 end
farmbuyer@1 846 end
farmbuyer@1 847
farmbuyer@110 848 local function gen_dd_entry (name, functbl, funci, arg, ttt)
farmbuyer@110 849 local entry
farmbuyer@110 850 if name == '--' then
farmbuyer@110 851 entry = {
farmbuyer@110 852 text = "", disabled = true, notCheckable = true,
farmbuyer@110 853 }
farmbuyer@110 854 else
farmbuyer@110 855 local a1 = functbl[name]
farmbuyer@110 856 if type(funci) == 'string' then
farmbuyer@110 857 a1 = functbl[funci]
farmbuyer@1 858 end
farmbuyer@110 859 entry = {
farmbuyer@110 860 text = name,
farmbuyer@110 861 func = dropdownmenu_handler, arg1 = a1, arg2 = arg,
farmbuyer@110 862 notCheckable = true,
farmbuyer@110 863 tooltipOnButton = true,
farmbuyer@110 864 tooltipWhileDisabled = true,
farmbuyer@110 865 tooltipTitle = ttt and name or nil,
farmbuyer@110 866 tooltipText = ttt,
farmbuyer@110 867 }
farmbuyer@1 868 end
farmbuyer@110 869 return entry
farmbuyer@1 870 end
farmbuyer@1 871
farmbuyer@37 872
farmbuyer@37 873 -- Tab 1: Events Of Interest
farmbuyer@37 874 -- This actually takes up quite a bit of the file.
farmbuyer@37 875 eoi_dropdownfuncs = dropdownfuncs{
farmbuyer@1 876 df_INSERT = function(rowi,text)
farmbuyer@1 877 local which = (text == 'loot') and "OUROL_EOI_INSERT_LOOT" or "OUROL_EOI_INSERT"
farmbuyer@1 878 local dialog = StaticPopup_Show(which,text)
farmbuyer@16 879 dialog.editBox:SetScript("OnTextChanged",StaticPopup_EditBoxOnTextChanged)
farmbuyer@1 880 dialog.data = {rowindex=rowi, display=_d, kind=text}
farmbuyer@1 881 end,
farmbuyer@1 882
farmbuyer@1 883 df_DELETE = function(rowi)
farmbuyer@84 884 local gone = tremove (g_loot, rowi)
farmbuyer@100 885 addon:Fire ('DelEOIEntry', gone)
farmbuyer@1 886 addon:Print("Removed %s.",
farmbuyer@55 887 gone.itemlink or gone.bossname or gone.startday.text)
farmbuyer@100 888 if gone.kind == 'loot' then
farmbuyer@100 889 addon:Fire ('DelLootEntry', gone)
farmbuyer@100 890 if IsShiftKeyDown() then
farmbuyer@100 891 local okay,err = addon:_delHistoryEntry (gone)
farmbuyer@100 892 if okay then
farmbuyer@100 893 addon:Print("Removed history entry %s from %s.",
farmbuyer@100 894 gone.itemlink, addon:colorize(gone.person,gone.person_class))
farmbuyer@100 895 else
farmbuyer@100 896 addon:Print(err)
farmbuyer@100 897 end
farmbuyer@84 898 end
farmbuyer@36 899 end
farmbuyer@1 900 end,
farmbuyer@1 901
farmbuyer@110 902 df_DISPOSITION = function(rowi,disp) -- all "mark as <x>" entries start here
farmbuyer@110 903 addon:loot_mark_disposition ("local", rowi, disp)
farmbuyer@110 904 end,
farmbuyer@110 905
farmbuyer@1 906 ["Delete remaining entries for this day"] = function(rowi,kind)
farmbuyer@28 907 -- if kind is boss, also need to stop at new timestamp
farmbuyer@28 908 local fencepost = addon._find_timeboss_fencepost (kind, rowi)
farmbuyer@1 909 local count = fencepost and (fencepost-rowi) or (#g_loot-rowi+1)
farmbuyer@1 910 repeat
farmbuyer@37 911 eoi_dropdownfuncs.df_DELETE(rowi)
farmbuyer@1 912 count = count - 1
farmbuyer@1 913 until count < 1
farmbuyer@1 914 end,
farmbuyer@1 915
farmbuyer@1 916 ["Rebroadcast this loot entry"] = function(rowi)
farmbuyer@1 917 local e = g_loot[rowi]
farmbuyer@1 918 -- This only works because GetItemInfo accepts multiple argument formats
farmbuyer@71 919 addon:vbroadcast('loot', e.person, e.unique, e.itemlink, e.count, e.cols[3].value)
farmbuyer@28 920 addon:Print("Rebroadcast entry", rowi, e.itemlink)
farmbuyer@1 921 end,
farmbuyer@1 922
farmbuyer@1 923 ["Rebroadcast this boss"] = function(rowi,kind)
farmbuyer@28 924 -- if kind is boss, also need to stop at new timestamp
farmbuyer@28 925 local fencepost = addon._find_timeboss_fencepost (kind, rowi) or #g_loot
farmbuyer@28 926 -- this could be a lot of traffic, but frankly it's counterproductive
farmbuyer@28 927 -- to try to micromanage when ChatThrottleLib is already doing so
farmbuyer@28 928 repeat
farmbuyer@28 929 local e = g_loot[rowi]
farmbuyer@28 930 if e.kind == 'boss' then
farmbuyer@56 931 addon:vbroadcast('boss', e.reason, e.bossname, e.instance)
farmbuyer@28 932 elseif e.kind == 'loot' then
farmbuyer@28 933 -- This only works because GetItemInfo accepts multiple argument formats
farmbuyer@71 934 addon:vbroadcast('loot', e.person, e.unique, e.itemlink, e.count, e.cols[3].value)
farmbuyer@28 935 end
farmbuyer@55 936 addon:Print("Rebroadcast entry", rowi, e.itemlink or e.bossname or UNKNOWN)
farmbuyer@28 937 rowi = rowi + 1
farmbuyer@28 938 until rowi >= fencepost
farmbuyer@1 939 end,
farmbuyer@1 940
farmbuyer@1 941 ["Show only this player"] = function(rowi)
farmbuyer@95 942 local st = assert(gui.eoiST)
farmbuyer@1 943 _d:SetUserData("player filter name", g_loot[rowi].person)
farmbuyer@1 944 st:SetFilter(_d:GetUserData("player filter by name"))
farmbuyer@1 945 _d:GetUserData("eoi_filter_reset"):SetDisabled(false)
farmbuyer@81 946 -- it'd be more futureproof to get the button and call some kind
farmbuyer@81 947 -- of :GetText() on it, but no such function is provided by acegui
farmbuyer@81 948 setstatus[[Use the "Reset Player Filter" button in the lower-right to return to normal.]]
farmbuyer@1 949 end,
farmbuyer@1 950
farmbuyer@1 951 ["Change from 'wipe' to 'kill'"] = function(rowi)
farmbuyer@1 952 addon:_mark_boss_kill(rowi)
farmbuyer@1 953 -- the fillout function called automatically will start too far down the list
farmbuyer@95 954 gui.eoiST:OuroLoot_Refresh()
farmbuyer@1 955 end,
farmbuyer@1 956
farmbuyer@1 957 ["Edit note"] = function(rowi)
farmbuyer@84 958 eoi_editcell (rowi, _d:GetUserData("DD cell"))
farmbuyer@1 959 end,
farmbuyer@1 960
farmbuyer@1 961 df_REASSIGN = function(rowi,to_whom)
farmbuyer@81 962 addon:reassign_loot ("local", rowi, to_whom)
farmbuyer@1 963 CloseDropDownMenus() -- also need to close parent menu
farmbuyer@1 964 end,
farmbuyer@1 965 ["Enter name..."] = function(rowi)
farmbuyer@25 966 CloseDropDownMenus() -- also need to close parent menu
farmbuyer@1 967 local dialog = StaticPopup_Show "OUROL_REASSIGN_ENTER"
farmbuyer@1 968 dialog.data = {index=rowi, display=_d}
farmbuyer@1 969 end,
farmbuyer@1 970 }
farmbuyer@110 971
farmbuyer@110 972 do
farmbuyer@110 973 local function E (name, funci, arg, ttt)
farmbuyer@110 974 return gen_dd_entry (name, eoi_dropdownfuncs, funci, arg, ttt)
farmbuyer@110 975 end
farmbuyer@110 976
farmbuyer@110 977 gui.dropdown.eoi_time = {
farmbuyer@110 978 {
farmbuyer@110 979 -- this is the dropdown title, text filled in on the fly
farmbuyer@110 980 isTitle = true,
farmbuyer@110 981 notClickable = true,
farmbuyer@110 982 notCheckable = true,
farmbuyer@110 983 },
farmbuyer@110 984 E("Rebroadcast this day", "Rebroadcast this boss", 'time', "Broadcasts everything from here down until a new day."),
farmbuyer@110 985 E("Delete remaining entries for this day", nil, 'time', "Erases everything from here down until a new day.\n\nHold down the Shift key to also delete the corresponding entries from player History."),
farmbuyer@110 986 E("Insert new loot entry", 'df_INSERT', 'loot', "Inserts new loot above this one, prompting you for information."),
farmbuyer@110 987 E("Insert new boss kill event", 'df_INSERT', 'boss', "Inserts new event above this one, prompting you for information."),
farmbuyer@110 988 E(CLOSE),
farmbuyer@110 989 }
farmbuyer@110 990 gui.dropdown.eoi_loot = {
farmbuyer@110 991 {
farmbuyer@110 992 -- this is the dropdown title, text filled in on the fly
farmbuyer@110 993 notClickable = true,
farmbuyer@110 994 notCheckable = true,
farmbuyer@110 995 },
farmbuyer@110 996 E("--"),
farmbuyer@110 997 E("Rebroadcast this loot entry", nil, nil, "Sends this loot event, including special notes, as if it just happened."),
farmbuyer@110 998 E("Delete this loot event", 'df_DELETE', nil, "Permanent, no going back!\n\nHold down the Shift key to also delete the corresponding entry from player's History."),
farmbuyer@110 999 E("Delete remaining entries for this boss", "Delete remaining entries for this day", 'boss', "Erases everything from here down until a new boss/day.\n\nHold down the Shift key to also delete the corresponding entries from player History."),
farmbuyer@110 1000 E("Insert new loot entry", 'df_INSERT', 'loot', "Inserts new loot above this one, prompting you for information."),
farmbuyer@110 1001 E("Insert new boss kill event", 'df_INSERT', 'boss', "Inserts new event above this one, prompting you for information."),
farmbuyer@110 1002 E("Edit note", nil, nil, "Same as double-clicking in the Notes column."),
farmbuyer@110 1003 E("--"),
farmbuyer@110 1004 E(CLOSE),
farmbuyer@110 1005 }
farmbuyer@110 1006 gui.dropdown.eoi_player = {
farmbuyer@1 1007 {
farmbuyer@1 1008 -- this is the dropdown title, text filled in on the fly
farmbuyer@1 1009 isTitle = true,
farmbuyer@1 1010 notClickable = true,
farmbuyer@1 1011 notCheckable = true,
farmbuyer@1 1012 },
farmbuyer@1 1013 {
farmbuyer@1 1014 text = "Reassign to...",
farmbuyer@1 1015 hasArrow = true,
farmbuyer@1 1016 --menuList = filled in in the fly,
farmbuyer@25 1017 tooltipOnButton = true,
farmbuyer@25 1018 tooltipWhileDisabled = true,
farmbuyer@1 1019 },
farmbuyer@110 1020 E("Show only this player"),
farmbuyer@110 1021 E(CLOSE),
farmbuyer@110 1022 }
farmbuyer@110 1023 gui.dropdown.eoi_boss = {
farmbuyer@110 1024 {
farmbuyer@110 1025 -- this is the dropdown title, text filled in on the fly
farmbuyer@110 1026 isTitle = true,
farmbuyer@110 1027 notClickable = true,
farmbuyer@110 1028 notCheckable = true,
farmbuyer@110 1029 },
farmbuyer@110 1030 E("Change from 'wipe' to 'kill'", nil, nil, "Also collapses previous wipe entries."), -- KILLWIPE
farmbuyer@110 1031 E("Rebroadcast this boss", nil, 'boss', "Broadcasts the kill event and all subsequent loot until next boss."),
farmbuyer@110 1032 E("Delete this boss event", 'df_DELETE', nil, "Permanent, no going back!"),
farmbuyer@110 1033 E("Delete remaining entries for this boss", "Delete remaining entries for this day", 'boss', "Erases everything from here down until a new boss/day.\n\nHold down the Shift key to also delete the corresponding entries from player History."),
farmbuyer@110 1034 E("Insert new loot entry", 'df_INSERT', 'loot', "Inserts new loot above this one, prompting you for information."),
farmbuyer@110 1035 E("Insert new boss kill event", 'df_INSERT', 'boss', "Inserts new event above this one, prompting you for information."),
farmbuyer@110 1036 E("--"),
farmbuyer@110 1037 E(CLOSE),
farmbuyer@110 1038 }
farmbuyer@110 1039 end
farmbuyer@110 1040
farmbuyer@1 1041
farmbuyer@84 1042 --[[ quoted verbatim from lib-st docs (table->stable for obvious reasons):
farmbuyer@1 1043 rowFrame This is the UI Frame table for the row.
farmbuyer@1 1044 cellFrame This is the UI Frame table for the cell in the row.
farmbuyer@1 1045 data This is the data table supplied to the scrolling table (in case you lost it :) )
farmbuyer@1 1046 cols This is the cols table supplied to the scrolling table (again, in case you lost it :) )
farmbuyer@1 1047 row This is the number of the UI row that the event was triggered for.<br/> ex. If your scrolling table only shows ten rows, this number will be a number between 1 and 10.
farmbuyer@1 1048 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 1049 column This is the index of which column the event was triggered in.
farmbuyer@84 1050 stable This is a reference to the scrollingtable table.
farmbuyer@1 1051 ... Any arguments generated by the '''NORMAL''' Blizzard event triggered by the frame are passed as is.
farmbuyer@1 1052 ]]
farmbuyer@84 1053 local function eoi_st_OnEnter (rowFrame, cellFrame, data, cols, row, realrow, column, stable, motion)
farmbuyer@1 1054 if (row == nil) or (realrow == nil) then return end -- mouseover column header
farmbuyer@1 1055 local e = data[realrow]
farmbuyer@103 1056 if e == nil then return end -- something horrible has happened
farmbuyer@1 1057 local kind = e.kind
farmbuyer@72 1058 local tt = GameTooltip -- can this be hoisted? does GT ever get securely replaced?
farmbuyer@1 1059
farmbuyer@96 1060 if gui._do_debugging_tooltip and column == 1 and kind ~= 'hist' then
farmbuyer@72 1061 _build_debugging_tooltip (cellFrame, realrow)
farmbuyer@72 1062 end
farmbuyer@84 1063 if (kind == 'loot' and column == 1) or (kind == 'hist' and column == 2) then
farmbuyer@72 1064 tt:SetOwner (cellFrame, "ANCHOR_RIGHT", -20, 0)
farmbuyer@19 1065 if e.cache_miss then
farmbuyer@72 1066 tt:ClearLines()
farmbuyer@72 1067 tt:AddLine("Missing Cache Data")
farmbuyer@72 1068 tt:AddLine([[Wait a few seconds, then type]], 0.8, 0.8, 0.8, 1)
farmbuyer@81 1069 tt:AddLine([[/ouroloot fix cache]], 0, 1, 64/255, nil)
farmbuyer@72 1070 tt:AddLine([[and redisplay this window.]], 0.8, 0.8, 0.8, 1)
farmbuyer@72 1071 tt:Show()
farmbuyer@19 1072 elseif e.itemlink then
farmbuyer@72 1073 tt:SetHyperlink (e.itemlink)
farmbuyer@16 1074 end
farmbuyer@1 1075
farmbuyer@1 1076 elseif kind == 'loot' and column == 2 then
farmbuyer@72 1077 tt:SetOwner (cellFrame, "ANCHOR_BOTTOMRIGHT", -50, 5)
farmbuyer@72 1078 tt:ClearLines()
farmbuyer@72 1079 tt:AddLine(e.person.." Loot:")
farmbuyer@1 1080 local counter = 0
farmbuyer@1 1081 for i,e2 in ipairs(data) do
farmbuyer@1 1082 if e2.person == e.person then -- would be awesome to test for alts
farmbuyer@1 1083 if counter > 10 then
farmbuyer@72 1084 tt:AddLine("...")
farmbuyer@1 1085 break
farmbuyer@1 1086 else
farmbuyer@1 1087 -- textures screw up too badly, strip them
farmbuyer@1 1088 local textured = e2.cols[1].value
farmbuyer@1 1089 local space = textured:find(" ")
farmbuyer@72 1090 tt:AddLine(textured:sub(space+1))
farmbuyer@1 1091 counter = counter + 1
farmbuyer@1 1092 end
farmbuyer@1 1093 end
farmbuyer@1 1094 end
farmbuyer@72 1095 tt:Show()
farmbuyer@1 1096
farmbuyer@1 1097 elseif kind == 'loot' and column == 3 then
farmbuyer@1 1098 setstatus(e.cols[column].value)
farmbuyer@1 1099
farmbuyer@1 1100 end
farmbuyer@1 1101
farmbuyer@1 1102 return false -- continue with default highlighting behavior
farmbuyer@1 1103 end
farmbuyer@84 1104 local function eoi_st_OnLeave (rowFrame, cellFrame, data, cols, row, realrow, column, stable, motion)
farmbuyer@1 1105 GameTooltip:Hide()
farmbuyer@72 1106 _hide_debugging_tooltip()
farmbuyer@103 1107 if (row == nil) or (realrow == nil) then return false end
farmbuyer@103 1108
farmbuyer@103 1109 if stable:GetSelection() ~= realrow then
farmbuyer@103 1110 if data[realrow].kind ~= 'loot' then
farmbuyer@103 1111 stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[data[realrow].reason or data[realrow].kind])
farmbuyer@103 1112 return true -- do not do anything further
farmbuyer@103 1113 else
farmbuyer@103 1114 return false -- continue with default un-highlighting behavior
farmbuyer@103 1115 end
farmbuyer@103 1116 else
farmbuyer@1 1117 return true -- do not do anything further
farmbuyer@1 1118 end
farmbuyer@1 1119 end
farmbuyer@1 1120
farmbuyer@84 1121 local function eoi_st_OnClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, down)
farmbuyer@1 1122 if (row == nil) or (realrow == nil) then return true end -- click column header, suppress reordering
farmbuyer@1 1123 local e = data[realrow]
farmbuyer@1 1124 local kind = e.kind
farmbuyer@1 1125
farmbuyer@1 1126 -- Check for shift-clicking a loot line
farmbuyer@84 1127 if IsModifiedClick("CHATLINK") and kind == 'loot' and column == 1
farmbuyer@16 1128 then
farmbuyer@1 1129 ChatEdit_InsertLink (e.itemlink)
farmbuyer@1 1130 return true -- do not do anything further
farmbuyer@1 1131 end
farmbuyer@1 1132
farmbuyer@103 1133 -- Zap any jump-to-line highlighting
farmbuyer@103 1134 stable:ClearSelection()
farmbuyer@103 1135
farmbuyer@1 1136 -- Remaining actions are all right-click
farmbuyer@1 1137 if button ~= "RightButton" then return true end
farmbuyer@84 1138 _d:SetUserData("DD index", realrow)
farmbuyer@1 1139
farmbuyer@1 1140 if kind == 'loot' and (column == 1 or column == 3) then
farmbuyer@84 1141 _d:SetUserData("DD cell", cellFrame)
farmbuyer@110 1142 gui.dropdown.eoi_loot[1].text = e.itemlink
farmbuyer@110 1143 EasyMenu (gui.dropdown.eoi_loot, dropdownmenuframe, cellFrame, 0, 0, "MENU")
farmbuyer@1 1144
farmbuyer@1 1145 elseif kind == 'loot' and column == 2 then
farmbuyer@111 1146 local ddep = gui.dropdown.eoi_player
farmbuyer@111 1147 ddep[1].text = e.person
farmbuyer@1 1148 local raiders = {}
farmbuyer@1 1149 for i = 1, GetNumRaidMembers() do
farmbuyer@1 1150 tinsert (raiders, (GetRaidRosterInfo(i)))
farmbuyer@1 1151 end
farmbuyer@1 1152 table.sort(raiders)
farmbuyer@1 1153 for i = 1, #raiders do
farmbuyer@1 1154 local name = raiders[i]
farmbuyer@110 1155 raiders[i] = gen_dd_entry (name, eoi_dropdownfuncs, 'df_REASSIGN', name)
farmbuyer@1 1156 end
farmbuyer@110 1157 tinsert (raiders, gen_dd_entry ("Enter name...", eoi_dropdownfuncs))
farmbuyer@110 1158 tinsert (raiders, gen_dd_entry (CLOSE, eoi_dropdownfuncs))
farmbuyer@111 1159 ddep[2].menuList = raiders
farmbuyer@109 1160
farmbuyer@109 1161 if not addon:_test_disposition (e.disposition, 'can_reassign') then
farmbuyer@111 1162 ddep[2].disabled = true
farmbuyer@111 1163 ddep[2].tooltipTitle = "Cannot Reassign"
farmbuyer@111 1164 ddep[2].tooltipText = "You must first mark this item as 'normal' or 'offspec' before reassignment."
farmbuyer@25 1165 else
farmbuyer@111 1166 ddep[2].disabled = nil
farmbuyer@111 1167 ddep[2].tooltipTitle = nil
farmbuyer@111 1168 ddep[2].tooltipText = nil
farmbuyer@25 1169 end
farmbuyer@111 1170 EasyMenu (ddep, dropdownmenuframe, cellFrame, 0, 0, "MENU")
farmbuyer@1 1171
farmbuyer@1 1172 elseif kind == 'boss' then
farmbuyer@110 1173 gui.dropdown.eoi_boss[1].text = e.bossname
farmbuyer@110 1174 -- KILLWIPE: update '2' if this is not the 2nd entry in gui.dropdown.eoi_boss
farmbuyer@110 1175 gui.dropdown.eoi_boss[2].tooltipWhileDisabled = nil
farmbuyer@110 1176 gui.dropdown.eoi_boss[2].disabled = e.reason ~= 'wipe' and true or nil
farmbuyer@110 1177 EasyMenu (gui.dropdown.eoi_boss, dropdownmenuframe, cellFrame, 0, 0, "MENU")
farmbuyer@1 1178
farmbuyer@1 1179 elseif kind == 'time' then
farmbuyer@110 1180 gui.dropdown.eoi_time[1].text = e.startday.text
farmbuyer@110 1181 EasyMenu (gui.dropdown.eoi_time, dropdownmenuframe, cellFrame, 0, 0, "MENU")
farmbuyer@1 1182
farmbuyer@1 1183 end
farmbuyer@1 1184
farmbuyer@1 1185 return true -- do not do anything further
farmbuyer@1 1186 end
farmbuyer@1 1187
farmbuyer@1 1188 function eoi_editcell (row_index, cell_frame)
farmbuyer@1 1189 local e = g_loot[row_index]
farmbuyer@1 1190 if not e then return end -- how the hell could we get this far?
farmbuyer@1 1191 local celldata = e.cols[3]
farmbuyer@95 1192 local box = AceGUI:Create("EditBox")
farmbuyer@1 1193 box:SetText(celldata.value)
farmbuyer@1 1194 box:SetUserData("old show", box.editbox:GetScript("OnShow"))
farmbuyer@1 1195 box:SetUserData("old escape", box.editbox:GetScript("OnEscapePressed"))
farmbuyer@1 1196 box.editbox:SetScript("OnShow", box.editbox.SetFocus)
farmbuyer@1 1197 box.editbox:SetScript("OnEscapePressed", function(_be)
farmbuyer@1 1198 _be:ClearFocus()
farmbuyer@1 1199 _be.obj:Release()
farmbuyer@1 1200 end)
farmbuyer@1 1201 box:SetCallback("OnEnterPressed", function(_b,event,value)
farmbuyer@1 1202 e.extratext = value
farmbuyer@1 1203 celldata.value = value
farmbuyer@1 1204 e.bcast_from = nil -- things get screwy if this field is still present. sigh.
farmbuyer@1 1205 e.extratext_byhand = true
farmbuyer@1 1206 value = value and value:match("^(x%d+)")
farmbuyer@1 1207 if value then e.count = value end
farmbuyer@1 1208 _b:Release()
farmbuyer@95 1209 return gui.eoiST:OuroLoot_Refresh(row_index)
farmbuyer@1 1210 end)
farmbuyer@1 1211 box:SetCallback("OnRelease", function(_b)
farmbuyer@1 1212 _b.editbox:ClearFocus()
farmbuyer@1 1213 _b.editbox:SetScript("OnShow", _b:GetUserData("old show"))
farmbuyer@1 1214 _b.editbox:SetScript("OnEscapePressed", _b:GetUserData("old escape"))
farmbuyer@1 1215 setstatus("")
farmbuyer@1 1216 end)
farmbuyer@1 1217 box.frame:SetAllPoints(cell_frame)
farmbuyer@1 1218 box.frame:SetParent(cell_frame)
farmbuyer@1 1219 box.frame:SetFrameLevel(cell_frame:GetFrameLevel()+1)
farmbuyer@1 1220 box.frame:Show()
farmbuyer@1 1221 setstatus("Press Enter or click Okay to accept changes, or press Escape to cancel them.")
farmbuyer@1 1222 end
farmbuyer@1 1223
farmbuyer@84 1224 local function eoi_st_OnDoubleClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button)
farmbuyer@1 1225 if (row == nil) or (realrow == nil) then return true end -- they clicked on column header, suppress reordering
farmbuyer@1 1226 local e = data[realrow]
farmbuyer@1 1227 local kind = e.kind
farmbuyer@1 1228
farmbuyer@84 1229 --_d:SetUserData("DD index", realrow)
farmbuyer@1 1230 if kind == 'loot' and column == 3 and button == "LeftButton" then
farmbuyer@1 1231 eoi_editcell (realrow, cellFrame)
farmbuyer@1 1232 end
farmbuyer@1 1233
farmbuyer@1 1234 return true -- do not do anything further
farmbuyer@1 1235 end
farmbuyer@1 1236
farmbuyer@103 1237 -- Used for anything not overridden elsewhere.
farmbuyer@103 1238 local function eoi_st_default_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable)
farmbuyer@103 1239 if not fShow then
farmbuyer@103 1240 cellFrame.text:SetText("")
farmbuyer@103 1241 if cellFrame.icontexture then
farmbuyer@103 1242 cellFrame.icontexture:Hide()
farmbuyer@103 1243 end
farmbuyer@103 1244 return
farmbuyer@103 1245 end
farmbuyer@103 1246
farmbuyer@103 1247 local e = data[realrow]
farmbuyer@103 1248 local cell = e.cols[column]
farmbuyer@103 1249
farmbuyer@103 1250 cellFrame.text:SetText(cell.value)
farmbuyer@103 1251 -- subset of what the default ST's docellupdate looks for
farmbuyer@103 1252 local color = cols[column].color and cols[column].color(data,cols,realrow,column,stable)
farmbuyer@103 1253 if color then
farmbuyer@103 1254 cellFrame.text:SetTextColor(color.r,color.g,color.b,color.a)
farmbuyer@103 1255 else
farmbuyer@103 1256 cellFrame.text:SetTextColor(1,1,1,1)
farmbuyer@103 1257 end
farmbuyer@103 1258
farmbuyer@103 1259 if stable:GetSelection() ~= realrow then
farmbuyer@103 1260 stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[e.reason or e.kind or ""])
farmbuyer@103 1261 else
farmbuyer@103 1262 stable:SetHighLightColor (rowFrame, stable:GetDefaultHighlight())
farmbuyer@103 1263 end
farmbuyer@103 1264 end
farmbuyer@103 1265
farmbuyer@1 1266 -- Used for EOI column 2 and Hist column 1. Both are player name columns.
farmbuyer@84 1267 local function eoi_st_col2_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable)
farmbuyer@1 1268 if not fShow then
farmbuyer@1 1269 cellFrame.text:SetText("")
farmbuyer@1 1270 if cellFrame.icontexture then
farmbuyer@1 1271 cellFrame.icontexture:Hide()
farmbuyer@1 1272 end
farmbuyer@1 1273 return
farmbuyer@1 1274 end
farmbuyer@1 1275
farmbuyer@1 1276 local e = data[realrow]
farmbuyer@1 1277 local cell = e.cols[column]
farmbuyer@1 1278
farmbuyer@1 1279 cellFrame.text:SetText(cell.value)
farmbuyer@1 1280
farmbuyer@1 1281 if e.person_class then
farmbuyer@1 1282 local icon
farmbuyer@1 1283 if cellFrame.icontexture then
farmbuyer@1 1284 icon = cellFrame.icontexture
farmbuyer@1 1285 else
farmbuyer@1 1286 icon = cellFrame:CreateTexture(nil,"BACKGROUND")
farmbuyer@1 1287 icon:SetPoint("LEFT", cellFrame, "LEFT")
farmbuyer@1 1288 icon:SetHeight(eoi_st_rowheight-4)
farmbuyer@1 1289 icon:SetWidth(eoi_st_rowheight-4)
farmbuyer@1 1290 icon:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes")
farmbuyer@1 1291 cellFrame.icontexture = icon
farmbuyer@1 1292 end
farmbuyer@1 1293 icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[e.person_class]))
farmbuyer@1 1294 icon:Show()
farmbuyer@1 1295 cellFrame.text:SetPoint("LEFT", icon, "RIGHT", 1, 0)
farmbuyer@86 1296 local color = addon.class_colors[e.person_class]
farmbuyer@92 1297 cellFrame.text:SetTextColor(color.r,color.g,color.b,color.a)
farmbuyer@1 1298 else
farmbuyer@1 1299 if cellFrame.icontexture then
farmbuyer@1 1300 cellFrame.icontexture:Hide()
farmbuyer@1 1301 cellFrame.text:SetPoint("LEFT", cellFrame, "LEFT")
farmbuyer@1 1302 end
farmbuyer@73 1303 cellFrame.text:SetTextColor(1,1,1,1)
farmbuyer@1 1304 end
farmbuyer@1 1305
farmbuyer@103 1306 if stable:GetSelection() ~= realrow then
farmbuyer@1 1307 stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[e.reason or e.kind or ""])
farmbuyer@103 1308 else
farmbuyer@103 1309 stable:SetHighLightColor (rowFrame, stable:GetDefaultHighlight())
farmbuyer@103 1310 end
farmbuyer@1 1311 end
farmbuyer@1 1312
farmbuyer@1 1313 local eoi_st_cols = {
farmbuyer@1 1314 { -- col 1
farmbuyer@1 1315 name = "Item",
farmbuyer@1 1316 width = 250,
farmbuyer@1 1317 },
farmbuyer@1 1318 { -- col 2
farmbuyer@1 1319 name = "Player",
farmbuyer@1 1320 width = 130,
farmbuyer@1 1321 DoCellUpdate = eoi_st_col2_DoCellUpdate,
farmbuyer@1 1322 },
farmbuyer@1 1323 { -- col 3
farmbuyer@1 1324 name = "Notes",
farmbuyer@3 1325 width = 250,
farmbuyer@73 1326 color = eoi_st_lootrow_col3_colortable_func,
farmbuyer@1 1327 },
farmbuyer@1 1328 }
farmbuyer@1 1329
farmbuyer@6 1330 local player_filter_all
farmbuyer@6 1331 local player_filter_by_name = function (st, e)
farmbuyer@1 1332 if e.kind ~= 'loot' then return true end
farmbuyer@1 1333 return e.person == _d:GetUserData("player filter name")
farmbuyer@1 1334 end
farmbuyer@1 1335
farmbuyer@1 1336 -- Tab 1: Events Of Interest (implementation)
farmbuyer@1 1337 tabs_OnGroupSelected["eoi"] = function(ocontainer,specials)
farmbuyer@1 1338 if (not addon.rebroadcast) and (not addon.enabled) and (#g_loot < 1) then
farmbuyer@40 1339 addon.dprint('flow', "Nothing to show in first tab, skipping creation")
farmbuyer@40 1340 return
farmbuyer@1 1341 end
farmbuyer@1 1342
farmbuyer@1 1343 -- The first time this function is called, we set up a persistent ST
farmbuyer@1 1344 -- object and store it. Any other delayed setup work is done, and then
farmbuyer@1 1345 -- this function replaces itself with a smaller, sleeker, sexier one.
farmbuyer@1 1346 -- This function will later be garbage collected.
farmbuyer@1 1347 local ST = LibStub("ScrollingTable"):CreateST(eoi_st_cols,eoi_st_displayed_rows,eoi_st_rowheight)
farmbuyer@95 1348 gui.eoiST = assert(ST)
farmbuyer@1 1349 if addon.author_debug then
farmbuyer@1 1350 _G.OLST = ST
farmbuyer@1 1351 end
farmbuyer@1 1352
farmbuyer@103 1353 ST.DoCellUpdate = eoi_st_default_DoCellUpdate
farmbuyer@1 1354 if not eoi_st_otherrow_bgcolortable_default then
farmbuyer@1 1355 eoi_st_otherrow_bgcolortable_default = ST:GetDefaultHighlightBlank()
farmbuyer@1 1356 setmetatable(eoi_st_otherrow_bgcolortable, {__index = function (bg, key)
farmbuyer@1 1357 return eoi_st_otherrow_bgcolortable_default
farmbuyer@1 1358 end})
farmbuyer@1 1359 end
farmbuyer@1 1360
farmbuyer@1 1361 -- Calling SetData breaks (trying to call Refresh) if g_loot hasn't gone
farmbuyer@1 1362 -- through this loop.
farmbuyer@1 1363 addon:_fill_out_eoi_data(1)
farmbuyer@1 1364 -- safety check begin
farmbuyer@1 1365 for i,e in ipairs(g_loot) do
farmbuyer@1 1366 if type(e.cols) ~= 'table' then
farmbuyer@1 1367 addon:Print("ARGH, index",i,"bad in eoi_OGS, type",type(e.cols),
farmbuyer@55 1368 "entry kind", e.kind, "data", e.itemname or e.bossname or e.startday.text,
farmbuyer@55 1369 "-- please take a screenshot and send to Farmbuyer@US-Kilrogg.")
farmbuyer@1 1370 tabledump(e)
farmbuyer@1 1371 end
farmbuyer@1 1372 end
farmbuyer@1 1373 -- safety check end
farmbuyer@1 1374 ST:SetData(g_loot)
farmbuyer@103 1375 ST:EnableSelection(true)
farmbuyer@1 1376 ST:RegisterEvents{
farmbuyer@1 1377 OnEnter = eoi_st_OnEnter,
farmbuyer@1 1378 OnLeave = eoi_st_OnLeave,
farmbuyer@1 1379 OnClick = eoi_st_OnClick,
farmbuyer@1 1380 OnDoubleClick = eoi_st_OnDoubleClick,
farmbuyer@1 1381 }
farmbuyer@1 1382
farmbuyer@1 1383 -- We want a single "update and redraw" function for the ST. Also, the
farmbuyer@1 1384 -- given refresh function is badly named and does nothing; the actual
farmbuyer@1 1385 -- function is SortData (also badly named when no sorting is being done),
farmbuyer@1 1386 -- which unconditionally calls the *hooked* Refresh.
farmbuyer@1 1387 local oldrefresh = ST.Refresh
farmbuyer@1 1388 ST.Refresh = function (self, opt_index)
farmbuyer@1 1389 addon:_fill_out_eoi_data(opt_index)
farmbuyer@1 1390 return oldrefresh(self)
farmbuyer@1 1391 end
farmbuyer@1 1392 ST.OuroLoot_Refresh = function (self, opt_index)
farmbuyer@1 1393 addon:_fill_out_eoi_data(opt_index)
farmbuyer@1 1394 -- safety check begin
farmbuyer@1 1395 for i,e in ipairs(g_loot) do
farmbuyer@1 1396 if type(e.cols) ~= 'table' then
farmbuyer@4 1397 addon:Print("ARGH, index",i,"bad in eoi refresh, refreshed at", opt_index, "type",type(e.cols),
farmbuyer@55 1398 "entry kind", e.kind, "data", e.itemname or e.bossname or e.startday.text,
farmbuyer@55 1399 "-- please take a screenshot and send to Farmbuyer@US-Kilrogg.")
farmbuyer@1 1400 tabledump(e)
farmbuyer@1 1401 end
farmbuyer@1 1402 end
farmbuyer@1 1403 -- safety check end
farmbuyer@1 1404 self:SortData() -- calls hooked refresh
farmbuyer@1 1405 end
farmbuyer@1 1406
farmbuyer@1 1407 -- No need to keep creating function closures that all just "return true",
farmbuyer@1 1408 -- instead we grab the one made inside lib-st. There's no "get filter" API
farmbuyer@1 1409 -- so we just reach inside.
farmbuyer@6 1410 player_filter_all = ST.Filter
farmbuyer@1 1411
farmbuyer@1 1412 -- Now set up the future drawing function...
farmbuyer@1 1413 tabs_OnGroupSelected["eoi"] = function(container,specials)
farmbuyer@95 1414 local st_widget = AceGUI:Create("lib-st")
farmbuyer@95 1415 local st = assert(gui.eoiST)
farmbuyer@1 1416
farmbuyer@95 1417 gui.which_ST = st
farmbuyer@84 1418
farmbuyer@1 1419 -- This is actually required each time
farmbuyer@6 1420 _d:SetUserData ("player filter clear", player_filter_all)
farmbuyer@6 1421 _d:SetUserData ("player filter by name", player_filter_by_name)
farmbuyer@1 1422
farmbuyer@1 1423 st:OuroLoot_Refresh()
farmbuyer@1 1424 st_widget:WrapST(st)
farmbuyer@3 1425 st_widget.head_offset = 15
farmbuyer@3 1426 st_widget.tail_offset = 0
farmbuyer@1 1427
farmbuyer@97 1428 if gui.opts.scroll_to_bottom then
farmbuyer@1 1429 local scrollbar = _G[st.scrollframe:GetName().."ScrollBar"]
farmbuyer@1 1430 if scrollbar then
farmbuyer@1 1431 local _,max = scrollbar:GetMinMaxValues()
farmbuyer@1 1432 scrollbar:SetValue(max) -- also calls hooked Refresh
farmbuyer@1 1433 end
farmbuyer@1 1434 end
farmbuyer@1 1435
farmbuyer@1 1436 container:SetLayout("Fill")
farmbuyer@1 1437 container:AddChild(st_widget)
farmbuyer@1 1438
farmbuyer@42 1439 local b
farmbuyer@42 1440 --[===[ b = mkbutton("Generate Header",
farmbuyer@42 1441 [[]])
farmbuyer@42 1442 b:SetFullWidth(true)
farmbuyer@42 1443 b:SetCallback("OnClick", function (_b)
farmbuyer@42 1444 end)
farmbuyer@42 1445 specials:AddChild(b) ]===]
farmbuyer@42 1446
farmbuyer@42 1447 b = mkbutton('eoi_filter_reset', "Reset Player Filter",
farmbuyer@1 1448 [[Return to showing complete loot information.]])
farmbuyer@1 1449 b:SetFullWidth(true)
farmbuyer@1 1450 b:SetCallback("OnClick", function (_b)
farmbuyer@95 1451 gui.eoiST:SetFilter(player_filter_all)
farmbuyer@1 1452 _b:SetDisabled(true)
farmbuyer@1 1453 end)
farmbuyer@6 1454 b:SetDisabled(st.Filter == player_filter_all)
farmbuyer@1 1455 specials:AddChild(b)
farmbuyer@1 1456
farmbuyer@95 1457 -- FIXME iterate over the new raiders table instead
farmbuyer@1 1458 local people = { "<nobody>" }
farmbuyer@93 1459 for i = 1, GetNumRaidMembers() do
farmbuyer@1 1460 tinsert(people,(GetRaidRosterInfo(i)))
farmbuyer@1 1461 end
farmbuyer@1 1462 table.sort(people)
farmbuyer@1 1463 local initial
farmbuyer@1 1464 for i,n in ipairs(people) do
farmbuyer@1 1465 if n == addon.sharder then initial = i end
farmbuyer@1 1466 end
farmbuyer@1 1467 b = mkbutton("Dropdown", nil, "",
farmbuyer@1 1468 [[If set, items received by this person will be automatically marked as disenchanted.]])
farmbuyer@1 1469 b:SetFullWidth(true)
farmbuyer@1 1470 b:SetLabel("Auto-mark as shard:")
farmbuyer@1 1471 b:SetList(people)
farmbuyer@1 1472 b:SetValue(initial or 1)
farmbuyer@1 1473 b:SetCallback("OnValueChanged", function(_dd,event,choice)
farmbuyer@1 1474 addon.sharder = (choice ~= 1) and people[choice] or nil
farmbuyer@1 1475 end)
farmbuyer@1 1476 specials:AddChild(b)
farmbuyer@1 1477
farmbuyer@42 1478 b = mkbutton('eoi_bcast_req', "Request B'casters",
farmbuyer@1 1479 [[Sends out a request for others to enable loot rebroadcasting if they have not already done so.]])
farmbuyer@1 1480 b:SetFullWidth(true)
farmbuyer@1 1481 b:SetCallback("OnClick", function ()
farmbuyer@1 1482 addon:Print("Sending request!")
farmbuyer@1 1483 addon.requesting = true
farmbuyer@1 1484 addon:broadcast('bcast_req')
farmbuyer@1 1485 end)
farmbuyer@1 1486 b:SetDisabled(not addon.enabled)
farmbuyer@1 1487 specials:AddChild(b)
farmbuyer@1 1488 end
farmbuyer@1 1489 -- ...and call it.
farmbuyer@1 1490 return tabs_OnGroupSelected["eoi"](ocontainer,specials)
farmbuyer@1 1491 end
farmbuyer@83 1492 noob_tips["eoi"] = _markup[[
farmbuyer@83 1493 <Shift-Left> while over an item link to paste it into chat.
farmbuyer@83 1494
farmbuyer@83 1495 <Right>-click any row to display a dropdown menu. The menu is different for
farmbuyer@83 1496 the Player column than it is for the Item/Notes columns, and different for
farmbuyer@103 1497 loot entries than it is for other rows.
farmbuyer@103 1498
farmbuyer@103 1499 A normal click on a line will remove any highlighting from opening the
farmbuyer@103 1500 display from a chat link.]]
farmbuyer@103 1501 tabs_CLI_special["eoi"] = function (name_or_lineno)
farmbuyer@103 1502 if type(name_or_lineno) == 'string' then
farmbuyer@103 1503 -- uh
farmbuyer@103 1504 elseif type(name_or_lineno) == 'number' then
farmbuyer@103 1505 if name_or_lineno < 1 or name_or_lineno > #g_loot then
farmbuyer@103 1506 return
farmbuyer@103 1507 end
farmbuyer@103 1508 local scrollhere = -9
farmbuyer@103 1509 repeat
farmbuyer@103 1510 scrollhere = scrollhere + 10
farmbuyer@103 1511 gui.eoiST.offset = scrollhere
farmbuyer@103 1512 until gui.eoiST:RowIsVisible(name_or_lineno)
farmbuyer@103 1513 -- Value must be in pixels, not "how many rows"
farmbuyer@103 1514 scrollhere = scrollhere * eoi_st_rowheight
farmbuyer@103 1515 -- But not past the bottom, it looks ugly
farmbuyer@103 1516 scrollhere = math.min (scrollhere,
farmbuyer@103 1517 (#gui.eoiST.filtered - eoi_st_displayed_rows) * eoi_st_rowheight)
farmbuyer@103 1518 gui.eoiST:SetSelection(name_or_lineno)
farmbuyer@110 1519 if name_or_lineno > eoi_st_displayed_rows then
farmbuyer@110 1520 -- don't try to scroll if there's not enough lines
farmbuyer@110 1521 local sf = gui.eoiST.scrollframe
farmbuyer@110 1522 sf:GetScript("OnVerticalScroll")(sf,scrollhere)
farmbuyer@110 1523 end
farmbuyer@103 1524 end
farmbuyer@103 1525 end
farmbuyer@1 1526
farmbuyer@37 1527
farmbuyer@1 1528 -- Tab 2/3 (generated text)
farmbuyer@1 1529 function tabs_generated_text_OGS (container, specials, text_kind)
farmbuyer@1 1530 container:SetLayout("Fill")
farmbuyer@95 1531 local box = AceGUI:Create("MultiLineEditBox")
farmbuyer@1 1532 box:SetFullWidth(true)
farmbuyer@1 1533 box:SetFullHeight(true)
farmbuyer@1 1534 box:SetLabel("Pressing the Escape key while typing will return keystroke control to the usual chat window.")
farmbuyer@1 1535 box:DisableButton(true)
farmbuyer@1 1536 addon:_fill_out_eoi_data(1)
farmbuyer@1 1537
farmbuyer@1 1538 -- Update the savedvar copy of the text before presenting it for editing,
farmbuyer@1 1539 -- then save it again when editing finishes. This way if the user goes
farmbuyer@1 1540 -- offline while editing, at least the unedited version is saved instead
farmbuyer@1 1541 -- of all the new text being lost entirely. (Yes, it's happened.)
farmbuyer@1 1542 --
farmbuyer@1 1543 -- No good local-ish place to store the cursor position that will also
farmbuyer@1 1544 -- survive the entire display being released. Abuse the generated text
farmbuyer@1 1545 -- cache for this purpose.
farmbuyer@1 1546 local pos = text_kind.."_pos"
farmbuyer@1 1547 if _generate_text(text_kind) then
farmbuyer@1 1548 g_loot[text_kind] = g_loot[text_kind] .. g_generated[text_kind]
farmbuyer@1 1549 g_generated[text_kind] = nil
farmbuyer@1 1550 end
farmbuyer@1 1551 box:SetText(g_loot[text_kind])
farmbuyer@1 1552 box.editBox:SetCursorPosition(g_generated[pos] or 0)
farmbuyer@1 1553 box.editBox:SetScript("OnShow", box.editBox.SetFocus)
farmbuyer@1 1554 box:SetCallback("OnRelease", function(_box)
farmbuyer@1 1555 box.editBox:ClearFocus()
farmbuyer@1 1556 g_loot[text_kind] = _box:GetText()
farmbuyer@1 1557 g_generated[pos] = _box.editBox:GetCursorPosition()
farmbuyer@1 1558 end)
farmbuyer@1 1559 container:AddChild(box)
farmbuyer@1 1560
farmbuyer@1 1561 local w = mkbutton("Regenerate",
farmbuyer@1 1562 [[+DISCARD> all text in this tab, and regenerate it from the current loot information.]])
farmbuyer@1 1563 w:SetFullWidth(true)
farmbuyer@1 1564 w:SetDisabled ((#g_loot == 0) and (box:GetText() == ""))
farmbuyer@1 1565 w:SetCallback("OnClick", function(_w)
farmbuyer@1 1566 box:SetText("")
farmbuyer@1 1567 g_loot[text_kind] = ""
farmbuyer@1 1568 g_loot.printed[text_kind] = 0
farmbuyer@1 1569 g_generated.last_instance = nil
farmbuyer@1 1570 g_generated[pos] = nil
farmbuyer@95 1571 addon:Print("'%s' has been regenerated.", gui.tabtexts[text_kind].title)
farmbuyer@1 1572 return addon:redisplay()
farmbuyer@1 1573 end)
farmbuyer@1 1574 specials:AddChild(w)
farmbuyer@1 1575 _populate_text_specials (box, specials, mkbutton, text_kind)
farmbuyer@1 1576 end
farmbuyer@1 1577
farmbuyer@37 1578
farmbuyer@1 1579 -- Tab 4: History
farmbuyer@1 1580 -- Much of the implementation here follows a similar desgin for the first
farmbuyer@4 1581 -- tab's handling of ST objects. We will even reuse its controlling tables
farmbuyer@4 1582 -- when feasible.
farmbuyer@37 1583 local histST, hist_dropdownfuncs
farmbuyer@84 1584 local hist_normal_status =
farmbuyer@84 1585 [[Click on a row to view all history for that player only. (Click column headers to re-sort.)]]
farmbuyer@84 1586 local hist_name_status =
farmbuyer@84 1587 [[Right-click on any row to return to normal history display.]]
farmbuyer@84 1588
farmbuyer@84 1589 local history_filter_by_recent = function (st, e)
farmbuyer@84 1590 if e.kind ~= 'hist' then return true end
farmbuyer@84 1591 return e.cols[2].OLi == 1
farmbuyer@84 1592 end
farmbuyer@84 1593
farmbuyer@84 1594 local history_filter_who
farmbuyer@84 1595 local history_filter_by_name = function (st, e)
farmbuyer@84 1596 if e.kind ~= 'hist' then return true end
farmbuyer@84 1597 return e.OLwho == history_filter_who
farmbuyer@84 1598 end
farmbuyer@1 1599
farmbuyer@37 1600 hist_dropdownfuncs = dropdownfuncs{
farmbuyer@87 1601 ["Delete this loot event from history"] = function()--rowi
farmbuyer@84 1602 local h = _d:GetUserData("DD history entry")
farmbuyer@87 1603 local numleft,err = addon:_delHistoryEntry (h.cols[2].OLu, h.itemlink)
farmbuyer@87 1604 if numleft then
farmbuyer@86 1605 addon:Print("Removed history entry %s from %s.",
farmbuyer@86 1606 h.itemlink, addon:colorize(h.OLwho,h.OLclass))
farmbuyer@87 1607 if numleft < 1 then
farmbuyer@87 1608 history_filter_who = nil
farmbuyer@92 1609 histST:SetFilter(history_filter_by_recent)
farmbuyer@87 1610 setstatus(hist_normal_status)
farmbuyer@87 1611 end
farmbuyer@84 1612 else
farmbuyer@84 1613 addon:Print(err)
farmbuyer@84 1614 end
farmbuyer@84 1615 end,
farmbuyer@84 1616
farmbuyer@87 1617 ["Delete this player's entire loot history"] = function()--rowi
farmbuyer@84 1618 local h = _d:GetUserData("DD history entry")
farmbuyer@84 1619 local name = h.OLwho
farmbuyer@84 1620 local player_i = addon.history.byname[name]
farmbuyer@84 1621 local gone = tremove (addon.history, player_i)
farmbuyer@84 1622 assert(gone.name == name)
farmbuyer@84 1623 addon:_build_history_names()
farmbuyer@86 1624 addon:Print("Removed player %s from history (%d total entries).",
farmbuyer@86 1625 addon:colorize(name,gone.person_class), #gone.unique)
farmbuyer@37 1626 end,
farmbuyer@37 1627 }
farmbuyer@110 1628
farmbuyer@110 1629 do
farmbuyer@110 1630 local function E (name, funci, arg, ttt)
farmbuyer@110 1631 return gen_dd_entry (name, hist_dropdownfuncs, funci, arg, ttt)
farmbuyer@110 1632 end
farmbuyer@110 1633
farmbuyer@110 1634 gui.dropdown.hist_general = {
farmbuyer@110 1635 {
farmbuyer@110 1636 -- this is the dropdown title, text filled in on the fly
farmbuyer@110 1637 isTitle = true,
farmbuyer@110 1638 notClickable = true,
farmbuyer@110 1639 notCheckable = true,
farmbuyer@110 1640 },
farmbuyer@110 1641 E("Delete this player's entire loot history", nil, nil, "Permanent, no going back!"),
farmbuyer@110 1642 E("--"),
farmbuyer@110 1643 E(CLOSE),
farmbuyer@110 1644 }
farmbuyer@110 1645 gui.dropdown.hist_specific = {
farmbuyer@110 1646 {
farmbuyer@110 1647 -- this is the dropdown title, text filled in on the fly
farmbuyer@110 1648 notClickable = true,
farmbuyer@110 1649 notCheckable = true,
farmbuyer@110 1650 },
farmbuyer@110 1651 E("Delete this loot event from history", nil, nil, "Permanent, no going back!"),
farmbuyer@110 1652 E("--"),
farmbuyer@110 1653 E(CLOSE),
farmbuyer@110 1654 }
farmbuyer@110 1655 end
farmbuyer@6 1656
farmbuyer@84 1657 -- Loot column
farmbuyer@84 1658 --[[
farmbuyer@84 1659 local function hist_st_col2_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable)
farmbuyer@84 1660 end]]
farmbuyer@84 1661
farmbuyer@84 1662 -- Formatted timestamp column
farmbuyer@84 1663 local function hist_st_col3_DoCellUpdate (rowFrame, cellFrame, data, cols, row, realrow, column, fShow, stable)
farmbuyer@84 1664 if not fShow then
farmbuyer@84 1665 cellFrame.text:SetText("")
farmbuyer@84 1666 return
farmbuyer@84 1667 end
farmbuyer@84 1668
farmbuyer@84 1669 local h = data[realrow]
farmbuyer@84 1670 local cell = h.cols[column]
farmbuyer@84 1671
farmbuyer@84 1672 cellFrame.text:SetText(cell.value)
farmbuyer@84 1673 cellFrame.text:SetTextColor(1,1,1,1)
farmbuyer@84 1674
farmbuyer@84 1675 --stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable[h.kind])
farmbuyer@84 1676 stable:SetHighLightColor (rowFrame, eoi_st_otherrow_bgcolortable_default)
farmbuyer@84 1677 end
farmbuyer@84 1678
farmbuyer@84 1679 local function hist_st_OnClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button, down)
farmbuyer@84 1680 if (row == nil) or (realrow == nil) then return false end -- click column header, do default resorting
farmbuyer@84 1681 local h = data[realrow]
farmbuyer@84 1682 assert(h.kind=='hist')
farmbuyer@84 1683
farmbuyer@84 1684 -- Four button combinations we need to care about:
farmbuyer@84 1685
farmbuyer@84 1686 -- Shift-left pastes loot
farmbuyer@84 1687 if IsModifiedClick("CHATLINK") and column == 2 then
farmbuyer@84 1688 ChatEdit_InsertLink (h.itemlink)
farmbuyer@84 1689 return true -- do not do anything further
farmbuyer@84 1690 end
farmbuyer@84 1691
farmbuyer@84 1692 _d:SetUserData("DD index", realrow)
farmbuyer@84 1693 _d:SetUserData("DD history entry", h)
farmbuyer@84 1694
farmbuyer@84 1695 -- The rest depends on whether we're filtering (focused in on a specific
farmbuyer@84 1696 -- player) or not.
farmbuyer@84 1697 if history_filter_who then
farmbuyer@84 1698 -- Shift-right opens a menu
farmbuyer@84 1699 if IsShiftKeyDown() and button == "RightButton" then
farmbuyer@110 1700 gui.dropdown.hist_specific[1].text = h.itemlink
farmbuyer@110 1701 EasyMenu (gui.dropdown.hist_specific, dropdownmenuframe, cellFrame, 0, 0, "MENU")
farmbuyer@84 1702
farmbuyer@84 1703 -- Right goes back to normal mode
farmbuyer@84 1704 elseif button == "RightButton" then
farmbuyer@84 1705 history_filter_who = nil
farmbuyer@84 1706 stable:SetFilter(history_filter_by_recent)
farmbuyer@84 1707 setstatus(hist_normal_status)
farmbuyer@84 1708 end
farmbuyer@84 1709
farmbuyer@84 1710 else -- not focused
farmbuyer@84 1711 -- Shift-right opens a menu
farmbuyer@84 1712 if IsShiftKeyDown() and button == "RightButton" then
farmbuyer@110 1713 gui.dropdown.hist_general[1].text = h.OLwho
farmbuyer@110 1714 EasyMenu (gui.dropdown.hist_general, dropdownmenuframe, cellFrame, 0, 0, "MENU")
farmbuyer@84 1715
farmbuyer@84 1716 -- Left focuses on a specific player
farmbuyer@84 1717 elseif button == "LeftButton" then
farmbuyer@84 1718 history_filter_who = h.OLwho
farmbuyer@84 1719 stable:SetFilter(history_filter_by_name)
farmbuyer@84 1720 setstatus(hist_name_status)
farmbuyer@84 1721 end
farmbuyer@84 1722 end
farmbuyer@84 1723
farmbuyer@84 1724 return true -- do not do anything further
farmbuyer@84 1725 end
farmbuyer@84 1726
farmbuyer@84 1727 --[[
farmbuyer@84 1728 local function hist_st_OnDoubleClick (rowFrame, cellFrame, data, cols, row, realrow, column, stable, button)
farmbuyer@84 1729 if (row == nil) or (realrow == nil) then return true end -- they clicked on column header, suppress reordering
farmbuyer@84 1730 local h = data[realrow]
farmbuyer@84 1731 assert(h.kind=='hist')
farmbuyer@84 1732
farmbuyer@84 1733 return true -- do not do anything further
farmbuyer@84 1734 end]]
farmbuyer@84 1735
farmbuyer@37 1736 local hist_st_cols = {
farmbuyer@37 1737 { -- col 1
farmbuyer@37 1738 name = "Player",
farmbuyer@37 1739 width = 130,
farmbuyer@37 1740 DoCellUpdate = eoi_st_col2_DoCellUpdate,
farmbuyer@37 1741 },
farmbuyer@37 1742 { -- col 2
farmbuyer@37 1743 name = "Most Recent Loot",
farmbuyer@37 1744 width = 250,
farmbuyer@84 1745 --DoCellUpdate = hist_st_col2_DoCellUpdate,
farmbuyer@37 1746 },
farmbuyer@37 1747 { -- col 3
farmbuyer@37 1748 name = "When",
farmbuyer@37 1749 width = 250,
farmbuyer@37 1750 DoCellUpdate = hist_st_col3_DoCellUpdate,
farmbuyer@37 1751 defaultsort = "asc",
farmbuyer@37 1752 sort = "asc",
farmbuyer@37 1753 sortnext = 1,
farmbuyer@37 1754 },
farmbuyer@37 1755 }
farmbuyer@37 1756
farmbuyer@37 1757 -- Tab 4: History (implementation)
farmbuyer@37 1758 tabs_OnGroupSelected["hist"] = function(container,specials)
farmbuyer@37 1759 histST = LibStub("ScrollingTable"):CreateST(hist_st_cols,eoi_st_displayed_rows,eoi_st_rowheight)
farmbuyer@95 1760 gui.histST = histST
farmbuyer@37 1761 if addon.author_debug then
farmbuyer@37 1762 _G.OLHST = histST
farmbuyer@1 1763 end
farmbuyer@1 1764
farmbuyer@37 1765 if not eoi_st_otherrow_bgcolortable_default then
farmbuyer@37 1766 eoi_st_otherrow_bgcolortable_default = histST:GetDefaultHighlightBlank()
farmbuyer@37 1767 setmetatable(eoi_st_otherrow_bgcolortable, {__index = function (bg, key)
farmbuyer@37 1768 return eoi_st_otherrow_bgcolortable_default
farmbuyer@37 1769 end})
farmbuyer@1 1770 end
farmbuyer@1 1771
farmbuyer@37 1772 addon:_build_history_names()
farmbuyer@37 1773 addon:_fill_out_hist_data(1)
farmbuyer@37 1774 histST:SetData(addon.history.st)
farmbuyer@37 1775 histST:RegisterEvents{
farmbuyer@37 1776 OnEnter = eoi_st_OnEnter,
farmbuyer@37 1777 OnLeave = eoi_st_OnLeave,
farmbuyer@37 1778 OnClick = hist_st_OnClick,
farmbuyer@37 1779 --OnDoubleClick = hist_st_OnDoubleClick,
farmbuyer@37 1780 }
farmbuyer@37 1781 local oldrefresh = histST.Refresh
farmbuyer@37 1782 histST.Refresh = function (self, opt_index)
farmbuyer@37 1783 addon:_fill_out_hist_data(opt_index)
farmbuyer@37 1784 return oldrefresh(self)
farmbuyer@37 1785 end
farmbuyer@37 1786 histST.OuroLoot_Refresh = function (self, opt_index)
farmbuyer@37 1787 addon:_fill_out_hist_data(opt_index)
farmbuyer@37 1788 self:SortData() -- calls hooked refresh
farmbuyer@6 1789 end
farmbuyer@6 1790
farmbuyer@37 1791 histST:SetFilter(history_filter_by_recent)
farmbuyer@6 1792
farmbuyer@37 1793 -- Zaps history for the given realm, or the current (current-playing
farmbuyer@37 1794 -- realm, not currently-displayed realm) one if not specified.
farmbuyer@37 1795 local function reset_current_realm (opt_realmname)
farmbuyer@37 1796 local r = assert(opt_realmname or GetRealmName())
farmbuyer@37 1797 -- new .history table:
farmbuyer@37 1798 addon.history_all[r] = addon:_prep_new_history_category (nil, r)
farmbuyer@37 1799 addon.history = addon.history_all[r]
farmbuyer@37 1800 addon.hist_clean = nil
farmbuyer@37 1801 -- new .history.st table:
farmbuyer@37 1802 histST:OuroLoot_Refresh()
farmbuyer@37 1803 histST:SetData(addon.history.st)
farmbuyer@37 1804 end
farmbuyer@6 1805
farmbuyer@1 1806 tabs_OnGroupSelected["hist"] = function(container,specials)
farmbuyer@95 1807 local st_widget = AceGUI:Create("lib-st")
farmbuyer@95 1808 gui.which_ST = histST
farmbuyer@37 1809 histST:OuroLoot_Refresh()
farmbuyer@37 1810 st_widget:WrapST(histST)
farmbuyer@37 1811 st_widget.head_offset = 15
farmbuyer@37 1812 st_widget.tail_offset = 0
farmbuyer@37 1813 container:SetLayout("Fill")
farmbuyer@37 1814 container:AddChild(st_widget)
farmbuyer@37 1815 setstatus(hist_normal_status)
farmbuyer@1 1816
farmbuyer@37 1817 local b
farmbuyer@37 1818 do
farmbuyer@37 1819 local realms,current = {},1
farmbuyer@37 1820 for realmname,histtable in pairs(addon.history_all) do
farmbuyer@37 1821 if type(histtable) == 'table' then
farmbuyer@37 1822 tinsert(realms,realmname)
farmbuyer@37 1823 if addon.history == histtable then current = #realms end
farmbuyer@4 1824 end
farmbuyer@4 1825 end
farmbuyer@37 1826 b = mkbutton("Dropdown", nil, "", [[Which realm to display]])
farmbuyer@1 1827 b:SetFullWidth(true)
farmbuyer@37 1828 b:SetLabel() -- required even when empty, see ace3 ticket #234
farmbuyer@37 1829 b:SetList(realms)
farmbuyer@37 1830 b:SetValue(current)
farmbuyer@37 1831 b:SetCallback("OnValueChanged", function(_dd,event,choice)
farmbuyer@37 1832 local r = realms[choice]
farmbuyer@37 1833 addon.history = addon:_prep_new_history_category (addon.history_all[r], r)
farmbuyer@37 1834 addon.hist_clean = nil
farmbuyer@6 1835 histST:OuroLoot_Refresh()
farmbuyer@6 1836 histST:SetData(addon.history.st)
farmbuyer@37 1837 -- Reset filters to normal
farmbuyer@37 1838 history_filter_who = nil
farmbuyer@37 1839 histST:SetFilter(history_filter_by_recent)
farmbuyer@37 1840 setstatus(hist_normal_status)
farmbuyer@1 1841 return addon:redisplay()
farmbuyer@1 1842 end)
farmbuyer@1 1843 specials:AddChild(b)
farmbuyer@37 1844 end
farmbuyer@1 1845
farmbuyer@95 1846 --[[ b = AceGUI:Create("Spacer") b:SetFullWidth(true) b:SetHeight(10) specials:AddChild(b) ]]
farmbuyer@4 1847
farmbuyer@37 1848 b = mkbutton("Regenerate",
farmbuyer@37 1849 [[Erases all history entries from the displayed realm, and regenerates it from current loot information.]])
farmbuyer@37 1850 b:SetFullWidth(true)
farmbuyer@37 1851 b:SetDisabled (#addon.history == 0)
farmbuyer@37 1852 b:SetCallback("OnClick", function(_b)
farmbuyer@37 1853 local dialog = StaticPopup_Show("OUROL_HIST_REGEN", addon.history.realm)
farmbuyer@37 1854 dialog.data = addon
farmbuyer@37 1855 dialog.data2 = function(_addon)
farmbuyer@37 1856 _addon:rewrite_history (_addon.history.realm)
farmbuyer@37 1857 histST:OuroLoot_Refresh()
farmbuyer@37 1858 histST:SetData(_addon.history.st)
farmbuyer@37 1859 end
farmbuyer@37 1860 end)
farmbuyer@37 1861 specials:AddChild(b)
farmbuyer@1 1862
farmbuyer@37 1863 b = mkbutton('hist_clear', "Clear Realm History",
farmbuyer@37 1864 [[|cffff1010Erases absolutely all> history entries from the displayed realm.]])
farmbuyer@37 1865 b:SetFullWidth(true)
farmbuyer@37 1866 b:SetCallback("OnClick", function (_b)
farmbuyer@37 1867 local dialog = StaticPopup_Show("OUROL_HIST_CLEAR", addon.history.realm)
farmbuyer@37 1868 dialog.data = addon
farmbuyer@37 1869 dialog.data2 = function(_addon)
farmbuyer@37 1870 reset_current_realm(_addon.history.realm)
farmbuyer@37 1871 end
farmbuyer@37 1872 end)
farmbuyer@37 1873 specials:AddChild(b)
farmbuyer@37 1874
farmbuyer@37 1875 b = mkbutton('hist_clear_all', "Clear All History",
farmbuyer@37 1876 [[|cffff1010Erases absolutely all> history entries from ALL realms.]])
farmbuyer@37 1877 b:SetFullWidth(true)
farmbuyer@37 1878 b:SetCallback("OnClick", function (_b)
farmbuyer@37 1879 local dialog = StaticPopup_Show("OUROL_HIST_CLEAR", "ALL realms")
farmbuyer@37 1880 dialog.data = addon
farmbuyer@37 1881 dialog.data2 = function(_addon)
farmbuyer@37 1882 _addon.history_all = {}
farmbuyer@37 1883 reset_current_realm()
farmbuyer@37 1884 end
farmbuyer@37 1885 end)
farmbuyer@37 1886 specials:AddChild(b)
farmbuyer@37 1887
farmbuyer@37 1888 b = mkbutton('hist_clear_old', "Clear Older",
farmbuyer@75 1889 [[Preserves only the latest loot entries for players on the displayed realm, removing all earlier ones.]])
farmbuyer@37 1890 b:SetFullWidth(true)
farmbuyer@37 1891 b:SetCallback("OnClick", function (_b)
farmbuyer@75 1892 local dialog = StaticPopup_Show("OUROL_HIST_PREEN", '', addon.history.realm, addon)
farmbuyer@37 1893 dialog.data = addon
farmbuyer@75 1894 dialog.data2 = function (_addon, howmany)
farmbuyer@75 1895 _addon:preen_history (_addon.history.realm, howmany)
farmbuyer@37 1896 _addon.hist_clean = nil
farmbuyer@37 1897 histST:OuroLoot_Refresh()
farmbuyer@37 1898 end
farmbuyer@37 1899 end)
farmbuyer@37 1900 specials:AddChild(b)
farmbuyer@1 1901 end
farmbuyer@37 1902 return tabs_OnGroupSelected["hist"](container,specials)
farmbuyer@1 1903 end
farmbuyer@83 1904 noob_tips["hist"] = _markup[[
farmbuyer@83 1905 <Left>-click a row to see all history for that player. <Right>-click any row
farmbuyer@83 1906 to return to showing all players.
farmbuyer@83 1907
farmbuyer@83 1908 <Shift-Left> while over an item link to paste it into chat. <Shift-Right>
farmbuyer@83 1909 any row to display a dropdown menu.]]
farmbuyer@95 1910 -- '/ol hi pla' -> set filter on Playername
farmbuyer@88 1911 tabs_CLI_special["hist"] = function (name)
farmbuyer@88 1912 name = '^'..name -- already tolower'd by onslash
farmbuyer@88 1913 for _,player in ipairs(addon.history) do
farmbuyer@88 1914 if player.name:lower():find(name) then
farmbuyer@88 1915 history_filter_who = player.name
farmbuyer@88 1916 histST:SetFilter(history_filter_by_name)
farmbuyer@88 1917 setstatus(hist_name_status)
farmbuyer@88 1918 break
farmbuyer@88 1919 end
farmbuyer@88 1920 end
farmbuyer@88 1921 -- If nothing found, reset to normal or just leave alone?
farmbuyer@88 1922 end
farmbuyer@1 1923
farmbuyer@37 1924
farmbuyer@6 1925 -- Tab 5: Help (content in verbage.lua)
farmbuyer@1 1926
farmbuyer@37 1927
farmbuyer@96 1928 -- Tab 6: Options (content in options.lua)
farmbuyer@1 1929
farmbuyer@1 1930
farmbuyer@1 1931 -- Simply to avoid recreating the same function over and over
farmbuyer@1 1932 local tabs_OnGroupSelected_func_args = { [2] = "OnGroupSelected" }
farmbuyer@1 1933 tabs_OnGroupSelected_func = function (tabs,event,group)
farmbuyer@1 1934 tabs_OnGroupSelected_func_args[1] = tabs
farmbuyer@1 1935 tabs_OnGroupSelected_func_args[3] = group
farmbuyer@98 1936 gui.opts = addon.db.profile
farmbuyer@83 1937 hide_noobtips_frame()
farmbuyer@1 1938 tabs:ReleaseChildren()
farmbuyer@1 1939 local spec = tabs:GetUserData("special buttons group")
farmbuyer@1 1940 spec:ReleaseChildren()
farmbuyer@95 1941 local h = AceGUI:Create("Heading")
farmbuyer@1 1942 h:SetFullWidth(true)
farmbuyer@95 1943 h:SetText(gui.tabtexts[group].title)
farmbuyer@1 1944 spec:AddChild(h)
farmbuyer@76 1945 do
farmbuyer@76 1946 addon.sender_list.sort()
farmbuyer@76 1947 local fmt = "Received broadcast data from %d |4player:players;."
farmbuyer@76 1948 if addon.history_suppress then
farmbuyer@76 1949 -- this is the druid class color reworked into hex
farmbuyer@76 1950 fmt = fmt .. " |cffff7d0aHistory recording suppressed.|r"
farmbuyer@76 1951 end
farmbuyer@76 1952 tabs.titletext:SetFormattedText (fmt, addon.sender_list.activeI)
farmbuyer@76 1953 end
farmbuyer@81 1954 local status,err = pcall (tabs_OnGroupSelected[group], tabs, spec, group)
farmbuyer@81 1955 if not status then
farmbuyer@81 1956 addon:horrible_horrible_error(err)
farmbuyer@81 1957 end
farmbuyer@97 1958 if gui.opts.gui_noob then
farmbuyer@83 1959 local tip = noob_tips[group]
farmbuyer@83 1960 if type(tip) == 'function' then
farmbuyer@83 1961 tip = tip()
farmbuyer@83 1962 end
farmbuyer@83 1963 if type(tip) == 'string' and tip ~= "" then
farmbuyer@83 1964 local w = get_noobtips_frame()
farmbuyer@83 1965 w:SetParent (_d.content)
farmbuyer@83 1966 w:ClearAllPoints()
farmbuyer@83 1967 w:SetPoint("BOTTOMLEFT", _d.frame, "BOTTOMRIGHT", 3, 3)
farmbuyer@83 1968 w:Show()
farmbuyer@83 1969 w:DoTextWork(tip)
farmbuyer@83 1970 end
farmbuyer@83 1971 end
farmbuyer@1 1972 --[====[
farmbuyer@1 1973 Unfortunately, :GetHeight() called on anything useful out of a TabGroup
farmbuyer@1 1974 returns the static default size (about 50 pixels) until the refresh
farmbuyer@1 1975 cycle *after* all the frames are shown. Trying to fix it up after a
farmbuyer@1 1976 single OnUpdate doesn't work either. So for now it's all hardcoded.
farmbuyer@1 1977
farmbuyer@83 1978 Using this to determine the actual height of the usable area. (Will
farmbuyer@83 1979 error until an ST is shown, which only happens if it's tracking, etc.)
farmbuyer@83 1980 416 pixels
farmbuyer@1 1981 if group == "eoi" then
farmbuyer@1 1982 local stframe = tabs.children[1].frame
farmbuyer@1 1983 print(stframe:GetTop(),"-",stframe:GetBottom(),"=",
farmbuyer@1 1984 stframe:GetTop()-stframe:GetBottom())
farmbuyer@1 1985 print(stframe:GetRight(),"-",stframe:GetLeft(),"=",
farmbuyer@1 1986 stframe:GetRight()-stframe:GetLeft())
farmbuyer@1 1987 end
farmbuyer@1 1988 ]====]
farmbuyer@1 1989 end
farmbuyer@1 1990
farmbuyer@1 1991 --[[
farmbuyer@1 1992 mkbutton ("WidgetType", 'display key', "Text On Widget", "the mouseover display text")
farmbuyer@1 1993 mkbutton ( [Button] 'display key', "Text On Widget", "the mouseover display text")
farmbuyer@1 1994 mkbutton ( [Button] [text] "Text On Widget", "the mouseover display text")
farmbuyer@1 1995 ]]
farmbuyer@83 1996 function mkbutton (opt_widget_type, opt_key, label, status)
farmbuyer@83 1997 if not label then
farmbuyer@83 1998 opt_widget_type, opt_key, label, status = "Button", opt_widget_type, opt_widget_type, opt_key
farmbuyer@83 1999 elseif not status then
farmbuyer@83 2000 opt_widget_type, opt_key, label, status = "Button", opt_widget_type, opt_key, label
farmbuyer@1 2001 end
farmbuyer@95 2002 local button = assert(AceGUI:Create(opt_widget_type))
farmbuyer@83 2003 if button.SetText then button:SetText(tostring(label)) end
farmbuyer@83 2004 status = _markup(status)
farmbuyer@83 2005 button:SetCallback("OnEnter", function() setstatus(status) end) -- maybe factor that closure out
farmbuyer@83 2006 button:SetCallback("OnLeave", statusy_OnLeave)
farmbuyer@83 2007 -- retrieval key may be specified as nil if all the parameters are given
farmbuyer@83 2008 if opt_key then _d:SetUserData (opt_key, button) end
farmbuyer@83 2009 return button
farmbuyer@1 2010 end
farmbuyer@96 2011 gui.mkbutton = mkbutton
farmbuyer@1 2012
farmbuyer@1 2013 --[[
farmbuyer@1 2014 Creates the main window.
farmbuyer@1 2015 ]]
farmbuyer@1 2016 function addon:BuildMainDisplay (opt_tabselect)
farmbuyer@1 2017 if self.display then
farmbuyer@1 2018 -- try to get everything to update, rebuild, refresh... ugh, no
farmbuyer@1 2019 self.display:Hide()
farmbuyer@1 2020 end
farmbuyer@92 2021 if self.NOLOAD then
farmbuyer@92 2022 -- don't even try
farmbuyer@92 2023 return
farmbuyer@92 2024 end
farmbuyer@1 2025
farmbuyer@25 2026 -- This probably causes taint... hm.
farmbuyer@25 2027 local prev_fade_time = UIDROPDOWNMENU_SHOW_TIME
farmbuyer@25 2028 UIDROPDOWNMENU_SHOW_TIME = 4
farmbuyer@25 2029
farmbuyer@47 2030 if dirty_tabs then
farmbuyer@84 2031 -- pointers known to be good by now, pass them back in
farmbuyer@84 2032 self:gui_init (g_loot, g_uniques)
farmbuyer@47 2033 self:zero_printed_fenceposts()
farmbuyer@47 2034 end
farmbuyer@97 2035 gui.opts = self.db.profile
farmbuyer@47 2036
farmbuyer@95 2037 local display = AceGUI:Create("Frame")
farmbuyer@1 2038 _d = display
farmbuyer@1 2039 self.display = display
farmbuyer@17 2040 display:SetTitle(window_title)
farmbuyer@1 2041 display:SetStatusText(self.status_text)
farmbuyer@1 2042 display:SetLayout("Flow")
farmbuyer@16 2043 display:SetStatusTable{width=900,height=550} -- default height is 500
farmbuyer@47 2044 display:EnableResize(false)
farmbuyer@96 2045 display:SetUserData("GUI state",gui)
farmbuyer@1 2046 display:SetCallback("OnClose", function(_display)
farmbuyer@25 2047 UIDROPDOWNMENU_SHOW_TIME = prev_fade_time
farmbuyer@83 2048 hide_noobtips_frame()
farmbuyer@95 2049 _d = nil
farmbuyer@1 2050 self.display = nil
farmbuyer@95 2051 AceGUI:Release(_display)
farmbuyer@6 2052 flib.clear()
farmbuyer@1 2053 collectgarbage()
farmbuyer@1 2054 end)
farmbuyer@1 2055
farmbuyer@1 2056 ----- Right-hand panel
farmbuyer@1 2057 local rhs_width = 0.20
farmbuyer@95 2058 local control = AceGUI:Create("SimpleGroup")
farmbuyer@1 2059 control:SetLayout("Flow")
farmbuyer@1 2060 control:SetRelativeWidth(rhs_width)
farmbuyer@1 2061 control.alignoffset = 25
farmbuyer@1 2062 control:PauseLayout()
farmbuyer@1 2063 local h,b
farmbuyer@1 2064
farmbuyer@1 2065 --- Main ---
farmbuyer@95 2066 h = AceGUI:Create("Heading")
farmbuyer@1 2067 h:SetFullWidth(true)
farmbuyer@1 2068 h:SetText("Main")
farmbuyer@1 2069 control:AddChild(h)
farmbuyer@1 2070
farmbuyer@1 2071 do
farmbuyer@1 2072 b = mkbutton("Dropdown", nil, "",
farmbuyer@1 2073 [[Enable full tracking, only rebroadcasting, or disable activity altogether.]])
farmbuyer@1 2074 b:SetFullWidth(true)
farmbuyer@1 2075 b:SetLabel("On/Off:")
farmbuyer@1 2076 b:SetList{"Full Tracking", "Broadcasting", "Disabled"}
farmbuyer@1 2077 b:SetValue(self.enabled and 1 or (self.rebroadcast and 2 or 3))
farmbuyer@1 2078 b:SetCallback("OnValueChanged", function(_w,event,choice)
farmbuyer@1 2079 if choice == 1 then self:Activate()
farmbuyer@1 2080 elseif choice == 2 then self:Activate(nil,true)
farmbuyer@1 2081 else self:Deactivate()
farmbuyer@1 2082 end
farmbuyer@1 2083 _w = display:GetUserData('comm_ident')
farmbuyer@1 2084 if _w and _w:IsVisible() then
farmbuyer@1 2085 _w:SetDisabled(self.enabled or self.rebroadcast)
farmbuyer@1 2086 end
farmbuyer@1 2087 _w = display:GetUserData('eoi_bcast_req')
farmbuyer@1 2088 if _w and _w:IsVisible() then
farmbuyer@1 2089 _w:SetDisabled(not self.enabled)
farmbuyer@1 2090 end
farmbuyer@1 2091 end)
farmbuyer@1 2092 control:AddChild(b)
farmbuyer@1 2093 end
farmbuyer@1 2094
farmbuyer@1 2095 b = mkbutton("Dropdown", 'threshold', "",
farmbuyer@1 2096 [[Items greater than or equal to this quality will be tracked/rebroadcast.]])
farmbuyer@1 2097 b:SetFullWidth(true)
farmbuyer@1 2098 b:SetLabel("Threshold:")
farmbuyer@1 2099 b:SetList(self.thresholds)
farmbuyer@1 2100 b:SetValue(self.threshold)
farmbuyer@1 2101 b:SetCallback("OnValueChanged", function(_dd,event,choice)
farmbuyer@1 2102 self:SetThreshold(choice)
farmbuyer@1 2103 end)
farmbuyer@1 2104 control:AddChild(b)
farmbuyer@1 2105
farmbuyer@4 2106 b = mkbutton("Clear Loot",
farmbuyer@1 2107 [[+Erases> all current loot information and generated text (but not saved texts).]])
farmbuyer@1 2108 b:SetFullWidth(true)
farmbuyer@1 2109 b:SetCallback("OnClick", function()
farmbuyer@1 2110 StaticPopup_Show("OUROL_CLEAR").data = self
farmbuyer@1 2111 end)
farmbuyer@1 2112 control:AddChild(b)
farmbuyer@1 2113
farmbuyer@95 2114 b = AceGUI:Create("Spacer")
farmbuyer@1 2115 b:SetFullWidth(true)
farmbuyer@16 2116 b:SetHeight(10)
farmbuyer@1 2117 control:AddChild(b)
farmbuyer@1 2118
farmbuyer@1 2119 --[[
farmbuyer@1 2120 --- Saved Texts ---
farmbuyer@1 2121 [ Save Current As... ]
farmbuyer@1 2122 saved1
farmbuyer@1 2123 saved2
farmbuyer@1 2124 ...
farmbuyer@1 2125 [ Load ] [ Delete ]
farmbuyer@1 2126 ]]
farmbuyer@95 2127 h = AceGUI:Create("Heading")
farmbuyer@1 2128 h:SetFullWidth(true)
farmbuyer@1 2129 h:SetText("Saved Texts")
farmbuyer@1 2130 control:AddChild(h)
farmbuyer@1 2131 b = mkbutton("Save Current As...",
farmbuyer@1 2132 [[Save forum/attendance/etc texts for later retrieval. Main loot information not included.]])
farmbuyer@1 2133 b:SetFullWidth(true)
farmbuyer@1 2134 b:SetCallback("OnClick", function()
farmbuyer@1 2135 StaticPopup_Show "OUROL_SAVE_SAVEAS"
farmbuyer@1 2136 _d:Hide()
farmbuyer@1 2137 end)
farmbuyer@1 2138 control:AddChild(b)
farmbuyer@1 2139
farmbuyer@16 2140 do
farmbuyer@95 2141 local scontainer = AceGUI:Create("SimpleGroup")
farmbuyer@16 2142 scontainer:SetFullWidth(true)
farmbuyer@16 2143 scontainer:SetFullHeight(false)
farmbuyer@16 2144 scontainer:SetAutoAdjustHeight(false)
farmbuyer@16 2145 scontainer:SetHeight(40) -- no relative height available anymore
farmbuyer@16 2146 scontainer:SetLayout("Fill")
farmbuyer@95 2147 local scroll = AceGUI:Create("ScrollFrame")
farmbuyer@16 2148 scroll:SetLayout("List")
farmbuyer@16 2149 local saved = self:check_saved_table(--[[silent_on_empty=]]true)
farmbuyer@16 2150 if saved then for i,s in ipairs(saved) do
farmbuyer@95 2151 local il = AceGUI:Create("InteractiveLabel")
farmbuyer@16 2152 il:SetFullWidth(true)
farmbuyer@16 2153 il:SetText(s.name)
farmbuyer@16 2154 il:SetUserData("num",i)
farmbuyer@16 2155 il:SetHighlight(1,1,1,0.4)
farmbuyer@16 2156 local str = ("%s %d entries %s"):format(s.date,s.count,s.name)
farmbuyer@16 2157 il:SetCallback("OnEnter", function() setstatus(str) end)
farmbuyer@16 2158 il:SetCallback("OnLeave", statusy_OnLeave)
farmbuyer@16 2159 il:SetCallback("OnClick", function(_il)
farmbuyer@16 2160 local prev = _d:GetUserData("saved selection")
farmbuyer@16 2161 if prev then
farmbuyer@16 2162 prev.highlight:Hide()
farmbuyer@16 2163 prev:SetColor()
farmbuyer@16 2164 end
farmbuyer@16 2165 _il:SetColor(0,1,0)
farmbuyer@16 2166 _il.highlight:Show()
farmbuyer@16 2167 _d:SetUserData("saved selection",_il)
farmbuyer@16 2168 _d:GetUserData("Load"):SetDisabled(false)
farmbuyer@16 2169 _d:GetUserData("Delete"):SetDisabled(false)
farmbuyer@16 2170 end)
farmbuyer@16 2171 scroll:AddChild(il)
farmbuyer@16 2172 end end
farmbuyer@16 2173 scontainer:AddChild(scroll)
farmbuyer@16 2174 control:AddChild(scontainer)
farmbuyer@16 2175 end
farmbuyer@1 2176
farmbuyer@1 2177 b = mkbutton("Load",
farmbuyer@1 2178 [[Load previously saved text. +REPLACES> all current loot information!]])
farmbuyer@1 2179 b:SetRelativeWidth(0.5)
farmbuyer@1 2180 b:SetCallback("OnClick", function()
farmbuyer@1 2181 local num = _d:GetUserData("saved selection"):GetUserData("num")
farmbuyer@1 2182 self:save_restore(num)
farmbuyer@1 2183 self:BuildMainDisplay()
farmbuyer@1 2184 end)
farmbuyer@1 2185 b:SetDisabled(true)
farmbuyer@1 2186 control:AddChild(b)
farmbuyer@1 2187 b = mkbutton("Delete",
farmbuyer@1 2188 [[Delete previously saved text.]])
farmbuyer@1 2189 b:SetRelativeWidth(0.5)
farmbuyer@1 2190 b:SetCallback("OnClick", function()
farmbuyer@1 2191 local num = _d:GetUserData("saved selection"):GetUserData("num")
farmbuyer@1 2192 self:save_delete(num)
farmbuyer@1 2193 self:BuildMainDisplay()
farmbuyer@1 2194 end)
farmbuyer@1 2195 b:SetDisabled(true)
farmbuyer@1 2196 control:AddChild(b)
farmbuyer@1 2197
farmbuyer@95 2198 b = AceGUI:Create("Spacer")
farmbuyer@1 2199 b:SetFullWidth(true)
farmbuyer@16 2200 b:SetHeight(10)
farmbuyer@1 2201 control:AddChild(b)
farmbuyer@1 2202
farmbuyer@1 2203 -- Other stuff on right-hand side
farmbuyer@95 2204 local tab_specials = AceGUI:Create("SimpleGroup")
farmbuyer@1 2205 tab_specials:SetLayout("Flow")
farmbuyer@1 2206 tab_specials:SetFullWidth(true)
farmbuyer@1 2207 control:AddChild(tab_specials)
farmbuyer@1 2208 control:ResumeLayout()
farmbuyer@1 2209
farmbuyer@1 2210 ----- Left-hand group
farmbuyer@95 2211 local tabs = AceGUI:Create("TabGroup")
farmbuyer@1 2212 tabs:SetLayout("Flow")
farmbuyer@1 2213 tabs.alignoffset = 25
farmbuyer@49 2214 local titletext_orig_fo = tabs.titletext:GetFontObject()
farmbuyer@49 2215 tabs.titletext:SetFontObject(GameFontNormalSmall)
farmbuyer@49 2216 tabs:SetCallback("OnRelease", function(_tabs)
farmbuyer@49 2217 tabs.titletext:SetFontObject(titletext_orig_fo)
farmbuyer@49 2218 end)
farmbuyer@1 2219 tabs:SetRelativeWidth(0.99-rhs_width)
farmbuyer@1 2220 tabs:SetFullHeight(true)
farmbuyer@1 2221 tabs:SetTabs(tabgroup_tabs)
farmbuyer@1 2222 tabs:SetCallback("OnGroupSelected", tabs_OnGroupSelected_func)
farmbuyer@1 2223 tabs:SetCallback("OnTabEnter", function(_tabs,event,value,tab)
farmbuyer@95 2224 setstatus(gui.tabtexts[value].desc)
farmbuyer@1 2225 end)
farmbuyer@1 2226 tabs:SetCallback("OnTabLeave", statusy_OnLeave)
farmbuyer@1 2227 tabs:SetUserData("special buttons group",tab_specials)
farmbuyer@76 2228 tabs:SelectTab((opt_tabselect and #opt_tabselect>0)
farmbuyer@76 2229 and opt_tabselect or "eoi")
farmbuyer@1 2230
farmbuyer@1 2231 display:AddChildren (tabs, control)
farmbuyer@1 2232 display:ApplyStatus()
farmbuyer@1 2233
farmbuyer@1 2234 display:Show() -- without this, only appears every *other* function call
farmbuyer@1 2235 return display
farmbuyer@1 2236 end
farmbuyer@1 2237
farmbuyer@95 2238 -- Searches tab titles from left to right.
farmbuyer@88 2239 function addon:OpenMainDisplayToTab (text, opt_arg)
farmbuyer@44 2240 text = '^'..text:lower()
farmbuyer@95 2241 for _,tab in ipairs(gui.taborder) do
farmbuyer@95 2242 local v = gui.tabtexts[tab]
farmbuyer@95 2243 if v and v.title:lower():find(text) then
farmbuyer@1 2244 self:BuildMainDisplay(tab)
farmbuyer@88 2245 if opt_arg and tabs_CLI_special[tab] then
farmbuyer@88 2246 tabs_CLI_special[tab](opt_arg)
farmbuyer@88 2247 end
farmbuyer@1 2248 return true
farmbuyer@1 2249 end
farmbuyer@1 2250 end
farmbuyer@1 2251 end
farmbuyer@1 2252
farmbuyer@1 2253 -- Essentially a re-click on the current tab (if the current tab were clickable).
farmbuyer@1 2254 function addon:redisplay ()
farmbuyer@1 2255 tabs_OnGroupSelected_func (unpack(tabs_OnGroupSelected_func_args))
farmbuyer@1 2256 end
farmbuyer@1 2257
farmbuyer@103 2258 function addon:GoToLootLine (line)
farmbuyer@103 2259 local lineno = tonumber(self.lootjumps[line])
farmbuyer@103 2260 self:OpenMainDisplayToTab ("Loot", lineno)
farmbuyer@103 2261 end
farmbuyer@103 2262
farmbuyer@1 2263
farmbuyer@110 2264 -- We need to be able to reference the dropdownmenu locals, and I didn't want to
farmbuyer@110 2265 -- bubble them up any higher.
farmbuyer@110 2266 function gui.add_dropdown_entry (menutag, name, func_tbl, func_or_othername, arg, tooltiptext)
farmbuyer@110 2267 local emtbl = assert(gui.dropdown[menutag])
farmbuyer@110 2268
farmbuyer@110 2269 if type(func_tbl) == 'table' then
farmbuyer@110 2270 -- use it directly
farmbuyer@110 2271 elseif func_tbl == nil then
farmbuyer@110 2272 -- determine it from the menu tag
farmbuyer@110 2273 func_tbl = (menutag:sub(1,3) == 'eoi' and eoi_dropdownfuncs)
farmbuyer@110 2274 or (menutag:sub(1,4) == 'hist' and hist_dropdownfuncs)
farmbuyer@110 2275 or error("Cannot figure out function table from menu tag name")
farmbuyer@110 2276 end
farmbuyer@110 2277
farmbuyer@110 2278 if type(func_or_othername) == 'string' then
farmbuyer@110 2279 -- gen_dd_entry handles this
farmbuyer@110 2280 elseif type(func_or_othername) == 'function' then
farmbuyer@110 2281 error"bah"
farmbuyer@110 2282 end
farmbuyer@110 2283
farmbuyer@110 2284 local index
farmbuyer@110 2285 if menutag == 'eoi_loot' then
farmbuyer@110 2286 index = 2
farmbuyer@110 2287 elseif menutag == 'eoi_player' then
farmbuyer@110 2288 index = 3
farmbuyer@110 2289 else
farmbuyer@110 2290 index = 2
farmbuyer@110 2291 end
farmbuyer@110 2292
farmbuyer@110 2293 local ent = gen_dd_entry (name, func_tbl, func_or_othername, arg, tooltiptext)
farmbuyer@110 2294 tinsert (emtbl, index, ent)
farmbuyer@110 2295 return ent
farmbuyer@110 2296 end
farmbuyer@110 2297
farmbuyer@110 2298
farmbuyer@1 2299 ------ Popup dialogs
farmbuyer@75 2300 local function build_my_slider_widget()
farmbuyer@75 2301 local s = CreateFrame("Slider", "OuroLootSlider", nil, "OptionsSliderTemplate")
farmbuyer@75 2302 s.text = OuroLootSliderText
farmbuyer@75 2303 s.low = OuroLootSliderLow
farmbuyer@75 2304 s.high = OuroLootSliderHigh
farmbuyer@75 2305 s:SetScript("OnValueChanged", function (_s, value)
farmbuyer@75 2306 _s.value = value -- conveniently, this is already of numeric type
farmbuyer@75 2307 --_s.text:SetText(tostring(value))
farmbuyer@75 2308 if _s.DoOnValueChanged then
farmbuyer@75 2309 _s:DoOnValueChanged()
farmbuyer@75 2310 end
farmbuyer@75 2311 end)
farmbuyer@75 2312 build_my_slider_widget = nil
farmbuyer@75 2313 return s
farmbuyer@75 2314 end
farmbuyer@75 2315
farmbuyer@1 2316 StaticPopupDialogs["OUROL_CLEAR"] = flib.StaticPopup{
farmbuyer@1 2317 text = "Clear current loot information and text?",
farmbuyer@16 2318 button1 = YES,
farmbuyer@16 2319 button2 = NO,
farmbuyer@1 2320 OnAccept = function (dialog, addon)
farmbuyer@1 2321 addon:Clear(--[[verbose_p=]]true)
farmbuyer@1 2322 end,
farmbuyer@1 2323 }
farmbuyer@1 2324
farmbuyer@37 2325 StaticPopupDialogs["OUROL_HIST_REGEN"] = flib.StaticPopup{
farmbuyer@37 2326 -- Concatenate this once at load time. There is no ITEM_QUALITY_LEGENDARY constant.
farmbuyer@75 2327 text = "Erase all history entries from " .. ITEM_QUALITY_COLORS[5].hex
farmbuyer@75 2328 .. "%s|r, and generate it anew from current loot?",
farmbuyer@37 2329 button1 = YES,
farmbuyer@37 2330 button2 = NO,
farmbuyer@37 2331 OnAccept = function (dialog, addon, data2)
farmbuyer@37 2332 data2(addon)
farmbuyer@37 2333 addon:Print("%s history has been regenerated.", addon.history.realm)
farmbuyer@37 2334 addon:redisplay()
farmbuyer@37 2335 end,
farmbuyer@37 2336 }
farmbuyer@37 2337
farmbuyer@16 2338 StaticPopupDialogs["OUROL_HIST_CLEAR"] = flib.StaticPopup{
farmbuyer@37 2339 -- Concatenate this once at load time. There is no ITEM_QUALITY_LEGENDARY constant.
farmbuyer@37 2340 text = "Erase all history entries from " .. ITEM_QUALITY_COLORS[5].hex .. "%s|r?",
farmbuyer@16 2341 button1 = YES,
farmbuyer@16 2342 button2 = NO,
farmbuyer@16 2343 OnAccept = function (dialog, addon, data2)
farmbuyer@16 2344 data2(addon)
farmbuyer@16 2345 addon:Print("Stimpy, you eeediot, you've pushed the history erase button!")
farmbuyer@16 2346 addon:redisplay()
farmbuyer@16 2347 end,
farmbuyer@16 2348 }
farmbuyer@16 2349
farmbuyer@16 2350 StaticPopupDialogs["OUROL_HIST_PREEN"] = flib.StaticPopup{
farmbuyer@37 2351 -- Concatenate this once at load time. There is no ITEM_QUALITY_LEGENDARY constant.
farmbuyer@75 2352 text = "This will erase all but the latest "
farmbuyer@75 2353 .. ITEM_QUALITY_COLORS[ITEM_QUALITY_UNCOMMON].hex
farmbuyer@75 2354 .. "%s|r for each player on "
farmbuyer@75 2355 .. ITEM_QUALITY_COLORS[5].hex .. "%s|r. " .. CONTINUE .. "?",
farmbuyer@16 2356 button1 = YES,
farmbuyer@16 2357 button2 = NO,
farmbuyer@75 2358 OnShow = function (dialog, addon)
farmbuyer@75 2359 local thistable = StaticPopupDialogs[dialog.which]
farmbuyer@75 2360 -- StaticPopup_Resize does not take extraFrame into account, so we
farmbuyer@89 2361 -- monkeypatch the sizing method that _Resize calls at the end.
farmbuyer@75 2362 dialog.saved_setheight = dialog.SetHeight
farmbuyer@75 2363 dialog.SetHeight = function (d, h)
farmbuyer@75 2364 return d.saved_setheight(d,h+35)
farmbuyer@75 2365 end
farmbuyer@75 2366 dialog.extraFrame:ClearAllPoints()
farmbuyer@75 2367 dialog.extraFrame:SetPoint("TOP", dialog.text, "BOTTOM")
farmbuyer@75 2368 dialog.extraFrame:SetWidth(150)
farmbuyer@75 2369 dialog.extraFrame:SetHeight(35)
farmbuyer@75 2370 dialog.extraFrame:Show()
farmbuyer@75 2371 local slider = _G.OuroLootSlider or build_my_slider_widget()
farmbuyer@75 2372 slider.DoOnValueChanged = function(s)
farmbuyer@75 2373 dialog.text:SetFormattedText (thistable.text,
farmbuyer@75 2374 s.value == 1 and "single entry" or (s.value .. " entries"),
farmbuyer@75 2375 addon.history.realm)
farmbuyer@75 2376 StaticPopup_Resize (dialog, "OUROL_HIST_PREEN")
farmbuyer@75 2377 end
farmbuyer@75 2378 slider:SetOrientation('HORIZONTAL')
farmbuyer@75 2379 slider:SetMinMaxValues(1,30)
farmbuyer@75 2380 slider:SetValueStep(1)
farmbuyer@75 2381 slider.low:SetText("1")
farmbuyer@75 2382 slider.high:SetText("30")
farmbuyer@75 2383 --slider.tooltipText = ???
farmbuyer@75 2384 slider:SetParent(dialog.extraFrame)
farmbuyer@75 2385 slider:ClearAllPoints()
farmbuyer@75 2386 slider:SetPoint("TOPLEFT",dialog.extraFrame,"TOPLEFT",0, -15)
farmbuyer@75 2387 slider:SetPoint("BOTTOMRIGHT",dialog.extraFrame,"BOTTOMRIGHT",0, 0)
farmbuyer@75 2388 slider:Show()
farmbuyer@75 2389 -- This causes OnValueChanged to fire, reformatting the text. Except
farmbuyer@75 2390 -- IF the slider has already been shown, and IF at the time it was hidden
farmbuyer@75 2391 -- it had the same value here, THEN there is technically no "change"
farmbuyer@75 2392 -- and no event is fired. We work around this clever optimization by
farmbuyer@75 2393 -- doing a pair of set's, forcing the last one to fire OVC.
farmbuyer@75 2394 slider:SetValue(1)
farmbuyer@75 2395 slider:SetValue(5)
farmbuyer@75 2396 end,
farmbuyer@75 2397 OnAccept = function (dialog, addon, callback)
farmbuyer@75 2398 local howmany = assert(tonumber(_G.OuroLootSlider.value))
farmbuyer@75 2399 callback (addon, howmany)
farmbuyer@75 2400 addon:Print("All loot prior to the most recent %d |4entry:entries; has been erased.", howmany)
farmbuyer@16 2401 addon:redisplay()
farmbuyer@16 2402 end,
farmbuyer@75 2403 OnHide = function (dialog, addon)
farmbuyer@75 2404 dialog.SetHeight = nil
farmbuyer@75 2405 dialog.saved_setheight = nil
farmbuyer@75 2406 dialog.extraFrame:ClearAllPoints()
farmbuyer@75 2407 _G.OuroLootSlider:Hide() -- parent is hidden, why is this required?
farmbuyer@75 2408 _G.OuroLootSlider:ClearAllPoints()
farmbuyer@75 2409 _G.OuroLootSlider:SetParent(nil)
farmbuyer@75 2410 end,
farmbuyer@16 2411 }
farmbuyer@16 2412
farmbuyer@27 2413 StaticPopupDialogs["OUROL_URL"] = { --flib.StaticPopup{
farmbuyer@27 2414 text = "Use Control-C or equivalent to copy this URL to your system clipboard:",
farmbuyer@27 2415 button1 = OKAY,
farmbuyer@27 2416 timeout = 0,
farmbuyer@27 2417 whileDead = true,
farmbuyer@27 2418 hideOnEscape = true,
farmbuyer@27 2419 enterClicksFirstButton = true,
farmbuyer@27 2420 hasEditBox = true,
farmbuyer@27 2421 editBoxWidth = 350,
farmbuyer@53 2422 preferredIndex = 3,
farmbuyer@27 2423 OnShow = function (dialog, url)
farmbuyer@27 2424 dialog.editBox:SetText(url)
farmbuyer@27 2425 dialog.editBox:SetFocus()
farmbuyer@27 2426 dialog.editBox:HighlightText()
farmbuyer@27 2427 end,
farmbuyer@27 2428 }
farmbuyer@27 2429
farmbuyer@1 2430 StaticPopupDialogs["OUROL_REMIND"] = flib.StaticPopup{
farmbuyer@77 2431 text = "Do you wish to activate Ouro Loot?|n|n(Hit the Escape key to close this window without clicking; Enter is the same as Activate)",
farmbuyer@1 2432 button1 = "Activate recording", -- "accept", left
farmbuyer@69 2433 button2 = "Broadcast Only", -- "cancel", middle
farmbuyer@69 2434 button3 = HELP_LABEL, -- "alt", right
farmbuyer@1 2435 OnAccept = function (dialog, addon)
farmbuyer@1 2436 addon:Activate()
farmbuyer@1 2437 end,
farmbuyer@69 2438 noCancelOnEscape = true,
farmbuyer@69 2439 OnCancel = function (dialog, addon)
farmbuyer@1 2440 addon:Activate(nil,true)
farmbuyer@1 2441 end,
farmbuyer@69 2442 OnAlt = function (dialog, addon)
farmbuyer@1 2443 -- hitting escape also calls this, but the 3rd arg would be "clicked"
farmbuyer@1 2444 -- in both cases, not useful here.
farmbuyer@89 2445 if MouseIsOver(dialog.button3) then
farmbuyer@1 2446 -- they actually clicked the button (or at least the mouse was over "Help"
farmbuyer@1 2447 -- when they hit escape... sigh)
farmbuyer@1 2448 addon:BuildMainDisplay('help')
farmbuyer@1 2449 else
farmbuyer@1 2450 addon.popped = true
farmbuyer@1 2451 end
farmbuyer@1 2452 end,
farmbuyer@1 2453 }
farmbuyer@1 2454
farmbuyer@69 2455 -- Callback for each Next/Accept stage of inserting a new loot or boss row via
farmbuyer@69 2456 -- dropdown. Thanks to noCancelOnReuse, each Show done here will technically
farmbuyer@69 2457 -- Hide and redisplay the same dialog, passing along the same 'data' structure
farmbuyer@69 2458 -- each time. The topmost call to our OnAccept will then finish by hiding the
farmbuyer@69 2459 -- (very last) dialog.
farmbuyer@69 2460 --
farmbuyer@69 2461 -- This is really, really hideous to read.
farmbuyer@69 2462 local function eoi_st_insert_OnAccept_boss (dialog, data, data2)
farmbuyer@69 2463 if data.all_done then
farmbuyer@69 2464 -- It'll probably be the final entry in the table, but there might have
farmbuyer@73 2465 -- been real loot happening while the user was clicking and typing.
farmbuyer@69 2466 local boss_index = addon._addBossEntry{
farmbuyer@69 2467 kind = 'boss',
farmbuyer@97 2468 bossname = (gui.opts.snarky_boss and addon.boss_abbrev[data.name] or data.name) or data.name,
farmbuyer@69 2469 reason = 'kill',
farmbuyer@69 2470 instance = data.instance,
farmbuyer@69 2471 duration = 0,
farmbuyer@69 2472 maxsize = data.max_raid_size,
farmbuyer@69 2473 raidersnap = data.yes_snap or {},
farmbuyer@69 2474 }
farmbuyer@69 2475 local entry = tremove(g_loot,boss_index)
farmbuyer@69 2476 tinsert(g_loot,data.rowindex,entry)
farmbuyer@69 2477 addon:_mark_boss_kill(data.rowindex)
farmbuyer@95 2478 gui.eoiST:OuroLoot_Refresh(data.rowindex)
farmbuyer@103 2479 local jumpprefix = addon.chatprefix ("GoToLootLine", data.rowindex)
farmbuyer@69 2480 dialog.data = nil -- free up memory
farmbuyer@103 2481 addon:PCFPrint (_G.DEFAULT_CHAT_FRAME, jumpprefix,
farmbuyer@103 2482 "Inserted %s %s at entry %d.",
farmbuyer@103 2483 data.kind, data.name, data.rowindex)
farmbuyer@69 2484 return
farmbuyer@69 2485 end
farmbuyer@69 2486
farmbuyer@69 2487 -- third click
farmbuyer@69 2488 if data.name and data.instance then
farmbuyer@69 2489 data.all_done = true
farmbuyer@69 2490 -- this is how we distinguish OnAccept from OnCancel ("clicked"); the
farmbuyer@69 2491 -- 3rd param is handled all in StaticPopup_OnClick
farmbuyer@69 2492 if data2 ~= 'clicked' then
farmbuyer@69 2493 data.yes_snap = data.maybe_snap
farmbuyer@69 2494 end
farmbuyer@69 2495 return eoi_st_insert_OnAccept_boss (dialog, data)
farmbuyer@69 2496 end
farmbuyer@69 2497
farmbuyer@69 2498 local text = dialog.editBox:GetText():trim()
farmbuyer@69 2499
farmbuyer@69 2500 -- second click
farmbuyer@69 2501 if data.name and text then
farmbuyer@69 2502 data.instance = text
farmbuyer@92 2503 -- not "reusing" this dialog in the same sense as with loot
farmbuyer@69 2504 dialog.data = nil
farmbuyer@69 2505 dialog:Hide()
farmbuyer@69 2506 local getsnap = StaticPopup_Show("OUROL_EOI_INSERT_INCLUDE_RAIDERSNAP")
farmbuyer@69 2507 getsnap.data = data
farmbuyer@69 2508 return true
farmbuyer@69 2509 end
farmbuyer@69 2510
farmbuyer@69 2511 -- first click
farmbuyer@69 2512 if text then
farmbuyer@69 2513 data.name = text
farmbuyer@69 2514 local maybe_instance
farmbuyer@69 2515 data.maybe_snap, data.max_raid_size, maybe_instance = addon:snapshot_raid()
farmbuyer@69 2516 local getinstance = StaticPopup_Show("OUROL_EOI_INSERT","instance")
farmbuyer@69 2517 getinstance.data = data
farmbuyer@69 2518 getinstance.editBox:SetText(maybe_instance)
farmbuyer@69 2519 -- This suppresses auto-hide (which would cause the getinstance dialog
farmbuyer@69 2520 -- to go away), but only when mouse clicking. OnEnter is on its own.
farmbuyer@69 2521 return true
farmbuyer@69 2522 end
farmbuyer@69 2523 end
farmbuyer@69 2524
farmbuyer@69 2525 local function eoi_st_insert_OnAccept_loot (dialog, data)
farmbuyer@69 2526 if data.all_done then
farmbuyer@69 2527 data.display:Hide()
farmbuyer@73 2528 local loot_index = assert(addon:CHAT_MSG_LOOT ("manual", data.recipient, data.name, data.notes))
farmbuyer@69 2529 local entry = tremove(g_loot,loot_index)
farmbuyer@69 2530 tinsert(g_loot,data.rowindex,entry)
farmbuyer@69 2531 addon:_fill_out_eoi_data(data.rowindex)
farmbuyer@69 2532 addon:BuildMainDisplay()
farmbuyer@79 2533 local clicky = _new_rebroadcast_hyperlink (entry.unique)
farmbuyer@103 2534 local jumpprefix = addon.chatprefix ("GoToLootLine", data.rowindex)
farmbuyer@69 2535 dialog.data = nil
farmbuyer@103 2536 addon:PCFPrint (_G.DEFAULT_CHAT_FRAME, jumpprefix,
farmbuyer@103 2537 "Inserted %s %s at entry %d. %s",
farmbuyer@78 2538 data.kind, data.name, data.rowindex, tostring(clicky))
farmbuyer@69 2539 return
farmbuyer@69 2540 end
farmbuyer@69 2541
farmbuyer@69 2542 local text = dialog.editBox:GetText():trim()
farmbuyer@69 2543
farmbuyer@69 2544 -- third click
farmbuyer@69 2545 if data.name and data.recipient and text then
farmbuyer@69 2546 data.notes = (text ~= "<none>") and text or nil
farmbuyer@69 2547 data.all_done = true
farmbuyer@69 2548 return eoi_st_insert_OnAccept_loot (dialog, data)
farmbuyer@69 2549 end
farmbuyer@69 2550
farmbuyer@69 2551 -- second click
farmbuyer@69 2552 if data.name and text then
farmbuyer@69 2553 data.recipient = text
farmbuyer@69 2554 local getnotes = StaticPopup_Show("OUROL_EOI_INSERT","notes")
farmbuyer@69 2555 getnotes.data = data
farmbuyer@69 2556 getnotes.editBox:SetText("<none>")
farmbuyer@69 2557 getnotes.editBox:HighlightText()
farmbuyer@69 2558 return true
farmbuyer@69 2559 end
farmbuyer@69 2560
farmbuyer@69 2561 -- first click
farmbuyer@69 2562 if text then
farmbuyer@69 2563 data.name = text
farmbuyer@69 2564 dialog:Hide() -- technically a "different" one about to be shown
farmbuyer@78 2565 StaticPopupDialogs["OUROL_EOI_INSERT"].autoCompleteParams =
farmbuyer@93 2566 AUTOCOMPLETE_LIST_TEMPLATES[IsInRaid() and "IN_GROUP" or "IN_GUILD"]
farmbuyer@69 2567 local getrecipient = StaticPopup_Show("OUROL_EOI_INSERT","recipient")
farmbuyer@78 2568 StaticPopupDialogs["OUROL_EOI_INSERT"].autoCompleteParams = nil
farmbuyer@69 2569 getrecipient.data = data
farmbuyer@69 2570 getrecipient.editBox:SetText("")
farmbuyer@69 2571 return true
farmbuyer@69 2572 end
farmbuyer@69 2573 end
farmbuyer@69 2574
farmbuyer@69 2575 local function eoi_st_insert_OnAccept (dialog, data)
farmbuyer@69 2576 if data.kind == 'boss' then
farmbuyer@69 2577 return eoi_st_insert_OnAccept_boss (dialog, data)
farmbuyer@69 2578 elseif data.kind == 'loot' then
farmbuyer@69 2579 return eoi_st_insert_OnAccept_loot (dialog, data)
farmbuyer@69 2580 end
farmbuyer@69 2581 end
farmbuyer@69 2582
farmbuyer@1 2583 -- The data member here is a table built with:
farmbuyer@1 2584 -- {rowindex=<GUI row receiving click>, display=_d, kind=<loot/boss>}
farmbuyer@1 2585 do
farmbuyer@1 2586 local t = flib.StaticPopup{
farmbuyer@75 2587 text = "Enter name of new %s, then click "..CONTINUE.." or press Enter:",
farmbuyer@75 2588 button1 = CONTINUE.." ->",
farmbuyer@1 2589 button2 = CANCEL,
farmbuyer@1 2590 hasEditBox = true,
farmbuyer@16 2591 editBoxWidth = 350,
farmbuyer@1 2592 maxLetters = 50,
farmbuyer@1 2593 noCancelOnReuse = true,
farmbuyer@1 2594 }
farmbuyer@1 2595 t.EditBoxOnEnterPressed = function(editbox)
farmbuyer@39 2596 if editbox:GetText() == "" then return end
farmbuyer@1 2597 local dialog = editbox:GetParent()
farmbuyer@1 2598 if not eoi_st_insert_OnAccept (dialog, dialog.data) then
farmbuyer@1 2599 dialog:Hide() -- replicate OnAccept click behavior
farmbuyer@1 2600 end
farmbuyer@1 2601 end
farmbuyer@1 2602 t.enterClicksFirstButton = nil -- no effect with editbox focused
farmbuyer@1 2603 t.OnAccept = eoi_st_insert_OnAccept
farmbuyer@1 2604 StaticPopupDialogs["OUROL_EOI_INSERT"] = t
farmbuyer@1 2605
farmbuyer@69 2606 -- This seems to be gratuitous use of metatables, really.
farmbuyer@1 2607 local OEIL = {
farmbuyer@75 2608 text = "Paste the new item into here, then click "..CONTINUE.." or press Enter:",
farmbuyer@1 2609 __index = StaticPopupDialogs["OUROL_EOI_INSERT"]
farmbuyer@1 2610 }
farmbuyer@1 2611 StaticPopupDialogs["OUROL_EOI_INSERT_LOOT"] = setmetatable(OEIL,OEIL)
farmbuyer@1 2612
farmbuyer@1 2613 hooksecurefunc("ChatEdit_InsertLink", function (link,...)
farmbuyer@1 2614 local dialogname = StaticPopup_Visible "OUROL_EOI_INSERT_LOOT"
farmbuyer@1 2615 if dialogname then
farmbuyer@16 2616 _G[dialogname.."EditBox"]:SetText(link)
farmbuyer@1 2617 return true
farmbuyer@1 2618 end
farmbuyer@1 2619 end)
farmbuyer@69 2620
farmbuyer@69 2621 t = flib.StaticPopup{
farmbuyer@69 2622 -- Concatenate this once at load time. There is no ITEM_QUALITY_LEGENDARY constant.
farmbuyer@69 2623 text = "Include a snapshot of the " .. ITEM_QUALITY_COLORS[5].hex
farmbuyer@77 2624 .. "CURRENT|r raid?|n|nClicking '" .. YES .. "' will allow this entry to "
farmbuyer@69 2625 .. "appear in attendance lists, but with the roster as it is NOW, not as it "
farmbuyer@69 2626 .. "was THEN. Clicking '" .. NO .."' means this kill cannot be included in "
farmbuyer@77 2627 .. "attendance.|n|n(Enter = '" .. YES .."', Escape = '" .. CANCEL .. "')",
farmbuyer@69 2628 button1 = YES, -- "accept", left
farmbuyer@69 2629 button2 = NO, -- "cancel", middle
farmbuyer@69 2630 button3 = CANCEL, -- "alt", right
farmbuyer@69 2631 }
farmbuyer@69 2632 -- Hitting Escape still hides the frame, but doesn't run OnCancel (which
farmbuyer@69 2633 -- is for the "No" button, not the "Cancel"/OnAlt button). Dizzy yet?
farmbuyer@69 2634 t.noCancelOnEscape = true
farmbuyer@69 2635 t.OnAccept = eoi_st_insert_OnAccept_boss
farmbuyer@69 2636 t.OnCancel = eoi_st_insert_OnAccept_boss
farmbuyer@69 2637 StaticPopupDialogs["OUROL_EOI_INSERT_INCLUDE_RAIDERSNAP"] = t
farmbuyer@1 2638 end
farmbuyer@1 2639
farmbuyer@1 2640 StaticPopupDialogs["OUROL_REASSIGN_ENTER"] = flib.StaticPopup{
farmbuyer@1 2641 text = "Enter the player name:",
farmbuyer@1 2642 button1 = ACCEPT,
farmbuyer@1 2643 button2 = CANCEL,
farmbuyer@1 2644 hasEditBox = true,
farmbuyer@1 2645 OnAccept = function(dialog, data)
farmbuyer@1 2646 local name = dialog.usertext --editBox:GetText()
farmbuyer@81 2647 addon:reassign_loot ("local", data.index, name)
farmbuyer@95 2648 gui.eoiST:OuroLoot_Refresh(data.index)
farmbuyer@1 2649 end,
farmbuyer@1 2650 }
farmbuyer@1 2651
farmbuyer@1 2652 StaticPopupDialogs["OUROL_SAVE_SAVEAS"] = flib.StaticPopup{
farmbuyer@1 2653 text = "Enter a name for the loot collection:",
farmbuyer@1 2654 button1 = ACCEPT,
farmbuyer@1 2655 button2 = CANCEL,
farmbuyer@1 2656 hasEditBox = true,
farmbuyer@1 2657 maxLetters = 30,
farmbuyer@1 2658 OnAccept = function(dialog)--, data)
farmbuyer@1 2659 local name = dialog.usertext --editBox:GetText()
farmbuyer@1 2660 addon:save_saveas(name)
farmbuyer@1 2661 addon:BuildMainDisplay()
farmbuyer@1 2662 end,
farmbuyer@1 2663 OnCancel = function(dialog)--, data, reason)
farmbuyer@1 2664 addon:BuildMainDisplay()
farmbuyer@1 2665 end,
farmbuyer@1 2666 }
farmbuyer@1 2667
farmbuyer@25 2668
farmbuyer@25 2669 -- Workaround this bug: http://us.battle.net/wow/en/forum/topic/3278901991
farmbuyer@25 2670 if true then
farmbuyer@25 2671 -- Verbatim copy of UIDropDownMenuTemplates.xml:155 or so, except as
farmbuyer@25 2672 -- tagged with CHANGE.
farmbuyer@25 2673 local function onenter (self, motion)
farmbuyer@25 2674 if ( self.hasArrow ) then
farmbuyer@25 2675 local level = self:GetParent():GetID() + 1;
farmbuyer@25 2676 local listFrame = _G["DropDownList"..level];
farmbuyer@25 2677 if ( not listFrame or not listFrame:IsShown() or select(2, listFrame:GetPoint()) ~= self ) then
farmbuyer@25 2678 ToggleDropDownMenu(self:GetParent():GetID() + 1, self.value, nil, nil, nil, nil, self.menuList, self);
farmbuyer@25 2679 end
farmbuyer@25 2680 else
farmbuyer@25 2681 CloseDropDownMenus(self:GetParent():GetID() + 1);
farmbuyer@25 2682 end
farmbuyer@25 2683 _G[self:GetName().."Highlight"]:Show();
farmbuyer@25 2684 UIDropDownMenu_StopCounting(self:GetParent());
farmbuyer@25 2685 if ( self.tooltipTitle ) then
farmbuyer@25 2686 if ( self.tooltipOnButton ) then
farmbuyer@25 2687 GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
farmbuyer@25 2688 GameTooltip:AddLine(self.tooltipTitle, 1.0, 1.0, 1.0);
farmbuyer@25 2689 GameTooltip:AddLine(self.tooltipText, nil,nil,nil,1); -- CHANGE added nil->1 arguments
farmbuyer@25 2690 GameTooltip:Show();
farmbuyer@25 2691 else
farmbuyer@25 2692 GameTooltip_AddNewbieTip(self, self.tooltipTitle, 1.0, 1.0, 1.0, self.tooltipText, 1);
farmbuyer@25 2693 end
farmbuyer@25 2694 end
farmbuyer@25 2695 end
farmbuyer@25 2696 -- end verbatime copy
farmbuyer@25 2697
farmbuyer@25 2698 for i = 1, UIDROPDOWNMENU_MAXLEVELS do
farmbuyer@25 2699 local list = _G["DropDownList"..i]
farmbuyer@25 2700 if list then
farmbuyer@25 2701 for j = 1, UIDROPDOWNMENU_MAXBUTTONS do
farmbuyer@25 2702 local button = _G["DropDownList"..i.."Button"..j]
farmbuyer@25 2703 if button then
farmbuyer@25 2704 --print("button fixup",i,j)
farmbuyer@25 2705 button:SetScript("OnEnter",onenter)
farmbuyer@25 2706 end
farmbuyer@25 2707 end
farmbuyer@25 2708 end
farmbuyer@25 2709 end
farmbuyer@25 2710 end
farmbuyer@25 2711
farmbuyer@109 2712 addon.FILES_LOADED = addon.FILES_LOADED + 1
farmbuyer@1 2713 -- vim:noet