annotate gui.lua @ 108:04ccd12c2a41

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