changeset 35:3304455a3f45

code organizing; UI stuff is in the UI script, Devian prime just deals with config and print corner menu elements placed and hooked, still needs follow-up code
author Nenue
date Sun, 27 Dec 2015 03:51:17 -0500
parents 7441f3bce940
children bec37163b7fe
files Devian.lua Devian.toc Devian.xml UI.lua
diffstat 4 files changed, 421 insertions(+), 338 deletions(-) [+]
line wrap: on
line diff
--- a/Devian.lua	Sun Dec 27 02:33:06 2015 -0500
+++ b/Devian.lua	Sun Dec 27 03:51:17 2015 -0500
@@ -10,9 +10,6 @@
 local D = _G.Devian
 local WORKSPACE_ON, WORKSPACE_OFF = 1, 2
 local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName()
-local DEVIAN_FRAME = 'DevianConsole'
-local DEVIAN_DOCK_FRAME = 'DevianDockFrame'
-local MSG_NEED_DEV_MODE = 'Must be in development mode to use this function.'
 local print = _G.print
 local db
 local defaults = {
@@ -45,7 +42,6 @@
   last_workspace = 2 -- default workspace to alternate with when just "/dvn" is issued
 }
 
-
 local function ScanAddOnList(cmd, ...)
   local list_state
 
@@ -88,13 +84,15 @@
         D:Print('No entry for argument #'..i..': '..tostring(args[i]))
         return
       end
-      oldprint(i, '->', ch.index, '-', ch.signature)
+      --@debug@
+      --print(i, '->', ch.index, '-', ch.signature)--@end-debug@
       if i > 2 then
         table.insert(worklist, ch.index)
       else
         target = ch
 
-        oldprint('arg1', args[2], target)
+        --@debug@
+        --print('arg1', args[2], target)--@end-debug@
       end
     end
     D:Print("Docking |cFF88FFFF"..table.concat(worklist, "|r, |cFF88FFFF").."|r with |cFFFFFF00"..target.index..', '..target.signature.."|r.")
@@ -221,179 +219,6 @@
 end
 
 
-local function Console_MinMax(self)
-  if self.minimized then
-    self:Maximize()
-  else
-    self:Minimize()
-  end
-end
-
-local function Console_Minimize(self)
-  self:SetHeight(20)
-  self:SetMaxResize(GetScreenWidth(),20)
-  self.minimized = true
-  self.out:Hide()
-  self:Save()
-end
-
-local function Console_Maximize(self)
-  local db = db.channels[self.index]
-  self:SetHeight(db.height)
-  self:SetMaxResize(GetScreenWidth(),GetScreenHeight())
-  self.minimized = nil
-  self.out:Show()
-  self:Save()
-end
-
-
-local function Console_Save(self)
-  local db = db.channels[self.index]
-  if self.x then
-    db.x = self.x
-  else
-    db.x = self:GetLeft()
-  end
-
-  if self.y then
-    db.y = self.y
-  else
-    db.y = (self:GetTop() - GetScreenHeight())
-  end
-
-  if self.width then
-    db.width = self.width
-  else
-    db.width = self:GetWidth()
-  end
-
-  if not self.minimized then
-    if self.height then
-      db.height = self.height
-    else
-      db.height = self:GetHeight()
-    end
-    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
-  --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)
-  self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y)
-  self:SetWidth(db.width)
-end
-
--- Console frame toggler
--- @paramsig [...]
--- @param ... one or more space-seperated channel keys
-local function Console_Toggle(input)
-  if db.workspace == 1 then
-    return D:Print(MSG_NEED_DEV_MODE)
-  end
-  local search = {}
-  local n = 0
-  if D:GetArgs(input,1) then
-    repeat
-      key, n = D:GetArgs(input,1,n)
-      if D.sig[key] then
-        table.insert(search, D.sig[key])
-      elseif D.console[key] then
-        table.insert(search, D.console[key])
-      end
-    until n == 1e9
-  else
-    search = D.console
-  end
-
-  db.enabled = (not db.enabled) and true or nil
-  for i, c in ipairs(search) do
-    --print(i,c.index)
-    if db.enabled then
-      c.enabled = true
-      c:Show()
-      if db.current_channel == c.index then
-        c:ToFront()
-      end
-      c:Save()
-    else
-      c:Hide()
-    end
-  end
-
-  if db.enabled then
-    D:Print('toggled on?')
-  else
-    D:Print('toggled off?')
-    end
-end
-
---- Brings the console to the front.
--- Frame method used to bring a console frame to the front of the display stack.
-local function Console_ToFront(c)
-  --print(D.raise_ct, 'Raising', c.signature)
-  --print(unpack(db.frontdrop))
-  --print(unpack(db.frontgrad))
-  --print(db.frontblend)
-  -- D.raise_ct = D.raise_ct + 1
-  c:Raise()
-  c:SetAlpha(db.frontalpha)
-  c.out.backdrop:SetTexture(unpack(db.frontdrop))
-  c.out.backdrop:SetGradientAlpha(unpack(db.frontgrad))
-  c.out.backdrop:SetBlendMode(db.frontblend)
-  db.current_channel = c.index
-
-  for _, part in pairs(c.border) do
-    part:SetTexture(unpack(db.frontborder))
-  end
-
-  for id, bc in pairs(D.console) do
-    if id ~= c.index then
-      --print(D.raise_ct, 'Lowering', bc.signature)
-      --print(unpack(db.backdrop))
-      --print(unpack(db.backgrad))
-      --print(db.backblend)
-      bc:SetAlpha(db.backalpha)
-      bc.out.backdrop:SetTexture(unpack(db.backdrop))
-      bc.out.backdrop:SetGradientAlpha(unpack(db.backgrad))
-      bc.out.backdrop:SetBlendMode(db.backblend)
-
-      for _, part in pairs(bc.border) do
-        part:SetTexture(unpack(db.backborder))
-      end
-    end
-
-  end
-
-end
-
-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
-    if up then
-      self:MinMax()
-    end
-  end
-end
-local function Console_MouseUp(self, button)
-  return Console_MouseDown(self, button, true)
-end
 
 --- Creates a Devian-style output.
 -- The first argument describes the channel to output on, and the remaining arguments are concatenated in a manner similar to default print()
