diff Devian.lua @ 32:c6a2c2df4790

v2 work
author Nenue
date Sat, 26 Dec 2015 21:51:57 -0500
parents 6fcfe60bbd0f
children e6650821a2c0
line wrap: on
line diff
--- a/Devian.lua	Sat Dec 26 05:18:24 2015 -0500
+++ b/Devian.lua	Sat Dec 26 21:51:57 2015 -0500
@@ -1,28 +1,31 @@
--- User: Krakyn
--- Created: 11/30/2015 7:46 AM
+--- ${PACKAGE_NAME}
+-- @file-author@
+-- @project-revision@ @project-hash@
+-- @file-revision@ @file-hash@
 if not LibStub then
   print('Something has happened...')
 end
 Devian = LibStub("AceAddon-3.0"):NewAddon("Devian", "AceConsole-3.0", "AceEvent-3.0")
 local MAJOR, MINOR = 'Devian-1.3', 'r@project-revision@'
 local D = _G.Devian
-local STATE_LOW, STATE_HIGH = 1, 2
+local WORKSPACE_ON, WORKSPACE_OFF = 1, 2
 local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName()
 local DEVIAN_FRAME = 'DevianConsole'
 local print = _G.print
 local db
 local defaults = {
-  ['global'] = {[STATE_LOW] = {}, [STATE_HIGH] = {}},
+  ['global'] = {{}, {}},
   ['tags'] = {},
-  ['channels'] = {[1] = {signature = 'Dvn', name = 'Main', header = "%n [%t]", x = 100, y = 800, height = 500, width = 600, enabled = true}},
+  ['channels'] = {[1] = {signature = 'Main', index = 1, x = 100, y = 800, height = 500, width = 600, enabled = true}},
   primary_channel = 1,
   current_channel = 1,
+  max_channel = 1,
   toggle = true,
-  dnd_status = true,
-  dnd_message = "Debugging. Your messages may get eaten.",
+  load_message = "Defaults loaded.",
   font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]],
   fontsize = 13,
   fontoutline = 'NONE',
+  headergrab = {'VERTICAL', 0, 0, 0, 0.5, 0.1, 0.1, 0.1, 0.3},
   backalpha = 0.5,
   backdrop = {0,0,0,0.4},
   backgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.3, 0, 0, 0, 0.5},
@@ -33,6 +36,8 @@
   frontalpha = 1,
   frontborder = {1,0,0,1},
   backborder = {0,0,1,0.75},
+  tagcolor = {},
+  workspace = 1,
 }
 
 
@@ -49,86 +54,145 @@
 
 
   -- no args, toggle ui
-  if mode == nil then
-    list_state = db.enabled and STATE_LOW or STATE_HIGH
-    db.enabled = (db.enabled == false) and true or false
-    --print(list_state, db.enabled)
+  if mode == 'dock' then
+    if #args <= 2 then
+      D:Print("Not enough arguments for dock command.")
+      return
+    end
 
-    if list_state == STATE_LOW then
+    local target
+    local worklist = {}
+    for i = 2, #args do
+      local ch
+      local k = tostring(args[i])
+      local j = tonumber(args[i])
+      if db.channels[j] then
+        ch = db.channels[j]
+      elseif D.sig[k] then
+        ch = D.sig[k]
+      elseif D.sigID[k] then
+        ch = db.channels[D.sigID[k]]
+      elseif db.tags[k] and db.tags[k][1] then
+        ch = db.channels[db.tags[j][1]]
+        -- last resort
+      else
+        D:Print('No entry for argument #'..i..': '..tostring(args[i]))
+        return
+      end
+      oldprint(i, '->', ch.index, '-', ch.signature)
+      if i > 2 then
+        table.insert(worklist, ch.index)
+      else
+        target = ch
+
+        oldprint('arg1', args[2], target)
+      end
     end
