annotate Veneer.lua @ 57:3cecf50070ba

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