annotate LibFarmbuyer.lua @ 115:289c7667adab

When fixing up missing item cache during load, make sure GUI displays from scratch. Put the bang back on UI tips checkbox (widget fixed). Revent r112, widgets both fixed now.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Tue, 14 Aug 2012 20:37:12 -0400
parents a57133ee3c9b
children fb4bda3ad05c
rev   line source
farmbuyer@1 1 --[[
farmbuyer@1 2 Not really meant for public use. Stuff that I keep using everywhere and
farmbuyer@1 3 got tired of reimplementing, or even copy-and-pasting. The notes here are
farmbuyer@1 4 reminders to myself.
farmbuyer@1 5
farmbuyer@1 6 Library contents:
farmbuyer@1 7 - author_debug
farmbuyer@1 8 Evaluates to true if I'm hacking on something.
farmbuyer@1 9
farmbuyer@19 10 - tableprint(t[,f])
farmbuyer@100 11 A single print() call to the tostring'd contents of T, including nils;
farmbuyer@100 12 strings are cleaned up with respect to embedded '|'/control chars. A
farmbuyer@100 13 single space is used during concatenation of T. If a function F is passed,
farmbuyer@100 14 calls that instead of print(). Returns the accumulated string and either
farmbuyer@100 15 T or the returned values of F, depending on which was used.
farmbuyer@1 16
farmbuyer@1 17 - safeprint(...)
farmbuyer@19 18 Same as tableprint() on the argument list. Returns the results of tableprint.
farmbuyer@45 19 Generates some garbage.
farmbuyer@1 20
farmbuyer@1 21 - safeiprint(...)
farmbuyer@19 22 Same as safeprint() but with <index> numbers inserted. Returns the results
farmbuyer@45 23 of tableprint. Generates some garbage.
farmbuyer@19 24 Ex: safeiprint(a,b,c) --> <1>,a,<2>,b,<3>,c
farmbuyer@1 25
farmbuyer@45 26 - safefprint/safefiprint(f,...)
farmbuyer@45 27 Takes a function F as first parameter, for passing to tableprint().
farmbuyer@45 28
farmbuyer@1 29 - t = StaticPopup(t)
farmbuyer@1 30 Fills out "typical" settings inside T, especially if T contains any kind
farmbuyer@1 31 of editbox:
farmbuyer@1 32 + cannot accept an empty editbox
farmbuyer@39 33 + pressing Enter runs OnAccept (also will not accept empty editbox)
farmbuyer@1 34 + editbox grabs keyboard focus
farmbuyer@1 35 + OnAccept runs with editbox's text in dialog.usertext
farmbuyer@1 36 Returns T.
farmbuyer@1 37
farmbuyer@1 38 - nullfunc()
farmbuyer@1 39 Empty placeholder function. Will be less useful if WoW ever moves to Lua 5.2.
farmbuyer@1 40 This is a fascinating and educational place to insert print calls...
farmbuyer@1 41
farmbuyer@1 42 - tabledump(t)/dumptable(t)
farmbuyer@1 43 If author_debug, this runs the builtin /dump command on T. Otherwise nothing.
farmbuyer@1 44
farmbuyer@1 45 - DoOnceNextUpdate(f)
farmbuyer@1 46 Runs F on the next frame refresh cycle. Multiple calls in one cycle will
farmbuyer@1 47 stack LIFO. Calls *while* processing the stack are safe, and will be stacked
farmbuyer@1 48 up for the next cycle.
farmbuyer@6 49
farmbuyer@6 50 - safecall (func, ...)
farmbuyer@6 51 A modified copy of the xpcall wrapper duplicated in every Ace3 file in the
farmbuyer@6 52 whole damn library.
farmbuyer@6 53
farmbuyer@6 54 - new(...), del(t), copy(t), clear()
farmbuyer@6 55 Ditto for table recycling.
farmbuyer@1 56 ]]
farmbuyer@1 57
farmbuyer@92 58 local MAJOR, MINOR = "LibFarmbuyer", 19
farmbuyer@1 59 assert(LibStub,MAJOR.." requires LibStub")
farmbuyer@1 60 local lib = LibStub:NewLibrary(MAJOR, MINOR)
farmbuyer@1 61 if not lib then return end
farmbuyer@1 62
farmbuyer@1 63 _G[MAJOR] = lib
farmbuyer@1 64
farmbuyer@1 65 ----------------------------------------------------------------------
farmbuyer@6 66 --[[
farmbuyer@6 67 Recycling functions yoinked from AceConfigDialog and tweaked
farmbuyer@6 68 ]]
farmbuyer@1 69 local new, del, copy, clear
farmbuyer@6 70 do
farmbuyer@6 71 local pool = setmetatable({},{__mode="k"})
farmbuyer@6 72 function clear()
farmbuyer@6 73 wipe(pool)
farmbuyer@6 74 end
farmbuyer@6 75 function new(...) -- slightly modified variant, takes optional initializers
farmbuyer@6 76 local t = next(pool)
farmbuyer@6 77 if t then
farmbuyer@6 78 pool[t] = nil
farmbuyer@6 79 for i = 1, select('#',...) do
farmbuyer@6 80 t[i] = select(i,...)
farmbuyer@6 81 end
farmbuyer@6 82 return t
farmbuyer@6 83 else
farmbuyer@6 84 return {...}
farmbuyer@6 85 end
farmbuyer@6 86 end
farmbuyer@6 87 function copy(t)
farmbuyer@6 88 local c = new()
farmbuyer@6 89 for k, v in pairs(t) do
farmbuyer@6 90 c[k] = v
farmbuyer@6 91 end
farmbuyer@6 92 return c
farmbuyer@6 93 end
farmbuyer@6 94 function del(t)
farmbuyer@6 95 wipe(t)
farmbuyer@6 96 pool[t] = true
farmbuyer@6 97 end
farmbuyer@6 98 end
farmbuyer@6 99 lib.new, lib.del, lib.copy, lib.clear = new, del, copy, clear
farmbuyer@1 100
farmbuyer@1 101
farmbuyer@1 102 ----------------------------------------------------------------------
farmbuyer@1 103 --[[
farmbuyer@95 104 safeprint and company (primarily for on-the-fly debugging)
farmbuyer@1 105 ]]
farmbuyer@56 106 local tconcat, tostring, tonumber = table.concat, tostring, tonumber
farmbuyer@1 107 local function undocontrol(c)
farmbuyer@1 108 return ("\\%.3d"):format(c:byte())
farmbuyer@1 109 end
farmbuyer@1 110 function lib.safeprint(...)
farmbuyer@1 111 local args = { n=select('#',...), ... }
farmbuyer@19 112 return lib.tableprint(args)
farmbuyer@1 113 end
farmbuyer@45 114 function lib.safefprint(f,...)
farmbuyer@45 115 local args = { n=select('#',...), ... }
farmbuyer@45 116 return lib.tableprint(args,f)
farmbuyer@45 117 end
farmbuyer@1 118 function lib.safeiprint(...)
farmbuyer@1 119 local args = { n=select('#',...), ... }
farmbuyer@1 120 local last = args.n
farmbuyer@1 121 while last > 0 do
farmbuyer@1 122 table.insert (args, last, "<"..last..">")
farmbuyer@1 123 last = last - 1
farmbuyer@1 124 end
farmbuyer@1 125 args.n = 2 * args.n
farmbuyer@19 126 return lib.tableprint(args)
farmbuyer@1 127 end
farmbuyer@45 128 function lib.safefiprint(f,...)
farmbuyer@45 129 local args = { n=select('#',...), ... }
farmbuyer@45 130 local last = args.n
farmbuyer@45 131 while last > 0 do
farmbuyer@45 132 table.insert (args, last, "<"..last..">")
farmbuyer@45 133 last = last - 1
farmbuyer@45 134 end
farmbuyer@45 135 args.n = 2 * args.n
farmbuyer@45 136 return lib.tableprint(args,f)
farmbuyer@45 137 end
farmbuyer@19 138 function lib.tableprint(t,f)
farmbuyer@1 139 for i = 1, (tonumber(t.n) or #t) do
farmbuyer@1 140 t[i] = tostring(t[i]):gsub('\124','\124\124')
farmbuyer@1 141 :gsub('(%c)', undocontrol)
farmbuyer@1 142 end
farmbuyer@56 143 local msg = tconcat(t,' ', 1, tonumber(t.n) or #t)
farmbuyer@45 144 if type(f) == 'function' then
farmbuyer@45 145 return msg,f(msg)
farmbuyer@1 146 else
farmbuyer@19 147 print(msg)
farmbuyer@19 148 return msg,t
farmbuyer@1 149 end
farmbuyer@1 150 end
farmbuyer@1 151
farmbuyer@1 152 -- See below for global versions.
farmbuyer@1 153
farmbuyer@1 154
farmbuyer@1 155 ----------------------------------------------------------------------
farmbuyer@1 156 local StaticPopupDialogs = _G.StaticPopupDialogs
farmbuyer@1 157
farmbuyer@1 158 local function EditBoxOnTextChanged_notempty (editbox) -- this is also called when first shown
farmbuyer@1 159 if editbox:GetText() ~= "" then
farmbuyer@1 160 editbox:GetParent().button1:Enable()
farmbuyer@1 161 else
farmbuyer@1 162 editbox:GetParent().button1:Disable()
farmbuyer@1 163 end
farmbuyer@1 164 end
farmbuyer@1 165 local function EditBoxOnEnterPressed_accept (editbox)
farmbuyer@39 166 if editbox:GetText() == "" then return end
farmbuyer@39 167 local dialog = editbox:GetParent()
farmbuyer@39 168 StaticPopupDialogs[dialog.which].OnAccept (dialog, dialog.data, dialog.data2)
farmbuyer@39 169 dialog:Hide()
farmbuyer@1 170 end
farmbuyer@69 171 local function OnShow_ontop (dialog, data)
farmbuyer@1 172 local info = StaticPopupDialogs[dialog.which]
farmbuyer@69 173 -- ace3's elements are hardcoded to this strata, make sure popups
farmbuyer@69 174 -- can also be seen (their toplevel=true attribute handles the
farmbuyer@69 175 -- framelevels within the same strata)
farmbuyer@69 176 info.saved_strata = dialog:GetFrameStrata()
farmbuyer@69 177 dialog:SetFrameStrata("FULLSCREEN_DIALOG")
farmbuyer@69 178 if info.hasEditBox then
farmbuyer@69 179 dialog.editBox:SetFocus()
farmbuyer@69 180 end
farmbuyer@1 181 if info.farm_OnShow then
farmbuyer@1 182 return info.farm_OnShow (dialog, data)
farmbuyer@1 183 end
farmbuyer@1 184 end
farmbuyer@1 185 local function OnAccept_witheditbox (dialog, data, data2)
farmbuyer@1 186 local info = StaticPopupDialogs[dialog.which]
farmbuyer@16 187 --dialog.usertext = dialog[info.hasWideEditBox and "wideEditBox" or "editBox"]:GetText():trim()
farmbuyer@16 188 dialog.usertext = dialog.editBox:GetText():trim()
farmbuyer@1 189 if info.farm_OnAccept then
farmbuyer@1 190 return info.farm_OnAccept (dialog, data, data2)
farmbuyer@1 191 end
farmbuyer@1 192 end
farmbuyer@69 193 local function OnHide_cleanup (dialog, data)
farmbuyer@69 194 local info = StaticPopupDialogs[dialog.which]
farmbuyer@69 195 if info.farm_OnHide then
farmbuyer@69 196 return info.farm_OnHide (dialog, data)
farmbuyer@69 197 end
farmbuyer@16 198 dialog.data = nil
farmbuyer@16 199 dialog.data2 = nil
farmbuyer@69 200 dialog:SetFrameStrata(info.saved_strata or "DIALOG")
farmbuyer@16 201 end
farmbuyer@1 202
farmbuyer@1 203 --[[
farmbuyer@1 204 StaticPopup
farmbuyer@1 205 ]]
farmbuyer@1 206 function lib.StaticPopup (t)
farmbuyer@57 207 if t.hasEditBox then
farmbuyer@57 208 t.EditBoxOnTextChanged = EditBoxOnTextChanged_notempty
farmbuyer@57 209 t.EditBoxOnEnterPressed = EditBoxOnEnterPressed_accept
farmbuyer@1 210 if t.OnAccept then
farmbuyer@1 211 t.farm_OnAccept = t.OnAccept
farmbuyer@1 212 end
farmbuyer@57 213 t.OnAccept = OnAccept_witheditbox
farmbuyer@1 214 -- this calls OnCancel with "clicked", unless noCancelOnEscape is set
farmbuyer@57 215 t.EditBoxOnEscapePressed = StaticPopup_EscapePressed
farmbuyer@57 216 end
farmbuyer@1 217
farmbuyer@69 218 t.farm_OnShow = t.OnShow
farmbuyer@69 219 t.OnShow = OnShow_ontop
farmbuyer@69 220 t.farm_OnHide = t.OnHide
farmbuyer@69 221 t.OnHide = OnHide_cleanup
farmbuyer@16 222
farmbuyer@57 223 t.timeout = 0
farmbuyer@57 224 t.whileDead = true
farmbuyer@57 225 t.hideOnEscape = true
farmbuyer@1 226 t.enterClicksFirstButton = true
farmbuyer@53 227 t.preferredIndex = 3 -- http://forums.wowace.com/showthread.php?t=19960
farmbuyer@1 228
farmbuyer@57 229 return t
farmbuyer@1 230 end
farmbuyer@1 231
farmbuyer@1 232
farmbuyer@1 233 ----------------------------------------------------------------------
farmbuyer@1 234 --[[
farmbuyer@1 235 This is ugly, but at least it all gets GC'd almost immediately.
farmbuyer@1 236 ]]
farmbuyer@1 237 function lib.nullfunc() end
farmbuyer@1 238
farmbuyer@1 239 if ({
farmbuyer@1 240 ["Bandwagon"] = true, ["Kilvin"] = true, ["Waterfaucet"] = true,
farmbuyer@1 241 ["Farmbuyer"] = true, ["Oxdeadbeef"] = true, ["Pointystick"] = true,
farmbuyer@1 242 ["Angryhobbit"] = true, ["Malrubius"] = true, ["Hemogoblin"] = true,
farmbuyer@16 243 ["Ossipago"] = true,
farmbuyer@1 244 })[UnitName("player")] then
farmbuyer@1 245 lib.author_debug = true
farmbuyer@1 246 _G.safeprint = lib.safeprint
farmbuyer@1 247 _G.safeiprint = lib.safeiprint
farmbuyer@1 248 function lib.tabledump(t)
farmbuyer@73 249 -- Should instead load this and then call the subcommands directly.
farmbuyer@73 250 --_G.UIParentLoadAddOn("Blizzard_DebugTools")
farmbuyer@1 251 _G.LibF_DEBUG = t
farmbuyer@1 252 _G.SlashCmdList.DUMP("LibF_DEBUG")
farmbuyer@1 253 end
farmbuyer@1 254 else
farmbuyer@92 255 -- make sure earlier lib's members aren't lingering
farmbuyer@92 256 lib.author_debug = nil
farmbuyer@92 257 _G.safeprint = nil
farmbuyer@92 258 _G.safeiprint = nil
farmbuyer@1 259 lib.tabledump = lib.nullfunc
farmbuyer@1 260 end
farmbuyer@1 261 lib.dumptable = lib.tabledump
farmbuyer@1 262
farmbuyer@1 263
farmbuyer@1 264 ----------------------------------------------------------------------
farmbuyer@1 265 --[[
farmbuyer@1 266 DoOnceNextUpdate
farmbuyer@1 267 ]]
farmbuyer@1 268 do
farmbuyer@1 269 local frame = CreateFrame("Frame", "LibFarmbuyerDONUFrame")
farmbuyer@1 270 frame:Hide()
farmbuyer@1 271 frame:SetScript("OnUpdate", function()
farmbuyer@1 272 frame:Hide()
farmbuyer@1 273 local q = frame.nexttime
farmbuyer@1 274 local tmp
farmbuyer@1 275 frame.nexttime = nil
farmbuyer@1 276 while q do
farmbuyer@1 277 tmp = q
farmbuyer@1 278 q.f(frame)
farmbuyer@1 279 q = q.n
farmbuyer@1 280 del(tmp)
farmbuyer@1 281 end
farmbuyer@1 282 end)
farmbuyer@1 283
farmbuyer@1 284 function lib.DoOnceNextUpdate (func)
farmbuyer@1 285 local nextt = new()
farmbuyer@1 286 nextt.f = func
farmbuyer@1 287 nextt.n = frame.nexttime
farmbuyer@1 288 frame.nexttime = nextt
farmbuyer@1 289 frame:Show()
farmbuyer@1 290 end
farmbuyer@1 291 end
farmbuyer@1 292
farmbuyer@1 293
farmbuyer@1 294 ----------------------------------------------------------------------
farmbuyer@6 295 --[[
farmbuyer@6 296 safecall
farmbuyer@6 297 ]]
farmbuyer@1 298 do
farmbuyer@6 299 local xpcall = xpcall
farmbuyer@6 300
farmbuyer@6 301 local function errorhandler(err)
farmbuyer@6 302 --return geterrorhandler()(err)
farmbuyer@6 303 --print("in error handler", err)
farmbuyer@6 304 return err
farmbuyer@1 305 end
farmbuyer@6 306
farmbuyer@6 307 local template = ([[
farmbuyer@6 308 local xpcall, eh = ...
farmbuyer@6 309 local method, ARGS
farmbuyer@6 310 local function call() return method(ARGS) end
farmbuyer@6 311
farmbuyer@6 312 local function dispatch (func, ...)
farmbuyer@6 313 method = func
farmbuyer@6 314 if not method then return end
farmbuyer@6 315 ARGS = ...
farmbuyer@6 316 return xpcall (call, eh)
farmbuyer@1 317 end
farmbuyer@6 318
farmbuyer@6 319 return dispatch
farmbuyer@6 320 ]]):gsub('\t',' ')
farmbuyer@6 321
farmbuyer@6 322 local function CreateDispatcher(argCount)
farmbuyer@6 323 local ARGS = {}
farmbuyer@6 324 for i = 1, argCount do ARGS[i] = "arg"..i end
farmbuyer@19 325 local code = template:gsub("ARGS", tconcat(ARGS, ", "))
farmbuyer@6 326 return assert(loadstring(code, "LibF/safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
farmbuyer@1 327 end
farmbuyer@6 328
farmbuyer@6 329 local Dispatchers = setmetatable({
farmbuyer@6 330 [0] = function(func)
farmbuyer@6 331 return xpcall (func, errorhandler)
farmbuyer@1 332 end
farmbuyer@6 333 }, {
farmbuyer@6 334 __index = function (Ds, argCount)
farmbuyer@6 335 local dispatcher = CreateDispatcher(argCount)
farmbuyer@6 336 Ds[argCount] = dispatcher
farmbuyer@6 337 return dispatcher
farmbuyer@6 338 end
farmbuyer@6 339 })
farmbuyer@6 340
farmbuyer@6 341 function lib.safecall (func, ...)
farmbuyer@6 342 if type(func) == 'function' then
farmbuyer@6 343 return Dispatchers[select('#', ...)](func, ...)
farmbuyer@6 344 end
farmbuyer@1 345 end
farmbuyer@1 346 end
farmbuyer@1 347
farmbuyer@6 348
farmbuyer@6 349 ----------------------------------------------------------------------
farmbuyer@6 350
farmbuyer@1 351 -- vim: noet