+    D:Print("Docking |cFF88FFFF"..table.concat(worklist, "|r, |cFF88FFFF").."|r with |cFFFFFF00"..target.index..', '..target.signature.."|r.")
+    return D:DockFrame(target.index, unpack(worklist))
+
+
   elseif mode == 'stack' then
     return D:StackFrames()
   elseif mode == 'grid' then
     return D:DistributeFrames()
   elseif mode == 'tag' then -- tagging
+
     if tag ~= nil and dest ~= nil then
-      local channel = D:SetChannel(dest:match('%a+'), dest:match('%d+'))
-      if not D.tags[tag] then
-        D.tags[tag] = {}
-      end
-      if D.tags[tag][channel.index] then
-        D.tags[tag][channel.index] = nil
-        D:Print('Removed |cFFFFFF00'..tag..'|r to |cFF00FFFF['..channel.index..', '..channel.signature..']|r')
-      else
-        D.tags[tag][channel.index] = channel.index
-        D:Print('Assigning |cFFFFFF00'..tag..'|r to |cFF00FFFF['..channel.index..', '..channel.signature..']|r')
+      -- convert to ID
+      if tonumber(dest) == nil and D.sigID[dest] then
+        dest = db.channels[D.sigID[dest]].index
       end
 
+      -- make a new channel?
+      if not db.channels[dest] then
+        dest = db.max_channel + 1
+        D:Print('Creating a new channel for '.. tag)
+        D:SetChannel(tag, dest)
+      end
+
+      if db.tags[tag] and db.tags[tag][dest] then
+        db.tags[tag][dest] = nil
+        D:Print('Hiding |cFF88FFFF'..tag..'|r messages in |cFFFFFF00'..db.channels[dest].index ..':'.. db.channels[dest].index)
+      else
+        if not db.tags[tag] then
+          db.tags[tag] = {}
+        end
+        db.tags[tag][dest] = dest
+        D:Print('Showing |cFF88FFFF'..tag..'|r messages in |cFFFFFF00'..db.channels[dest].index ..':'.. db.channels[dest].index)
+      end
     else
       D:Print('Usage: /dvn tag <prefix> <console name or number>')
     end
     return
-  elseif mode ~= nil then
-    mode = tonumber(mode)
-    if mode > 2 then
-      --print('Something has happened.')
-      return
+  elseif tonumber(mode) ~= nil or mode == 'save' then
+    -- iterating for something
+    if mode == 'save' then
+      if tonumber(tag) == nil then
+        T:Print('Save ID is invalid:', tag)
+      end
+      list_state = tonumber(tag)
+    else
+      list_state = tonumber(mode)
+      db.workspace = list_state
     end
-    list_state = mode == STATE_LOW and STATE_LOW or STATE_HIGH
+  elseif mode == nil then
+    list_state = db.last_workspace and db.last_workspace or 1
+  else
+    return D:PrintHelp()
   end
+
+  -- start the iterating
   local char_list, global_list = db[PLAYER_REALM][list_state], db.global[list_state]
-
   local playername = UnitName("player")
 
   for i = 1, GetNumAddOns() do
     local name = GetAddOnInfo(i)
     local enableState, globalState = GetAddOnEnableState(playername, i), GetAddOnEnableState(nil, i)
 
-    if mode == STATE_LOW or mode == STATE_HIGH then
+    if mode == 'save' then
       char_list[name] = enableState
       global_list[name] = globalState
     else
       if char_list[name] or global_list[name] then
-
-      if char_list[name] ~= 0 and global_list[name] ~= 0 then
-        local value = false
-        if char_list[name] == 2 and global_list[name] == 1 then
-          value = UnitName("player")
-        elseif global_list[name] == 2 then
-          value = true
+        if char_list[name] ~= 0 and global_list[name] ~= 0 then
+          local value = false
+          if char_list[name] == 2 and global_list[name] == 1 then
+            value = UnitName("player")
+          elseif global_list[name] == 2 then
+            value = true
+          end
+          --print('EnableAddOn(', i, ',', value,')')
+          EnableAddOn(i, value)
+        else
+          local value = true
+          if char_list[name] == 2 and global_list[name] == 1 then
+            value = UnitName("player")
+          end
+          --print('DisableAddOn(', i, ',', value,')')
+          DisableAddOn(i,value)
         end
