annotate Devian.lua @ 94:c3511ea79774

Added tag v2.2.95-rc1 for changeset f6fae1a4c66c
author Nenue
date Wed, 19 Oct 2016 16:48:14 -0400
parents f6fae1a4c66c
children 33bc8baba858
rev   line source
Nenue@50 1 --- Devian - Devian.lua
Nenue@32 2 -- @file-author@
Nenue@32 3 -- @project-revision@ @project-hash@
Nenue@32 4 -- @file-revision@ @file-hash@
Nenue@66 5
Nenue@91 6 --GLOBALS: Devian, DevianLoadMessage, DEVIAN_WORKSPACE, DEVIAN_PNAME, DEVIAN_PID
Nenue@91 7
Nenue@91 8 DEVIAN_WORKSPACE = false
Nenue@91 9 DEVIAN_PNAME = 'Dvn'
Nenue@91 10 DEVIAN_PID = 0
Nenue@79 11
Nenue@66 12 local ADDON, D = ...
Nenue@79 13 local MAJOR, MINOR = 'Devian-2.0', 'r@project-revision@'
Nenue@79 14 local D = LibStub("AceAddon-3.0"):NewAddon(D, "Devian", "AceConsole-3.0", "AceEvent-3.0")
Nenue@79 15 local L = D.L
Nenue@79 16 Devian = D
Nenue@72 17 local sub, GetTime, print, _G = string.sub, GetTime, print, _G
Nenue@72 18 local format, setmetatable, getprinthandler, setprinthandler = string.format, setmetatable, getprinthandler, setprinthandler
Nenue@79 19 local tinsert, tremove, rawset = tinsert, tremove, rawset
Nenue@66 20 local currentProfile
Nenue@66 21 local playerName = UnitName("player")
Nenue@66 22 local playerRealm = playerName .. '-' .. GetRealmName()
Nenue@66 23 local num_dock_tabs = 0
Nenue@93 24 local charStates ={}
Nenue@79 25
Nenue@79 26 DevianLoadMessage = setmetatable({}, {
Nenue@79 27 __call = function(t, msg)
Nenue@79 28 rawset(t, #t+1, msg)
Nenue@79 29 end,
Nenue@79 30 __index = function(t)
Nenue@79 31 return #t
Nenue@79 32 end
Nenue@79 33 })
Nenue@79 34
Nenue@66 35 --@debug@
Nenue@66 36 D.debugmode = true
Nenue@66 37 --@end-debug@
Nenue@66 38 D.print = function(...)
Nenue@66 39 if currentProfile and not currentProfile.workspace then
Nenue@66 40 return
Nenue@66 41 end
Nenue@66 42
Nenue@66 43 if D.debugmode then
Nenue@66 44 return print('Dvn', ...)
Nenue@66 45 else
Nenue@93 46 return nop
Nenue@66 47 end
Nenue@0 48 end
Nenue@66 49 local print = D.print
Nenue@66 50
Nenue@66 51 D.L = setmetatable({}, {
Nenue@66 52 __index= function(t,k)
Nenue@66 53 return k
Nenue@66 54 end,
Nenue@66 55 __call = function(t,k,...)
Nenue@72 56 return format((t[k] or k) , ...)
Nenue@66 57 end
Nenue@66 58 })
Nenue@46 59 D:SetDefaultModuleState(false)
Nenue@66 60 D.oldprint = getprinthandler()
Nenue@66 61 if not _G.oldprint then _G.oldprint = D.oldprint end
Nenue@66 62
Nenue@47 63 local pairs, tostring, tonumber, ipairs, type = pairs, tostring, tonumber, ipairs, type
Nenue@66 64 local max, rand, format, print = max, math.random, string.format, print
Nenue@47 65 local insert, wipe, concat = table.insert, table.wipe, table.concat
Nenue@47 66 local select, unpack = select, unpack
Nenue@47 67 local GetNumAddOns, GetAddOnInfo, GetAddOnEnableState, EnableAddOn = GetNumAddOns, GetAddOnInfo, GetAddOnEnableState, EnableAddOn
Nenue@47 68 local UnitName, DisableAddOn = UnitName, DisableAddOn
Nenue@66 69
Nenue@9 70 local db
Nenue@13 71 local defaults = {
Nenue@66 72 global = {{}, {}},
Nenue@66 73 default_channel = {
Nenue@55 74 signature = 'Main',
Nenue@55 75 x = 100, y = 800,
Nenue@55 76 height = 500, width = 600,
Nenue@66 77 enabled = true},
Nenue@66 78 current_profile = 1,
Nenue@66 79 main_profile = 1,
Nenue@66 80 last_profile = 1,
Nenue@66 81 profilesName = {},
Nenue@66 82 profiles = {
Nenue@45 83 },
Nenue@33 84 font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]], -- font info
Nenue@13 85 fontsize = 13,
Nenue@13 86 fontoutline = 'NONE',
Nenue@45 87
Nenue@45 88 headergrad = {'VERTICAL', 0, 0, 0, 1,
Nenue@45 89 1, 0.1, 0.1, 1}, -- header info
Nenue@33 90 headerdrop = {1,1,1,1},
Nenue@45 91 headerblend = 'BLEND',
Nenue@33 92 headeralpha = 1,
Nenue@45 93 headerfontcolor = {1,1,1,1},
Nenue@45 94
Nenue@45 95 backdrop = {1,1,1,1}, -- background frame info
Nenue@56 96 backgrad = {'VERTICAL', 0, 0, 0, .75, 0,0,0, .65},
Nenue@55 97 backblend = 'BLEND',
Nenue@45 98 backalpha = 1,
Nenue@45 99 backborder = {.5,.5,.5,1},
Nenue@45 100 backheader = {.25,.25,.25,1},
Nenue@45 101
Nenue@45 102 frontdrop = {1,1,1,1}, -- foreground frame info
Nenue@56 103 frontgrad = {'VERTICAL', 0, 0, 0, 1, 0,0,0, 0.95},
Nenue@55 104 frontblend = 'BLEND',
Nenue@28 105 frontalpha = 1,
Nenue@45 106 frontborder = {.07,.47,1,1},
Nenue@45 107 frontheader = {1,1,1,1},
Nenue@33 108 tagcolor = {}, -- tag color repository
Nenue@36 109 workspace = 2, -- current profile
Nenue@47 110 last_workspace = 2, -- default workspace to alternate with when just "/dvn" is issued
Nenue@47 111
Nenue@47 112 dock_onshow_fade_time = 2.5,
Nenue@47 113 dock_onshow_fade_from = 1,
Nenue@47 114 dock_onshow_fade_to = 0.2,
Nenue@47 115
Nenue@47 116 dock_alpha_on = 1,
Nenue@47 117 dock_alpha_off = 0.2,
Nenue@47 118 dock_fade_in = 0.15,
Nenue@47 119 dock_fade_out = 0.45,
Nenue@47 120 dock_button_alpha_on = 1,
Nenue@47 121 dock_button_alpha_off = 0.2,
Nenue@50 122 dock_button_fade_in = 0.075,
Nenue@55 123 dock_button_fade_out = 0.075,
Nenue@47 124
Nenue@55 125 movement_fade = true,
Nenue@55 126 movement_fade_time = 0.15,
Nenue@60 127 movement_fade_from = 1,
Nenue@60 128 movement_fade_to = 0,
Nenue@60 129 movement_translation_x = 25,
Nenue@60 130 movement_translation_y = 25,
Nenue@13 131 }
Nenue@9 132
Nenue@66 133 D.console = {}
Nenue@66 134 D.max_channel = 0
Nenue@0 135
Nenue@67 136 D.InWorkspace = function ()
Nenue@67 137 return db.profiles[db.current_profile].workspace
Nenue@67 138 end
Nenue@67 139
Nenue@86 140 local profileTemplate = {
Nenue@86 141 name = function(id, name) return name end,
Nenue@86 142 workspace = function(id, name) return (id ~= 1) end,
Nenue@86 143 current_channel = 1,
Nenue@86 144 default_channel = 1,
Nenue@86 145 num_channels = 1,
Nenue@86 146 max_channel = 1, -- the highest created channel id
Nenue@86 147 enabled = true, -- allow enabled consoles to appear
Nenue@86 148 channels = {
Nenue@86 149 {
Nenue@86 150 index = 1,
Nenue@86 151 signature = 'Main',
Nenue@86 152 x = 100, y = 800,
Nenue@86 153 height = 500, width = 600,
Nenue@86 154 enabled = true
Nenue@86 155 }
Nenue@86 156 },
Nenue@86 157 loadouts = {},
Nenue@86 158 global = {},
Nenue@86 159 tags = {},
Nenue@86 160 char = {
Nenue@86 161 [playerRealm] = {}
Nenue@86 162 },
Nenue@86 163 unlisted = {}
Nenue@86 164 }
Nenue@86 165
Nenue@86 166 --- Applies complex template tables
Nenue@86 167 -- If he value is a function, then it will invoke f(...) and use whatever gets returned
Nenue@86 168 function D.DeepCopy(src, dest, ...)
Nenue@86 169
Nenue@86 170 for k,v in pairs(src) do
Nenue@86 171 if not dest[k] then
Nenue@93 172 --oldprint('Rebuilding conf value', k)
Nenue@86 173 if type(v) == 'table' then
Nenue@86 174 dest[k] = {}
Nenue@86 175 D.DeepCopy(v, dest[k], ...)
Nenue@86 176
Nenue@86 177 else
Nenue@86 178 if type(v) == 'function' then
Nenue@86 179 v = v(...)
Nenue@86 180 end
Nenue@86 181 dest[k] = v
Nenue@86 182 end
Nenue@86 183 end
Nenue@86 184 end
Nenue@86 185 end
Nenue@86 186
Nenue@66 187 D.Profile = function (id, name)
Nenue@66 188
Nenue@66 189 if name and not id and db.profilesName[name] then
Nenue@66 190 id = db.profilesName[name]
Nenue@66 191 print('ID located by name, |cFF00FF00'..name..'|r is |cFFFFFF00'.. id..'|r')
Nenue@66 192 end
Nenue@66 193
Nenue@66 194 if not id or not db.profiles[id] then
Nenue@66 195 if not id then
Nenue@66 196 id = #db.profiles+1
Nenue@66 197 print('Generated profile ID: |cFFFFFF00'.. id .. '|r')
Nenue@66 198 end
Nenue@66 199
Nenue@66 200 if not name or db.profilesName[name] then
Nenue@66 201 local newName = name or (id == 1 and 'Main' or 'Profile')
Nenue@66 202 local prefix = newName
Nenue@66 203 local i = 2
Nenue@66 204 while db.profilesName[newName] do
Nenue@66 205 i = i + 1
Nenue@66 206 newName = prefix .. i
Nenue@66 207 end
Nenue@66 208 name = newName
Nenue@66 209 print('Generated profile name: |cFF00FF00'..newName..'|r')
Nenue@66 210 end
Nenue@86 211
Nenue@86 212
Nenue@86 213
Nenue@66 214 print('Creating profile')
Nenue@66 215 db.profilesName[name] = id
Nenue@86 216 db.profiles[id] = {}
Nenue@66 217 end
Nenue@66 218
Nenue@86 219
Nenue@86 220
Nenue@66 221 D.currentProfile = db.profiles[id]
Nenue@66 222 currentProfile = D.currentProfile
Nenue@86 223
Nenue@86 224 D.DeepCopy(profileTemplate, currentProfile, id, name)
Nenue@86 225
Nenue@86 226
Nenue@66 227 currentProfile.char[playerRealm] = currentProfile.char[playerRealm] or {}
Nenue@66 228 if currentProfile.workspace then
Nenue@79 229 DEVIAN_WORKSPACE = true
Nenue@91 230 DEVIAN_PNAME = currentProfile.name
Nenue@89 231 DEVIAN_PID = id
Nenue@66 232 setprinthandler(D.Message)
Nenue@66 233 else
Nenue@79 234 DEVIAN_WORKSPACE = false
Nenue@93 235 DEVIAN_PNAME = nil
Nenue@93 236 print = nop
Nenue@66 237 end
Nenue@89 238 DEVIAN_PID =id
Nenue@66 239
Nenue@66 240 D.unlisted = currentProfile.unlisted
Nenue@66 241 D.channels = currentProfile.channels
Nenue@66 242 D.tags = currentProfile.tags
Nenue@66 243 D.channelinfo = currentProfile.channels
Nenue@66 244 D.char = currentProfile.char[playerRealm]
Nenue@66 245 D.global = currentProfile.global
Nenue@66 246 D.num_channels = currentProfile.num_channels
Nenue@66 247 D.enabled = currentProfile.enabled
Nenue@66 248 D.sig = {}
Nenue@66 249 D.sigID = {}
Nenue@66 250 D.IDsig = {}
Nenue@72 251 D.dock = _G.DevianDock
Nenue@66 252 D.dock.buttons = D.dock.buttons or {}
Nenue@66 253
Nenue@66 254 return id, name
Nenue@66 255 end
Nenue@66 256
Nenue@66 257 local targetGlobal, targetChar
Nenue@86 258 D.Command = function (cmd)
Nenue@66 259 local list_id, scan_func, reload
Nenue@86 260
Nenue@14 261 local args = {}
Nenue@86 262 if cmd then
Nenue@86 263 local i, j = 0, 0
Nenue@86 264 repeat
Nenue@86 265 i, j = cmd:find("%S+", j+1)
Nenue@86 266 if i and j then
Nenue@86 267 tinsert(args, cmd:sub(i, j))
Nenue@86 268 end
Nenue@86 269
Nenue@86 270 until not(i or j)
Nenue@14 271 end
Nenue@14 272 local mode, tag, dest = unpack(args)
Nenue@0 273
Nenue@86 274
Nenue@14 275 -- no args, toggle ui
Nenue@86 276 if mode == 'rc' then
Nenue@93 277 return D:ResetChannels(tag)
Nenue@86 278 elseif mode == 'stack' then
Nenue@14 279 return D:StackFrames()
Nenue@14 280 elseif mode == 'grid' then
Nenue@14 281 return D:DistributeFrames()
Nenue@14 282 elseif mode == 'tag' then -- tagging
Nenue@93 283 return D:Tag(tag, dest)
Nenue@73 284 elseif mode == 'new' then
Nenue@93 285 return D:New(tag)
Nenue@93 286 elseif mode == 'dock' then
Nenue@93 287 D.db.dockPoint = tag
Nenue@93 288 return D:UpdateDock()
Nenue@73 289 elseif mode == 'remove' then
Nenue@93 290 return D:Remove(tag)
Nenue@89 291 elseif mode ~= nil then
Nenue@89 292 -- profile selector or save command
Nenue@66 293 if mode == 'save' then
Nenue@66 294 list_id = tonumber(tag)
Nenue@89 295 else
Nenue@89 296 list_id = tonumber(mode)
Nenue@89 297 end
Nenue@89 298
Nenue@89 299 if not list_id then
Nenue@89 300 if db.profilesName[tostring(list_id)] then
Nenue@89 301 list_id = db.profilesName[tostring(list_id)]
Nenue@89 302 else
Nenue@89 303
Nenue@89 304 D:Print(L('Unable to resolve profile ID/name', list_id, dest))
Nenue@89 305 return
Nenue@66 306 end
Nenue@89 307 end
Nenue@89 308
Nenue@89 309
Nenue@89 310 if mode == 'save' then
Nenue@66 311 D.Profile(list_id, dest)
Nenue@66 312 scan_func = D.Save
Nenue@89 313
Nenue@89 314
Nenue@89 315 local name = currentProfile.name
Nenue@89 316 if dest then
Nenue@89 317 dest = dest:gsub("$%s+", ''):gsub("%s+^", '')
Nenue@89 318 if dest then
Nenue@89 319 if name then
Nenue@89 320 db.profilesName[name] = nil
Nenue@89 321 end
Nenue@89 322 db.profiles[list_id].name = dest
Nenue@89 323 db.profilesName[dest] = list_id
Nenue@92 324
Nenue@92 325 name = dest
Nenue@89 326 end
Nenue@89 327 end
Nenue@89 328
Nenue@89 329
Nenue@89 330 D:Print("Profile |cFFFFFF00".. list_id .."|r:|cFF00FFFF".. name .."|r saved.")
Nenue@66 331 else
Nenue@32 332
Nenue@89 333 if db.profiles[list_id] then
Nenue@89 334 D.LoadMessage ("Switched profiles.")
Nenue@89 335 if list_id ~= db.main_profile then
Nenue@89 336 db.last_profile = list_id
Nenue@89 337 end
Nenue@89 338 db.current_profile = list_id
Nenue@89 339 scan_func = D.Load
Nenue@89 340 else
Nenue@89 341 return D:PrintHelp()
Nenue@89 342 end
Nenue@36 343
Nenue@0 344 end
Nenue@32 345 elseif mode == nil then
Nenue@66 346 list_id = (db.current_profile ~= db.main_profile) and db.main_profile or db.last_profile
Nenue@77 347 D.LoadMessage ("Switched between main and recent profile ("..db.current_profile..' and '..list_id..')')
Nenue@66 348 db.current_profile = list_id
Nenue@66 349 scan_func = D.Load
Nenue@32 350 else
Nenue@89 351
Nenue@89 352
Nenue@32 353 return D:PrintHelp()
Nenue@0 354 end
Nenue@77 355
Nenue@77 356 if not db.profiles[list_id] then
Nenue@77 357 db.profiles[list_id] = {global = {}, char = {} }
Nenue@77 358 D.LoadMessage ("Starting profile #|cFF00FFFF".. list_id..'|r')
Nenue@77 359 end
Nenue@67 360 if not db.profiles[list_id].char[playerRealm] then
Nenue@67 361 db.profiles[list_id].char[playerRealm] = {}
Nenue@67 362 end
Nenue@67 363
Nenue@66 364 targetGlobal = db.profiles[list_id].global
Nenue@66 365 targetChar = db.profiles[list_id].char[playerRealm]
Nenue@32 366
Nenue@67 367
Nenue@66 368 if scan_func then
Nenue@93 369 wipe(charStates)
Nenue@66 370 for id, name, enableState, globalState in D.Addons() do
Nenue@66 371 scan_func(id, name, enableState, globalState)
Nenue@0 372 end
Nenue@0 373 end
Nenue@0 374
Nenue@66 375 if scan_func == D.Load then
Nenue@72 376 _G.ReloadUI()
Nenue@93 377 if AddonList_Update then
Nenue@93 378 AddonList_Update()
Nenue@93 379 end
Nenue@93 380 elseif (scan_func == D.Save) then
Nenue@93 381 print('reckoning')
Nenue@93 382 local updated = {}
Nenue@93 383 for addon, newState in pairs(charStates) do
Nenue@93 384 for character, addons in pairs(db.profiles[list_id].char) do
Nenue@93 385 if addons[addon] then
Nenue@93 386 print(addon, addons[addon], '::', newState)
Nenue@93 387 if (addons[addon] ~= newState) then
Nenue@93 388 addons[addon] = newState
Nenue@93 389 updated[character] = (updated[character] or 0) + 1
Nenue@93 390 end
Nenue@93 391
Nenue@93 392 end
Nenue@93 393
Nenue@93 394 end
Nenue@93 395 end
Nenue@93 396 for character, numAddons in pairs(updated) do
Nenue@93 397 print(character, numAddons, 'settings')
Nenue@93 398 end
Nenue@93 399
Nenue@66 400 end
Nenue@93 401
Nenue@93 402
Nenue@66 403 D.Profile(db.current_profile)
Nenue@66 404 end
Nenue@66 405
Nenue@66 406 D.Addons = function()
Nenue@66 407 local playername = UnitName("player")
Nenue@66 408 return function(n, i)
Nenue@66 409 if i >= n then
Nenue@66 410 return nil
Nenue@66 411 end
Nenue@66 412
Nenue@66 413 i = i + 1
Nenue@66 414 local name = GetAddOnInfo(i)
Nenue@66 415 local enableState, globalState = GetAddOnEnableState(playername, i), GetAddOnEnableState(nil, i)
Nenue@66 416 return i, name, enableState, globalState
Nenue@66 417 end, GetNumAddOns(), 0
Nenue@66 418 end
Nenue@66 419
Nenue@66 420 D.Load = function(id, name, charState, globalState)
Nenue@93 421 print('load', tostring(name), tostring(charState), tostring(globalState))
Nenue@93 422 if targetGlobal[name] == 2 then
Nenue@93 423 EnableAddOn(id, true)
Nenue@93 424 elseif targetChar[name] == 2 then
Nenue@93 425 EnableAddOn(id, playerName)
Nenue@93 426 elseif targetGlobal[name] == 0 then
Nenue@93 427 DisableAddOn(id, true)
Nenue@93 428 elseif targetChar[name] == 0 then
Nenue@93 429 DisableAddOn(id, playerName)
Nenue@93 430 end
Nenue@93 431
Nenue@93 432 if not (targetChar[name] or targetGlobal[name]) then
Nenue@66 433 tinsert(D.unlisted, name)
Nenue@66 434 end
Nenue@93 435
Nenue@66 436 end
Nenue@93 437
Nenue@93 438
Nenue@66 439 D.Save = function(id, name, charState, globalState)
Nenue@93 440 if (charState ~= 0) or (globalState ~= 0) then
Nenue@93 441 print('save', id, name, playerRealm .. ': '.. charState, 'All: '.. globalState)
Nenue@93 442 end
Nenue@93 443
Nenue@66 444 targetGlobal[name] = globalState
Nenue@66 445 targetChar[name] = charState
Nenue@93 446
Nenue@93 447 -- if enabling/disabling globally
Nenue@93 448 if globalState ~= 1 then
Nenue@93 449 charStates[name] = globalState
Nenue@93 450 end
Nenue@66 451 end
Nenue@57 452
Nenue@66 453 D.Tag = function(self, tag, dest)
Nenue@66 454 local sig
Nenue@66 455 if tag ~= nil and dest ~= nil then
Nenue@66 456 --@debug@
Nenue@66 457 --print(tag, dest)
Nenue@66 458 --@end-debug@
Nenue@66 459
Nenue@66 460 -- convert to ID
Nenue@66 461 if tonumber(dest) == nil then
Nenue@66 462 if D.sigID[dest] then
Nenue@66 463 dest = currentProfile.channels[D.sigID[dest]].index
Nenue@66 464 else
Nenue@66 465 sig = dest
Nenue@66 466 end
Nenue@57 467 else
Nenue@66 468 dest = tonumber(dest)
Nenue@32 469 end
Nenue@66 470 --@debug@
Nenue@66 471 --print('2 tag,dest,sig', tag, dest, sig)--@end-debug@
Nenue@66 472
Nenue@66 473 -- make a new channel?
Nenue@66 474 local channel
Nenue@66 475 if not currentProfile.channels[dest] then
Nenue@66 476 dest = D.max_channel + 1
Nenue@66 477 D:Print(L('New channel created', sig and (dest..':'..sig) or dest ))
Nenue@66 478 channel = D:SetChannel(sig or tag,dest)
Nenue@66 479 else
Nenue@66 480 channel = D.channels[dest]
Nenue@66 481 end
Nenue@66 482 --@debug@
Nenue@66 483 --print('3 tag,dest,channel.sig=',tag, dest, channel.signature)--@end-debug@
Nenue@66 484
Nenue@66 485 if not currentProfile.tags[tag] then -- no tag table?
Nenue@66 486 currentProfile.tags[tag] = {}
Nenue@66 487 end
Nenue@66 488
Nenue@66 489 if currentProfile.tags[tag][dest] then -- is tag set?
Nenue@66 490 currentProfile.tags[tag][dest] = nil
Nenue@66 491 D:Print(L('Tag removed from channel', tag, currentProfile.channels[dest].index, currentProfile.channels[dest].signature))
Nenue@66 492 else
Nenue@66 493 currentProfile.tags[tag][dest] = dest
Nenue@66 494 D:Print(L('Tag added to channel', tag, currentProfile.channels[dest].index, currentProfile.channels[dest].signature))
Nenue@66 495 end
Nenue@66 496 D:UpdateDock()
Nenue@66 497 else
Nenue@66 498 D:Print(L['Command tag help'])
Nenue@0 499 end
Nenue@0 500 end
Nenue@0 501
Nenue@86 502 D.ResetChannels = function(self, profile)
Nenue@86 503 currentProfile.current_channel = 1
Nenue@86 504 currentProfile.primary_channel = 1
Nenue@86 505 currentProfile.channels = {}
Nenue@86 506 D.DeepCopy(profileTemplate.channels, currentProfile.channels)
Nenue@86 507 currentProfile.tags = {}
Nenue@86 508 D.LoadMessage('Profile reset.')
Nenue@86 509 ReloadUI()
Nenue@86 510 end
Nenue@86 511
Nenue@73 512 D.New = function(self, tag)
Nenue@73 513 if tag and not self.sigID[tag] then
Nenue@73 514 local id = D.max_channel + 1
Nenue@73 515 D.SetChannel(tag, id)
Nenue@73 516 end
Nenue@73 517 end
Nenue@0 518
Nenue@73 519 D.Remove = function(self, dest)
Nenue@73 520 dest = D.sigID[dest] or tonumber(dest)
Nenue@73 521 if D.console[dest] and D.channels[dest] then
Nenue@73 522 for tag, tagDest in pairs(D.tags) do
Nenue@73 523 for i = #tagDest, 0 do
Nenue@73 524 -- work downward so we aren't skipping entries
Nenue@73 525 if tagDest[i] == dest then
Nenue@73 526 tremove(tagDest, i)
Nenue@73 527 end
Nenue@73 528 end
Nenue@73 529 end
Nenue@73 530 D.console[dest]:Hide()
Nenue@73 531 D.channels[dest] = nil
Nenue@73 532 tremove(D.console, dest)
Nenue@93 533 D.dock.buttons[dest]:SetShown(false)
Nenue@73 534 D:UpdateDock()
Nenue@73 535 D:Print('Removed channel #'..dest)
Nenue@73 536 end
Nenue@73 537 end
Nenue@13 538
Nenue@77 539 --- Queue up a message to appear after UI reload
Nenue@77 540 function D.LoadMessage(msg)
Nenue@77 541
Nenue@77 542 tinsert(_G.DevianLoadMessage, msg)
Nenue@77 543 end
Nenue@77 544
Nenue@18 545 --- Creates a Devian-style output.
Nenue@18 546 -- The first argument describes the channel to output on, and the remaining arguments are concatenated in a manner similar to default print()
Nenue@18 547 -- This becomes the print handler when development mode is active. The original print() function is assigned to oldprint().
Nenue@18 548 -- @param Tag, signature, or numeric index of the channel to output on. Defaults to primary channel.
Nenue@18 549 -- @param ... Output contents.
Nenue@72 550
Nenue@66 551 function D.Message(prefix, ...)
Nenue@67 552 if not currentProfile.workspace then
Nenue@23 553 return D.oldprint(prefix, ...)
Nenue@23 554 end
Nenue@57 555 prefix = tostring(prefix)
Nenue@57 556 if prefix == nil then
Nenue@55 557 prefix = 'nil*'
Nenue@1 558 end
Nenue@9 559
Nenue@18 560 local sendq = {}
Nenue@30 561 local tag, id, tagged
Nenue@13 562 local byName = true
Nenue@18 563 if D.tags[prefix] then
Nenue@18 564 for _, id in pairs(D.tags[prefix]) do
Nenue@18 565 if D.console[id] then
Nenue@18 566 sendq[id] = D.console[id]
Nenue@30 567 tagged = true
Nenue@18 568 end
Nenue@18 569 end
Nenue@18 570 end
Nenue@18 571
Nenue@13 572 if D.sig[prefix] then
Nenue@18 573 sendq[D.sig[prefix].index] = D.sig[prefix]
Nenue@13 574 elseif D.console[prefix] then
Nenue@18 575 sendq[D.console[prefix]] = D.console[prefix]
Nenue@30 576 elseif not tagged then
Nenue@18 577 sendq[D.primary_channel] = D.console[D.primary_channel]
Nenue@13 578 end
Nenue@18 579
Nenue@9 580 -- color me timbers
Nenue@9 581 local pcolor
Nenue@18 582 if (not db.tagcolor[prefix]) and byName then
Nenue@86 583 -- numbers, use white
Nenue@86 584 if prefix:match('^%d+%.%d+') then
Nenue@73 585 pcolor = 'FFFFFF'
Nenue@73 586 else
Nenue@73 587 local c = {
Nenue@73 588 rand(64,255), rand(64,255), rand(64,255)
Nenue@73 589 }
Nenue@73 590 if c[1] > 223 and c[2] > 223 and c[3] > 223 then
Nenue@73 591 c[rand(1,3)] = rand(64,223)
Nenue@73 592 end
Nenue@73 593 db.tagcolor[prefix] = format('%02X%02X%02X', unpack(c))
Nenue@73 594 pcolor = db.tagcolor[prefix]
Nenue@0 595 end
Nenue@73 596 else
Nenue@73 597 pcolor = db.tagcolor[prefix]
Nenue@0 598 end
Nenue@0 599
Nenue@55 600 local buffer = {}
Nenue@0 601 for i = 1, select('#',...) do
Nenue@0 602 local var = select(i, ...)
Nenue@0 603
Nenue@0 604 if type(var) == 'table' then
Nenue@20 605 if type(var.GetName) == 'function' then
Nenue@72 606 var = '[table:'..tostring(var:GetName())..']'
Nenue@20 607 else
Nenue@32 608 var = '<'..tostring(var)..'>'
Nenue@20 609 end
Nenue@20 610
Nenue@0 611 elseif type(var) == 'boolean' then
Nenue@75 612 var = var and 'true' or 'false'
Nenue@0 613 elseif type(var) == 'function' then
Nenue@72 614 var = '['..tostring(var)..']'
Nenue@0 615 elseif type(var) == 'nil' then
Nenue@75 616 var = 'nil'
Nenue@60 617 else
Nenue@60 618 var = tostring(var)
Nenue@0 619 end
Nenue@0 620
Nenue@47 621 insert(buffer, var)
Nenue@0 622 end
Nenue@47 623 local message = concat(buffer, ' ')
Nenue@18 624 for id, channel in pairs(sendq) do
Nenue@55 625 if channel.width < 250 then
Nenue@72 626 prefix = sub(prefix, 0,2)
Nenue@55 627 end
Nenue@73 628 --currentProfile.last_channel = channel.index
Nenue@58 629 channel.out:AddMessage('|cFF'.. pcolor..prefix ..'|r ' .. message, 0.8, 0.8, 0.8, nil, nil, prefix, GetTime())
Nenue@93 630 if not D.dock.usedButtons[id].newMessage then
Nenue@93 631 D.dock.usedButtons[id].newMessage = true
Nenue@93 632 D.dock.usedButtons[id].caption.pulse:Play()
Nenue@93 633 D.dock.usedButtons[id]:Update()
Nenue@58 634 end
Nenue@18 635 end
Nenue@47 636 wipe(buffer)
Nenue@0 637 end
Nenue@0 638
Nenue@14 639
Nenue@32 640
Nenue@14 641
Nenue@32 642 function D:PrintHelp()
Nenue@32 643 D:Print("|cFFFFFF00/dvn|r",
Nenue@32 644 "\n |cFFFFFF00<number>|r - Loads a saved addon list. List 1 is treated as a gameplay profile and consoles will be disabled by default.")
Nenue@47 645 D:Print("|cFFFFFF00/dvc|r [<key>, ...]", "- Hides and show consoles. A list of channel keys can be passed to specify which ones get toggled.")
Nenue@32 646
Nenue@32 647 D:Print("|cFFFFFF00/resetdvn|r", "- Resets all but profile data SavedVariables.")
Nenue@32 648 D:Print("|cFFFFFF00/cleandvn|r", "- Fully resets SavedVariables, profiles and all.")
Nenue@32 649 end
Nenue@32 650
Nenue@66 651 local blocked = {profiles = true, debugmode = true}
Nenue@66 652 D.SetDefaults = function()
Nenue@72 653 local DevianDB = _G.DevianDB
Nenue@66 654 for k,v in pairs(DevianDB) do
Nenue@66 655 if not blocked[k] then
Nenue@66 656 DevianDB[k] = nil
Nenue@60 657 end
Nenue@60 658 end
Nenue@66 659 for k,v in pairs(defaults) do
Nenue@66 660 if not blocked[k] then
Nenue@66 661 DevianDB[k] = v
Nenue@60 662 end
Nenue@60 663 end
Nenue@73 664
Nenue@77 665 D.LoadMessage "Non-user SavedVars have been reset."
Nenue@72 666 _G.ReloadUI()
Nenue@60 667 end
Nenue@66 668 D.SetDefaultsAll = function ()
Nenue@72 669 _G.DevianDB = nil
Nenue@77 670 D.LoadMessage "All SavedVars wiped."
Nenue@72 671 _G.ReloadUI()
Nenue@66 672 end
Nenue@73 673
Nenue@73 674 D.UnsetColors = function()
Nenue@73 675 db.tagcolor = {}
Nenue@73 676 D:Print('Tag color cache cleared.')
Nenue@73 677 end
Nenue@45 678
Nenue@33 679
Nenue@89 680 function D.ConsoleCommand (cmd)
Nenue@89 681 D:Console_Toggle(cmd)
Nenue@89 682 end
Nenue@87 683
Nenue@66 684
Nenue@66 685 function D:OnInitialize()
Nenue@81 686 L = D.L
Nenue@13 687
Nenue@33 688 -- pull defaults
Nenue@9 689 if not _G.DevianDB then
Nenue@13 690 _G.DevianDB = defaults
Nenue@9 691 end
Nenue@9 692 db = _G.DevianDB
Nenue@47 693 self.db = db
Nenue@0 694
Nenue@66 695 ---
Nenue@77 696 if #_G.DevianLoadMessage >= 1 then
Nenue@77 697 for i, msg in ipairs(_G.DevianLoadMessage) do
Nenue@77 698 D:Print(msg)
Nenue@77 699 end
Nenue@77 700
Nenue@77 701 table.wipe(_G.DevianLoadMessage)
Nenue@0 702 end
Nenue@0 703
Nenue@66 704
Nenue@89 705 -- commands
Nenue@89 706 local cmdlist = {
Nenue@89 707 ['dvn'] = "Command",
Nenue@89 708 ['devian'] = "Command",
Nenue@89 709 ['dvc'] = "ConsoleCommand",
Nenue@89 710 ['dvncolors'] = "UnsetColors",
Nenue@89 711 ['cleandvn'] = "SetDefaultsAll",
Nenue@89 712 ['resetdvn'] = "SetDefaults",
Nenue@89 713 }
Nenue@89 714 for cmd, func in pairs(cmdlist) do
Nenue@89 715 local CMD = cmd:upper()
Nenue@89 716 _G['SLASH_' .. CMD .. '1'] = "/"..cmd
Nenue@89 717
Nenue@89 718 if type(func == 'string') then
Nenue@93 719 --print('SLASH_' .. CMD .. '1','/'.. cmd, func)
Nenue@89 720 SlashCmdList[CMD] = D[func]
Nenue@89 721 else
Nenue@93 722 --print('SLASH_' .. CMD .. '1','/'.. cmd, func)
Nenue@89 723 SlashCmdList[CMD] = func
Nenue@89 724 end
Nenue@89 725 end
Nenue@89 726
Nenue@66 727 --- initialize the current profile
Nenue@66 728 local id, name = D.Profile(db.current_profile or 1)
Nenue@66 729 D:Print('Using profile |cFFFFFF00'.. id ..'|r: |cFF00FF00'..currentProfile.name..'|r')
Nenue@66 730 if currentProfile.workspace then
Nenue@66 731 D:Print('Workspace: '.. (#currentProfile.channels) .. ' channels, ' .. #currentProfile.tags .. ' tags.')
Nenue@86 732 if D.channels[currentProfile.default_channel] then
Nenue@86 733 D:Print('Default channel: |cFFFFFF00'..currentProfile.default_channel..'|r: |cFF00FFFF'.. D.channels[currentProfile.default_channel].signature..'|r')
Nenue@86 734 end
Nenue@0 735 end
Nenue@13 736
Nenue@86 737
Nenue@66 738 for i, cinfo in pairs(D.channels) do
Nenue@14 739 i = tonumber(i)
Nenue@66 740 if not D.primary_channel then
Nenue@66 741 D.primary_channel = i
Nenue@14 742 end
Nenue@66 743 D:SetChannel(cinfo, i)
Nenue@66 744 D.num_channels = D.num_channels + 1
Nenue@32 745 end
Nenue@86 746 D.primary_channel = D.primary_channel or 1
Nenue@32 747
Nenue@66 748 D.max_channel = max(D.max_channel, currentProfile.max_channel)
Nenue@66 749 if currentProfile.max_channel < D.max_channel then
Nenue@66 750 for i = currentProfile.max_channel, D.max_channel do
Nenue@66 751 D.console[i]:Hide()
Nenue@47 752 end
Nenue@36 753 end
Nenue@36 754
Nenue@66 755 if currentProfile.workspace then
Nenue@66 756 if D.console[currentProfile.current_channel] then
Nenue@69 757 --print('bringing', D.console[currentProfile.current_channel].signature, 'to the front')
Nenue@66 758 D.console[currentProfile.current_channel]:ToFront()
Nenue@66 759 -- bring the current channel to the front
Nenue@47 760 end
Nenue@72 761 _G.DevianDock:Show()
Nenue@66 762 D:UpdateDock()
Nenue@36 763 end
Nenue@66 764 end
Nenue@89 765