annotate Devian.lua @ 34:7441f3bce940

Debugging pass on console code.
author Nenue
date Sun, 27 Dec 2015 02:33:06 -0500
parents e6650821a2c0
children 3304455a3f45
rev   line source
Nenue@32 1 --- ${PACKAGE_NAME}
Nenue@32 2 -- @file-author@
Nenue@32 3 -- @project-revision@ @project-hash@
Nenue@32 4 -- @file-revision@ @file-hash@
Nenue@0 5 if not LibStub then
Nenue@0 6 print('Something has happened...')
Nenue@0 7 end
Nenue@0 8 Devian = LibStub("AceAddon-3.0"):NewAddon("Devian", "AceConsole-3.0", "AceEvent-3.0")
Nenue@13 9 local MAJOR, MINOR = 'Devian-1.3', 'r@project-revision@'
Nenue@0 10 local D = _G.Devian
Nenue@32 11 local WORKSPACE_ON, WORKSPACE_OFF = 1, 2
Nenue@0 12 local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName()
Nenue@13 13 local DEVIAN_FRAME = 'DevianConsole'
Nenue@33 14 local DEVIAN_DOCK_FRAME = 'DevianDockFrame'
Nenue@33 15 local MSG_NEED_DEV_MODE = 'Must be in development mode to use this function.'
Nenue@18 16 local print = _G.print
Nenue@9 17 local db
Nenue@13 18 local defaults = {
Nenue@32 19 ['global'] = {{}, {}},
Nenue@13 20 ['tags'] = {},
Nenue@32 21 ['channels'] = {[1] = {signature = 'Main', index = 1, x = 100, y = 800, height = 500, width = 600, enabled = true}},
Nenue@33 22 primary_channel = 1, -- the channel to which default output is sent
Nenue@33 23 current_channel = 1, -- the front channel
Nenue@33 24 max_channel = 1, -- the highest created channel id
Nenue@33 25 enable = true, -- allow enabled consoles to appear
Nenue@33 26 load_message = "Defaults loaded.", -- messages to be displayed after reload
Nenue@33 27 font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]], -- font info
Nenue@13 28 fontsize = 13,
Nenue@13 29 fontoutline = 'NONE',
Nenue@33 30 headergrad = {'VERTICAL', 0, 0, 0, 0.5, 0.1, 0.1, 0.1, 0.3}, -- header info
Nenue@33 31 headerdrop = {1,1,1,1},
Nenue@33 32 headeralpha = 1,
Nenue@33 33 backdrop = {0,0,0,1}, -- background frame info
Nenue@14 34 backgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.3, 0, 0, 0, 0.5},
Nenue@33 35 backblend = 'MOD',
Nenue@33 36 backalpha = 0.7,
Nenue@33 37 backborder = {0,0,1,0.75},
Nenue@33 38 frontdrop = {0,0,0,1}, -- foreground frame info
Nenue@14 39 frontgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.9, 0, 0, 0, 0.9},
Nenue@33 40 frontblend = 'MOD',
Nenue@28 41 frontalpha = 1,
Nenue@22 42 frontborder = {1,0,0,1},
Nenue@33 43 tagcolor = {}, -- tag color repository
Nenue@33 44 workspace = 1, -- current profile
Nenue@33 45 last_workspace = 2 -- default workspace to alternate with when just "/dvn" is issued
Nenue@13 46 }
Nenue@9 47
Nenue@4 48
Nenue@13 49 local function ScanAddOnList(cmd, ...)
Nenue@0 50 local list_state
Nenue@0 51
Nenue@14 52 local args = {}
Nenue@14 53 local arg, n = D:GetArgs(cmd, 1)
Nenue@14 54 while arg do
Nenue@14 55 table.insert(args, arg)
Nenue@14 56 arg, n = D:GetArgs(cmd,1,n)
Nenue@14 57 end
Nenue@14 58 local mode, tag, dest = unpack(args)
Nenue@0 59
Nenue@13 60
Nenue@14 61 -- no args, toggle ui
Nenue@32 62 if mode == 'dock' then
Nenue@33 63 if db.workspace == 1 then
Nenue@33 64 D:Print('Must be in dev mode to use this.')
Nenue@33 65 return
Nenue@33 66 end
Nenue@32 67 if #args <= 2 then
Nenue@32 68 D:Print("Not enough arguments for dock command.")
Nenue@32 69 return
Nenue@32 70 end
Nenue@0 71
Nenue@32 72 local target
Nenue@32 73 local worklist = {}
Nenue@32 74 for i = 2, #args do
Nenue@32 75 local ch
Nenue@32 76 local k = tostring(args[i])
Nenue@32 77 local j = tonumber(args[i])
Nenue@32 78 if db.channels[j] then
Nenue@32 79 ch = db.channels[j]
Nenue@32 80 elseif D.sig[k] then
Nenue@32 81 ch = D.sig[k]
Nenue@32 82 elseif D.sigID[k] then
Nenue@32 83 ch = db.channels[D.sigID[k]]
Nenue@32 84 elseif db.tags[k] and db.tags[k][1] then
Nenue@32 85 ch = db.channels[db.tags[j][1]]
Nenue@32 86 -- last resort
Nenue@32 87 else
Nenue@32 88 D:Print('No entry for argument #'..i..': '..tostring(args[i]))
Nenue@32 89 return
Nenue@32 90 end
Nenue@32 91 oldprint(i, '->', ch.index, '-', ch.signature)
Nenue@32 92 if i > 2 then
Nenue@32 93 table.insert(worklist, ch.index)
Nenue@32 94 else
Nenue@32 95 target = ch
Nenue@32 96
Nenue@32 97 oldprint('arg1', args[2], target)
Nenue@32 98 end
Nenue@0 99 end
Nenue@32 100 D:Print("Docking |cFF88FFFF"..table.concat(worklist, "|r, |cFF88FFFF").."|r with |cFFFFFF00"..target.index..', '..target.signature.."|r.")
Nenue@32 101 return D:DockFrame(target.index, unpack(worklist))
Nenue@32 102
Nenue@32 103
Nenue@14 104 elseif mode == 'stack' then
Nenue@33 105 if db.workspace == 1 then
Nenue@33 106 return D:Print(MSG_NEED_DEV_MODE)
Nenue@33 107 end
Nenue@14 108 return D:StackFrames()
Nenue@14 109 elseif mode == 'grid' then
Nenue@33 110 if db.workspace == 1 then
Nenue@33 111 return D:Print(MSG_NEED_DEV_MODE)
Nenue@33 112 end
Nenue@14 113 return D:DistributeFrames()
Nenue@14 114 elseif mode == 'tag' then -- tagging
Nenue@33 115 if db.workspace == 1 then
Nenue@33 116 return D:Print(MSG_NEED_DEV_MODE)
Nenue@33 117 end
Nenue@32 118
Nenue@14 119 if tag ~= nil and dest ~= nil then
Nenue@32 120 -- convert to ID
Nenue@32 121 if tonumber(dest) == nil and D.sigID[dest] then
Nenue@32 122 dest = db.channels[D.sigID[dest]].index
Nenue@18 123 end
Nenue@18 124
Nenue@32 125 -- make a new channel?
Nenue@32 126 if not db.channels[dest] then
Nenue@32 127 dest = db.max_channel + 1
Nenue@32 128 D:Print('Creating a new channel for '.. tag)
Nenue@32 129 D:SetChannel(tag, dest)
Nenue@32 130 end
Nenue@32 131
Nenue@32 132 if db.tags[tag] and db.tags[tag][dest] then
Nenue@32 133 db.tags[tag][dest] = nil
Nenue@34 134 D:Print('Hiding |cFF88FFFF'..tag..'|r messages in |cFFFFFF00'..db.channels[dest].index ..':'.. db.channels[dest].signature)
Nenue@32 135 else
Nenue@32 136 if not db.tags[tag] then
Nenue@32 137 db.tags[tag] = {}
Nenue@32 138 end
Nenue@32 139 db.tags[tag][dest] = dest
Nenue@34 140 D:Print('Showing |cFF88FFFF'..tag..'|r messages in |cFFFFFF00'..db.channels[dest].index ..':'.. db.channels[dest].signature)
Nenue@32 141 end
Nenue@14 142 else
Nenue@14 143 D:Print('Usage: /dvn tag <prefix> <console name or number>')
Nenue@14 144 end
Nenue@14 145 return
Nenue@32 146 elseif tonumber(mode) ~= nil or mode == 'save' then
Nenue@32 147 -- iterating for something
Nenue@32 148 if mode == 'save' then
Nenue@32 149 if tonumber(tag) == nil then
Nenue@32 150 T:Print('Save ID is invalid:', tag)
Nenue@32 151 end
Nenue@32 152 list_state = tonumber(tag)
Nenue@32 153 else
Nenue@32 154 list_state = tonumber(mode)
Nenue@32 155 db.workspace = list_state
Nenue@33 156 if list_state ~= 1 then
Nenue@33 157 db.last_workspace = list_state
Nenue@33 158 end
Nenue@33 159
Nenue@0 160 end
Nenue@32 161 elseif mode == nil then
Nenue@33 162 list_state = (db.workspace == 1) and db.last_workspace or 1
Nenue@33 163 db.workspace = list_state
Nenue@33 164 db.load_message = "quick swapped workspace #"..list_state
Nenue@32 165 else
Nenue@32 166 return D:PrintHelp()
Nenue@0 167 end
Nenue@32 168
Nenue@32 169 -- start the iterating
Nenue@0 170 local char_list, global_list = db[PLAYER_REALM][list_state], db.global[list_state]
Nenue@0 171 local playername = UnitName("player")
Nenue@0 172
Nenue@0 173 for i = 1, GetNumAddOns() do
Nenue@0 174 local name = GetAddOnInfo(i)
Nenue@0 175 local enableState, globalState = GetAddOnEnableState(playername, i), GetAddOnEnableState(nil, i)
Nenue@0 176
Nenue@32 177 if mode == 'save' then
Nenue@0 178 char_list[name] = enableState
Nenue@0 179 global_list[name] = globalState
Nenue@0 180 else
Nenue@13 181 if char_list[name] or global_list[name] then
Nenue@32 182 if char_list[name] ~= 0 and global_list[name] ~= 0 then
Nenue@32 183 local value = false
Nenue@32 184 if char_list[name] == 2 and global_list[name] == 1 then
Nenue@32 185 value = UnitName("player")
Nenue@32 186 elseif global_list[name] == 2 then
Nenue@32 187 value = true
Nenue@32 188 end
Nenue@32 189 --print('EnableAddOn(', i, ',', value,')')
Nenue@32 190 EnableAddOn(i, value)
Nenue@32 191 else
Nenue@32 192 local value = true
Nenue@32 193 if char_list[name] == 2 and global_list[name] == 1 then
Nenue@32 194 value = UnitName("player")
Nenue@32 195 end
Nenue@32 196 --print('DisableAddOn(', i, ',', value,')')
Nenue@32 197 DisableAddOn(i,value)
Nenue@0 198 end
Nenue@33 199 elseif mode ~= 'save' then
Nenue@32 200 if type(db.unlisted) ~= 'table' then
Nenue@32 201 db.unlisted = {}
Nenue@0 202 end
Nenue@32 203 table.insert(db.unlisted, name)
Nenue@13 204 end
Nenue@0 205
Nenue@0 206 end
Nenue@0 207 end
Nenue@0 208
Nenue@32 209 if mode ~= 'save' then
Nenue@33 210 --db.load_message = "AddOn profile ".. list_state .." was loaded."
Nenue@0 211 ReloadUI()
Nenue@0 212 else
Nenue@32 213 D:Print('Profile #'.. (list_state)..' saved.')
Nenue@32 214 if list_state == 1 then
Nenue@32 215 D:Print('This will be your main AddOn list.')
Nenue@32 216 elseif list_state == db.default_list then
Nenue@32 217 db.last_workspace = list_state
Nenue@32 218 D:Print('This will be your default workspace')
Nenue@32 219 end
Nenue@0 220 end
Nenue@0 221 end
Nenue@0 222
Nenue@0 223
Nenue@13 224 local function Console_MinMax(self)
Nenue@13 225 if self.minimized then
Nenue@7 226 self:Maximize()
Nenue@7 227 else
Nenue@7 228 self:Minimize()
Nenue@7 229 end
Nenue@7 230 end
Nenue@13 231
Nenue@13 232 local function Console_Minimize(self)
Nenue@13 233 self:SetHeight(20)
Nenue@13 234 self:SetMaxResize(GetScreenWidth(),20)
Nenue@13 235 self.minimized = true
Nenue@14 236 self.out:Hide()
Nenue@14 237 self:Save()
Nenue@7 238 end
Nenue@0 239
Nenue@13 240 local function Console_Maximize(self)
Nenue@13 241 local db = db.channels[self.index]
Nenue@13 242 self:SetHeight(db.height)
Nenue@13 243 self:SetMaxResize(GetScreenWidth(),GetScreenHeight())
Nenue@13 244 self.minimized = nil
Nenue@14 245 self.out:Show()
Nenue@14 246 self:Save()
Nenue@13 247 end
Nenue@13 248
Nenue@13 249
Nenue@13 250 local function Console_Save(self)
Nenue@13 251 local db = db.channels[self.index]
Nenue@14 252 if self.x then
Nenue@14 253 db.x = self.x
Nenue@14 254 else
Nenue@14 255 db.x = self:GetLeft()
Nenue@14 256 end
Nenue@14 257
Nenue@14 258 if self.y then
Nenue@14 259 db.y = self.y
Nenue@14 260 else
Nenue@14 261 db.y = (self:GetTop() - GetScreenHeight())
Nenue@14 262 end
Nenue@14 263
Nenue@14 264 if self.width then
Nenue@14 265 db.width = self.width
Nenue@14 266 else
Nenue@14 267 db.width = self:GetWidth()
Nenue@14 268 end
Nenue@14 269
Nenue@13 270 if not self.minimized then
Nenue@14 271 if self.height then
Nenue@14 272 db.height = self.height
Nenue@14 273 else
Nenue@14 274 db.height = self:GetHeight()
Nenue@14 275 end
Nenue@14 276 self:SetHeight(db.height)
Nenue@13 277 end
Nenue@14 278
Nenue@32 279 db.dockedTo = self.dockedTo
Nenue@32 280 db.docked = self.docked
Nenue@32 281
Nenue@14 282 db.minimized = self.minimized and true or nil
Nenue@14 283 db.enabled = self:IsVisible() and true or nil
Nenue@14 284 db.active = self.active and true or nil
Nenue@17 285 --print('save:', db.signature, 'min=', db.minimized, ' enabled=', db.enabled, ' active = ', db.active, 'x=', db.x, 'y=', db.y, 'h=', db.height, 'w=', db.width)
Nenue@13 286 self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y)
Nenue@14 287 self:SetWidth(db.width)
Nenue@13 288 end
Nenue@13 289
Nenue@14 290 -- Console frame toggler
Nenue@14 291 -- @paramsig [...]
Nenue@14 292 -- @param ... one or more space-seperated channel keys
Nenue@13 293 local function Console_Toggle(input)
Nenue@33 294 if db.workspace == 1 then
Nenue@33 295 return D:Print(MSG_NEED_DEV_MODE)
Nenue@33 296 end
Nenue@14 297 local search = {}
Nenue@28 298 local n = 0
Nenue@28 299 if D:GetArgs(input,1) then
Nenue@14 300 repeat
Nenue@28 301 key, n = D:GetArgs(input,1,n)
Nenue@14 302 if D.sig[key] then
Nenue@14 303 table.insert(search, D.sig[key])
Nenue@14 304 elseif D.console[key] then
Nenue@14 305 table.insert(search, D.console[key])
Nenue@14 306 end
Nenue@14 307 until n == 1e9
Nenue@13 308 else
Nenue@13 309 search = D.console
Nenue@13 310 end
Nenue@13 311
Nenue@33 312 db.enabled = (not db.enabled) and true or nil
Nenue@28 313 for i, c in ipairs(search) do
Nenue@33 314 --print(i,c.index)
Nenue@33 315 if db.enabled then
Nenue@28 316 c.enabled = true
Nenue@14 317 c:Show()
Nenue@26 318 if db.current_channel == c.index then
Nenue@26 319 c:ToFront()
Nenue@26 320 end
Nenue@33 321 c:Save()
Nenue@14 322 else
Nenue@13 323 c:Hide()
Nenue@13 324 end
Nenue@13 325 end
Nenue@14 326
Nenue@33 327 if db.enabled then
Nenue@14 328 D:Print('toggled on?')
Nenue@14 329 else
Nenue@14 330 D:Print('toggled off?')
Nenue@14 331 end
Nenue@13 332 end
Nenue@13 333
Nenue@18 334 --- Brings the console to the front.
Nenue@18 335 -- Frame method used to bring a console frame to the front of the display stack.
Nenue@14 336 local function Console_ToFront(c)
Nenue@14 337 --print(D.raise_ct, 'Raising', c.signature)
Nenue@14 338 --print(unpack(db.frontdrop))
Nenue@14 339 --print(unpack(db.frontgrad))
Nenue@14 340 --print(db.frontblend)
Nenue@22 341 -- D.raise_ct = D.raise_ct + 1
Nenue@14 342 c:Raise()
Nenue@28 343 c:SetAlpha(db.frontalpha)
Nenue@14 344 c.out.backdrop:SetTexture(unpack(db.frontdrop))
Nenue@14 345 c.out.backdrop:SetGradientAlpha(unpack(db.frontgrad))
Nenue@14 346 c.out.backdrop:SetBlendMode(db.frontblend)
Nenue@20 347 db.current_channel = c.index
Nenue@18 348
Nenue@18 349 for _, part in pairs(c.border) do
Nenue@24 350 part:SetTexture(unpack(db.frontborder))
Nenue@18 351 end
Nenue@14 352
Nenue@14 353 for id, bc in pairs(D.console) do
Nenue@14 354 if id ~= c.index then
Nenue@14 355 --print(D.raise_ct, 'Lowering', bc.signature)
Nenue@14 356 --print(unpack(db.backdrop))
Nenue@14 357 --print(unpack(db.backgrad))
Nenue@14 358 --print(db.backblend)
Nenue@28 359 bc:SetAlpha(db.backalpha)
Nenue@14 360 bc.out.backdrop:SetTexture(unpack(db.backdrop))
Nenue@14 361 bc.out.backdrop:SetGradientAlpha(unpack(db.backgrad))
Nenue@14 362 bc.out.backdrop:SetBlendMode(db.backblend)
Nenue@18 363
Nenue@18 364 for _, part in pairs(bc.border) do
Nenue@24 365 part:SetTexture(unpack(db.backborder))
Nenue@14 366 end
Nenue@18 367 end
Nenue@18 368
Nenue@14 369 end
Nenue@14 370
Nenue@14 371 end
Nenue@14 372
Nenue@32 373 local function Console_MouseDown(self, button, up)
Nenue@32 374 if button == 'LeftButton' then
Nenue@32 375 if up then
Nenue@32 376 self:StopMovingOrSizing()
Nenue@32 377 self:ToFront()
Nenue@32 378 self.x = nil
Nenue@32 379 self.y = nil
Nenue@32 380 self.width = nil
Nenue@32 381 self.height = nil
Nenue@32 382 self:Save()
Nenue@32 383 elseif self.out.grip:IsMouseOver() then
Nenue@32 384 self:StartSizing()
Nenue@32 385 else
Nenue@32 386 self:StartMoving()
Nenue@32 387 end
Nenue@22 388 else
Nenue@32 389 if up then
Nenue@32 390 self:MinMax()
Nenue@14 391 end
Nenue@13 392 end
Nenue@32 393 end
Nenue@32 394 local function Console_MouseUp(self, button)
Nenue@32 395 return Console_MouseDown(self, button, true)
Nenue@13 396 end
Nenue@13 397
Nenue@18 398 --- Creates a Devian-style output.
Nenue@18 399 -- The first argument describes the channel to output on, and the remaining arguments are concatenated in a manner similar to default print()
Nenue@18 400 -- This becomes the print handler when development mode is active. The original print() function is assigned to oldprint().
Nenue@18 401 -- @param Tag, signature, or numeric index of the channel to output on. Defaults to primary channel.
Nenue@18 402 -- @param ... Output contents.
Nenue@0 403 local function Message(prefix, ...)
Nenue@33 404 if not db.enabled then
Nenue@23 405 return D.oldprint(prefix, ...)
Nenue@23 406 end
Nenue@23 407
Nenue@1 408 if prefix == nil then
Nenue@13 409 prefix = 1
Nenue@1 410 end
Nenue@9 411
Nenue@18 412 local sendq = {}
Nenue@30 413 local tag, id, tagged
Nenue@13 414 local byName = true
Nenue@18 415 if D.tags[prefix] then
Nenue@18 416 for _, id in pairs(D.tags[prefix]) do
Nenue@18 417 if D.console[id] then
Nenue@18 418 sendq[id] = D.console[id]
Nenue@30 419 tagged = true
Nenue@18 420 end
Nenue@18 421 end
Nenue@18 422 end
Nenue@18 423
Nenue@13 424 if D.sig[prefix] then
Nenue@18 425 sendq[D.sig[prefix].index] = D.sig[prefix]
Nenue@13 426 elseif D.console[prefix] then
Nenue@18 427 sendq[D.console[prefix]] = D.console[prefix]
Nenue@30 428 elseif not tagged then
Nenue@18 429 sendq[D.primary_channel] = D.console[D.primary_channel]
Nenue@13 430 end
Nenue@18 431
Nenue@9 432 -- color me timbers
Nenue@9 433 local pcolor
Nenue@18 434 if (not db.tagcolor[prefix]) and byName then
Nenue@30 435 local c = {
Nenue@30 436 math.random(64,255), math.random(64,255), math.random(64,255)
Nenue@30 437 }
Nenue@30 438 if c[1] > 223 and c[2] > 223 and c[3] > 223 then
Nenue@30 439 c[math.random(1,3)] = math.random(64,223)
Nenue@0 440 end
Nenue@30 441
Nenue@18 442 db.tagcolor[prefix] = string.format('%02X%02X%02X', unpack(c))
Nenue@0 443 end
Nenue@18 444 pcolor = db.tagcolor[prefix]
Nenue@0 445
Nenue@18 446 local buffer = {'|cFF'.. pcolor..prefix ..'|r'}
Nenue@0 447 for i = 1, select('#',...) do
Nenue@0 448 local var = select(i, ...)
Nenue@0 449
Nenue@0 450 if type(var) == 'table' then
Nenue@20 451 if type(var.GetName) == 'function' then
Nenue@32 452 var = '<table:'..var:GetName()..'>'
Nenue@20 453 else
Nenue@32 454 var = '<'..tostring(var)..'>'
Nenue@20 455 end
Nenue@20 456
Nenue@0 457 elseif type(var) == 'boolean' then
Nenue@0 458 var = var and 'true' or 'false'
Nenue@0 459 elseif type(var) == 'function' then
Nenue@0 460 var = '<funcref>'
Nenue@0 461 elseif type(var) == 'nil' then
Nenue@0 462 var = 'nil'
Nenue@0 463 end
Nenue@0 464
Nenue@0 465 table.insert(buffer, var)
Nenue@0 466 end
Nenue@18 467 local message = table.concat(buffer, ' ')
Nenue@18 468 for id, channel in pairs(sendq) do
Nenue@18 469 channel.out:AddMessage(message)
Nenue@18 470 end
Nenue@0 471 table.wipe(buffer)
Nenue@0 472 end
Nenue@0 473
Nenue@14 474
Nenue@32 475 --- Constructs the frame object for a console channel
Nenue@32 476 -- Initializes the console channel at a specified index.
Nenue@32 477 -- Configuration data can be overridden by passing a desired settings table.
Nenue@32 478 -- @param i Numeric index of the channel as it manifests in db.channels
Nenue@32 479 -- @param vars Optional settings table to be used.
Nenue@32 480 local function CreateConsole(i, vars)
Nenue@33 481 if tonumber(i) == nil or math.floor(i) ~= i then
Nenue@33 482 error('Non-integer index value.')
Nenue@33 483 end
Nenue@33 484 if not vars then
Nenue@33 485 vars = db.channels[i] and db.channels[i] or db.channels[db.primary_channel]
Nenue@33 486 end
Nenue@33 487 local f
Nenue@33 488 if vars.docked then
Nenue@33 489 f = CreateFrame('Frame','DevianDockFrame' .. i, DEVIAN_DOCK_FRAME)
Nenue@33 490 else
Nenue@33 491 f= CreateFrame('Frame', 'DevianChannelFrame' .. i, UIParent, DEVIAN_FRAME)
Nenue@33 492 end
Nenue@33 493 --@debug@
Nenue@33 494 --print(f:GetName())
Nenue@32 495
Nenue@33 496 --print('create(2)')
Nenue@33 497 for k,v in pairs(vars) do
Nenue@33 498 f[k] = v
Nenue@33 499 --@debug@
Nenue@33 500 --print(' f['..type(k)..' '..tostring(k)..'] = '..type(v)..' '..tostring(v))
Nenue@14 501 end
Nenue@14 502
Nenue@32 503 f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y)
Nenue@32 504 f:SetSize(vars.width, vars.height)
Nenue@32 505 f:Lower()
Nenue@32 506 f.out:SetFont(db.font, db.fontsize, db.fontoutline)
Nenue@32 507 if (db.current_channel == i) then
Nenue@32 508 f.out.backdrop:SetTexture(unpack(db.frontdrop))
Nenue@32 509 else
Nenue@32 510 f.out.backdrop:SetTexture(unpack(db.backdrop))
Nenue@32 511 end
Nenue@14 512
Nenue@33 513
Nenue@33 514
Nenue@32 515 f.Save = Console_Save
Nenue@32 516 f.Minimize = Console_Minimize
Nenue@32 517 f.Maximize = Console_Maximize
Nenue@32 518 f.MinMax = Console_MinMax
Nenue@32 519 f.ToFront = Console_ToFront
Nenue@32 520 f.Toggle = D.Console_Toggle
Nenue@32 521 f:SetScript('OnMouseDown', Console_MouseDown)
Nenue@32 522 f:SetScript('OnMouseUp', Console_MouseUp)
Nenue@33 523
Nenue@32 524 if vars.minimized then
Nenue@32 525 f:Minimize()
Nenue@32 526 else
Nenue@32 527 f:Maximize()
Nenue@32 528 end
Nenue@33 529 if db.enabled and f.enabled then
Nenue@33 530 f:Show()
Nenue@33 531 end
Nenue@32 532
Nenue@32 533 return f
Nenue@14 534 end
Nenue@14 535
Nenue@33 536 --- Updates console information and returns the handle of the channel object that was worked on.
Nenue@33 537 -- When key is nil or not a valid handle, a new channel is created using whatever signature can be found in cinfo.
Nenue@33 538 -- The signature can be passed as a string, or as a table entry under the key 'signature'
Nenue@33 539 -- If the signature of a new channel is also a tag, the channel will be added to that tag
Nenue@33 540 -- @param cinfo string signature of a new channel, or a table of config variables to be imposed on the channel
Nenue@33 541 -- @param key string signature or index number of channel to operate on
Nenue@33 542 -- @usage channel = D:SetChannel('new', nil) -- creates a new channel
Nenue@33 543 -- @usage channel = D:SetChannel({x = 200, y = 100}, 4) -- updates channel #4
Nenue@33 544 function D:SetChannel(cinfo, key)
Nenue@14 545 local t_info = {}
Nenue@33 546 local channel, isNew, id, sig, t_id
Nenue@33 547 -- obtain source data
Nenue@33 548 if tonumber(key) ~= nil and db.channels[key] then
Nenue@33 549 id = tonumber(key)
Nenue@33 550 elseif D.sigID[tostring(key)] then
Nenue@33 551 id = D.sigID[tostring(key)]
Nenue@32 552 else
Nenue@33 553 id = db.primary_channel
Nenue@32 554 isNew = true
Nenue@32 555 end
Nenue@33 556 local dbvars = db.channels[id]
Nenue@33 557 t_id = id -- overridden later if new
Nenue@33 558 t_info.index = t_id --
Nenue@33 559 --@debug@
Nenue@33 560 --print('setchan(1) cinfo, key, id=', cinfo, key, id)--@end-debug@
Nenue@28 561
Nenue@33 562
Nenue@33 563 -- obtain config info
Nenue@33 564 if type(cinfo) == 'string' then
Nenue@33 565 sig = cinfo
Nenue@33 566 cinfo = {signature = sig}
Nenue@33 567 elseif type(cinfo) ~= 'table' then -- stop here if a table wans't passed
Nenue@33 568 error('Expecting table of string as arg1')
Nenue@33 569 elseif cinfo.signature then -- new sig
Nenue@33 570 sig = cinfo.signature
Nenue@33 571 elseif isNew then -- new channel sig
Nenue@33 572 sig = 'Ch'
Nenue@33 573 else -- old sig
Nenue@33 574 sig = db.channels[id].signature
Nenue@33 575 end
Nenue@33 576 t_info.signature = sig
Nenue@32 577 --@debug@
Nenue@33 578 --print('setchan(2) sig,id,isNew=', sig, id, isNew)--@end-debug@
Nenue@32 579
Nenue@33 580 for k,v in pairs(cinfo) do -- allow all cinfo to pass
Nenue@33 581 t_info[k] = v
Nenue@32 582 end
Nenue@32 583
Nenue@33 584 local blocked = { -- ignore these vars:
Nenue@33 585 ['docked'] = true, -- table
Nenue@33 586 ['dockedTo'] = true, -- table-related
Nenue@33 587 ['signature'] = true} -- already determined
Nenue@33 588 for k,v in pairs(dbvars) do
Nenue@33 589 if not t_info[k] and not blocked[k] then -- already set or blocked?
Nenue@33 590 t_info[k] = v
Nenue@33 591 end
Nenue@33 592 end
Nenue@33 593 -- new channel overrides
Nenue@33 594 if isNew then
Nenue@33 595 if D.sigID[sig]then -- find a non-clashing signature
Nenue@33 596 local result, i = sig, 1
Nenue@33 597 while D.sigID[result] do
Nenue@33 598 result = sig .. i
Nenue@33 599 i = i + 1
Nenue@33 600 end
Nenue@33 601 t_info.signature = result
Nenue@33 602 end
Nenue@33 603 t_id = db.max_channel + 1
Nenue@33 604 t_info.index = t_id
Nenue@33 605 --@debug@
Nenue@33 606 --print('setchan(3a) isNew, sig, t_info.signature=', isNew, sig, t_info.signature)--@end-debug@
Nenue@33 607 else
Nenue@33 608 --@debug@
Nenue@33 609 --print('setchan(3b) isNew, sig, t_info.signature=', isNew, sig, t_info.signature)--@end-debug@
Nenue@28 610 end
Nenue@28 611
Nenue@33 612 local channel
Nenue@33 613 if not self.console[t_id] then -- create a frame
Nenue@33 614 if isNew then -- position the channel frame
Nenue@33 615 t_info.x = t_info.x + 20
Nenue@33 616 t_info.y = t_info.y - 20
Nenue@33 617 db.channels[t_id] = t_info
Nenue@33 618 --@debug@
Nenue@33 619 print('setchan(4a)', 't_id, x, y=', t_id, t_info.x, t_info.y)--@end-debug@
Nenue@14 620 end
Nenue@33 621 channel = CreateConsole(t_id, t_info)
Nenue@33 622 self.console[t_id] = channel
Nenue@33 623 self.sig[t_info.signature] = channel
Nenue@33 624 self.sigID[t_info.signature] = t_id
Nenue@33 625 self.IDsig[t_id] = t_info.signature
Nenue@33 626
Nenue@33 627 end
Nenue@33 628 channel = self.console[t_id]
Nenue@33 629 if channel.minimized then
Nenue@33 630 channel:Minimize()
Nenue@33 631 else
Nenue@33 632 channel:Maximize()
Nenue@14 633 end
Nenue@14 634
Nenue@33 635 if channel.enabled and db.enabled then -- hide or show last since Min/Max mess with visibility
Nenue@33 636 print('setchan(5a) enable')
Nenue@33 637 channel:Show()
Nenue@33 638 else
Nenue@33 639 print('setchan(5a) disable')
Nenue@33 640 channel:Hide()
Nenue@33 641 end
Nenue@32 642 --@debug@
Nenue@33 643 --print('setchan(end); c:IsVisible(), c.enabled, db.enabled=', channel:IsVisible(), channel.enabled, db.enabled)--@end-debug@
Nenue@18 644 return channel
Nenue@14 645 end
Nenue@14 646
Nenue@32 647 function D:PrintHelp()
Nenue@32 648 D:Print("|cFFFFFF00/dvn|r",
Nenue@32 649 "\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@32 650
Nenue@32 651 D:Print("|cFFFFFF00/resetdvn|r", "- Resets all but profile data SavedVariables.")
Nenue@32 652 D:Print("|cFFFFFF00/cleandvn|r", "- Fully resets SavedVariables, profiles and all.")
Nenue@32 653 end
Nenue@32 654
Nenue@0 655 function D:OnEnable()
Nenue@33 656 print(MAJOR, MINOR)
Nenue@33 657
Nenue@33 658 if db.unlisted and #db.unlisted > 0 then
Nenue@33 659 D:Print('New AddOns have been found since the last profile update: '.. table.concat(db.unlisted, ', '))
Nenue@33 660 table.wipe(db.unlisted)
Nenue@33 661 end
Nenue@33 662
Nenue@33 663 if db.workspace == 1 then
Nenue@33 664 D:Print('Gameplay mode active (list #'..db.workspace..'). Print handling turned |cFFFFFF00OFF|r.')
Nenue@33 665 else
Nenue@33 666 D:Print('Development mode active (list #'..db.workspace..'). Print handling |cFF00FF00ON|r.')
Nenue@33 667 end
Nenue@33 668
Nenue@33 669 end
Nenue@33 670
Nenue@33 671 function D:OnInitialize()
Nenue@13 672 -- commands
Nenue@33 673 self:RegisterChatCommand("cleandvn", function(args)
Nenue@33 674 DevianDB = nil
Nenue@33 675 DevianDB = {
Nenue@33 676 load_message = "All SavedVars wiped."
Nenue@33 677 }
Nenue@33 678 ReloadUI()
Nenue@33 679 end)
Nenue@33 680 self:RegisterChatCommand("resetdvn", function(args)
Nenue@33 681 for k,v in pairs(DevianDB) do
Nenue@33 682 if k ~= 'global' then
Nenue@33 683 DevianDB[k] = nil
Nenue@33 684 end
Nenue@33 685 end
Nenue@33 686
Nenue@33 687 DevianDB.load_message = "Non-user SavedVars have been reset."
Nenue@33 688 for k,v in pairs(defaults) do
Nenue@33 689 DevianDB[k] = v
Nenue@33 690 end
Nenue@33 691 ReloadUI()
Nenue@33 692 end)
Nenue@13 693 local cmdlist = {
Nenue@13 694 ['dvn'] = ScanAddOnList,
Nenue@13 695 ['devian'] = ScanAddOnList,
Nenue@13 696 ['dvc'] = Console_Toggle,
Nenue@13 697 }
Nenue@13 698 for cmd, func in pairs(cmdlist) do
Nenue@13 699 self:RegisterChatCommand(cmd, func, true)
Nenue@13 700 end
Nenue@13 701
Nenue@33 702 -- pull defaults
Nenue@9 703 if not _G.DevianDB then
Nenue@13 704 _G.DevianDB = defaults
Nenue@9 705 end
Nenue@9 706 db = _G.DevianDB
Nenue@32 707 self.tags = db.tags
Nenue@32 708 self.channelinfo = db.channels
Nenue@0 709
Nenue@0 710 if not db[PLAYER_REALM] then
Nenue@32 711 db[PLAYER_REALM] = {[WORKSPACE_ON] = {}, [WORKSPACE_OFF] = {}}
Nenue@0 712 end
Nenue@0 713
Nenue@32 714 if db.load_message then
Nenue@32 715 D:Print(db.load_message)
Nenue@32 716 db.load_message = nil
Nenue@0 717 end
Nenue@0 718 D.oldprint = getprinthandler()
Nenue@0 719 if not _G.oldprint then
Nenue@0 720 _G.oldprint = D.oldprint
Nenue@0 721 end
Nenue@13 722
Nenue@33 723 -- Stop here in game mode
Nenue@33 724 if db.workspace == 1 then
Nenue@33 725 return
Nenue@33 726 end
Nenue@33 727
Nenue@32 728 self.max_channel = 0
Nenue@14 729 self.num_channels = 0
Nenue@13 730 self.console = {}
Nenue@13 731 self.sig = {}
Nenue@14 732 self.sigID = {}
Nenue@14 733 self.IDsig = {}
Nenue@14 734 for i, cinfo in pairs(db.channels) do
Nenue@14 735 i = tonumber(i)
Nenue@14 736 if not self.primary_channel then
Nenue@14 737 self.primary_channel = i
Nenue@14 738 end
Nenue@14 739 self:SetChannel(cinfo, i)
Nenue@32 740 self.max_channel = math.max(i, self.max_channel)
Nenue@32 741 self.num_channels = self.num_channels + 1
Nenue@32 742 end
Nenue@32 743
Nenue@32 744 for i, channel in pairs(db.channels) do
Nenue@32 745 if type(channel.docked) == 'table' then
Nenue@32 746 oldprint('docking',i, unpack(channel.docked))
Nenue@32 747 self.DockFrame(i, unpack(channel.docked))
Nenue@14 748 end
Nenue@13 749 end
Nenue@18 750
Nenue@18 751 if self.console[db.current_channel] then
Nenue@18 752 self.console[db.current_channel]:ToFront()
Nenue@28 753 -- bring the current channel to the front
Nenue@18 754 end
Nenue@33 755 setprinthandler(Message)
Nenue@33 756 print = function(...)
Nenue@33 757 _G.print('Dvn', ...)
Nenue@23 758 end
Nenue@0 759 end