changeset 98:33bc8baba858

start of a lot of v3 groundwork based on better knowledge of the addon interface: - use of mixin as a lexical center for generated frames - removal of unfinished segments
author Nenue
date Wed, 26 Oct 2016 10:17:43 -0400
parents 34131d11e61b
children 7d94df3804a7
files Console.lua Console.xml Devian.lua Devian.toc Devian.xml Dock.lua Dock.xml UI.lua
diffstat 8 files changed, 544 insertions(+), 301 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Console.lua	Wed Oct 26 10:17:43 2016 -0400
@@ -0,0 +1,146 @@
+-- Mixin for console
+local _, D = ...
+DevianConsoleMixin = {}
+
+function DevianConsoleMixin:OnLoad()
+  self:SetMaxResize(GetScreenWidth(), GetScreenHeight())
+  self:SetMinResize(100, 24)
+
+  self:EnableMouse(true)
+  self:RegisterForDrag('LeftButton')
+  self:SetMovable(true)
+  self:SetResizable(true)
+  self.out:SetFont("Interface\\Addons\\Devian\\font\\SourceCodePro-Regular.ttf", 13, 'NORMAL')
+  self.out:SetJustifyH('LEFT')
+  self.out:SetFading(false)
+
+  self.width = self:GetWidth()
+  self.height = self:GetWidth()
+end
+
+function DevianConsoleMixin:Setup(info)
+  for k,v in pairs(info) do
+    self[k] = v
+    --oldprint(k,v)
+  end
+  self.Dock = DevianDock:GetDockButton(self)
+  self:Update()
+end
+
+function DevianConsoleMixin:Update()
+  self.title:SetText(self.index..' '.. (self.signature or '?'))
+  self:SetSize(self.width, self.height)
+  self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', self.x, self.y)
+  --  oldprint(self:GetName(), self.x, self.y)
+
+  local isFront = D.currentProfile.current_channel == self.index
+  local r,g,b,a = unpack(D.db.backborder)
+  if isFront then
+    r,g,b,a = unpack(D.db.frontborder)
+    self.backdrop:SetColorTexture(0,0,0,1)
+  else
+    self.backdrop:SetColorTexture(0,0,0,0.5)
+
+  end
+  for name, region in pairs(self.border) do
+    region:SetColorTexture(r,g,b,a)
+  end
+
+  --oldprint(self:GetID(), self.enabled, self.minimized, self.x, self.y)
+  self.isFront = isFront
+  self:SetShown(self.enabled)
+  self.out:SetShown(self.enabled)
+end
+
+
+function DevianConsoleMixin:OnShow()
+  self:Update()
+end
+
+
+
+function DevianConsoleMixin:OnHide() end
+
+function DevianConsoleMixin:OnMouseWheel(delta)
+
+  local up =  delta > 0
+  if IsControlKeyDown() then
+    if up then self.out:ScrollToTop()
+    else self.out:ScrollToBottom() end
+  elseif IsShiftKeyDown() then
+    if up then self.out:PageUp()
+    else self.out:PageDown() end
+  else
+    if up then self.out:ScrollUp()
+    else self.out:ScrollDown() end
+  end
+end
+function DevianConsoleMixin:MinMax(minimized)
+  minimized = minimized or self.minimized
+  if minimized then
+    self:Maximize()
+  else
+    self:Minimize()
+  end
+end
+
+function DevianConsoleMixin:Minimize()
+  self:SetHeight(20)
+  self:SetMaxResize(GetScreenWidth(),20)
+  self.minimized = true
+  self.out:Hide()
+  D.channels[self.index].minimized = true
+end
+
+function DevianConsoleMixin:Maximize()
+  local db = D.channels[self.index]
+  self:SetHeight(db.height)
+  self:SetMaxResize(GetScreenWidth(),GetScreenHeight())
+  self.minimized = nil
+  self.out:Show()
+  D.channels[self.index].minimized = nil
+end
+
+function DevianConsoleMixin:OnMouseUp(button)
+  if button == 'LeftButton' then
+    self:ToFront()
+  else
+    self:MinMax()
+  end
+end
+
+function DevianConsoleMixin:OnLeave()
+end
+
+function DevianConsoleMixin:OnEnter()
+end
+
+function DevianConsoleMixin:OnDragStart()
+
+    self:StartMoving()
+end
+
+function DevianConsoleMixin:OnDragStop()
+  self.x = self:GetLeft()
+  self.y = self:GetTop() - GetScreenHeight()
+  D.currentProfile.channels[self:GetID()].x = self:GetLeft()
+  D.currentProfile.channels[self:GetID()].y = self:GetTop() - GetScreenHeight()
+  self:StopMovingOrSizing()
+end
+
+function DevianConsoleMixin:Reset()
+end
+
+function DevianConsoleMixin:ToFront()
+  self:Raise()
+  D.currentProfile.current_channel = self.index
+  for index, channel in ipairs(D.console) do
+    channel:Update()
+  end
+end
+
+function DevianConsoleMixin:Toggle()
+  self.enabled = (not self.enabled)
+  --oldprint(self:GetID(), self.enabled)
+  self:Update()
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Console.xml	Wed Oct 26 10:17:43 2016 -0400
@@ -0,0 +1,154 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
+..\FrameXML\UI.xsd">
+  <Script file="Console.lua" />
+
+
+  <Frame name="DevianConsoleTemplate" toplevel="true" parent="UIParent" mixin="DevianConsoleMixin" virtual="true" hidden="true">
+    <Scripts>
+      <OnLoad method="OnLoad" />
+      <OnShow method="OnShow" />
+      <OnMouseWheel method="OnMouseWheel" />
+      <OnDragStart method="OnDragStart" />
+      <OnDragStop method="OnDragStop" />
+      <OnMouseUp method="OnMouseUp" />
+      <OnEnter method="OnEnter" />
+      <OnLeave method="OnLeave" />
+    </Scripts>
+    <Layers>
+      <Layer level="OVERLAY">
+        <Texture parentKey="header" inherits="DevianHeader">
+          <Anchors>
+            <Anchor point="TOPLEFT" />
+            <Anchor point="TOPRIGHT" />
+            <Size y="20" />
+          </Anchors>
+        </Texture>
+        <FontString parentKey="title" font="Interface\Addons\Devian\font\SourceCodePro-Bold.ttf" wordwrap="true"
+                    justifyH="LEFT"
+                    indented="true">
+          <Anchors>
+            <Anchor point="TOPLEFT" x="4" y="0" />
+          </Anchors>
+          <Size y="20" />
+          <FontHeight>
+            <AbsValue val="12"/>
+          </FontHeight>
+        </FontString>
+      </Layer>
+      <Layer level="BORDER">
+        <Texture name="DevBorderUR" parentArray="border" parentkey="topright" inherits="DevianBorder">
+          <Anchors>
+            <Anchor point="BOTTOMLEFT" relativePoint="TOPRIGHT" />
+          </Anchors>
+        </Texture>
+        <Texture name="DevBorderU" parentArray="border" parentKey="top" inherits="DevianBorder">
+          <Anchors>
+            <Anchor point="TOPLEFT"  y="2" />
+            <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT" />
+          </Anchors>
+        </Texture>
+        <Texture name="DevBorderUL" parentArray="border" parentKey="topleft" inherits="DevianBorder">
+          <Anchors>
+            <Anchor point="BOTTOMRIGHT" parentArray="border" relativePoint="TOPLEFT" />
+          </Anchors>
+        </Texture>
+        <Texture name="DevBorderL" parentArray="border" parentKey="left" inherits="DevianBorder">
+          <Anchors>
+            <Anchor point="TOPLEFT"  x="-2" />
+            <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMLEFT" />
+          </Anchors>
+        </Texture>
+        <Texture name="DevBorderBL" parentArray="border" inherits="DevianBorder">
+          <Anchors>
+            <Anchor point="TOPRIGHT" relativePoint="BOTTOMLEFT" />
+          </Anchors>
+        </Texture>
+        <Texture name="DevBorderB" parentArray="border" inherits="DevianBorder">
+          <Anchors>
+            <Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT" />
+            <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" y="-2" />
+          </Anchors>
+        </Texture>
+        <Texture name="DevBorderBR" parentArray="border" inherits="DevianBorder">
+          <Anchors>
+            <Anchor point="TOPLEFT" relativePoint="BOTTOMRIGHT" />
+          </Anchors>
+        </Texture>
+        <Texture name="DevBorderR" parentArray="border" parentKey="right" inherits="DevianBorder">
+          <Anchors>
+            <Anchor point="TOPLEFT" relativePoint="TOPRIGHT" />
+            <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="2" />
+          </Anchors>
+        </Texture>
+      </Layer>
+
+      <Layer level="ARTWORK">
+        <Texture name="$parentBackdrop" parentKey="backdrop" setAllPoints="true" alphaMode="BLEND">
+          <Color r="1" g="1" b="1" a="1"/>
+        </Texture>
+      </Layer>
+    </Layers>
+    <Frames>
+      <Button name="$parentMenuButton"  parentKey="dropmenu" inherits="DevianDDButton" enableMouse="true">
+        <Anchors>
+          <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" x="-4" y="0" />
+        </Anchors>
+      </Button>
+
+      <Frame name="$parentDDMenu" parentKey="menuFrame" id="1">
+        <Scripts>
+          <OnLoad>
+          </OnLoad>
+        </Scripts>
+      </Frame>
+      <ScrollingMessageFrame inherits="DevianBuffer" />
+
+
+      <ScrollingMessageFrame parentKey="out" name="$parentScrollFrame" maxLines="500" fade="false" displayDuration="3600" fadeDuration="3600" insertMode="BOTTOM">
+        <Anchors>
+          <Anchor point="TOPLEFT" x="3" y="-20" />
+          <Anchor point="BOTTOMRIGHT" x="-3" y="0" />
+        </Anchors>
+        <Layers>
+          <Layer level="OVERLAY">
+          </Layer>
+        </Layers>
+      </ScrollingMessageFrame>
+      <Button name="$parentResizeButton" parentKey="ResizeButton">
+        <Scripts>
+          <OnLoad>
+            self:RegisterForDrag('LeftButton')
+          </OnLoad>
+          <OnDragStart>
+            self:GetParent():StartSizing()
+          </OnDragStart>
+          <OnDragStop>
+            self:GetParent():StopMovingOrSizing()
+          </OnDragStop>
+        </Scripts>
+        <Anchors>
+          <Anchor point="BOTTOMRIGHT" x="-1" y="1" />
+        </Anchors>
+        <Size x="18" y="18" />
+        <Layers>
+          <Layer level="ARTWORK">
+            <Texture name="DevianGripperRight" file="Interface\Addons\Devian\corner.blp" parentKey="grip" alphaMode="ADD">
+              <Color r="0.4" g="0.4" b="0.4" a="1"/>
+              <Gradient orientation="VERTICAL">
+                <MaxColor r="0.9" g="0.9" b="0.9" a="1"/>
+                <MinColor r="0.4" g="0.4" b="0.4" a="1"/>
+              </Gradient>
+            </Texture>
+          </Layer>
+        </Layers>
+      </Button>
+
+    </Frames>
+    <Animations>
+      <AnimationGroup name="moveFade" parentKey="moveFade" setToFinalAlpha="true">
+        <Alpha parentKey="alphaOut" duration="0.5" order="1" />
+        <Translation parentKey="translateOut" duration="0.5" order="1" />
+      </AnimationGroup>
+    </Animations>
+  </Frame>
+</Ui>
\ No newline at end of file
--- a/Devian.lua	Tue Oct 25 12:35:12 2016 -0400
+++ b/Devian.lua	Wed Oct 26 10:17:43 2016 -0400
@@ -11,9 +11,8 @@
 
 local ADDON, D = ...
 local MAJOR, MINOR = 'Devian-2.0', 'r@project-revision@'