-        --print('EnableAddOn(', i, ',', value,')')
-        EnableAddOn(i, value)
       else
-        local value = true
-        if char_list[name] == 2 and global_list[name] == 1 then
-          value = UnitName("player")
+        if type(db.unlisted) ~= 'table' then
+          db.unlisted = {}
         end
-        --print('DisableAddOn(', i, ',', value,')')
-        DisableAddOn(i,value)
-      end
+        table.insert(db.unlisted, name)
       end
 
     end
   end
 
-  if mode == nil then
+  if mode ~= 'save' then
+    db.load_message = "AddOn profile ".. list_state .." was loaded."
     ReloadUI()
-  end
-  if mode == STATE_LOW then
-    D:Print('Developement AddOn list saved.')
   else
-    D:Print('Standard AddOn list saved.')
+      D:Print('Profile #'.. (list_state)..' saved.')
+    if list_state == 1 then
+      D:Print('This will be your main AddOn list.')
+    elseif list_state == db.default_list then
+      db.last_workspace = list_state
+      D:Print('This will be your default workspace')
+    end
   end
 end
 
@@ -188,6 +252,9 @@
     self:SetHeight(db.height)
   end
 
+  db.dockedTo = self.dockedTo
+  db.docked = self.docked
+
   db.minimized = self.minimized and true or nil
   db.enabled = self:IsVisible() and true or nil
   db.active = self.active and true or nil
@@ -278,57 +345,29 @@
 
 end
 
---- Constructs the frame object for a console channel
--- Initializes the console channel at a specified index.
--- Configuration data can be overridden by passing a desired settings table.
--- @param i Numeric index of the channel as it manifests in db.channels
--- @param vars Optional settings table to be used.
-local function CreateConsole(i, vars)
-
-  if not vars then
-    vars = db.channels[i]
-  end
-
-  --print('make:', vars.signature, '(', vars.x, vars.y, ')', vars.width, 'x', vars.height)
-  local f = CreateFrame('Frame', 'DevianChannelFrame' .. tostring(i), UIParent, DEVIAN_FRAME)
-  f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y)
-  f:SetSize(vars.width, vars.height)
-  f:Lower()
-  f.out:SetFont(db.font, db.fontsize, db.fontoutline)
-  if (db.current_channel == i) then
-    f.out.backdrop:SetTexture(unpack(db.frontdrop))
+local function Console_MouseDown(self, button, up)
+  if button == 'LeftButton' then
+    if up then
+      self:StopMovingOrSizing()
+      self:ToFront()
+      self.x = nil
+      self.y = nil
+      self.width = nil
+      self.height = nil
+      self:Save()
+    elseif self.out.grip:IsMouseOver() then
+      self:StartSizing()
+    else
+      self:StartMoving()
+    end
   else
-    f.out.backdrop:SetTexture(unpack(db.backdrop))
-  end
-
-  f.Save = Console_Save
-  f.Minimize = Console_Minimize
-  f.Maximize = Console_Maximize
-  f.MinMax = Console_MinMax
-  f.ToFront = Console_ToFront
-  f.Toggle = D.Console_Toggle
-  f.name = vars.name
-  f.index = i
-  f.signature = vars.signature
-  f.format = vars.header
-  f.x = vars.x
-  f.y = vars.y
-  f.width = vars.width
-  f.height = vars.height
-
-  if vars.enabled  then
-    f.enabled = true
-    if db.toggle then
-      f:Show()
+    if up then
+      self:MinMax()
     end
   end
-  if vars.minimized then
-    f:Minimize()
-  else
-    f:Maximize()
-  end
-
-  return f
+end
+local function Console_MouseUp(self, button)
+  return Console_MouseDown(self, button, true)
 end
 
 --- Creates a Devian-style output.
