annotate Init.lua @ 37:e84d645c8ab8

- revised the tracker update function to build its complete data list up front and use the values as points of comparison for determining possible out of place blocks, which will be iterated over afterward to remove what wasn't re-used - also entailed revising the exact role of global event handlers and function hooks, limiting their directions of communication so one doesn't end up calling the other multiple or inifinity times - schema handling polish
author Nenue
date Mon, 18 Apr 2016 07:56:23 -0400
parents 66b927b46776
children 1f8f9cc3d956
rev   line source
Nenue@0 1 --- Modulizer framework
Nenue@0 2 -- OnInitialize
Nenue@0 3 -- OnUpdate
Nenue@0 4 -- OnEnable -- run when GetSpecialization() returns true
Nenue@0 5
Nenue@0 6 local ADDON, A = ...
Nenue@0 7 Veneer = Veneer or CreateFrame('Frame', 'Veneer', UIParent)
Nenue@0 8 local B = Veneer
Nenue@3 9 local wipe, min, max, random, tinsert, tremove = table.wipe, math.min, math.max, math.random, table.insert, table.remove
Nenue@0 10 local pairs, ipairs, select, unpack, _G = pairs, ipairs, select, unpack, _G
Nenue@0 11 local type, tostring, format = type, tostring, string.format
Nenue@0 12 A.frame = B
Nenue@0 13
Nenue@0 14 --- Cache tables
Nenue@0 15 local initOnced
Nenue@0 16 local modules = {}
Nenue@0 17 local queuedModules = {}
Nenue@3 18 local checkForConfig = {}
Nenue@0 19 local moduleStack = {
Nenue@0 20 }
Nenue@0 21
Nenue@37 22 --- Utilities
Nenue@37 23 B.wipeall = function (...)
Nenue@37 24 for i = 1, select('#', ...) do
Nenue@37 25 wipe(select(i, ...))
Nenue@37 26 end
Nenue@37 27 end
Nenue@37 28
Nenue@0 29 --- Various region categories
Nenue@0 30 B.displays = {}
Nenue@0 31 B.configLayers = {}
Nenue@0 32 B.configLayersRef = {}
Nenue@0 33
Nenue@37 34
Nenue@0 35 --@debug@
Nenue@0 36 --- Generates a print handler pointing to a static channel signature
Nenue@0 37 -- @usage func = B.print(sig)
Nenue@0 38 -- @param sig channel name or number
Nenue@0 39 local printfuncs = {}
Nenue@0 40 B.print = function(pref, ...)
Nenue@0 41 if Devian and Devian.InWorkspace() then
Nenue@0 42 printfuncs[pref] = printfuncs[pref] or function(...) print(pref, ...) end
Nenue@0 43
Nenue@0 44 return printfuncs[pref]
Nenue@0 45 else
Nenue@0 46 return function () end
Nenue@0 47 end
Nenue@0 48 end
Nenue@0 49
Nenue@0 50 local rgb = {}
Nenue@0 51 local getcolor = function()
Nenue@0 52 local n, p = 0, 4
Nenue@0 53 for i = 1, 3 do
Nenue@0 54 rgb[i] = min(random(n,p) * 64, 255)
Nenue@0 55 if rgb[i] == 255 then
Nenue@0 56 p = 4
Nenue@0 57 elseif rgb[i] > 0 then
Nenue@0 58 n = 2
Nenue@0 59 end
Nenue@0 60 end
Nenue@0 61 return unpack(rgb)
Nenue@0 62 end
Nenue@0 63
Nenue@0 64 local color = {}
Nenue@0 65 local fprints = {}
Nenue@0 66 B.fprint = function()
Nenue@0 67 if not (Devian and Devian.InWorkspace()) then
Nenue@0 68 return function() end
Nenue@0 69 end
Nenue@0 70
Nenue@0 71
Nenue@0 72 local sig = debugstack(2,1)
Nenue@0 73 if fprints[sig] then
Nenue@0 74 return fprints[sig]
Nenue@0 75 end
Nenue@0 76
Nenue@0 77 local func = sig:match("%`(%a+)%'")
Nenue@0 78 if not func then
Nenue@0 79 func = sig:match("<(.-)>")
Nenue@0 80 end
Nenue@0 81 func = func:gsub('(%l+)(%u)', function(a, b) return a:sub(0,2) .. b end, 1)
Nenue@0 82 func = func:gsub('^.+%\\', '')
Nenue@0 83 if not func then
Nenue@0 84 func = 'noname'
Nenue@0 85 end
Nenue@0 86
Nenue@0 87 local r, g, b = getcolor()
Nenue@0 88 color[sig] = color[sig] or format('|cFF%02X%02X%02X%s|r', r, g, b, func)
Nenue@0 89
Nenue@0 90 --print(color[func] .. ' ( ' .. table.concat(args, ', ')..' )' )
Nenue@0 91 func = B.print(func)
Nenue@0 92 fprints[sig] = func
Nenue@0 93 return func
Nenue@0 94 end
Nenue@0 95
Nenue@0 96 --@end-debug@
Nenue@0 97 --[=[@non-debug@
Nenue@0 98 B.print = function() end
Nenue@0 99 --@end-non-debug@]=]
Nenue@0 100
Nenue@0 101 -- for the Mikk script
Nenue@0 102 -- GLOBALS: NUM_LE_RAID_BUFF_TYPES
Nenue@0 103 -- GLOBALS: BUFF_FLASH_TIME_ON, BUFF_FLASH_TIME_OFF, BUFF_MIN_ALPHA, BUFF_WARNING_TIME, BUFF_DURATION_WARNING_TIME
Nenue@0 104 -- GLOBALS: BUFFS_PER_ROW, BUFF_MAX_DISPLAY, BUFF_ACTUAL_DISPLAY, DEBUFF_MAX_DISPLAY, DEBUFF_ACTUAL_DISPLAY, BUFF_ROW_SPACING
Nenue@0 105 -- GLOBALS: CONSOLIDATED_BUFFS_PER_ROW, CONSOLIDATED_BUFF_ROW_HEIGHT, NUM_TEMP_ENCHANT_FRAMES
Nenue@0 106 -- GLOBALS: BUFF_BUTTON_HEIGHT, BUFF_FRAME_BASE_EXTENT, BUFF_HORIZ_SPACING
Nenue@0 107
Nenue@0 108 local print = B.print('Bfl')
Nenue@0 109
Nenue@0 110 --- Template for making perpendicular traversals of the displays structure; also makes sure the table is there
Nenue@0 111 B.Abstract = function(dest, key, table)
Nenue@0 112 if table then
Nenue@0 113 for _, v in pairs(dest) do
Nenue@0 114 v[key] = {}
Nenue@0 115 end
Nenue@0 116 end
Nenue@0 117 B[key] = setmetatable({}, {
Nenue@0 118 __index = function(t, k)
Nenue@0 119 return dest[k][key]
Nenue@0 120 end,
Nenue@0 121 __newindex = function(_, k, v)
Nenue@0 122 print('abstract write ('..key..'):', k)
Nenue@0 123 dest[k][key] = v
Nenue@0 124 end,
Nenue@0 125 __tostring = function() return 'Abstract:'..key..'' end
Nenue@0 126 })
Nenue@0 127
Nenue@0 128
Nenue@0 129 return B[key]
Nenue@0 130 end
Nenue@0 131
Nenue@0 132
Nenue@0 133 --- localize for speed
Nenue@0 134 local layers, refs, displays = B.configLayers, B.configLayersRef, B.displays
Nenue@0 135
Nenue@24 136 local ModulesCall = function(func, flag)
Nenue@0 137
Nenue@0 138 local n = 0
Nenue@0 139 for i = 1, #moduleStack do
Nenue@0 140 print('calling level '..i)
Nenue@0 141 local stackset = moduleStack[i]
Nenue@0 142
Nenue@0 143 for name, module in pairs(stackset) do
Nenue@0 144 n = n + 1
Nenue@0 145
Nenue@0 146
Nenue@0 147 if module[func] then
Nenue@24 148 -- nil = pass
Nenue@24 149 if not flag or module.Conf[flag] then
Nenue@24 150 if (flag) then
Nenue@24 151 print(' check', flag, '=', module.Conf[flag])
Nenue@24 152 end
Nenue@24 153
Nenue@24 154 print(' ',n..' '..name..'.'..func..'()')
Nenue@24 155 module[func](module, module.Conf)
Nenue@24 156 end
Nenue@24 157
Nenue@0 158 end
Nenue@0 159 end
Nenue@0 160 end
Nenue@0 161 end
Nenue@0 162
Nenue@0 163
Nenue@0 164 local Enable = function()
Nenue@0 165 end
Nenue@0 166
Nenue@0 167 --- The things that happen repeatedly
Nenue@0 168 local Init = function ()
Nenue@0 169 end
Nenue@0 170
Nenue@0 171
Nenue@0 172 --- Things that happen immediately upon entering world
Nenue@0 173 local InitOnce = function()
Nenue@0 174 print('entering world first time')
Nenue@0 175 local defaults = B.ConfDefaults
Nenue@0 176 print('|cFFFFFF00Veneer|r')
Nenue@0 177 if not VeneerData then
Nenue@0 178 VeneerData = {}
Nenue@0 179 for k,v in pairs(defaults) do
Nenue@24 180
Nenue@24 181
Nenue@0 182 VeneerData[k] = v
Nenue@0 183 end
Nenue@0 184 print('Veneer defaults being used.')
Nenue@0 185 end
Nenue@0 186
Nenue@0 187 B.Conf = setmetatable(VeneerData, {__index = function(_, k) return defaults[k] end})
Nenue@0 188
Nenue@14 189
Nenue@14 190
Nenue@0 191 -- suffix tables
Nenue@0 192 for name, display in pairs(displays) do
Nenue@0 193 display.conf = setmetatable({}, {
Nenue@0 194 __index = function(_, k)
Nenue@0 195 --print('config check '.. name .. k)
Nenue@0 196 return B.Conf[name .. k] or B.Conf['BuffButton' .. k]
Nenue@0 197 end,
Nenue@0 198 __newindex = function(_, k , v)
Nenue@0 199 B.Conf[name..k] = v
Nenue@0 200 end,
Nenue@0 201 })
Nenue@0 202 end
Nenue@0 203
Nenue@0 204 -- To ensure that modules are run in controlled order, walk the dependency list; if the dep shows up
Nenue@0 205 -- in the loaded manifest, remove the value. If the dep list isn't empty, move that module to the next
Nenue@0 206 -- layer.
Nenue@0 207 local loaded = {}
Nenue@0 208 local stackLevels = #moduleStack
Nenue@0 209 local i = 1
Nenue@0 210 moduleStack[1] = modules
Nenue@0 211 repeat
Nenue@0 212 print('setting init level '.. i)
Nenue@0 213 local queue = moduleStack[i]
Nenue@0 214 for name, module in pairs(queue) do
Nenue@0 215
Nenue@0 216 if queuedModules[name] and #queuedModules[name] > 0 then
Nenue@0 217 local p = #queuedModules[name]
Nenue@0 218 for j = 1, p do
Nenue@0 219 local dep = queuedModules[name][j]
Nenue@0 220
Nenue@0 221 if loaded[dep] then
Nenue@0 222 print( ' ' .. dep .. ' OK')
Nenue@0 223 queuedModules[name][j] = nil
Nenue@0 224 for k = j, p do
Nenue@0 225 print(' shift ' .. (k+1) .. ' ('..tostring(queuedModules[name][k+1])..') to ' .. k ..'')
Nenue@0 226 queuedModules[name][k] = queuedModules[name][k+1]
Nenue@0 227 end
Nenue@0 228 end
Nenue@0 229 end
Nenue@0 230
Nenue@0 231 if #queuedModules[name] == 0 then
Nenue@0 232 queuedModules[name] = nil
Nenue@0 233 print(' |cFF00FFFF'.. name ..'|r deps OK')
Nenue@0 234 loaded[name] = true
Nenue@0 235 else
Nenue@0 236
Nenue@0 237 print(' |cFFFF8800' .. name ..'|r pending')
Nenue@0 238 local next = i+1
Nenue@0 239 if not moduleStack[next] then
Nenue@0 240 moduleStack[next] = {}
Nenue@0 241 end
Nenue@0 242 stackLevels = next
Nenue@0 243 moduleStack[next][name] = module
Nenue@0 244 queue[name] = nil
Nenue@0 245 end
Nenue@0 246
Nenue@0 247 else
Nenue@0 248 print(' |cFF00FF00'.. name ..'|r no deps')
Nenue@0 249 loaded[name] = true
Nenue@0 250 end
Nenue@0 251 end
Nenue@0 252 i = i + 1
Nenue@0 253 until i > stackLevels
Nenue@0 254
Nenue@0 255
Nenue@0 256 for level, batch in ipairs(moduleStack) do
Nenue@0 257 print('config level', level)
Nenue@0 258 for name, module in pairs(batch) do
Nenue@24 259 if not VeneerData[name] then
Nenue@24 260 VeneerData[name] = {}
Nenue@24 261 end
Nenue@24 262
Nenue@14 263 if module.defaults then
Nenue@14 264 print('setting defaults for module', name)
Nenue@14 265 --[===[@non-debug@
Nenue@14 266 if not VeneerData[name] then
Nenue@14 267 --@end-non-debug@]===]
Nenue@14 268 VeneerData[name] = {}
Nenue@14 269 --[===[@non-debug@
Nenue@14 270 end
Nenue@14 271 --@end-non-debug@]===]
Nenue@14 272 for k,v in pairs(module.defaults) do
Nenue@14 273 VeneerData[name][k] = v
Nenue@14 274 end
Nenue@14 275 module.Conf = VeneerData[name]
Nenue@14 276 end
Nenue@0 277
Nenue@24 278 if VeneerData[name].enabled == nil then
Nenue@24 279 VeneerData[name].enabled = true
Nenue@24 280 end
Nenue@24 281
Nenue@0 282 end
Nenue@0 283 end
Nenue@3 284
Nenue@3 285
Nenue@3 286 if #checkForConfig >= 1 then
Nenue@3 287 local queuedFrame = tremove(checkForConfig)
Nenue@3 288 while queuedFrame do
Nenue@3 289 B.SetConfigLayers(queuedFrame)
Nenue@3 290 B.InitXMLFrame(queuedFrame)
Nenue@3 291 queuedFrame = tremove(checkForConfig)
Nenue@3 292 end
Nenue@3 293 end
Nenue@0 294 -- remove from existing
Nenue@0 295 end
Nenue@0 296
Nenue@0 297 --- Fires an update to all modules
Nenue@0 298 local lastUpdate
Nenue@0 299 function B.UpdateAll(...)
Nenue@0 300 lastUpdate = GetTime()
Nenue@24 301 ModulesCall('OnUpdate')
Nenue@0 302 end
Nenue@0 303
Nenue@0 304 B:RegisterEvent('PLAYER_ENTERING_WORLD')
Nenue@0 305 B:SetScript('OnEvent', function(self, event)
Nenue@0 306 if event == 'PLAYER_ENTERING_WORLD' then
Nenue@0 307 if not initOnced then
Nenue@0 308 InitOnce()
Nenue@0 309 ModulesCall('OnInitialize')
Nenue@0 310 initOnced = true
Nenue@0 311 C_Timer.After(1, function()
Nenue@0 312 if GetSpecialization() then
Nenue@0 313 print(GetSpecialization(), 'enabling')
Nenue@24 314
Nenue@24 315 ModulesCall('OnEnable', 'enabled')
Nenue@0 316 B:SetScript('OnUpdate', nil)
Nenue@0 317 end
Nenue@0 318 end)
Nenue@0 319 end
Nenue@0 320 end
Nenue@0 321
Nenue@0 322 B.UpdateAll()
Nenue@24 323
Nenue@24 324 if event == 'PLAYER_ENTERING_WORLD' then
Nenue@24 325 B.UpdateConfigLayers()
Nenue@24 326 end
Nenue@24 327
Nenue@0 328 end)
Nenue@0 329
Nenue@0 330 --- Modulizer method
Nenue@0 331 --
Nenue@0 332 function B:RegisterModule (name, module, ...)
Nenue@0 333 if modules[name] then
Nenue@0 334 print('pulling modules[|cFFFF8800'.. tostring(name) ..'|r]')
Nenue@0 335 return modules[name]
Nenue@0 336 end
Nenue@0 337
Nenue@0 338 print('new module |cFF00BBFF'.. tostring(name) ..'|r')
Nenue@0 339 if module then
Nenue@0 340 if modules[name] then
Nenue@0 341 error("Module table for '"..tostring(name).."' already exists.")
Nenue@0 342 end
Nenue@0 343 else
Nenue@0 344 module = CreateFrame('Frame', 'Veneer' .. tostring(name) .. 'Handler', B, 'VeneerHandlerTemplate')
Nenue@0 345 end
Nenue@0 346 modules[name] = module
Nenue@3 347 B[name] = module
Nenue@0 348 if select('#', ...) >= 1 then
Nenue@0 349 local numDeps = select('#', ...)
Nenue@0 350 print(' '..numDeps..' deps detected')
Nenue@0 351 for i = 1, numDeps do
Nenue@0 352 local dep = select(i, ...)
Nenue@0 353 -- means that init/enable funcs are ordered to run after deps do their things
Nenue@0 354 queuedModules[name] = queuedModules[name] or {}
Nenue@0 355 tinsert(queuedModules[name], dep)
Nenue@0 356 print(' needs '..dep)
Nenue@0 357 end
Nenue@0 358 end
Nenue@0 359 return module
Nenue@0 360 end
Nenue@0 361
Nenue@0 362
Nenue@0 363 B.SetConfigLayers = function(frame)
Nenue@0 364 local print = B.fprint()
Nenue@0 365 if not frame.config then
Nenue@24 366 --print(frame:GetName(), 'has no config layers')
Nenue@0 367 return
Nenue@0 368 end
Nenue@24 369 --print('Registering config layers from', frame:GetName())
Nenue@0 370
Nenue@0 371 for i, subframe in ipairs(frame.config) do
Nenue@0 372 -- make sure there are no duplicates
Nenue@0 373 if not refs[subframe] then
Nenue@0 374 local key = #layers+1
Nenue@0 375 layers[key] = subframe
Nenue@0 376 refs[subframe] = key
Nenue@0 377 end
Nenue@24 378 --print(' ', i, subframe:GetName())
Nenue@0 379 end
Nenue@0 380 end
Nenue@0 381
Nenue@0 382 B.RemoveConfigLayers = function(frame)
Nenue@3 383
Nenue@0 384 local print = B.fprint()
Nenue@0 385 print('|cFFFF0000RemoveConfigLayers', frame:GetName())
Nenue@0 386 for i, subframe in pairs(layers) do
Nenue@0 387 if subframe:GetParent() == frame then
Nenue@0 388 print('|cFFFF8800 ', subframe:GetParent():GetName(), '|cFFFFFF00', subframe:GetName())
Nenue@0 389 layers[i]:Hide()
Nenue@0 390 layers[i] = nil
Nenue@0 391 refs[subframe] = nil
Nenue@0 392 end
Nenue@0 393 end
Nenue@0 394 end
Nenue@0 395
Nenue@0 396 B.UpdateConfigLayers = function()
Nenue@0 397 local print = B.fprint()
Nenue@0 398 local func = B.Conf.GuidesMode and 'Show' or 'Hide'
Nenue@0 399 local numAnchors = 0
Nenue@0 400 for name, display in pairs(displays) do
Nenue@0 401 numAnchors = numAnchors + 1
Nenue@0 402 display.anchor:EnableMouse(B.Conf.GuidesMode)
Nenue@0 403 if B.Conf.GuidesMode then
Nenue@0 404 display.anchor:SetScript('OnUpdate', display.anchor.OnUpdate)
Nenue@0 405 else
Nenue@0 406 display.anchor:SetScript('OnUpdate', nil)
Nenue@0 407
Nenue@0 408 for i, anchorButton in ipairs(display.anchor.anchorButton) do
Nenue@0 409 anchorButton:Hide()
Nenue@0 410 end
Nenue@0 411
Nenue@0 412 end
Nenue@24 413 print(B.Conf.ConfigMode)
Nenue@24 414 display.anchor:EnableMouse(B.Conf.ConfigMode)
Nenue@0 415 end
Nenue@0 416 for id, region in pairs(layers) do
Nenue@0 417 print(id, region:GetName(), func)
Nenue@0 418 region[func](region)
Nenue@0 419 end
Nenue@0 420
Nenue@0 421 print('['..func..'] updated', #layers, 'regions,', numAnchors, 'frames')
Nenue@3 422 end
Nenue@3 423
Nenue@24 424 local XMLFrame_SetEnabled = function(self, value)
Nenue@24 425 local name = self:GetName()
Nenue@24 426
Nenue@24 427
Nenue@24 428 if not B.Conf[name] then
Nenue@24 429 B.Conf[name] = {
Nenue@24 430 enabled = true
Nenue@24 431 }
Nenue@24 432 end
Nenue@24 433
Nenue@24 434 print()
Nenue@24 435 local enabled
Nenue@24 436 if value == nil then
Nenue@24 437 if B.Conf[name].enabled == nil then
Nenue@24 438 print('toggle based on visibility')
Nenue@24 439 enabled = (not self:IsVisible()) and true or false
Nenue@24 440 else
Nenue@24 441 print('toggle a config value =', B.Conf[name].enabled)
Nenue@24 442 enabled = B.Conf[name].enabled
Nenue@24 443 end
Nenue@24 444
Nenue@24 445 enabled = (enabled ~= true) and true or false
Nenue@24 446 else
Nenue@24 447 print('use argument value', value)
Nenue@24 448 enabled = value
Nenue@24 449 end
Nenue@24 450
Nenue@24 451 print('arg =', value, 'conf =', B.Conf[name].enabled, 'result=', enabled)
Nenue@24 452
Nenue@24 453 B.Conf[name].enabled = enabled
Nenue@24 454
Nenue@24 455 local stateFunc = enabled and 'Show' or 'Hide'
Nenue@24 456 local eventFunc = enabled and 'OnToggle' or 'OnToggle'
Nenue@24 457 for i, region in pairs(self.toggled) do
Nenue@24 458 region[stateFunc](region)
Nenue@24 459 end
Nenue@24 460 if self.OnToggle then
Nenue@24 461 self:OnToggle(B.Conf[name].enabled)
Nenue@24 462 end
Nenue@24 463 if B.Conf[name].enabled then
Nenue@24 464 if self.OnEnable then
Nenue@24 465 self:OnEnable()
Nenue@24 466 end
Nenue@24 467 else
Nenue@24 468 if self.OnDisable then
Nenue@24 469 self:OnDisable()
Nenue@24 470 end
Nenue@24 471 end
Nenue@24 472
Nenue@24 473
Nenue@24 474 end
Nenue@3 475 --- Generic handlers for keeping track of XML-defined frames
Nenue@3 476 B.OnLoad = function(self)
Nenue@3 477 tinsert(checkForConfig, self)
Nenue@24 478 self.SetEnabled = XMLFrame_SetEnabled
Nenue@3 479 end
Nenue@3 480
Nenue@3 481 B.InitXMLFrame = function(self)
Nenue@24 482 local name = self:GetName()
Nenue@24 483 print('|cFF00FF00hello from '.. name)
Nenue@3 484
Nenue@21 485 if self.drag then
Nenue@21 486 self:RegisterForDrag('LeftButton')
Nenue@21 487 else
Nenue@21 488 self:EnableMouse(false)
Nenue@21 489 end
Nenue@21 490
Nenue@24 491 if not B.Conf[name] then
Nenue@24 492 B.Conf[name] = {
Nenue@24 493 enabled = true,
Nenue@24 494 }
Nenue@3 495 end
Nenue@24 496 local c = B.Conf[name]
Nenue@24 497
Nenue@24 498 if c.position then
Nenue@24 499 print('restoring frame position', unpack(c.position))
Nenue@24 500 self:ClearAllPoints()
Nenue@24 501 local anchorTo, relativePoint, x, y = unpack(c.position)
Nenue@24 502 self:SetPoint(anchorTo, UIParent, relativePoint, x, y)
Nenue@24 503 else
Nenue@24 504 local a, _, b, c, d = self:GetPoint(1)
Nenue@24 505 print('seeding default position', a, b, c, d)
Nenue@24 506 c.position = {a, b, c, d}
Nenue@13 507 end
Nenue@24 508 local state = c.enabled
Nenue@24 509 self:SetEnabled(state)
Nenue@3 510 end
Nenue@3 511
Nenue@3 512 B.OnDragStart = function(self)
Nenue@3 513 self.xA = self:GetLeft()
Nenue@3 514 self.yA = self:GetBottom()
Nenue@3 515 self.anchorTo, self.relativeTo, self.relativePoint, self.x, self.y = self:GetPoint(1)
Nenue@3 516 print('acquire anchor', self:GetPoint(1))
Nenue@3 517 print(self:GetName(), 'start moving ('..self.x..', '..self.y..')')
Nenue@3 518 self:StartMoving()
Nenue@3 519 end
Nenue@3 520
Nenue@3 521 B.OnDragStop = function(self)
Nenue@24 522 local name = self:GetName()
Nenue@24 523 print(name, 'stop moving ('..self:GetLeft()..', '..self:GetBottom()..')')
Nenue@3 524 local xB = self:GetLeft() - self.xA
Nenue@3 525 local yB = self:GetBottom() - self.yA
Nenue@3 526 print('storing anchor point', self.anchorTo, self.relativePoint, self.x + xB, self.y + yB)
Nenue@3 527
Nenue@3 528 self:StopMovingOrSizing()
Nenue@24 529 B.Conf[name].position = {self.anchorTo, self.relativePoint, self.x + xB, self.y + yB}
Nenue@3 530 B.InitXMLFrame(self)
Nenue@0 531 end