-local D =  LibStub("AceAddon-3.0"):NewAddon(D, "Devian", "AceConsole-3.0", "AceEvent-3.0")
-local L = D.L
-Devian = D
+local D_INITIALIZED
+local next = next
 local sub, GetTime, print, _G = string.sub, GetTime, print, _G
 local format, setmetatable, getprinthandler, setprinthandler = string.format, setmetatable, getprinthandler, setprinthandler
 local tinsert, tremove, rawset = tinsert, tremove, rawset
@@ -23,6 +22,28 @@
 local num_dock_tabs = 0
 local charStates ={}
 
+local registeredTags = {}
+
+
+DevianCore = {}
+
+function DevianCore:OnLoad ()
+  self:RegisterEvent('ADDON_LOADED')
+  self:RegisterEvent('PLAYER_LOGIN')
+  self:SetShown(true)
+end
+
+function DevianCore:OnEvent(event, arg)
+  if event == 'ADDON_LOADED' or event == 'PLAYER_LOGIN' then
+    --print(event, arg, DevianDB)
+    if (arg == 'Devian') and not D_INITIALIZED then
+      D_INITIALIZED = true
+      self:Initialize()
+      self:UnregisterAllEvents()
+    end
+  end
+end
+
 DevianLoadMessage = setmetatable({}, {
   __call = function(t, msg)
     rawset(t, #t+1, msg)
@@ -37,7 +58,7 @@
 --@end-debug@
 D.print = function(...)
   if currentProfile and not currentProfile.workspace then
-    return
+    return nop
   end
 
   if D.debugmode then
@@ -50,13 +71,12 @@
 
 D.L = setmetatable({}, {
   __index= function(t,k)
-    return k
+    return tostring(k)
   end,
   __call = function(t,k,...)
-    return format((t[k] or k) , ...)
+    return format((t[k]) , ...)
   end
 })
-D:SetDefaultModuleState(false)
 D.oldprint = getprinthandler()
 if not _G.oldprint then _G.oldprint = D.oldprint end
 
@@ -67,12 +87,12 @@
 local GetNumAddOns, GetAddOnInfo, GetAddOnEnableState, EnableAddOn = GetNumAddOns, GetAddOnInfo, GetAddOnEnableState, EnableAddOn
 local UnitName, DisableAddOn = UnitName, DisableAddOn
 
-local db
+local db, L
 local defaults = {
   global = {{}, {}},
   default_channel = {
     signature = 'Main',
-    x = 100, y = 800,
+    x = 100, y = -200,
     height = 500, width = 600,
     enabled = true},
   current_profile = 1,
@@ -149,7 +169,7 @@
     {
       index = 1,
       signature = 'Main',
-      x = 100, y = 800,
+      x = 100, y = -200,
       height = 500, width = 600,
       enabled = true
     }
@@ -184,6 +204,44 @@
   end
 end
 
+D.FixProfile = function(forced)
+
+  local numChannels = 0
+  local minChannel = 400
+  local sortedChannels = {}
+  local sortedTags = {}
+  local maxChannel = 0
+  for k,v in pairs(currentProfile.channels) do
+    numChannels = numChannels + 1
+    maxChannel = max(tonumber(k), maxChannel)
+    minChannel = min(tonumber(k), minChannel)
+    tinsert(sortedChannels, v)
+  end
+  if (maxChannel > numChannels) or forced then
+    oldprint('fixing channels data')
+    table.sort(sortedChannels, function(a,b)
+      return (b.index > a.index)
+    end)
+    for i, info in ipairs(sortedChannels) do
+      for tag, tagSet in pairs(currentProfile.tags) do
+        for _, index in pairs(tagSet) do
+          if index == info.index then
+            sortedTags[tag] = sortedTags[tag] or {}
+            sortedTags[tag][i] = i
+          end
+        end
+      end
+
+      info.index = i
+    end
+    currentProfile.channels = sortedChannels
+    currentProfile.tags = sortedTags
+  else
+    minChannel = 2
+  end
+  currentProfile.lastUpdateFix = MINOR
+end
+
 D.Profile = function (id, name)
 
   if name and not id and db.profilesName[name] then
@@ -229,6 +287,7 @@
     DEVIAN_WORKSPACE = true
     DEVIAN_PNAME = currentProfile.name
     DEVIAN_PID = id
+    print('setting phandler')
     setprinthandler(D.Message)
   else
     DEVIAN_WORKSPACE = false
@@ -237,6 +296,16 @@
   end
   DEVIAN_PID =id
 
+
+  -- Attempt to fix bad data
+  --@debug@
+  MINOR = 70100
+  --@end-debug@
+  if (currentProfile.lastUpdateFix or 0) < MINOR then
+    D.FixProfile(true)
+  end
+
+
   D.unlisted = currentProfile.unlisted
   D.channels = currentProfile.channels
   D.tags = currentProfile.tags
@@ -251,6 +320,8 @@
   D.dock = _G.DevianDock
   D.dock.buttons = D.dock.buttons or {}
 
+
+
   return id, name
 end
 
@@ -450,6 +521,19 @@
   end
 end
 
+D.UpdateTags = function()
+
+  wipe(registeredTags)
+  for tag, tagSet in pairs(currentProfile.tags) do
+    registeredTags[tag] = registeredTags[tag] or {}
+    for _, id in pairs(tagSet) do
+      if D.console[id] then
+        tinsert(registeredTags[tag], D.console[id])
+      end
+    end
+  end
+end
+
 D.Tag = function(self, tag, dest)
   local sig
   if tag ~= nil and dest ~= nil then
@@ -473,11 +557,11 @@
     -- make a new channel?
     local channel
     if not currentProfile.channels[dest] then
-      dest = D.max_channel + 1
+      dest = #D.channels + 1
       D:Print(L('New channel created', sig and (dest..':'..sig) or dest ))
-      channel = D:SetChannel(sig or tag,dest)
+      channel = D:GetOrCreateChannel(dest, tag)
     else
-      channel = D.channels[dest]
+      channel = currentProfile.channels[dest]
     end
     --@debug@
     --print('3 tag,dest,channel.sig=',tag, dest, channel.signature)--@end-debug@
@@ -487,13 +571,14 @@
     end
 
     if currentProfile.tags[tag][dest] then -- is tag set?
-    currentProfile.tags[tag][dest] = nil
-    D:Print(L('Tag removed from channel', tag, currentProfile.channels[dest].index, currentProfile.channels[dest].signature))
+      currentProfile.tags[tag][dest] = nil
+      D:Print(L('Tag removed from channel', tag, currentProfile.channels[dest].index, currentProfile.channels[dest].signature))
     else
       currentProfile.tags[tag][dest] = dest
-      D:Print(L('Tag added to channel', tag, currentProfile.channels[dest].index, currentProfile.channels[dest].signature))
+      D:Print(L('Tag added to channel', tag, channel.index, channel.signature))
     end
-    D:UpdateDock()
+    D.UpdateTags()
+    DevianDock:Update()
   else
     D:Print(L['Command tag help'])
   end
@@ -547,35 +632,32 @@
 -- This becomes the print handler when development mode is active. The original print() function is assigned to oldprint().
 -- @param Tag, signature, or numeric index of the channel to output on. Defaults to primary channel.
 -- @param ... Output contents.
-
+local default_sendq = {}
 function D.Message(prefix, ...)
   if not currentProfile.workspace then
     return D.oldprint(prefix, ...)
   end
+  local print = D.oldprint
   prefix =  tostring(prefix)
   if prefix == nil then
     prefix = 'nil*'
   end
 
-  local sendq = {}
+  local sendq = default_sendq
   local tag, id, tagged
   local byName = true
-  if D.tags[prefix] then
-    for _, id in pairs(D.tags[prefix]) do
-      if D.console[id] then
-        sendq[id] = D.console[id]
-        tagged = true
-      end
+
+  if registeredTags[prefix] then
+    sendq = registeredTags[prefix]
+  else
+    if D.sig[prefix] then
+      sendq[D.sig[prefix].index] = D.sig[prefix]
+    elseif not tagged then
+      sendq[1] = D.console[D.primary_channel]
     end
   end
 
-  if D.sig[prefix] then
-    sendq[D.sig[prefix].index] = D.sig[prefix]
-  elseif D.console[prefix] then
-    sendq[D.console[prefix]] = D.console[prefix]
-  elseif not tagged then
-    sendq[D.primary_channel] = D.console[D.primary_channel]
-  end
+
 
   -- color me timbers
   local pcolor
@@ -625,12 +707,11 @@
     if channel.width < 250 then
       prefix = sub(prefix, 0,2)
     end
-    --currentProfile.last_channel = channel.index
-    channel.out:AddMessage('|cFF'.. pcolor..prefix ..'|r ' .. message, 0.8, 0.8, 0.8, nil, nil, prefix, GetTime())
-    if not D.dock.usedButtons[id].newMessage then
-      D.dock.usedButtons[id].newMessage = true
-      D.dock.usedButtons[id].caption.pulse:Play()
-      D.dock.usedButtons[id]:Update()
+    channel.out:AddMessage('|cFF'.. pcolor..prefix ..'|r ' .. message, 0.8, 0.8, 0.8)
+    if channel.Dock and not channel.Dock.newMessage then
+      channel.Dock.newMessage = true
+      channel.Dock.caption.pulse:Play()
+      channel.Dock:Update()
     end
   end
   wipe(buffer)
@@ -682,15 +763,15 @@
 end
 
 
-function D:OnInitialize()
+function DevianCore:Initialize()
   L = D.L
 
   -- pull defaults
-  if not _G.DevianDB then
-    _G.DevianDB = defaults
+  if not DevianDB then
+    DevianDB = defaults
   end
+  D.db = _G.DevianDB
   db = _G.DevianDB
-  self.db = db
 
   ---
   if #_G.DevianLoadMessage >= 1 then
@@ -735,16 +816,16 @@
   end
 
 
-  for i, cinfo in pairs(D.channels) do
-    i = tonumber(i)
+
+  for index, cinfo in ipairs(D.channels) do
+    --oldprint(index, cinfo.signature)
     if not D.primary_channel then
-      D.primary_channel = i
+      D.primary_channel = index
     end
-    D:SetChannel(cinfo, i)
-    D.num_channels = D.num_channels + 1
+    D:GetOrCreateChannel(index)
+    D.num_channels = #D.channels
   end
   D.primary_channel = D.primary_channel or 1
-
   D.max_channel = max(D.max_channel, currentProfile.max_channel)
   if currentProfile.max_channel < D.max_channel then
     for i = currentProfile.max_channel, D.max_channel do
@@ -752,14 +833,53 @@
     end
   end
 
+  D.UpdateTags()
+
   if currentProfile.workspace then
     if D.console[currentProfile.current_channel] then
       --print('bringing', D.console[currentProfile.current_channel].signature, 'to the front')
       D.console[currentProfile.current_channel]:ToFront()
       -- bring the current channel to the front
     end
-    _G.DevianDock:Show()
-    D:UpdateDock()
+    DevianDock:Update()
   end
+
+  print('devian')
 end
 
+function D:Print (...)
+  local msg = '|cFF00FF44Devian|r:'
+  for i = 1, select('#', ...) do
+    msg = msg .. ' ' .. tostring(select(i, ...))
+  end
+  DEFAULT_CHAT_FRAME:AddMessage(msg)
+end
+
+function D:GetActiveChannel()
+  return D.console[currentProfile.current_channel]
+end
+
+function D:GetOrCreateChannel(id, name)
+  local info = D.channels[id]
+  local frame = D.console[id]
+  if not frame then
+
+    --print('new frame')
+    frame = CreateFrame('Frame', 'DevianConsole'..id, Devian, 'DevianConsoleTemplate')
+    frame:SetID(id)
+    D.console[id] = frame
+  end
+  if not info then
+    --print('new channel')
+    info = {
+    }
+    D.DeepCopy(defaults.default_channel, info)
+    info.index = id
+    info.signature = name
+    D.channels[id] = info
+  end
+
+
+  frame:Setup(info)
+  return frame
+end
\ No newline at end of file
--- a/Devian.toc	Tue Oct 25 12:35:12 2016 -0400
+++ b/Devian.toc	Wed Oct 26 10:17:43 2016 -0400
@@ -11,8 +11,8 @@
 Libs\CallbackHandler-1.0\CallbackHandler-1.0.lua
 Libs\AceEvent-3.0\AceEvent-3.0.xml
 Devian.xml
-Devian.lua
+Console.xml
+Dock.xml
 Locale.lua
 UI.lua
 Config.lua
-Dock.lua
--- a/Devian.xml	Tue Oct 25 12:35:12 2016 -0400
+++ b/Devian.xml	Wed Oct 26 10:17:43 2016 -0400
@@ -1,16 +1,17 @@
 <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
 ..\FrameXML\UI.xsd">
   <!--@no-lib-strip@-->
-  <Script file="Libs\LibStub\LibStub.lua" />
-  <Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml" />
-  <Include file="Libs\AceConsole-3.0\Console-3.0.xml" />
   <!--@end-no-lib-strip@-->
 
+  <Script file="Devian.lua" />
 
-  <Texture virtual="true" name="DevianBorder" setAllPoints="false">
-    <Color r="1" g="0" b="0" a="1" />
-    <Size x="2" y="2" />
-  </Texture>
+  <Frame name="Devian" mixin="DevianCore" parent="UIParent">
+      <Scripts>
+        <OnLoad method="OnLoad" />
+        <OnEvent method="OnEvent" />
+      </Scripts>
+  </Frame>
+
 
 
   <Texture virtual="true" name="DevianHeader" alphaMode="BLEND">
@@ -48,216 +49,12 @@
     </Scripts>
   </Button>
 
-  <Font name="DevianDockHeader" font="Fonts\ARIALN.TTF" outline="NORMAL" virtual="true" height="14" />
 
-  <Font name="DevianText" font="Interface\Addons\Devian\font\SourceCodePro-Regular.ttf" outline="NORMAL" virtual="true">
-    <FontHeight>
-      <AbsValue val="13" />
-    </FontHeight>
+  <Font name="DevianText" font="Interface\Addons\Devian\font\SourceCodePro-Regular.ttf" height="13" justifyH="LEFT" outline="NORMAL" virtual="true">
     <Color r="1" g="1" b="1" a="1" />
   </Font>
 
-  <Frame name="DevianDDMenu" virtual="true" inherits="UIDropDownMenuTemplate" id="1">
-    <Scripts>
-      <OnLoad>
-        </OnLoad>
-    </Scripts>
-  </Frame>
 
-  <ScrollingMessageFrame
-      name="DevianBuffer"
-      maxLines="500"
-      fade="false"
-      displayduration="2147483647"
-      insertMode="BOTTOM"
-      virtual="true">
-    <Anchors>
-      <Anchor point="TOPLEFT" y="-20" />
-      <Anchor point="BOTTOMRIGHT" />
-    </Anchors>
-    <FontString inherits="DevianFont" wordwrap="true"
-                 justifyH="LEFT"
-                 indented="true"
-                 setAllPoints="true"
-                  parentArray="_msg">
-      <FontHeight>
-        <AbsValue val="13"/>
-      </FontHeight>
-    </FontString>
-
-    <Layers>
-      <Layer level="ARTWORK">
-        <Texture name="$parentBackdrop" parentKey="backdrop" setAllPoints="true" alphaMode="BLEND">
-          <Color r="1" g="1" b="1" a="1"/>
-          <Gradient orientation="VERTICAL">
-            <MinColor r="0" g="0" b="0" a="0.7"/>
-            <MaxColor r="0" g="0" b="0" a="0.3"/>
-          </Gradient>
-        </Texture>
-      </Layer>
-      <Layer level="OVERLAY">
-        <Texture name="DevianGripperRight" file="Interface\Addons\Devian\corner.blp" parentKey="grip" strata="HIGH" alphaMode="ADD">
-          <Anchors>
-            <Anchor point="BOTTOMRIGHT" x="-1" y="1" />
-          </Anchors>
-          <Size x="18" y="18" />
-          <Color r="0.4" g="0.4" b="0.4" a="1"/>
-          <Gradient orientation="VERTICAL">
-            <MaxColor r="0.9" g="0.9" b="0.9" a="1"/>
-            <MinColor r="0.4" g="0.4" b="0.4" a="1"/>
-          </Gradient>
-        </Texture>
-      </Layer>
-    </Layers>
-  </ScrollingMessageFrame>
-
-  <Frame
-      name="DevianConsole"
-      parent="UIParent"
-      enableMouse="true"
-      enableMouseWheel="true"
-      clampedToScreen="true"
-      movable="true"
-      resizable="true"
-      toplevel="true"
-      hidden="true"
-      virtual="true">
-    <ResizeBounds>
-      <minResize x="200" y="20" />
-      <maxResize x="1920" y="1200" />
-    </ResizeBounds>
-    <Scripts>
-      <OnShow>
-        self.title:SetText(self.index..' '.. self.signature)
-      </OnShow>
-      <OnMouseWheel>
-        local up =  delta > 0
-        if IsControlKeyDown() then
-          if up then self.out:ScrollToTop()
-          else self.out:ScrollToBottom() end
-        elseif IsShiftKeyDown() then
-          if up then self.out:PageUp()
-          else self.out:PageDown() end
-        else
-          if up then self.out:ScrollUp()
-          else self.out:ScrollDown() end
-        end
-      </OnMouseWheel>
-    </Scripts>
-    <Layers>
-      <Layer level="OVERLAY">
-        <Texture parentKey="header" inherits="DevianHeader">
-          <Anchors>
-            <Anchor point="TOPLEFT" />
-            <Anchor point="TOPRIGHT" />
-            <Size y="20" />
-          </Anchors>
-        </Texture>
-        <FontString parentKey="title" font="Interface\Addons\Devian\font\SourceCodePro-Bold.ttf" wordwrap="true"
-                    justifyH="LEFT"
-                    indented="true">
-          <Anchors>
-            <Anchor point="TOPLEFT" x="4" y="0" />
-          </Anchors>
-          <Size y="20" />
-          <FontHeight>
-            <AbsValue val="12"/>
-          </FontHeight>
-        </FontString>
-      </Layer>
-      <Layer level="BORDER">
-        <Texture name="DevBorderUR" parentArray="border" parentkey="topright" inherits="DevianBorder">
-          <Anchors>
-            <Anchor point="BOTTOMLEFT" relativePoint="TOPRIGHT" />
-          </Anchors>
-        </Texture>
-        <Texture name="DevBorderU" parentArray="border" parentKey="top" inherits="DevianBorder">
-          <Anchors>
-            <Anchor point="TOPLEFT"  y="2" />
-            <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT" />
-          </Anchors>
-        </Texture>
-        <Texture name="DevBorderUL" parentArray="border" parentKey="topleft" inherits="DevianBorder">
-          <Anchors>
-            <Anchor point="BOTTOMRIGHT" parentArray="border" relativePoint="TOPLEFT" />
-          </Anchors>
-        </Texture>
-        <Texture name="DevBorderL" parentArray="border" parentKey="left" inherits="DevianBorder">
-          <Anchors>
-            <Anchor point="TOPLEFT"  x="-2" />
-            <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMLEFT" />
-          </Anchors>
-        </Texture>
-        <Texture name="DevBorderBL" parentArray="border" inherits="DevianBorder">
-          <Anchors>
-            <Anchor point="TOPRIGHT" relativePoint="BOTTOMLEFT" />
-          </Anchors>
-        </Texture>
-        <Texture name="DevBorderB" parentArray="border" inherits="DevianBorder">
-          <Anchors>
-            <Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT" />
-            <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" y="-2" />
-          </Anchors>
-        </Texture>
-        <Texture name="DevBorderBR" parentArray="border" inherits="DevianBorder">
-          <Anchors>
-            <Anchor point="TOPLEFT" relativePoint="BOTTOMRIGHT" />
-          </Anchors>
-        </Texture>
-        <Texture name="DevBorderR" parentArray="border" parentKey="right" inherits="DevianBorder">
-          <Anchors>
-            <Anchor point="TOPLEFT" relativePoint="TOPRIGHT" />
-            <Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT" x="2" />
-          </Anchors>
-        </Texture>
-      </Layer>
-    </Layers>
-    <Frames>
-      <Button name="$parentMenuButton"  parentKey="dropmenu" inherits="DevianDDButton" enableMouse="true">
-        <Anchors>
-          <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" x="-4" y="0" />
-        </Anchors>
-      </Button>
-      <Frame name="$parentDDMenu" parentKey="menuFrame" inherits="DevianDDMenu" />
-      <ScrollingMessageFrame parentKey="out" inherits="DevianBuffer" />
-    </Frames>
-    <Animations>
-      <AnimationGroup name="moveFade" parentKey="moveFade" setToFinalAlpha="true" ignoreFramerateThrottle="true">
-        <Alpha parentKey="alphaOut" duration="0.5" order="1" />
-        <Translation parentKey="translateOut" duration="0.5" order="1" />
-      </AnimationGroup>
-    </Animations>
-  </Frame>
-
-  <Frame
-      name="DevianDock"
-      parent="UIParent"
-      enableMouse="true"
-      alpha="0.1"
-      hidden="true"
-      frameStrata="LOW">
-    <Scripts>
-      <OnMouseWheel>
-        Devian.Dock_OnMouseWheel(self, delta)
-      </OnMouseWheel>
-    </Scripts>
-    <Size x="32" y="20" />
-    <Layers>
-      <Layer level="ARTWORK">
-        <Texture name="$parentBar" parent="DevianDock" setAllPoints="true" parentKey="caption" alphaMode="BLEND">
-          <Color r="1" g="1" b="1" a="1" />
-          <Gradient orientation="VERTICAL">
-            <MaxColor r="0.15" g=".15" b="0.15" a="0.4" />
-            <MinColor r="0" g="0" b="0" a="0" />
-          </Gradient>
-        </Texture>
-
-      </Layer>
-      <Layer level="OVERLAY">
-
-      </Layer>
-    </Layers>
-  </Frame>
   <Button name="DevianExecButton" parent="UIParent" hidden="true">
     <Size x="32" y="32" />
     <Anchors>
--- a/Dock.lua	Tue Oct 25 12:35:12 2016 -0400
+++ b/Dock.lua	Wed Oct 26 10:17:43 2016 -0400
@@ -7,9 +7,13 @@
 local _, D = ...
 local ceil, floor, sqrt, pairs, GetScreenWidth, GetScreenHeight =  math.ceil, math.floor, math.sqrt, pairs, GetScreenWidth, GetScreenHeight
 local db
-local print = D.print
+local print = DEVIAN_WORKSPACE and function(...) print('DvnDock', ...) end or nop
 local DOCK_BUTTON_PADDING = 6
 
+DevianDockHandler = {
+  usedButtons = {},
+  buttons = {},
+}
 DevianDockButtonMixin = {}
 
 --- Updates region visibility as needed
@@ -37,18 +41,19 @@
 end
 
 local numBeacons = 0
-function D:GetDockButton(console)
-  self.dock.usedButtons = self.dock.usedButtons or {}
-
-  local button = self.dock.usedButtons[console.index]
+function DevianDockHandler:GetDockButton(console)
+  self.usedButtons = self.usedButtons or {}
+  local index = console:GetID()
+  local button = self.usedButtons[index]
   if not button then
     numBeacons = numBeacons + 1
     button = CreateFrame('Button', 'DevianDockBeacon'.. numBeacons, UIParent, 'DevianBeacon')
     button.color = {r = math.random(), g = math.random(), b = math.random()}
     button.Stripe:SetColorTexture(button.color.r, button.color.g, button.color.b,1)
     button.console = console
-    self.dock.usedButtons[console.index] = button
-    tinsert(self.dock.buttons, button)
+    self.usedButtons[index] = button
+    tinsert(self.buttons, button)
+    --oldprint('create dock', index, console.signature)
   end
   button.index = console.index
   button.caption.name:SetText(console.signature)
@@ -60,10 +65,11 @@
   --print("click", self:GetName(), button, self.console.index)
   if button == "LeftButton" then
     if IsShiftKeyDown() then
-      D:Console_Toggle(self.console.index, 0)
+      self.console:Toggle()
     else
-      if self.console.index == D.currentProfile.current_channel or (not self.console.enabled) then
-        D:Console_Toggle(self.console.index)
+      if self.console.isFront or (not self.console.enabled) then
+
+        self.console:Toggle()
         if self.console.enabled then
           if self.console.minimized then
             self.console:MinMax()
@@ -77,7 +83,6 @@
   elseif button == "RightButton" then
     self.console:MinMax()
   end
-  self.console:Save()
 end
 function DevianDockButtonMixin:OnShow()
   self:Update()
@@ -148,22 +153,22 @@
   end
 end
 
-function D:Dock_OnMouseWheel(delta)
+function DevianDockHandler:OnMouseWheel(delta)
   if delta >= 1 then
-    D.dockScale = (D.dockScale or 1) - 0.1
+    self.dockScale = (self.dockScale or 1) - 0.1
   else
-    D.dockScale = (D.dockScale or 1) + 0.1
+    self.dockScale = (self.dockScale or 1) + 0.1
   end
-  D:UpdateDock()
+  self:Update()
 end
 
 --- Space everything and set the dock size
-function D:UpdateDock()
+function DevianDockHandler:Update()
   local pad_offset = 12
   local drawWidth = 0
   local lastButton
   local numButtons = 0
-  for i, d in ipairs(self.dock.buttons) do
+  for i, d in ipairs(self.buttons) do
     if d and d:IsShown() then
       d:SetScale(D.dockScale or 1)
       if lastButton then
@@ -179,9 +184,10 @@
     end
   end
   self.numButtons = numButtons
-  self.dock:SetWidth(drawWidth)
-  self.db.dockPoint = self.db.dockPoint or 'TOP'
-  self.dock:SetPoint(self.db.dockPoint, UIParent, self.db.dockPoint, 0, 0)
+  self:SetWidth(drawWidth)
+
+  D.db.dockPoint = D.db.dockPoint or 'TOPLEFT'
+  self:SetPoint(D.db.dockPoint , UIParent, D.db.dockPoint , 0, 0)
 end
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Dock.xml	Wed Oct 26 10:17:43 2016 -0400
@@ -0,0 +1,37 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
+..\FrameXML\UI.xsd">
+  <Script file="Dock.lua" />
+
+  <Font name="DevianDockHeader" font="Fonts\ARIALN.TTF" outline="NORMAL" virtual="true" height="14" />
+
+
+
+  <Frame
+      name="DevianDock"
+      parent="UIParent"
+      enableMouse="true"
+      alpha="0.1"
+      hidden="true"
+      mixin="DevianDockHandler"
+      frameStrata="LOW">
+    <Scripts>
+      <OnMouseWheel method="OnMouseWheel" />
+    </Scripts>
+    <Size x="32" y="20" />
+    <Layers>
+      <Layer level="ARTWORK">
+        <Texture name="$parentBar" parent="DevianDock" setAllPoints="true" parentKey="caption" alphaMode="BLEND">
+          <Color r="1" g="1" b="1" a="1" />
+          <Gradient orientation="VERTICAL">
+            <MaxColor r="0.15" g=".15" b="0.15" a="0.4" />
+            <MinColor r="0" g="0" b="0" a="0" />
+          </Gradient>
+        </Texture>
+
+      </Layer>
+      <Layer level="OVERLAY">
+
+      </Layer>
+    </Layers>
+  </Frame>
+</Ui>
\ No newline at end of file
--- a/UI.lua	Tue Oct 25 12:35:12 2016 -0400
+++ b/UI.lua	Wed Oct 26 10:17:43 2016 -0400
@@ -41,27 +41,12 @@
 
 
 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
 
@@ -143,8 +128,6 @@
   if button == 'LeftButton' then
     if up then
       self:StopMovingOrSizing()
-      self:ToFront()
-      self:Save()
     elseif self.out.grip:IsMouseOver() then
       self:StartSizing()
     else