@@ -385,9 +424,9 @@
 
     if type(var) == 'table' then
       if type(var.GetName) == 'function' then
-        var = '<table:'..(var:GetName() or '?')..'>'
+        var = '<table:'..var:GetName()..'>'
       else
-        var = '<table>'
+        var = '<'..tostring(var)..'>'
       end
 
     elseif type(var) == 'boolean' then
@@ -407,42 +446,62 @@
   table.wipe(buffer)
 end
 
---- Spaces each frame evenly across the screen.
-function D:DistributeFrames() --
-  --print('frame grid:', max, num_side)
-  local max = self.num_channels
-  local num_side = math.ceil(math.sqrt(max))
-  local w = GetScreenWidth() / num_side
-  local h = GetScreenHeight() / num_side
-  for i, frame in pairs(D.console) do
-    local dx = (i-1) % num_side
-    local dy = math.floor((i-1) / num_side)
 
-    --print('move:', frame.signature, 'dx=', dx, 'dy=', dy)
-    --print('move:', frame.signature, '                                       x=', dx * w, 'y=', -(dy * h), 'h=', h, 'w=', w)
-    frame.width = w
-    frame.height = h
-    frame.x = dx * w
-    frame.y = -(dy * h)
-    frame:Save()
+--- Constructs the frame object for a console channel
+-- Initializes the console channel at a specified index.
+-- Configuration data can be overridden by passing a desired settings table.
+-- @param i Numeric index of the channel as it manifests in db.channels
+-- @param vars Optional settings table to be used.
+local function CreateConsole(i, vars)
+
+  if not vars then
+    vars = db.channels[i]
   end
 
-end
+  --print('make:', vars.signature, '(', vars.x, vars.y, ')', vars.width, 'x', vars.height)
+  local f = CreateFrame('Frame', 'DevianChannelFrame' .. tostring(i), UIParent, DEVIAN_FRAME)
+  f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y)
+  f:SetSize(vars.width, vars.height)
+  f:Lower()
+  f.out:SetFont(db.font, db.fontsize, db.fontoutline)
+  if (db.current_channel == i) then
+    f.out.backdrop:SetTexture(unpack(db.frontdrop))
+  else
+    f.out.backdrop:SetTexture(unpack(db.backdrop))
+  end
 
---- Place all frames stacked beneath the primary frame.
-function D:StackFrames()
-  local last
-  for i, frame in pairs(self.console) do
-    if last then
-      frame.x = last.x
-      frame.y = last.y - 20
-    else
-      frame.x = (GetScreenWidth()-frame:GetWidth())/2
-      frame.y = 0
+  f.Save = Console_Save
+  f.Minimize = Console_Minimize
+  f.Maximize = Console_Maximize
+  f.MinMax = Console_MinMax
+  f.ToFront = Console_ToFront
+  f.Toggle = D.Console_Toggle
+  f.name = vars.name
+  f.index = i
+  f.signature = vars.signature
+  f.format = vars.header
+  f.x = vars.x
+  f.y = vars.y
+  f.width = vars.width
+  f.height = vars.height
+  f.docked = vars.docked
+  f.dockedTo = vars.dockedTo
+
+  f:SetScript('OnMouseDown', Console_MouseDown)
+  f:SetScript('OnMouseUp', Console_MouseUp)
+  if vars.enabled  then
+    f.enabled = true
+    if db.toggle then
+      f:Show()
     end
-    frame:Save()
-    last = frame
   end
+  if vars.minimized then
+    f:Minimize()
+  else
+    f:Maximize()
+  end
+
+  return f
 end
 
 --- Updates a console "channel" entry, generating a new one if necessary.
@@ -452,87 +511,109 @@
 -- @param cinfo Config variables table, or a string to be used as channel signature
 -- @param i Console index. If valid, settings will be inherited from that channel.
 function D:SetChannel(cinfo, i)