@@ -472,177 +297,7 @@
 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 tonumber(i) == nil or math.floor(i) ~= i then
-    error('Non-integer index value.')
-  end
-  if not vars then
-    vars = db.channels[i] and db.channels[i] or db.channels[db.primary_channel]
-  end
-  local f
-  if vars.docked then
-    f = CreateFrame('Frame','DevianDockFrame' .. i, DEVIAN_DOCK_FRAME)
-  else
-    f= CreateFrame('Frame', 'DevianChannelFrame' .. i, UIParent, DEVIAN_FRAME)
-  end
-  --@debug@
-  --print(f:GetName())
 
-  --print('create(2)')
-  for k,v in pairs(vars) do
-    f[k] = v
-    --@debug@
-    --print(' f['..type(k)..' '..tostring(k)..'] = '..type(v)..' '..tostring(v))
-  end
-
-  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
-
-
-
-  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:SetScript('OnMouseDown', Console_MouseDown)
-  f:SetScript('OnMouseUp', Console_MouseUp)
-
-  if vars.minimized then
-    f:Minimize()
-  else
-    f:Maximize()
-  end
-  if db.enabled and f.enabled then
-      f:Show()
-  end
-
-  return f
-end
-
---- Updates console information and returns the handle of the channel object that was worked on.
--- When key is nil or not a valid handle, a new channel is created using whatever signature can be found in cinfo.
--- The signature can be passed as a string, or as a table entry under the key 'signature'
--- If the signature of a new channel is also a tag, the channel will be added to that tag
--- @param cinfo string signature of a new channel, or a table of config variables to be imposed on the channel
--- @param key string signature or index number of channel to operate on
--- @usage channel = D:SetChannel('new', nil) -- creates a new channel
--- @usage channel = D:SetChannel({x = 200, y = 100}, 4) -- updates channel #4
-function D:SetChannel(cinfo, key)
-  local t_info = {}
-  local channel, isNew, id, sig, t_id
-  -- obtain source data
-  if tonumber(key) ~= nil and  db.channels[key] then
-    id = tonumber(key)
-  elseif D.sigID[tostring(key)] then
-    id = D.sigID[tostring(key)]
-  else
-    id = db.primary_channel
-    isNew = true
-  end
-  local dbvars = db.channels[id]
-  t_id = id           -- overridden later if new
-  t_info.index = t_id --
-  --@debug@
-  --print('setchan(1) cinfo, key, id=', cinfo, key, id)--@end-debug@
-
-
-  -- obtain config info
-  if type(cinfo) == 'string' then
-    sig = cinfo
-    cinfo = {signature = sig}
-  elseif type(cinfo) ~= 'table' then -- stop here if a table wans't passed
-    error('Expecting table of string as arg1')
-  elseif cinfo.signature then -- new sig
-    sig = cinfo.signature
-  elseif isNew then -- new channel sig
-    sig = 'Ch'
-  else -- old sig
-    sig = db.channels[id].signature
-  end
-  t_info.signature = sig
-  --@debug@
-  --print('setchan(2) sig,id,isNew=', sig, id, isNew)--@end-debug@
-
-  for k,v in pairs(cinfo) do -- allow all cinfo to pass
-    t_info[k] = v
-  end
-
-  local blocked = {          -- ignore these vars:
-    ['docked'] = true,       -- table
-    ['dockedTo'] = true,     -- table-related
-    ['signature'] = true}    -- already determined
-  for k,v in pairs(dbvars) do
-    if not t_info[k] and not blocked[k] then -- already set or blocked?
-      t_info[k] = v
-    end
-  end
-  -- new channel overrides
-  if isNew then
-    if D.sigID[sig]then -- find a non-clashing signature
-    local result, i = sig, 1
-    while D.sigID[result] do
-      result = sig .. i
-      i = i + 1
-    end
-    t_info.signature = result
-    end
-    t_id = db.max_channel + 1
-    t_info.index = t_id
-    --@debug@
-    --print('setchan(3a) isNew, sig, t_info.signature=', isNew, sig, t_info.signature)--@end-debug@
-  else
-    --@debug@
-    --print('setchan(3b) isNew, sig, t_info.signature=', isNew, sig, t_info.signature)--@end-debug@
-  end
-
-  local channel
-  if not self.console[t_id] then -- create a frame
-    if isNew then -- position the channel frame
-      t_info.x = t_info.x + 20
-      t_info.y = t_info.y - 20
-      db.channels[t_id] = t_info
-      --@debug@
-      print('setchan(4a)', 't_id, x, y=', t_id, t_info.x, t_info.y)--@end-debug@
-    end
-    channel = CreateConsole(t_id, t_info)
-    self.console[t_id] = channel
-    self.sig[t_info.signature] = channel
-    self.sigID[t_info.signature] = t_id
-    self.IDsig[t_id] = t_info.signature
-
-  end
-  channel = self.console[t_id]
-  if channel.minimized then
-    channel:Minimize()
-  else
-    channel:Maximize()
-  end
-
-  if channel.enabled and db.enabled then -- hide or show last since Min/Max mess with visibility
-    print('setchan(5a) enable')
-    channel:Show()
-  else
-    print('setchan(5a) disable')
-    channel:Hide()
-  end
-  --@debug@
-  --print('setchan(end); c:IsVisible(), c.enabled, db.enabled=', channel:IsVisible(), channel.enabled, db.enabled)--@end-debug@
-  return channel
-end
 
 function D:PrintHelp()
   D:Print("|cFFFFFF00/dvn|r",
@@ -724,7 +379,9 @@
   if db.workspace == 1 then
     return
   end
-
+  -----------------------------------------------------------------------
+  self.db = db
+  self.channels = db.channels
   self.max_channel = 0
   self.num_channels = 0
   self.console = {}
--- a/Devian.toc	Sun Dec 27 02:33:06 2015 -0500
+++ b/Devian.toc	Sun Dec 27 03:51:17 2015 -0500
@@ -7,4 +7,5 @@
 ## OptionalDeps: Ace3
 Devian.xml
 Devian.lua
+UI.lua
 Dock.lua
\ No newline at end of file
--- a/Devian.xml	Sun Dec 27 02:33:06 2015 -0500
+++ b/Devian.xml	Sun Dec 27 03:51:17 2015 -0500
@@ -3,7 +3,8 @@
   <Script file="Libs\LibStub\LibStub.lua" />
   <Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml" />
   <Include file="Libs\AceAddon-3.0\Console-3.0.xml" />
-  <!--@end-no-lib-strip@-->.
+  <!--@end-no-lib-strip@-->
+
 
   <Texture virtual="true" name="DevianBorder" setAllPoints="false">
     <Color r="1" g="0" b="0" a="1" />
@@ -24,6 +25,42 @@
     </Gradient>
   </Texture>
 
+  <Button virtual="true" name="DevianDDButton" parentKey="button" alphaMode="BLEND">
+    <Scripts>
+      <OnClick>
+        ToggleDropDownMenu(1, nil, self:GetParent().menuFrame, self, 0, 0);
+      </OnClick>
+    </Scripts>
+    <Size x="16" y="16" />
+    <Layers>
+      <Layer level="ARTWORK">
+        <Texture file="Interface\Addons\Devian\menu-button.blp" setAllPoints="true" alphaMode="ADD">
+          <Color a="1" r="1" g="1" b="1" />
+        </Texture>
+      </Layer>
+    </Layers>
+  </Button>
+
+
+
+  <Frame name="DevianDDMenu" virtual="true" inherits="UIDropDownMenuTemplate" id="1">
+    <Scripts>
+      <OnLoad>
+        local f = self:GetParent()
+        UIDropDownMenu_Initialize(self, function()
+          local info            = {
+            text       = "Some Text",
+            value      = "OptionVariable",
+            func       = function () print(self:GetParent().signature, 'how') end
+          }
+          -- can also be done as function() FunctionCalledWhenOptionIsClicked() end;
+
+          -- Add the above information to the options menu as a button.
+          UIDropDownMenu_AddButton(info);
+        end, 'MENU')</OnLoad>
+    </Scripts>
+  </Frame>
+
   <ScrollingMessageFrame
       name="DevianBuffer"
       maxLines="500"
@@ -174,12 +211,16 @@
       </Layer>
     </Layers>
     <Frames>
+      <Frame name="$parentDDMenu" parentKey="menuFrame" inherits="DevianDDMenu" />
+      <Button name="$parentMenuButton" parentKey="menuButton" inherits="DevianDDButton" enableMouse="true">
+        <Anchors>
+          <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" x="-4" y="0" />
+        </Anchors>
+      </Button>
       <ScrollingMessageFrame parentKey="out" inherits="DevianBuffer" />
     </Frames>
   </Frame>
 
-
-
   <Frame
       name="DevianDockFrame"
       inherits="DevianConsole"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI.lua	Sun Dec 27 03:51:17 2015 -0500
@@ -0,0 +1,369 @@
+--- ${PACKAGE_NAME}
+-- @file-author@
+-- @project-revision@ @project-hash@
+-- @file-revision@ @file-hash@
+-- Created: 12/27/2015 3:01 AM
+
+
+if not LibStub then
+  print('Something has happened...')
+end
+local D = LibStub("AceAddon-3.0"):GetAddon("Devian")
+
+
+
+local DEVIAN_FRAME = 'DevianConsole'
+local DEVIAN_DOCK_FRAME = 'DevianDockFrame'
+local MSG_NEED_DEV_MODE = 'Must be in development mode to use this function.'
+
+
+local function Console_MinMax(self)
+  if self.minimized then
+    self:Maximize()
+  else
+    self:Minimize()
+  end
+end
+
+local function Console_Minimize(self)
+  self:SetHeight(20)
+  self:SetMaxResize(GetScreenWidth(),20)
+  self.minimized = true
+  self.out:Hide()
+  self:Save()
+end
+
+local function Console_Maximize(self)
+  local db = D.channels[self.index]
+  self:SetHeight(db.height)
+  self:SetMaxResize(GetScreenWidth(),GetScreenHeight())
+  self.minimized = nil
+  self.out:Show()
+  self:Save()
+end
+
+
+local function Console_Save(self)
+  local db = D.channels[self.index]
+  if self.x then
+    db.x = self.x
+  else
+    db.x = self:GetLeft()
+  end
+
+  if self.y then
+    db.y = self.y
+  else
+    db.y = (self:GetTop() - GetScreenHeight())
+  end
+
+  if self.width then
+    db.width = self.width
+  else
+    db.width = self:GetWidth()
+  end
+
+  if not self.minimized then
+    if self.height then
+      db.height = self.height
+    else
+      db.height = self:GetHeight()
+    end
+    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
+  --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)
+  self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y)
+  self:SetWidth(db.width)
+end
+
+-- Console frame toggler
+-- @paramsig [...]
+-- @param ... one or more space-seperated channel keys
+local function Console_Toggle(input)
+  local db = D.db
+  if db.workspace == 1 then
+    return D:Print(MSG_NEED_DEV_MODE)
+  end
+  local search = {}
+  local n = 0
+  if D:GetArgs(input,1) then
+    repeat
+      key, n = D:GetArgs(input,1,n)
+      if D.sig[key] then
+        table.insert(search, D.sig[key])
+      elseif D.console[key] then
+        table.insert(search, D.console[key])
+      end
+    until n == 1e9
+  else
+    search = D.console
+  end
+
+  db.enabled = (not db.enabled) and true or nil
+  for i, c in ipairs(search) do
+    --print(i,c.index)
+    if db.enabled then
+      c.enabled = true
+      c:Show()
+      if db.current_channel == c.index then
+        c:ToFront()
+      end
+      c:Save()
+    else
+      c:Hide()
+    end
+  end
+
+  if db.enabled then
+    D:Print('toggled on?')
+  else
+    D:Print('toggled off?')
+  end
+end
+
+--- Brings the console to the front.
+-- Frame method used to bring a console frame to the front of the display stack.
+local function Console_ToFront(c)
+  local db = D.db
+  --print(D.raise_ct, 'Raising', c.signature)
+  --print(unpack(db.frontdrop))
+  --print(unpack(db.frontgrad))
+  --print(db.frontblend)
+  -- D.raise_ct = D.raise_ct + 1
+  c:Raise()
+  c:SetAlpha(db.frontalpha)
+  c.out.backdrop:SetTexture(unpack(db.frontdrop))
+  c.out.backdrop:SetGradientAlpha(unpack(db.frontgrad))
+  c.out.backdrop:SetBlendMode(db.frontblend)
+  db.current_channel = c.index
+
+  for _, part in pairs(c.border) do
+    part:SetTexture(unpack(db.frontborder))
+  end
+
+  for id, bc in pairs(D.console) do
+    if id ~= c.index then
+      --print(D.raise_ct, 'Lowering', bc.signature)
+      --print(unpack(db.backdrop))
+      --print(unpack(db.backgrad))
+      --print(db.backblend)
+      bc:SetAlpha(db.backalpha)
+      bc.out.backdrop:SetTexture(unpack(db.backdrop))
+      bc.out.backdrop:SetGradientAlpha(unpack(db.backgrad))
+      bc.out.backdrop:SetBlendMode(db.backblend)
+
+      for _, part in pairs(bc.border) do
+        part:SetTexture(unpack(db.backborder))
+      end
+    end
+  end
+end
+
+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
+    if up then
+      self:MinMax()
+    end
+  end
+end
+local function Console_MouseUp(self, button)
+  return Console_MouseDown(self, button, true)
+end
+print('load check')
+
+
+--- 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)
+  local db = D.db
+  if tonumber(i) == nil or math.floor(i) ~= i then
+    error('Non-integer index value.')
+  end
+  if not vars then
+    vars = D.channels[i] and D.channels[i] or D.channels[db.primary_channel]
+  end
+  local f
+  if vars.docked then
+    f = CreateFrame('Frame','DevianDockFrame' .. i, DEVIAN_DOCK_FRAME)
+  else
+    f= CreateFrame('Frame', 'DevianChannelFrame' .. i, UIParent, DEVIAN_FRAME)
+  end
+  --@debug@
+  --print(f:GetName())
+
+  --print('create(2)')
+  for k,v in pairs(vars) do
+    f[k] = v
+    --@debug@
+    print(' f['..type(k)..' '..tostring(k)..'] = '..type(v)..' '..tostring(v))
+  end
+
+  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
+
+
+
+  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:SetScript('OnMouseDown', Console_MouseDown)
+  f:SetScript('OnMouseUp', Console_MouseUp)
+
+  if vars.minimized then
+    f:Minimize()
+  else
+    f:Maximize()
+  end
+  if db.enabled and f.enabled then
+    f:Show()
+  end
+
+  return f
+end
+
+
+--- Updates console information and returns the handle of the channel object that was worked on.
+-- When key is nil or not a valid handle, a new channel is created using whatever signature can be found in cinfo.
+-- The signature can be passed as a string, or as a table entry under the key 'signature'
+-- If the signature of a new channel is also a tag, the channel will be added to that tag
+-- @param cinfo string signature of a new channel, or a table of config variables to be imposed on the channel
+-- @param key string signature or index number of channel to operate on
+-- @usage channel = D:SetChannel('new', nil) -- creates a new channel
+-- @usage channel = D:SetChannel({x = 200, y = 100}, 4) -- updates channel #4
+function D:SetChannel(cinfo, key)
+  local db = self.db
+  local t_info = {}
+  local channel, isNew, id, sig, t_id
+  -- obtain source data
+  if tonumber(key) ~= nil and  db.channels[key] then
+    id = tonumber(key)
+  elseif D.sigID[tostring(key)] then
+    id = D.sigID[tostring(key)]
+  else
+    id = db.primary_channel
+    isNew = true
+  end
+  local dbvars = db.channels[id]
+  t_id = id           -- overridden later if new
+  t_info.index = t_id --
+  --@debug@
+  --print('setchan(1) cinfo, key, id=', cinfo, key, id)--@end-debug@
+
+
+  -- obtain config info
+  if type(cinfo) == 'string' then
+    sig = cinfo
+    cinfo = {signature = sig}
+  elseif type(cinfo) ~= 'table' then -- stop here if a table wans't passed
+  error('Expecting table of string as arg1')
+  elseif cinfo.signature then -- new sig
+  sig = cinfo.signature
+  elseif isNew then -- new channel sig
+  sig = 'Ch'
+  else -- old sig
+  sig = db.channels[id].signature
+  end
+  t_info.signature = sig
+  --@debug@
+  --print('setchan(2) sig,id,isNew=', sig, id, isNew)--@end-debug@
+
+  for k,v in pairs(cinfo) do -- allow all cinfo to pass
+  t_info[k] = v
+  end
+
+  local blocked = {          -- ignore these vars:
+    ['docked'] = true,       -- table
+    ['dockedTo'] = true,     -- table-related
+    ['signature'] = true}    -- already determined
+  for k,v in pairs(dbvars) do
+    if not t_info[k] and not blocked[k] then -- already set or blocked?
+    t_info[k] = v
+    end
+  end
+  -- new channel overrides
+  if isNew then
+    if D.sigID[sig]then -- find a non-clashing signature
+    local result, i = sig, 1
+    while D.sigID[result] do
+      result = sig .. i
+      i = i + 1
+    end
+    t_info.signature = result
+    end
+    t_id = db.max_channel + 1
+    t_info.index = t_id
+    --@debug@
+    --print('setchan(3a) isNew, sig, t_info.signature=', isNew, sig, t_info.signature)--@end-debug@
+  else
+    --@debug@
+    --print('setchan(3b) isNew, sig, t_info.signature=', isNew, sig, t_info.signature)--@end-debug@
+  end
+
+  local channel
+  if not self.console[t_id] then -- create a frame
+  if isNew then -- position the channel frame
+  t_info.x = t_info.x + 20
+  t_info.y = t_info.y - 20
+  db.channels[t_id] = t_info
+  --@debug@
+  print('setchan(4a)', 't_id, x, y=', t_id, t_info.x, t_info.y)--@end-debug@
+  end
+  channel = CreateConsole(t_id, t_info)
+  self.console[t_id] = channel
+  self.sig[t_info.signature] = channel
+  self.sigID[t_info.signature] = t_id
+  self.IDsig[t_id] = t_info.signature
+
+  end
+  channel = self.console[t_id]
+  if channel.minimized then
+    channel:Minimize()
+  else
+    channel:Maximize()
+  end
+
+  if channel.enabled and db.enabled then -- hide or show last since Min/Max mess with visibility
+  print('setchan(5a) enable')
+  channel:Show()
+  else
+    print('setchan(5a) disable')
+    channel:Hide()
+  end
+  --@debug@
+  --print('setchan(end); c:IsVisible(), c.enabled, db.enabled=', channel:IsVisible(), channel.enabled, db.enabled)--@end-debug@
+  return channel
+end
\ No newline at end of file