-  --print('join:', i , cinfo)
+  -- try to resolve from arguments
+  local dbvars
   local t_info = {}
-  local dbvars = db.channels[self.primary_channel]
-  local signame
+  local channel
+  local isNew
+  if type(i) =='number' and  db.channels[i] then
+      dbvars = db.channels[i]
+  elseif type(i) == 'string' and D.sig[i] then
+    dbvars = db.channels[D.sig[i].index]
+  else
+    dbvars = db.channels[db.primary_channel]
+    isNew = true
+  end
 
+  --@debug@
+  print('setchan(1)', cinfo, i, isNew)--@end-debug@
+
+  if type(cinfo) == 'string' and not db.sig[cinfo] then
+    t_info.signature = cinfo
+    cinfo = {}
+  elseif type(cinfo) ~= 'table' then
+    error('Expecting table of string as arg1')
+  end
+
+  --@debug@
+  print('setchan(2)', cinfo, i, isNew)--@end-debug@
+
+  --TODO: figure out why tag assignments are getting eaten
   -- is cinfo a table or signature?
-  if type(cinfo) == 'string' then
-    signame = tostring(cinfo)
-    t_info.signature = signame
-  elseif type(cinfo) ~= 'table' then
-    cinfo = {}
-  end
+
+
 
   -- did we get a signature string?
   if not (cinfo.signature or t_info.signature) then
-    t_info.signature = 'Console'
+    t_info.signature = 'noname'
   end
 
-  -- was an index given?
-  if D.sigID[t_info.signature] then
-    i = D.sigID[t_info.signature]
-    -- the signature has one
-  elseif not i then
-    i = D.num_channels + 1
-    t_info.index = i
-    -- or we need to make a new one
-  else
-    i = tonumber(i)
-    -- is it valid?
-    if db.channels[i] then
-      dbvars = db.channels[i]
-      -- that is our base vars
-    else
-      if D.sig[t_info.signature] then
-        local sigvar = t_info.signature
-        local j = 2
-        while D.sig[sigvar] do
-          sigvar = sigvar .. j
-          j = j + 1
-        end
-        t_info.signature = sigvar
-      end
-
-      i = D.num_channels + 1
-      t_info.index = i
-      -- make a new index number and fix the signature
+  --@debug@
+  print('setchan(3)', cinfo, i, isNew, t_info.signature)--@end-debug@
+  -- look for existing sigs
+  if D.sig[t_info.signature] then
+    local sigvar = t_info.signature
+    local j = 2
+    while D.sig[sigvar] do
+      sigvar = sigvar .. j
+      j = j + 1
     end
+    t_info.signature = sigvar
   end
 
+  --@debug@
+  print('setchan(4)', cinfo, i, isNew, t_info.signature)--@end-debug@
   -- can proceed to fill in from base vars here
   for k,v in pairs(dbvars) do
     if not t_info[k] then
       if cinfo[k] then
         t_info[k] = cinfo[k]
+        --@debug@
+        print('setchan(5a)', 'cinfo', k)--@end-debug@
       elseif db.channels[self.primary_channel][k] then
         t_info[k] = db.channels[self.primary_channel][k]
+        --@debug@
+        print('setchan(5b)', 'db', self.primary_channel, k)--@end-debug@
       end
     end
   end
 
   -- we're working with a fresh channel right?
-  if not db.channels[i] then
+  if isNew then
+    i = D.num_channels + 1
+    t_info.index = i
     t_info.x = t_info.x + 20
     t_info.y = t_info.y - 20
     db.channels[i] = t_info
-    -- set its position just off of the base vars and store it
+    --@debug@
+    print('setchan(6)', 'new index', i)--@end-debug@
   end
 
   -- can proceed to display something from here
   if not self.console[i] then
     self.console[i] = CreateConsole(i, t_info)
     -- if it isn't already spawned, create the frame
+    --@debug@
+    print('setchan(7)', 'new console', i)--@end-debug@
   end
   local channel = self.console[i]
   self.sig[t_info.signature] = channel
   self.sigID[t_info.signature] = i
   self.IDsig[i] = t_info.signature
 
+  --@debug@
+  print('setchan(8)', 'end', self.sig[t_info.signature], self.sigID[t_info.signature], self.IDsig[i], self.docked)--@end-debug@
   return channel
 end
 
+function D:PrintHelp()
+  D:Print("|cFFFFFF00/dvn|r",
+    "\n |cFFFFFF00<number>|r - Loads a saved addon list. List 1 is treated as a gameplay profile and consoles will be disabled by default.")
+
+  D:Print("|cFFFFFF00/resetdvn|r", "- Resets all but profile data SavedVariables.")
+  D:Print("|cFFFFFF00/cleandvn|r", "- Fully resets SavedVariables, profiles and all.")
+end
+
 function D:OnEnable()
   -- commands
   local cmdlist = {
@@ -544,10 +625,10 @@
     self:RegisterChatCommand(cmd, func, true)
   end
 
-  if db.enabled == true then
-    D:Print('Standard AddOn list active. Type /dvn to switch to development mode.')
+  if db.workspace == 1 then
+    D:Print('Gameplay mode active. Print handling turned |cFFFFFF00OFF|r..')
   else
-    D:Print('Development AddOn list active. Type /dvn to revert to regular operation.')
+    D:Print('Development mode active (list #'..db.workspace..'). Print handling |cFF00FF00ON|r.')
   end
 
 end
@@ -558,29 +639,35 @@
     DevianDB = nil
     ReloadUI()
     end)
+  self:RegisterChatCommand("resetdvn", function(args)
+    for k,v in pairs(DevianDB) do
+      if k ~= 'global' then
+        DevianDB[k] = nil
+      end
+    end
+
+    for k,v in pairs(defaults) do
+      DevianDB[k] = v
+    end
+    ReloadUI()
+  end)
 
   -- savedvars
   local cherry = false
   if not _G.DevianDB then
     _G.DevianDB = defaults
-    cherry = "Type /dvnsave to snapshot your current UI"
   end
   db = _G.DevianDB
+  self.tags = db.tags
+  self.channelinfo = db.channels
 
   if not db[PLAYER_REALM] then
-    db[PLAYER_REALM] = {[STATE_LOW] = {}, [STATE_HIGH] = {}}
-    if not cherry then
-      cherry = "This character didn't have an AddOn table."
-    end
+    db[PLAYER_REALM] = {[WORKSPACE_ON] = {}, [WORKSPACE_OFF] = {}}
   end
 
-
-  if not db.tags then
-    db.tags = {}
-  end
-  self.tags = db.tags
-  if cherry then
-    D:Print(cherry)
+  if db.load_message then
+    D:Print(db.load_message)
+    db.load_message = nil
   end
   D.oldprint = getprinthandler()
   if not _G.oldprint then
@@ -588,7 +675,7 @@
   end
 
   --self.raise_ct = 0
-  self.last_channel = 0
+  self.max_channel = 0
   self.num_channels = 0
   self.console = {}
   self.sig = {}
@@ -600,10 +687,15 @@
       self.primary_channel = i
     end
     self:SetChannel(cinfo, i)
-    if i > self.last_channel then
-      self.last_channel = i
+    self.max_channel = math.max(i, self.max_channel)
+    self.num_channels = self.num_channels + 1
+  end
+
+  for i, channel in pairs(db.channels) do
+    if type(channel.docked) == 'table' then
+      oldprint('docking',i, unpack(channel.docked))
+      self.DockFrame(i, unpack(channel.docked))
     end
-    self.num_channels = self.num_channels + 1
   end
 
   if self.console[db.current_channel] then
@@ -619,7 +711,8 @@
 
 
   -- only do this in dev mode
-  if db.enabled == false then
+  if db.workspace > 1 then
+
     setprinthandler(Message)
     print = function(...)
       _G.print('Dvn', ...)