changeset 84:16b300d96724

rewritten using mixin attributes
author Nenue
date Tue, 18 Oct 2016 13:07:21 -0400
parents 4ec4fd89fced
children 1196b8175674
files Modules/BuffFrame.lua Modules/BuffFrame.xml Modules/OrderHall.lua Modules/WorldState.lua Modules/WorldState.xml Veneer.lua Veneer.toc Veneer.xml
diffstat 8 files changed, 906 insertions(+), 736 deletions(-) [+]
line wrap: on
line diff
--- a/Modules/BuffFrame.lua	Tue Oct 18 01:57:02 2016 -0400
+++ b/Modules/BuffFrame.lua	Tue Oct 18 13:07:21 2016 -0400
@@ -25,9 +25,17 @@
 local BUFF_FRAMES_X = -230
 local BUFF_FRAMES_Y = -4
 
+VeneerBuffFrameMixin = {
+  moduleName = 'Buff Frames',
+  defaultCluster = 'TOPRIGHT',
+  Buttons = {},
+  DetectedFrames = {},
+  AuraCache = {}
+}
+local plugin = VeneerBuffFrameMixin
 
-local plugin = CreateFrame('Frame', 'VeneerBuffFrame', UIParent)
-local vn, print = LibStub("LibKraken").register(Veneer, plugin)
+local vn = Veneer
+local print = DEVIAN_WORKSPACE and function(...) _G.print('BuffFrame', ...) end or function() end
 local tprint = DEVIAN_WORKSPACE and function(...) _G.print('Timer', ...) end or function() end
 
 local _G, UIParent = _G, UIParent
@@ -68,56 +76,96 @@
 }
 
 
-local GetVeneer = function(frame)
+function plugin:Acquire(target)
 
-  if not (veneers[frame]) then
-    local name = frame:GetName()
+  local frame = self.Buttons[target]
+  if not (self.Buttons[target]) then
+    local name = target:GetName()
+    local id = target:GetID()
     print('|cFF88FF00Creating', name,'Veneer')
-    local veneer = vn.GetVeneer(frame, 'VeneerBuffTemplate')
-    local id = frame:GetID()
 
+    frame = vn:Acquire(target, 'VeneerBuffTemplate')
 
-    veneer.progress:SetPoint('BOTTOMLEFT', veneer, 'BOTTOMLEFT', -1, -7)
-    veneer.progress:SetPoint('TOPRIGHT', veneer, 'BOTTOMRIGHT', 1, -2)
-    veneer.progress:SetHeight(BUFF_PROGRESS_SIZE + (BUFF_PROGRESS_INSET * 2))
+    frame.progress:SetHeight(BUFF_PROGRESS_SIZE + (BUFF_PROGRESS_INSET * 2))
 
-    veneer.progress.bg:SetColorTexture(0,0,0,1)
+    frame.progress.fg:ClearAllPoints()
+    frame.progress.fg:SetPoint('BOTTOMLEFT', BUFF_PROGRESS_INSET,BUFF_PROGRESS_INSET)
+    frame.progress.fg:SetPoint('TOP', 0, -BUFF_PROGRESS_INSET)
 
-    veneer.progress.fg:SetColorTexture(1,1,1,1)
-    veneer.progress.fg:ClearAllPoints()
-    veneer.progress.fg:SetPoint('BOTTOMLEFT', BUFF_PROGRESS_INSET,BUFF_PROGRESS_INSET)
-    veneer.progress.fg:SetPoint('TOP', 0, -BUFF_PROGRESS_INSET)
 
-    veneer.duration:SetFontObject(VeneerNumberFont)
-    veneer.duration:ClearAllPoints()
-    veneer.duration:SetPoint('BOTTOM', veneer, 'BOTTOM', 0, 2)
+    frame.underlay:SetParent(UIParent)
+    frame.underlay:SetFrameStrata('BACKGROUND')
+    frame.border:SetColorTexture(0,0,0,1)
+    frame.border:SetPoint('TOPLEFT', frame, 'TOPLEFT', -BORDER_SIZE_L, BORDER_SIZE_U)
+    frame.border:SetPoint('BOTTOMRIGHT', frame, 'BOTTOMRIGHT', BORDER_SIZE_R, -BORDER_SIZE_D)
+    frame.border:Show()
 
-    veneer.count:SetFontObject(VeneerNumberFont)
-    veneer.count:ClearAllPoints()
-    veneer.count:SetPoint('TOPRIGHT', veneer, 'TOPRIGHT', -3, -3)
-    veneer.count:SetJustifyH('RIGHT')
-    veneer.count:SetSize(30,30)
-
-    veneer.underlay:SetParent(UIParent)
-    veneer.underlay:SetFrameStrata('BACKGROUND')
-    veneer.border:SetColorTexture(0,0,0,1)
-    veneer.border:SetPoint('TOPLEFT', veneer, 'TOPLEFT', -BORDER_SIZE_L, BORDER_SIZE_U)
-    veneer.border:SetPoint('BOTTOMRIGHT', veneer, 'BOTTOMRIGHT', BORDER_SIZE_R, -BORDER_SIZE_D)
-    veneer.border:Show()
-
-
-    veneers[frame] = veneer
+    self.Buttons[target] = frame
   end
-
-
-  return veneers[frame]
+  return frame
 end
 
+function plugin:OnLoad()
+  Veneer:AddHandler(self, self.defaultCluster)
+end
 
+function plugin:Setup()
+
+
+  hooksecurefunc("BuffFrame_Update", function(...) self:OnBuffFrameUpdate(...) end)
+  hooksecurefunc("AuraButton_UpdateDuration", function(...) self:OnUpdateDuration(...) end)
+  hooksecurefunc("AuraButton_Update", function(...) self:OnAuraButton_Update(...) end)
+  hooksecurefunc("BuffFrame_UpdateAllBuffAnchors", function(...) self:OnUpdateAllBuffAnchors(...) end)
+  hooksecurefunc("TemporaryEnchantFrame_Update", function(...) self:OnTemporaryEnchantFrameUpdate(...) end)
+  for i = 1, 3 do
+    self:SetupButton('TempEnchant'..i)
+    _G['TempEnchant'..i..'Border']:SetVertexColor(0.5,0,1,1)
+  end
+end
 -- Associates skinning elements with said button
-local SkinFrame = function(name)
+local surrogates = {
+  Show = false,
+  Hide = false,
+  SetText = false,
+  SetVertexColor = function(surrogate, frame, r, g, b, a)
+    frame:Hide()
+    print('|cFF0088FFborder:SetVertexColor|r', r,g,b,a)
+    surrogate.progress.fg:SetColorTexture(r,g,b,a)
+    surrogate.border:Show()
+  end,
+}
+local DoRegionHooks =  function (veneer, region)
+
+  if region then
+    print('hooking', region:GetName())
+    region:ClearAllPoints()
+    for method, callback in ipairs(surrogates) do
+      print(method, callback)
+      if region[method] then
+        local func
+        if callback then
+          print('hooking', region:GetName(), method)
+          func = function(self,...)
+          print(self:GetName(), ':', method)
+          self:ClearAllPoints()
+          veneer[method](...)
+          end
+        else
+          func = function(self, ...)
+            self:ClearAllPoints()
+            callback(veneer, region, ...)
+          end
+        end
+        hooksecurefunc(region, method, callback)
+      end
+    end
+  end
+end
+
+
+function plugin:SetupButton (name)
   local frame = _G[name ]
-  if skinnedFrames[frame] then
+  if self.DetectedFrames[frame] then
     print('|cFFFF4400Attempting to skin a frame that already went through.|r')
     return
   end
@@ -127,30 +175,22 @@
   local border = _G[name .. 'Border']
   local count = _G[name .. 'Count']
   local duration = _G[name .. 'Duration']
-  local veneer = GetVeneer(frame)
+  local veneer = self:Acquire(frame)
+  local offset = BUFF_BUTTON_ZOOM/2
 
-  skinnedFrames[frame] = frame
+  self.DetectedFrames[frame] = frame
   frame:SetSize(BUFF_BUTTON_SIZE,BUFF_BUTTON_SIZE)
+  icon:SetTexCoord(offset, 1 - offset, offset, 1 - offset)
 
 
-  local offset = BUFF_BUTTON_ZOOM/2
-  icon:SetTexCoord(offset, 1 - offset, offset, 1 - offset)
+  DoRegionHooks(veneer, border)
+  DoRegionHooks(veneer.duration, duration)
+  DoRegionHooks(veneer.count, count)
   if border then
-    border:Hide()
-    hooksecurefunc(border, 'SetVertexColor', function(frame, r, g, b, a)
-      frame:Hide()
-      print('|cFF0088FFborder:SetVertexColor|r', r,g,b,a)
-      veneer.progress.fg:SetColorTexture(r,g,b,a)
-      veneer.border:Show()
-    end)
-
-
-
     local color = DebuffTypeColor["none"]
     if aurasCache[frame] and aurasCache[frame][5] then
       color = DebuffTypeColor[aurasCache[frame][5]]
     end
-
     veneer.progress.fg:SetColorTexture(color.r,color.g,color.b)
     veneer.border:SetColorTexture(0,0,0,1)
     veneer.border:Show()
@@ -158,44 +198,6 @@
     veneer.border:SetColorTexture(0,0,0,1)
     veneer.border:Show()
   end
-  if duration then
-    duration:ClearAllPoints()
-    --duration:SetPoint('TOP', frame, 'BOTTOM', 0, -8)
-    --duration:SetFontObject(VeneerNumberFont)
-    --duration:SetDrawLayer('OVERLAY')
-
-    hooksecurefunc(duration, 'Hide', function(self, text)
-      veneer.duration:Hide()
-    end)
-    hooksecurefunc(duration, 'Show', function(self, text)
-      veneer.duration:Show()
-    end)
-  end
-  if count then
-    count:ClearAllPoints()
-    hooksecurefunc(count, 'SetText', function(self, text)
-      print(self:GetName(), 'SetText', text)
-      local n = veneer.count:GetNumPoints()
-      for i = 1, n do
-        print(i, veneer.count:GetPoint(n))
-      end
-      veneer.count:Show()
-      veneer.count:SetText(text)
-    end)
-    hooksecurefunc(count, 'Hide', function(self)
-      if veneer.count.isUpdating then
-        print('|cFFFF4400blocked Hide hook|r')
-        return
-      end
-
-      print(self:GetName(), 'Hide')
-      veneer.count:Hide()
-    end)
-    hooksecurefunc(count, 'Show', function(self)
-      print(self:GetName(), 'Show')
-      veneer.count:Show()
-    end)
-  end
 
 
   hooksecurefunc(frame, "Hide", function(self)
@@ -221,11 +223,11 @@
 
 
 --- Set widgets to reflect the passed parameters
-local UpdateVeneer = function (frame, duration, expires)
-  local veneer = GetVeneer(frame)
+function plugin:UpdateButton (frame, duration, expires)
+  local veneer = self:Acquire(frame)
   -- is it a new button?
-  if not skinnedFrames[frame] then
-    SkinFrame(frame:GetName())
+  if not self.DetectedFrames[frame] then
+    self:SetupButton(frame:GetName())
   end
 
 
@@ -277,7 +279,7 @@
 
 
 --- Provides the number of changed indices for use in deciding between partial and full veneer updates
-local CacheCheck = function(frame, ...)
+function plugin:ButtonHasChanged (frame, ...)
   aurasCache[frame] = aurasCache[frame] or {}
   local hasChange = 0
   local numVals = select('#',...)
@@ -291,11 +293,11 @@
   return hasChange
 end
 
-local AuraButton_Update = function(name, index, filter)
+function plugin:OnAuraButton_Update (name, index, filter)
   local bName = name..index
   local frame = _G[bName]
   if frame and frame:IsVisible() then
-    local cacheDiff = CacheCheck(frame, UnitAura(frame.unit, frame:GetID(), frame.filter))
+    local cacheDiff = self:ButtonHasChanged(frame, UnitAura(frame.unit, frame:GetID(), frame.filter))
     -- if the name or expirationTime changed
     if (cacheDiff >= 1) then
       print('|cFFFF4400', frame:GetName(), 'diff:', cacheDiff)
@@ -305,13 +307,13 @@
       expirationCache[name] = frame.expirationTime
       print(unpack(aurasCache[frame]))
 
-      UpdateVeneer(frame, aurasCache[frame][6], aurasCache[frame][7])
+      self:UpdateButton(frame, aurasCache[frame][6], aurasCache[frame][7])
     end
 
   end
 end
 
-local BuffFrame_UpdateAllBuffAnchors = function()
+function plugin:OnUpdateAllBuffAnchors ()
   local todo = {}
   if #pendingFrames >= 1 then
 
@@ -381,8 +383,8 @@
   end
 end
 
-local AuraButton_UpdateDuration = function(frame, timeLeft)
-  local veneer = GetVeneer(frame)
+function plugin:OnUpdateDuration (frame, timeLeft)
+  local veneer = self:Acquire(frame)
   local hours =  floor(timeLeft/3600)
   local minutes = floor(mod(timeLeft, 3600)/60)
   local seconds = floor(mod(timeLeft, 60))
@@ -417,7 +419,7 @@
 
 -- Obtains the first instance of Tenchant use
 
-local TemporaryEnchantFrame_Update = function(...)
+function plugin:OnTemporaryEnchantFrameUpdate (...)
   local numVals = select('#', ...)
   local numItems = numVals / 4
   if numItems >= 1 then
@@ -440,7 +442,7 @@
           UpdateVeneer(frame, timeRemaining/1000, GetTime()+(timeRemaining/1000))
         end
       else
-        GetVeneer(frame):Hide()
+        self:Acquire(frame):Hide()
       end
 
     end
@@ -448,45 +450,9 @@
   end
 
 end
-
-local BuffFrame_Update = function(...)
-
+function plugin:OnBuffFrameUpdate ()
 end
 
 
-hooksecurefunc("BuffFrame_Update", BuffFrame_Update)
-hooksecurefunc("AuraButton_UpdateDuration", AuraButton_UpdateDuration)
-hooksecurefunc("AuraButton_Update", AuraButton_Update)
-hooksecurefunc("BuffFrame_UpdateAllBuffAnchors", BuffFrame_UpdateAllBuffAnchors)
-hooksecurefunc("TemporaryEnchantFrame_Update", TemporaryEnchantFrame_Update)
+-- The TempEnchant frames are hardcoded in the base FrameXML, so get them now
 
--- The TempEnchant frames are hardcoded in the base FrameXML, so get them now
-for i = 1, 3 do
-
-  SkinFrame('TempEnchant'..i)
-  _G['TempEnchant'..i..'Border']:SetVertexColor(0.5,0,1,1)
-
-end
-
-local OrderHallCommandBarMod = CreateFrame('Frame')
-function OrderHallCommandBarMod:Refresh()
-  OrderHallCommandBar.Background:SetAlpha(0.5)
-  OrderHallCommandBar:ClearAllPoints()
-  OrderHallCommandBar:SetPoint('TOP')
-  OrderHallCommandBar:SetWidth(580)
-end
-function OrderHallCommandBarMod:Setup()
-  if OrderHallCommandBar then
-    print('mapping orderhall bar')
-    hooksecurefunc(OrderHallCommandBar, 'Show', OrderHallCommandBarMod.Refresh)
-    self:Refresh()
-    self:UnregisterEvent('ADDON_LOADED')
-  else
-    self:RegisterEvent('ADDON_LOADED')
-    self:SetScript('OnEvent', OrderHallCommandBarMod.Setup)
-  end
-end
-plugin.init = function ()
-  plugin.db = vn.db[PLUGIN_NAME]
-  OrderHallCommandBarMod:Setup()
-end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Modules/BuffFrame.xml	Tue Oct 18 13:07:21 2016 -0400
@@ -0,0 +1,72 @@
+<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="BuffFrame.lua" />
+
+  <Frame name="VeneerBuffFrame" mixin="VeneerBuffFrameMixin" inherits="VeneerMixinScripts" />
+  <Frame name="VeneerBuffTemplate" virtual="true" inherits="VeneerTemplate" hidden="true">
+    <Scripts>
+      <OnLoad>
+        self.duration = self.progress.duration
+        self.count = self.progress.count
+        self.border = self.underlay.bg
+      </OnLoad>
+    </Scripts>
+    <Frames>
+      <!--
+
+    frame.progress:SetPoint('BOTTOMLEFT', frame, 'BOTTOMLEFT', -1, -7)
+    frame.progress:SetPoint('TOPRIGHT', frame, 'BOTTOMRIGHT', 1, -2)
+    frame.progress:SetHeight(BUFF_PROGRESS_SIZE + (BUFF_PROGRESS_INSET * 2))
+
+    frame.progress.bg:SetColorTexture(0,0,0,1)
+    frame.progress.fg:SetColorTexture(1,1,1,1)
+    frame.progress.fg:ClearAllPoints()
+    frame.progress.fg:SetPoint('BOTTOMLEFT', BUFF_PROGRESS_INSET,BUFF_PROGRESS_INSET)
+    frame.progress.fg:SetPoint('TOP', 0, -BUFF_PROGRESS_INSET)
+      -->
+
+      <Frame name="$parentUnderlay" parentKey="underlay" frameStrata="BACKGROUND">
+        <Layers>
+          <Layer level="BORDER">
+            <Texture parentKey="bg" setAllPoints="true" hidden="true" />
+          </Layer>
+        </Layers>
+      </Frame>
+      <Cooldown name="$parentCooldown" parentKey="cooldown" inherits="CooldownFrameTemplate" reverse="true" setAllPoints="true">
+        <EdgeTexture>
+          <Color a="0" r="0" g="0" b="0" />
+        </EdgeTexture>
+      </Cooldown>
+      <Frame name="$parentProgress" parentKey="progress" frameStrata="MEDIUM">
+        <Anchors>
+          <Anchor point="BOTTOMLEFT" x="-1" y="-7" />
+          <Anchor point="TOPRIGHT" relativePoint="BOTTOMRIGHT" x="1" y="-2" />
+        </Anchors>
+        <Layers>
+          <Layer level="BACKGROUND">
+            <Texture parentKey="bg" setAllPoints="true">
+              <Color a="1" r="0" g="0" b="0" />
+            </Texture>
+          </Layer>
+          <Layer level="ARTWORK">
+            <Texture parentKey="fg" >
+              <Color a="1" r="1" g="1" b="1" />
+            </Texture>
+          </Layer>
+          <Layer level="OVERLAY">
+            <FontString name="$parentDuration" parentKey="duration" inherits="VeneerNumberFont">
+              <Anchors>
+                <Anchor point="BOTTOM" x="0" y="2" />
+              </Anchors>
+            </FontString>
+            <FontString name="$parentCount" parentKey="count" inherits="VeneerNumberFont" justifyH="RIGHT">
+              <Anchors>
+                <Anchor point="TOPRIGHT" x="-3" y="-3" />
+              </Anchors>
+            </FontString>
+          </Layer>
+        </Layers>
+      </Frame>
+    </Frames>
+  </Frame>
+</Ui>
\ No newline at end of file
--- a/Modules/OrderHall.lua	Tue Oct 18 01:57:02 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
--- Veneer
--- OrderHall.lua
--- Created: 10/7/2016 10:55 PM
--- %file-revision%
---
-
-VeneerWorldStateCurrencyMixin = {}
-VeneerWorldStateProgressMixin = {}
-VeneerWorldStateMixin = {
-  maxHeight = 0,
-  detectedFrames = {}
-}
-local print = DEVIAN_WORKSPACE and function(...) print('VnWorldState', ...) end or nop
-
-function VeneerWorldStateMixin:Setup()
-  --DEFAULT_CHAT_FRAME:AddMessage('Loaded')
-  print('All:Setup()')
-
-  self.modules = self.modules or {self:GetChildren()}
-  for i, frame in ipairs(self.modules) do
-    if frame.Setup then
-      frame:Setup()
-    end
-
-    frame:SetScript('OnSizeChanged', function()
-      local h = frame:GetHeight()
-      if h > self.maxHeight then
-        self.maxHeight = h
-        self:SetHeight(h)
-        print('updating max height:', h)
-      elseif h < self.maxHeight then
-        self:UpdateSize()
-      end
-    end)
-    frame:SetScript('OnHide', function()
-      print('|cFF0088FF'..frame:GetName()..':OnHide()')
-      self:UpdateSize()
-    end)
-    frame:SetScript('OnShow', function()
-      frame.timeLived = 0
-      print('|cFF0088FF'..frame:GetName()..':OnShow()')
-      self:UpdateSize()
-    end)
-
-    function frame.ShowPanel(frame)
-      frame:SetShown(true)
-      self:Show()
-    end
-    function frame.HidePanel(frame)
-      frame:SetShown(false)
-      self:UpdateSize()
-    end
-  end
-  self:SetOrderHallUIMods()
-end
-
-function VeneerWorldStateMixin:SetOrderHallUIMods()
-  if OrderHallCommandBar then
-    if not self.detectedFrames[OrderHallCommandBar] then
-      self.detectedFrames[OrderHallCommandBar] = true
-      hooksecurefunc(OrderHallCommandBar,'Show', function()
-        self:SetOrderHallUIMods()
-      end)
-      hooksecurefunc(OrderHallCommandBar,'Hide', function()
-        self:SetOrderHallUIMods()
-      end)
-    end
-
-
-    OrderHallCommandBar:ClearAllPoints()
-    OrderHallCommandBar:SetPoint('TOP')
-    OrderHallCommandBar:SetWidth(600)
-    OrderHallCommandBar.Background:SetColorTexture(0,0,0,0.5)
-    OrderHallCommandBar.WorldMapButton:Hide()
-    OrderHallCommandBar:EnableMouse(false)
-
-    if OrderHallCommandBar:IsVisible() then
-      self:SetPoint('TOP', OrderHallCommandBar, 'BOTTOM')
-      print('anchoring to CommandBar')
-    else
-      self:SetPoint('TOP', UIParent, 'TOP')
-      print('anchoring to UIParent')
-    end
-  else
-    self:SetPoint('TOP', UIParent, 'TOP')
-    print('anchoring to UIParent')
-  end
-end
-local initialized
-function VeneerWorldStateMixin:OnEvent(event, arg)
-  print(event, arg)
-
-  if event == 'PLAYER_LOGIN' and not initialized then
-    if IsLoggedIn() then
-      initialized = true
-      self:Setup()
-      self:UnregisterEvent('PLAYER_LOGIN')
-    end
-  elseif event == 'ADDON_LOADED' then
-    if initialized and IsAddOnLoaded('Blizzard_OrderHallUI') then
-      self:SetOrderHallUIMods()
-    end
-  elseif event == 'PLAYER_ENTERING_WORLD' then
-    self:Update()
-  elseif event == 'PLAYER_REGEN_ENABLED' then
-    self:SetShown(true)
-  elseif event == 'PLAYER_REGEN_DISABLED' then
-    self:SetShown(false)
-  end
-end
-
-function VeneerWorldStateMixin:Update()
-  self.modules = {self:GetChildren()}
-  print('|cFFFFFF00All:Update()|r')
-  print(self:GetChildren())
-  for i, frame in ipairs(self.modules) do
-    if frame.Update then
-      print('  |cFFFF00FF'.. frame:GetName() .. ':Update()')
-      frame:Update()
-    end
-  end
-  self:SetOrderHallUIMods()
-end
-
-function VeneerWorldStateMixin:UpdateSize()
-  print('|cFFFFFF00All:UpdateSize()|r')
-  print(self:GetChildren())
-  self.modules = {self:GetChildren()}
-  self.maxHeight = 0
-  for i, frame in ipairs(self.modules) do
-    print('  '..frame:GetName()..':',frame:IsShown(), frame:IsVisible(), frame:GetHeight())
-    if frame:IsShown() then
-      self.maxHeight = max(self.maxHeight, frame:GetHeight())
-    end
-  end
-  if self.maxHeight == 0 then
-    print ('height zero')
-    self:Hide()
-  else
-    self:Show()
-    print ('height update:', self.maxHeight)
-    self:SetHeight(self.maxHeight)
-  end
-
-end
-
-
-
-function VeneerWorldStateMixin:OnLoad ()
-  self:RegisterEvent('PLAYER_LOGIN')
-  self:RegisterEvent('ADDON_LOADED')
-  self:RegisterEvent('ARTIFACT_UPDATE')
-  self:RegisterEvent('ARTIFACT_XP_UPDATE')
-  self:RegisterEvent('PLAYER_ENTERING_WORLD')
-  self:RegisterEvent('PLAYER_REGEN_ENABLED')
-  self:RegisterEvent('PLAYER_REGEN_DISABLED')
-end
-
-function VeneerWorldStateCurrencyMixin:OnLoad ()
-
-  self:RegisterEvent('ZONE_CHANGED')
-  self:RegisterEvent('CURRENCY_DISPLAY_UPDATE')
-  self:RegisterEvent('CHAT_MSG_CURRENCY')
-
-end
-
-function VeneerWorldStateCurrencyMixin:OnEvent (event, arg)
-  self:Update()
-end
-
-
-function VeneerWorldStateCurrencyMixin:Update()
-
-  print('  Zone:', GetZoneText())
-  if GetZoneText() == 'Suramar' then
-    local name, earned, texture, earnedThisWeek, weeklyMax, totalMax = GetCurrencyInfo(1155)
-
-    self.Icon:SetTexture(texture)
-    self.Label:SetFormattedText("%d / %d", earned, totalMax)
-    self:Show()
-    self:SetWidth(self.Icon:GetWidth() + self.Label:GetStringWidth() + 6)
-    self:SetSize(200,16)
-  else
-    self:Hide()
-  end
-
-
-end
-
-function VeneerWorldStateProgressMixin:OnUpdate(sinceLast)
-  self.timeLived = (self.timeLived or 0) + sinceLast
-  if self.timeLived >= 3 and not self.TransitionFadeOut:IsPlaying() then
-    if not self.timeOut then
-      self.timeOut = true
-      self.TransitionFadeOut:Play()
-    end
-  end
-end
-
-
-function VeneerWorldStateProgressMixin:OnLoad()
-  self:RegisterEvent('PLAYER_EQUIPMENT_CHANGED')
-
-  self:RegisterEvent("PLAYER_XP_UPDATE");
-  self:RegisterEvent("UPDATE_EXHAUSTION");
-  self:RegisterEvent("PLAYER_LEVEL_UP");
-  self:RegisterEvent("PLAYER_UPDATE_RESTING");
-
-  self:RegisterEvent("ARTIFACT_UPDATE");
-  self:RegisterEvent("ARTIFACT_XP_UPDATE");
-  self:RegisterEvent("ARTIFACT_CLOSE");
-  self:RegisterEvent("ARTIFACT_MAX_RANKS_UPDATE");
-
-  self.progressPercent = 0
-  self.progressAmount = 0
-  self.progressMax = 1
-  self.progressOverflow = 0
-end
-
-function VeneerWorldStateProgressMixin:Setup()
-  self:UpdateXPGain()
-
-  if self.canGainXP then
-    self.mode = 'xp'
-  else
-    self.mode = 'artifact'
-  end
-  print('setup mode:', self.mode)
-end
-
-function VeneerWorldStateProgressMixin:OnEvent(event, ...)
-  local lastMode = self.mode
-  if event == 'PLAYER_LEVEL_UP' or event == 'ENABLE_XP_GAIN' or event == 'DISABLE_XP_GAIN' then
-    self:UpdateXPGain()
-  elseif event == 'ARTIFACT_XP_UPDATE' or event == 'ARTIFACT_UPDATE' then
-    self.mode = 'artifact'
-
-  elseif event == 'PLAYER_EQUIPMENT_CHANGED' then
-    local slot, hasEquip = ...
-    if slot == 16 then
-      self.mode = 'artifact'
-      lastMode = nil
-    end
-  elseif event == 'PLAYER_XP_UPDATE' or event == 'PLAYER_LEVEL_UP' then
-    print('forcing to XP mode')
-    self.mode = 'xp'
-  end
-  self.modeChanged = (lastMode ~= self.mode)
-  if self.modeChanged and self:IsVisible() then
-    print('|cFF88FF00'..self:GetName()..'.TransitionFadeOut:Play()', event, ...)
-    self.TransitionFadeIn:Stop()
-    self.TransitionFadeOut:Play()
-  else
-    print('|cFFFFFF00'..self:GetName()..':Update()', event, ...)
-    self:Update()
-  end
-end
-function VeneerWorldStateProgressMixin:UpdateXPGain()
-  self.canGainXP = (UnitLevel('player') < GetMaxPlayerLevel()) and (not IsXPUserDisabled())
-  if not self.canGainXP then
-    self.ProgressBar:SetColorTexture(0.75,0.75,0.75)
-  end
-end
-
-local GetEquippedArtifactInfo = _G.C_ArtifactUI.GetEquippedArtifactInfo
-local GetCostForPointAtRank = _G.C_ArtifactUI.GetCostForPointAtRank
-function VeneerWorldStateProgressMixin:Update()
-  local hasNewInfo = false
-  local progressChange = false
-  print('  current mode:', self.mode)
-
-
-  if self.mode == 'xp' then
-    local xp = UnitXP('player')
-    local xpMax = UnitXPMax('player')
-    local bonusXP = GetXPExhaustion()
-    if xp then
-      self.progressPercent = xp / xpMax
-    end
-
-    self.progressText = 'Level ' .. UnitLevel('player') .. ': ' .. xp .. '/' .. xpMax
-
-    if bonusXP then
-      self.ProgressBar:SetColorTexture(0, 0.5,1)
-      self.OverflowBar:Show()
-      self.OverflowBar:ClearAllPoints()
-      self.OverflowBar:SetPoint('BOTTOMLEFT', self.ProgressBar, 'BOTTOMRIGHT', 0, 0)
-      print(bonusXP, (xpMax - xp))
-      if bonusXP < (xpMax - xp) then
-
-        self.OverflowBar:SetPoint('TOPRIGHT', self.ProgressBG, 'TOPRIGHT', (bonusXP / xpMax) * self:GetWidth(), 0)
-      else
-        self.OverflowBar:SetPoint('TOPRIGHT', self.ProgressBG, 'TOPRIGHT', 0, 0)
-      end
-    else
-      self.OverflowBar:Hide()
-      self.ProgressBar:SetColorTexture(0.5,0,1)
-    end
-    hasNewInfo = (self.progressAmount ~= xp)
-
-    progressChange = (hasNewInfo and not self.modeChanged) and ((xp - self.progressAmount) / xpMax)
-
-
-    self.progressAmount = xp
-    self.progressMax = xpMax
-  elseif self.mode == 'artifact' then
-
-    local itemID, altItemID, name, icon, totalXP, pointsSpent = GetEquippedArtifactInfo()
-    print('  C_AUI:', itemID, altItemID, name, icon, totalXP, pointsSpent)
-
-    if itemID then
-      local nextRankCost = GetCostForPointAtRank(pointsSpent) or 0
-      hasNewInfo = (self.progressAmount ~= totalXP)
-      progressChange = (hasNewInfo and not self.modeChanged) and (((totalXP - self.progressAmount) / nextRankCost))
-
-      if totalXP > nextRankCost then
-        self.progressPercent = 1
-        self.progressOverflow = totalXP - nextRankCost
-      else
-        self.progressPercent = totalXP / nextRankCost
-      end
-
-      self.progressText = name .. ' ('..pointsSpent .. '): '.. totalXP .. ' / ' .. nextRankCost
-
-      self.ProgressBar:SetColorTexture(1,0.5,0,1)
-      self.OverflowBar:Hide()
-
-
-      self.progressAmount = totalXP
-      self.progressMax = nextRankCost
-    else
-      self.progressAmount = 0
-      self.progressMax = 1
-      self.progressText = ''
-    end
-  end
-
-  if self.mode then
-    self:SetSize(600,16)
-    if hasNewInfo then
-      self.timeOut = nil
-      self.timeLived = 0
-      if self.TransitionFadeOut:IsPlaying() then
-        self.TransitionFadeOut:Stop()
-        self:SetAlpha(1)
-      end
-      if not self:IsVisible() then
-        self.TransitionFadeIn:Play()
-      else
-        self:ShowPanel()
-      end
-
-    end
-
-    print(self.ProgressBG:GetWidth())
-    print('  Percent:', floor(self.progressPercent*100)/100, 'BarLength:', floor(self:GetWidth()* self.progressPercent), 'NewInfo:', hasNewInfo, 'IsShown:', self:IsShown())
-
-
-    if progressChange then
-      print('  Render change:', progressChange)
-      self.ProgressAdded:Show()
-      self.ProgressAdded:SetPoint('BOTTOMLEFT', self.ProgressBar, 'BOTTOMRIGHT', - (self:GetWidth() * progressChange), 0)
-      self.ProgressAdded:SetPoint('TOPRIGHT', self.ProgressBar, 'TOPRIGHT', 0, 0)
-      self.ProgressFlash:Play()
-    end
-
-
-    if self.progressPercent > 0 then
-      self.ProgressBar:Show()
-      self.ProgressBar:SetPoint('TOPRIGHT', self.ProgressBG, 'TOPLEFT', self:GetWidth()* self.progressPercent , 0)
-
-      self.Label:SetText(self.progressText)
-    else
-      self.ProgressBar:Hide()
-    end
-  else
-    self:HidePanel()
-  end
-
-  self.modeChanged = nil
-end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Modules/WorldState.lua	Tue Oct 18 13:07:21 2016 -0400
@@ -0,0 +1,426 @@
+-- Veneer
+-- WorldState.lua
+-- Created: 10/7/2016 10:55 PM
+-- %file-revision%
+--
+
+VeneerWorldStateCurrencyMixin = {}
+VeneerWorldStateProgressMixin = {
+  keepOpen = true
+}
+VeneerWorldStateMixin = {
+  maxHeight = 0,
+  detectedFrames = {}
+}
+local print = DEVIAN_WORKSPACE and function(...) print('VnWorldState', ...) end or nop
+
+function VeneerWorldStateMixin:Setup()
+  --DEFAULT_CHAT_FRAME:AddMessage('Loaded')
+  print('|cFFFFFF00'..self:GetName()..'|r:Setup()')
+
+  self.modules = self.modules or {self:GetChildren()}
+  for i, frame in ipairs(self.modules) do
+    print('--'.. frame:GetName()..' exists')
+    if frame.Setup then
+      print('--'.. frame:GetName()..':Setup()')
+      frame:Setup()
+    end
+
+    frame:SetScript('OnSizeChanged', function()
+      local h = frame:GetHeight()
+      if h > self.maxHeight then
+        self.maxHeight = h
+        self:SetHeight(h)
+        print('updating max height:', h)
+      elseif h < self.maxHeight then
+        self:UpdateSize()
+      end
+    end)
+    frame:SetScript('OnHide', function()
+      print('|cFF0088FF'..frame:GetName()..':OnHide()')
+      self:UpdateSize()
+    end)
+    frame:SetScript('OnShow', function()
+      frame.timeLived = 0
+      print('|cFF0088FF'..frame:GetName()..':OnShow()')
+      self:UpdateSize()
+    end)
+
+    function frame.ShowPanel(frame)
+      frame:SetShown(true)
+      self:Show()
+    end
+    function frame.HidePanel(frame)
+      frame:SetShown(false)
+      self:UpdateSize()
+    end
+  end
+  self:SetOrderHallUIMods()
+  self:UnregisterEvent('PLAYER_LOGIN')
+end
+
+function VeneerWorldStateMixin:SetOrderHallUIMods()
+  if OrderHallCommandBar then
+    if not self.detectedFrames[OrderHallCommandBar] then
+      self.detectedFrames[OrderHallCommandBar] = true
+      hooksecurefunc(OrderHallCommandBar,'Show', function()
+        self:SetOrderHallUIMods()
+      end)
+      hooksecurefunc(OrderHallCommandBar,'Hide', function()
+        self:SetOrderHallUIMods()
+        self:UpdateSize()
+      end)
+    end
+
+
+    OrderHallCommandBar:ClearAllPoints()
+    OrderHallCommandBar:SetPoint('TOP')
+    OrderHallCommandBar:SetWidth(600)
+    OrderHallCommandBar.Background:SetColorTexture(0,0,0,0.5)
+    OrderHallCommandBar.WorldMapButton:Hide()
+    OrderHallCommandBar:EnableMouse(false)
+
+    if OrderHallCommandBar:IsVisible() then
+      self:SetPoint('TOP', OrderHallCommandBar, 'BOTTOM')
+      print('anchoring to CommandBar')
+    else
+      self:SetPoint('TOP', UIParent, 'TOP')
+      print('anchoring to UIParent')
+    end
+
+    self:UnregisterEvent('ADDON_LOADED')
+  else
+    self:SetPoint('TOP', UIParent, 'TOP')
+    print('anchoring to UIParent')
+  end
+end
+
+
+function VeneerWorldStateMixin:OnLoad ()
+  print('|cFFFFFF00'..self:GetName()..'|r!')
+  self:RegisterEvent('PLAYER_LOGIN')
+  self:RegisterEvent('ADDON_LOADED')
+  self:RegisterEvent('ARTIFACT_UPDATE')
+  self:RegisterEvent('ARTIFACT_XP_UPDATE')
+  self:RegisterEvent('PLAYER_ENTERING_WORLD')
+  self:RegisterEvent('PLAYER_REGEN_ENABLED')
+  self:RegisterEvent('PLAYER_REGEN_DISABLED')
+end
+
+function VeneerWorldStateMixin:OnEvent(event, arg)
+  print(event, arg)
+
+  if event == 'PLAYER_LOGIN' then
+    if IsLoggedIn() and not self.initialized then
+      self.initialized = true
+      self:Setup()
+    end
+  elseif event == 'ADDON_LOADED' then
+    if self.initialized and IsAddOnLoaded('Blizzard_OrderHallUI') then
+      self:SetOrderHallUIMods()
+    end
+  elseif event == 'PLAYER_ENTERING_WORLD' then
+    self:Update()
+  elseif event == 'PLAYER_REGEN_ENABLED' then
+    self:SetShown(true)
+  elseif event == 'PLAYER_REGEN_DISABLED' then
+    self:SetShown(false)
+  end
+end
+
+function VeneerWorldStateMixin:Update()
+  self.modules = {self:GetChildren()}
+  print('|cFFFFFF00All:Update()|r')
+  print(self:GetChildren())
+  for i, frame in ipairs(self.modules) do
+    if frame.Update then
+      print('  |cFFFF00FF'.. frame:GetName() .. ':Update()')
+      frame:Update()
+    end
+  end
+  self:SetOrderHallUIMods()
+end
+
+function VeneerWorldStateMixin:UpdateSize()
+  print('|cFFFFFF00All:UpdateSize()|r')
+  print(self:GetChildren())
+  self.modules = {self:GetChildren()}
+  self.maxHeight = 0
+  for i, frame in ipairs(self.modules) do
+    print('  '..frame:GetName()..':',frame:IsShown(), frame:IsVisible(), frame:GetHeight())
+    if frame:IsShown() then
+      self.maxHeight = max(self.maxHeight, frame:GetHeight())
+    end
+  end
+  if self.maxHeight == 0 then
+    print ('height zero')
+    self:Hide()
+  else
+    self:Show()
+    print ('height update:', self.maxHeight)
+    self:SetHeight(self.maxHeight)
+  end
+
+end
+
+
+
+function VeneerWorldStateMixin:OnMouseDown()
+end
+
+function VeneerWorldStateCurrencyMixin:OnLoad ()
+
+  self:RegisterEvent("PLAYER_ENTERING_WORLD");
+  self:RegisterEvent("ZONE_CHANGED");
+  self:RegisterEvent("ZONE_CHANGED_INDOORS");
+  self:RegisterEvent("ZONE_CHANGED_NEW_AREA");
+  self:RegisterEvent('CURRENCY_DISPLAY_UPDATE')
+  self:RegisterEvent('CHAT_MSG_CURRENCY')
+
+end
+
+function VeneerWorldStateCurrencyMixin:OnEvent (event, arg)
+  self:Update()
+end
+
+
+function VeneerWorldStateCurrencyMixin:Update()
+
+  print('  Zone:', GetZoneText())
+  if GetZoneText() == 'Suramar' then
+    local name, earned, texture, earnedThisWeek, weeklyMax, totalMax = GetCurrencyInfo(1155)
+
+    self.Icon:SetTexture(texture)
+    self.Label:SetFormattedText("%d / %d", earned, totalMax)
+    self:Show()
+    self:SetWidth(self.Icon:GetWidth() + self.Label:GetStringWidth() + 6)
+    self:SetSize(200,16)
+  else
+    self:Hide()
+  end
+
+
+end
+
+function VeneerWorldStateProgressMixin:OnUpdate(sinceLast)
+  if self.keepOpen then
+    return
+  end
+
+  self.timeLived = (self.timeLived or 0) + sinceLast
+  if self.timeLived >= 3 and not self.TransitionFadeOut:IsPlaying() then
+    if not self.timeOut then
+      self.timeOut = true
+      self.TimedFadeOut:Play()
+    end
+  end
+end
+
+
+function VeneerWorldStateProgressMixin:OnLoad()
+  self:RegisterEvent('PLAYER_EQUIPMENT_CHANGED')
+
+  self:RegisterEvent("PLAYER_XP_UPDATE");
+  self:RegisterEvent("UPDATE_EXHAUSTION");
+  self:RegisterEvent("PLAYER_LEVEL_UP");
+  self:RegisterEvent("PLAYER_UPDATE_RESTING");
+
+  self:RegisterEvent("ARTIFACT_UPDATE");
+  self:RegisterEvent("ARTIFACT_XP_UPDATE");
+  self:RegisterEvent("ARTIFACT_CLOSE");
+  self:RegisterEvent("ARTIFACT_MAX_RANKS_UPDATE");
+
+  self.progressPercent = 0
+  self.progressAmount = 0
+  self.progressMax = 1
+  self.progressOverflow = 0
+
+end
+
+function VeneerWorldStateProgressMixin:Setup()
+  self:UpdateXPGain()
+
+  if self.canGainXP then
+    self.mode = 'xp'
+  else
+    self.mode = 'artifact'
+  end
+  print('setup mode:', self.mode)
+end
+
+function VeneerWorldStateProgressMixin:OnEvent(event, ...)
+  local lastMode = self.mode
+  if event == 'PLAYER_LEVEL_UP' or event == 'ENABLE_XP_GAIN' or event == 'DISABLE_XP_GAIN' then
+    self:UpdateXPGain()
+  elseif event == 'ARTIFACT_XP_UPDATE' or event == 'ARTIFACT_UPDATE' then
+    self.mode = 'artifact'
+
+  elseif event == 'PLAYER_EQUIPMENT_CHANGED' then
+    local slot, hasEquip = ...
+    if slot == 16 then
+      self.mode = 'artifact'
+      lastMode = nil
+    end
+  elseif event == 'PLAYER_XP_UPDATE' or event == 'PLAYER_LEVEL_UP' then
+    print('forcing to XP mode')
+    self.mode = 'xp'
+  end
+  self.modeChanged = (lastMode ~= self.mode)
+  if self.modeChanged and self:IsVisible() then
+    print('|cFF88FF00'..self:GetName()..'.TransitionFadeOut:Play()', event, ...)
+    self:AnimateMode()
+  else
+    print('|cFFFFFF00'..self:GetName()..':Update()', event, ...)
+    self:Update()
+  end
+end
+function VeneerWorldStateProgressMixin:UpdateXPGain()
+  self.canGainXP = (UnitLevel('player') < GetMaxPlayerLevel()) and (not IsXPUserDisabled())
+  if not self.canGainXP then
+    self.ProgressBar:SetColorTexture(0.75,0.75,0.75)
+  end
+end
+
+local GetEquippedArtifactInfo = _G.C_ArtifactUI.GetEquippedArtifactInfo
+local GetCostForPointAtRank = _G.C_ArtifactUI.GetCostForPointAtRank
+function VeneerWorldStateProgressMixin:Update()
+  local hasNewInfo = false
+  local progressChange = false
+  print('  current mode:', self.mode)
+
+
+  if self.mode == 'xp' then
+    local xp = UnitXP('player')
+    local xpMax = UnitXPMax('player')
+    local bonusXP = GetXPExhaustion()
+    if xp then
+      self.progressPercent = xp / xpMax
+    end
+
+    self.progressText = '|cFFFFCC00' .. UnitLevel('player') .. '|r ' .. xp .. '/' .. xpMax
+
+    if bonusXP then
+      self.ProgressBar:SetColorTexture(0, 0.5,1)
+      self.OverflowBar:Show()
+      self.OverflowBar:ClearAllPoints()
+      self.OverflowBar:SetPoint('BOTTOMLEFT', self.ProgressBar, 'BOTTOMRIGHT', 0, 0)
+
+    else
+      self.ProgressBar:SetColorTexture(0.5,0,1)
+    end
+    hasNewInfo = (self.progressAmount ~= xp)
+
+    progressChange = (hasNewInfo and not self.modeChanged) and ((xp - self.progressAmount) / xpMax)
+
+    self.progressOverFlow = bonusXP
+    self.progressAmount = xp
+    self.progressMax = xpMax
+  elseif self.mode == 'artifact' then
+
+    local itemID, altItemID, name, icon, totalXP, pointsSpent = GetEquippedArtifactInfo()
+    print('  C_AUI:', itemID, altItemID, name, icon, totalXP, pointsSpent)
+
+    if itemID then
+      local nextRankCost = GetCostForPointAtRank(pointsSpent) or 0
+      hasNewInfo = (self.progressAmount ~= totalXP)
+      progressChange = (hasNewInfo and not self.modeChanged) and (((totalXP - self.progressAmount) / nextRankCost))
+
+      if totalXP > nextRankCost then
+        self.progressPercent = 1
+        self.progressPercent = totalXP / nextRankCost
+      end
+
+      self.progressText = name .. ' ('..pointsSpent .. '): '.. totalXP .. ' / ' .. nextRankCost
+
+      self.ProgressBar:SetColorTexture(1,0.5,0,1)
+      self.OverflowBar:Hide()
+
+      self.progressOverFlow = 0
+      self.progressAmount = totalXP
+      self.progressMax = nextRankCost
+    else
+      self.progressAmount = 0
+      self.progressMax = 1
+      self.progressText = ''
+    end
+  end
+
+  if self.mode then
+    self:SetSize(600,16)
+    if hasNewInfo then
+      self.timeOut = nil
+      self.timeLived = 0
+      if self.TransitionFadeOut:IsPlaying() then
+        self.TransitionFadeOut:Stop()
+        self:SetAlpha(1)
+      end
+      if not self:IsVisible() then
+        self.TransitionFadeIn:Play()
+      else
+        self:ShowPanel()
+      end
+
+    end
+
+    --print(self.ProgressBG:GetWidth())
+    print('  Percent:', floor(self.progressPercent*100)/100, 'BarLength:', floor(self:GetWidth()* self.progressPercent), 'NewInfo:', hasNewInfo, 'IsShown:', self:IsShown())
+
+
+    if progressChange then
+      print('  Render change:', progressChange)
+      self.ProgressAdded:Show()
+      self.ProgressAdded:SetPoint('BOTTOMLEFT', self.ProgressBar, 'BOTTOMRIGHT', - (self:GetWidth() * progressChange), 0)
+      self.ProgressAdded:SetPoint('TOPRIGHT', self.ProgressBar, 'TOPRIGHT', 0, 0)
+      self.ProgressFlash:Play()
+    end
+
+
+    if self.progressPercent > 0 then
+      self.ProgressBar:Show()
+      self.ProgressBar:SetPoint('TOPRIGHT', self.ProgressBG, 'TOPLEFT', self:GetWidth()* self.progressPercent , 0)
+      self.Label:SetText(self.progressText)
+
+      self.progressLeft = self.progressMax - self.progressAmount
+      if self.progressOverflow >= self.progressLeft then
+
+        self.OverflowBar:SetPoint('TOPRIGHT', self.ProgressBar, 'TOPRIGHT', (self.progressOverflow / self.progressMax) * self:GetWidth(), 0)
+      else
+        self.OverflowBar:SetPoint('TOPRIGHT', self.ProgressBG, 'TOPRIGHT', 0, 0)
+      end
+
+    else
+      self.ProgressBar:Hide()
+    end
+  else
+    --self:HidePanel()
+  end
+
+  self.modeChanged = nil
+end
+
+function VeneerWorldStateProgressMixin:OnMouseDown(button)
+  if button == 'RightButton' then
+    if self.keepOpen then
+      self.keepOpen = nil
+    else
+      self.keepOpen = true
+    end
+    print('keepOpen =', self.keepOpen)
+  else
+    if self.mode == 'xp' then
+      self.mode = 'artifact'
+    else
+      self.mode = 'xp'
+    end
+    self:AnimateMode()
+  end
+
+end
+
+function VeneerWorldStateProgressMixin:AnimateMode()
+
+  self.TransitionFadeIn:Stop()
+  print('|cFF88FF00'..self:GetName()..'.TransitionFadeOut:Play()')
+  self.modeChanged = true
+  self.TransitionFadeOut:Play()
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Modules/WorldState.xml	Tue Oct 18 13:07:21 2016 -0400
@@ -0,0 +1,134 @@
+<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="WorldState.lua" />
+
+  <Frame name="VeneerWorldState" mixin="VeneerWorldStateMixin" parent="UIParent" inherits="VeneerMixinScripts">
+    <Anchors>
+      <Anchor point="TOP" />
+    </Anchors>
+    <Size x="600" y="24" />
+    <Frames>
+      <Frame name="$parentProgress" parentKey="Progress" mixin="VeneerWorldStateProgressMixin" inherits="VeneerMixinScripts" enableMouse="true">
+        <Anchors>
+          <Anchor point="TOPLEFT" />
+        </Anchors>
+        <Animations>
+          <AnimationGroup parentKey="TransitionFadeOut" setToFinalAlpha="true">
+            <Alpha fromAlpha="1" toAlpha="0" duration="0.15" order="1" />
+            <Scripts>
+              <OnPlay>
+                --print('VnWorldState','fade out')
+              </OnPlay>
+              <OnFinished>
+                self:GetParent():Hide()
+                self:GetParent():Update()
+              </OnFinished>
+            </Scripts>
+          </AnimationGroup>
+          <AnimationGroup parentKey="TransitionFadeIn" setToFinalAlpha="true">
+            <Alpha fromAlpha="0" toAlpha="1" duration="0.15" order="1" />
+            <Scripts>
+              <OnPlay>
+                self:GetParent():ShowPanel()
+                self:GetParent().timeLived = 0
+                --print('VnWorldState', 'fade in')
+              </OnPlay>
+              <OnFinished>
+                self:GetParent().timeLived = 0
+              </OnFinished>
+            </Scripts>
+          </AnimationGroup>
+          <AnimationGroup parentKey="TimedFadeOut" setToFinalAlpha="true">
+            <Alpha fromAlpha="1" toAlpha="0" duration="1.12" order="1" />
+            <Scripts>
+              <OnPlay>
+                --print('VnWorldState','fade out')
+              </OnPlay>
+              <OnFinished>
+                self:GetParent():HidePanel()
+              </OnFinished>
+            </Scripts>
+          </AnimationGroup>
+
+          <AnimationGroup parentKey="ProgressFlash" setToFinalAlpha="true">
+            <Alpha fromAlpha="0" toAlpha="1" duration="0.15" order="1" childKey="ProgressAdded" />
+            <Alpha fromAlpha="1" toAlpha="0" duration="0.45" order="2" childKey="ProgressAdded" />
+
+            <Alpha childKey="Spark" fromAlpha="0" toAlpha="1" duration="0.15" order="1" />
+            <Alpha childKey="Spark" fromAlpha="1" toAlpha="0" duration="0.15" order="2" />
+            <Translation childKey="Spark" offsetX="600" offsetY="0" duration="0.30" order="1" />
+          </AnimationGroup>
+        </Animations>
+        <Layers>
+          <Layer level="BORDER">
+            <Texture parentKey="ProgressBG">
+              <Anchors>
+                <Anchor point="TOPRIGHT"  relativePoint="TOPRIGHT" />
+                <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" x="0" y="12" />
+              </Anchors>
+              <Color r="0" g="0" b="0" a="0.5" />
+            </Texture>
+          </Layer>
+          <Layer level="ARTWORK">
+            <Texture parentKey="ProgressBar">
+              <Anchors>
+                <Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT" relativeKey="$parent.ProgressBG" x="0" y="0" />
+              </Anchors>
+              <Color r="1" g="1" b="1" a="0.8" />
+            </Texture>
+            <Texture parentKey="OverflowBar" hidden="true">
+              <Anchors>
+                <Anchor point="BOTTOMLEFT" />
+              </Anchors>
+              <Color a=".6" r="1" g="0" b=".5" />
+            </Texture>
+            <Texture parentKey="ProgressAdded" hidden="true">
+
+              <Color a="1" r="1" g="1" b="1" />
+            </Texture>
+          </Layer>
+          <Layer level="OVERLAY">
+            <FontString parentKey="Label" inherits="VeneerNumberFont">
+              <Anchors>
+                <Anchor point="CENTER" />
+              </Anchors>
+            </FontString>
+
+            <Texture parentKey="Spark" hidden="false" alpha="0" alphaMode="ADD" atlas="OBJFX_LineBurst">
+              <Size x="60" y="15"/>
+              <Anchors>
+                <Anchor point="LEFT" />
+              </Anchors>
+            </Texture>
+          </Layer>
+        </Layers>
+      </Frame>
+
+      <Frame name="$parentZoneCurrency" parentKey="ZoneCurrency" mixin="VeneerWorldStateCurrencyMixin" hidden="true" inherits="VeneerMixinScripts">
+        <Anchors>
+          <Anchor point="TOPRIGHT" />
+        </Anchors>
+        <Layers>
+          <Layer level="ARTWORK">
+            <Texture parentKey="Icon" >
+              <Size x="24" y="24" />
+              <Anchors>
+                <Anchor point="LEFT" />
+              </Anchors>
+              <TexCoords left="0.15" right="0.85" top="0.15" bottom="0.85" />
+            </Texture>
+          </Layer>
+          <Layer level="OVERLAY">
+            <FontString parentKey="Label" inherits="VeneerNumberFont">
+              <Anchors>
+                <Anchor point="LEFT" relativePoint="RIGHT" relativeKey="$parent.Icon" x="2" y="0" />
+              </Anchors>
+            </FontString>
+          </Layer>
+        </Layers>
+      </Frame>
+    </Frames>
+  </Frame>
+
+</Ui>
\ No newline at end of file
--- a/Veneer.lua	Tue Oct 18 01:57:02 2016 -0400
+++ b/Veneer.lua	Tue Oct 18 13:07:21 2016 -0400
@@ -1,7 +1,25 @@
 -- Veneer
 -- Base framework for making things draggable.
 
-local vn, print = LibStub("LibKraken").register(Veneer)
+
+
+
+SLASH_VENEER1 = "/veneer"
+SLASH_VENEER2 = "/vn"
+
+SlashCmdList.VENEER = function(cmd)
+end
+VeneerCore = {
+  Frames = {},
+  ConfigLayers = {},
+  FrameClusters = {},
+  parserDepth = 0,
+  pendingCalls = {},
+}
+VeneerHandlerMixin = {
+  Reanchor = nop
+}
+local print = DEVIAN_WORKSPACE and function(...) print('Veneer', ...) end or nop
 local wipe = table.wipe
 
 local defaults = {
@@ -14,11 +32,9 @@
     height = 48,
   }
 }
+
 local configMode
-local veneers = {}
-
 local anonID = 0
-
 local tostring = tostring
 local IsFrameHandle = IsFrameHandle
 local GetAnonymousName = function(key)
@@ -32,8 +48,6 @@
   return (IsFrameHandle(table) and table:GetName()) or tostring(table)
 end
 
-
-
 local anchor_coefficients = {
   ['TOP'] = function(x, y) return x, y end,
   ['BOTTOM'] = function(x, y) return x,y end,
@@ -41,6 +55,108 @@
   ['RIGHT'] = function(x,y) return x,y end,
 }
 
+function VeneerCore:print(...)
+  local txt = '|cFFFFFF00Veneer|r:'
+  for i = 1, select('#', ...) do
+    txt = txt .. ' '.. tostring(select(i, ...))
+  end
+
+  DEFAULT_CHAT_FRAME:AddMessage(txt)
+end
+
+function VeneerCore:OnLoad()
+  print('|cFFFFFF00Veneer!|r')
+  self:RegisterEvent('ADDON_LOADED')
+  self:RegisterEvent('PLAYER_LOGIN')
+
+  self.DEVIAN_PNAME = 'Veneer'
+  self:RegisterForDrag('LeftButton')
+end
+
+function VeneerCore:OnEvent(event, ...)
+  if event == 'ADDON_LOADED' or event == 'PLAYER_LOGIN' then
+    if IsLoggedIn() and not self.intialized then
+      self.intialized = true
+      self:Setup()
+    end
+  end
+end
+
+function VeneerCore:OnDragStart()
+  self:StartMoving()
+end
+
+
+function VeneerCore:OnDragStop()
+  self:StopMovingOrSizing()
+end
+
+function VeneerCore:Setup ()
+  if (not VeneerData) or (not VeneerData.version) then
+    VeneerData = defaults
+  end
+  self.data = VeneerData
+
+
+  self:ExecuteOnClusters(nil, 'Setup')
+end
+
+function VeneerCore:AddHandler(handler, ...)
+  print('*** Adding handler:', handler.moduleName or handler:GetName())
+  local clusterTable = self.FrameClusters
+  for i = 1, select('#', ...) do
+    local anchor = select(i, ...)
+    clusterTable[anchor] = clusterTable[anchor] or {}
+    clusterTable = clusterTable[anchor]
+    print('    cluster layer', i, anchor)
+  end
+  for k,v in pairs(VeneerHandlerMixin) do
+    if not handler[k] then
+      handler[k] = v
+    end
+  end
+  tinsert(clusterTable, handler)
+  handler:Reanchor()
+end
+
+function VeneerCore:ExecuteOnClusters(layer, method)
+  self.parserDepth = self.parserDepth + 1
+  layer = layer or self.FrameClusters
+  if not layer then
+    if self.parserDepth >= 1 then
+      tinsert(self.pendingCalls, method)
+      print('delaying walk for', method)
+      return
+    end
+    print('|cFF00FFFFVeneer|r:'..method..'('..tostring(layer)..')')
+  else
+    print(' L'..self.parserDepth)
+  end
+  for anchor, cluster in pairs(layer) do
+    for index, frame in ipairs(cluster) do
+      print('  '..anchor..'.'..index..' = '..frame:GetName())
+      if frame[method] then
+        print('  '..frame:GetName()..':'..method..'(...)')
+        frame[method](frame)
+      end
+    end
+    if cluster.FrameClusters then
+      self:ExecuteOnClusters(cluster.FrameClusters, method)
+    end
+  end
+  self.parserDepth = self.parserDepth - 1
+
+  if (self.parserDepth == 0) and (#self.pendingCalls >= 1) then
+    local delayedMethod = tremove(self.pendingCalls, 1)
+    print('starting delayed walk for', delayedMethod)
+    self:ExecuteOnClusters(nil, delayedMethod)
+  end
+end
+
+function VeneerCore:Update()
+  self:ExecuteOnClusters(nil, 'Update')
+end
+
 local VeneerButton_OnDragStart = function(self)
   self.startingLeft = self:GetLeft()
   self.startingBottom = self:GetBottom()
@@ -123,10 +239,10 @@
 local ToggleVeneerConfig = function()
   if configMode then
     configMode = false
-    vn:print('Config mode off.')
+    Veneer:print('Config mode off.')
   else
     configMode = true
-    vn:print('Config mode on.')
+    Veneer:print('Config mode on.')
   end
 
   for frame, veneer in pairs(veneers) do
@@ -138,36 +254,33 @@
   VeneerButton_Update(self)
 end
 
-vn.GetVeneer = function(frame, template)
+function VeneerCore:Acquire (frame, template)
   if not frame then
     print('|cFFFF4400Unable to acquire frame...|r')
     return
   end
+  local veneer = self.Frames[frame]
+  if not veneer then
+    local name = type(frame) == 'table' and GetTableName(frame) or GetAnonymousName()
+    veneer = CreateFrame('Frame', name, frame, template or 'VeneerTemplate')
+    print('+veneer', name)
 
-  if veneers[frame] then
-    return veneers[frame]
+    veneer:SetAllPoints(frame)
+    veneer:SetParent(frame)
+    veneer.label:SetText(name)
+    veneer.bg:SetColorTexture(0,0,0,0)
+    veneer:Hide()
+    veneer:EnableMouse(false)
+
+    veneer:SetScript('OnShow', VeneerButton_OnShow)
+
+    -- find current X/Y
+    veneer.currentLeft = frame:GetLeft()
+    veneer.currentTop = frame:GetTop()
+    self.Frames[frame] = veneer
   end
 
-  local name = type(frame) == 'table' and GetTableName(frame) or GetAnonymousName()
-  local veneer = CreateFrame('Frame', name, frame, template or 'VeneerTemplate')
-  print('+veneer', name)
-
-  veneer:SetAllPoints(frame)
-  veneer:SetParent(frame)
-  veneer.label:SetText(name)
-  veneer.bg:SetColorTexture(0,0,0,0)
-  veneer:Hide()
-  veneer:EnableMouse(false)
-
-  veneer:SetScript('OnShow', VeneerButton_OnShow)
-
-  -- find current X/Y
-  veneer.currentLeft = frame:GetLeft()
-  veneer.currentTop = frame:GetTop()
-
-
-  veneers[frame] = veneer
-  return veneers[frame]
+  return veneer
 end
 
 local mixin_probe = {
@@ -175,30 +288,4 @@
   'ArtifactFrameUnderlay',
 }
 
-vn.event = function(event, arg)
 
-end
-
-vn.init = function()
-  if (not VeneerData) or (not VeneerData.version) then
-    VeneerData = defaults
-  end
-  vn.db = VeneerData
-
-end
-
-
-SLASH_VENEER1 = "/veneer"
-SLASH_VENEER2 = "/vn"
-
-SlashCmdList.VENEER = function(cmd)
-  for i, module in pairs(vn.modules) do
-    if module.cmd then
-      local result = module.cmd(cmd)
-      if result then
-        return
-      end
-    end
-  end
-  ToggleVeneerConfig()
-end
\ No newline at end of file
--- a/Veneer.toc	Tue Oct 18 01:57:02 2016 -0400
+++ b/Veneer.toc	Tue Oct 18 13:07:21 2016 -0400
@@ -10,6 +10,7 @@
 ## OptionalDeps: LibKraken, Devian
 
 Veneer.xml
-Options.lua
-Modules\BuffFrame.lua
-Modules\PaperDoll.lua
\ No newline at end of file
+##Options.lua
+##Modules\PaperDoll.lua
+Modules\WorldState.xml
+Modules\BuffFrame.xml
\ No newline at end of file
--- a/Veneer.xml	Tue Oct 18 01:57:02 2016 -0400
+++ b/Veneer.xml	Tue Oct 18 13:07:21 2016 -0400
@@ -1,5 +1,8 @@
 <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="Veneer.lua" />
+
   <Font name="VeneerFont" />
 
   <Font name="VeneerFont_Small" font="Fonts\FRIZQT__.TTF" outline="NORMAL" height="16" />
@@ -14,22 +17,26 @@
       </Font>
 
 
-  <Frame name="Veneer" hidden="true" enableMouse="true" movable="true" parent="UIParent" frameStrata="DIALOG">
+  <Frame name="VeneerMixinScripts" virtual="true">
+    <Scripts>
+      <OnLoad method="OnLoad"  />
+      <OnEvent method="OnEvent" />
+      <OnUpdate method="OnUpdate" />
+      <OnShow method="OnShow" />
+      <OnHide method="OnHide" />
+      <OnMouseDown method="OnMouseDown" />
+      <OnSizeChanged method="OnSizeChanged" />
+    </Scripts>
+  </Frame>
+
+  <Frame name="Veneer" inherits="VeneerMixinScripts" mixin="VeneerCore" hidden="true" enableMouse="true" movable="true" frameStrata="DIALOG">
     <Size x="400" y="400" />
     <Anchors>
       <Anchor point="CENTER" relativePoint="CENTER" x="0" y="0" />
     </Anchors>
     <Scripts>
-      <OnLoad>
-        self.DEVIAN_PNAME = 'Veneer'
-        self:RegisterForDrag('LeftButton')
-      </OnLoad>
-      <OnDragStart>
-        self:StartMoving()
-      </OnDragStart>
-      <OnDragStop>
-        self:StopMovingOrSizing()
-      </OnDragStop>
+      <OnDragStart method="OnDragStart" />
+      <OnDragStop method="OnDragStop" />
     </Scripts>
     <Layers>
       <Layer level="BACKGROUND">
@@ -121,51 +128,6 @@
   </Frame>
 
 
-  <Frame name="VeneerBuffTemplate" virtual="true" inherits="VeneerTemplate" hidden="true">
-    <Scripts>
-      <OnLoad>
-        self.duration = self.progress.duration
-        self.count = self.progress.count
-        self.border = self.underlay.bg
-      </OnLoad>
-    </Scripts>
-    <Frames>
-      <Frame name="$parentUnderlay" parentKey="underlay" frameStrata="BACKGROUND">
-        <Layers>
-          <Layer level="BORDER">
-            <Texture parentKey="bg" setAllPoints="true" hidden="true" />
-          </Layer>
-        </Layers>
-      </Frame>
-      <Cooldown name="$parentCooldown" parentKey="cooldown" inherits="CooldownFrameTemplate" reverse="true" setAllPoints="true">
-        <EdgeTexture>
-          <Color a="0" r="0" g="0" b="0" />
-        </EdgeTexture>
-      </Cooldown>
-      <Frame name="$parentProgress" parentKey="progress" frameStrata="MEDIUM">
-        <Layers>
-          <Layer level="BACKGROUND">
-            <Texture parentKey="bg" />
-          </Layer>
-          <Layer level="ARTWORK">
-            <Texture parentKey="fg" />
-          </Layer>
-          <Layer level="OVERLAY">
-            <FontString name="$parentDuration" parentKey="duration" inherits="VeneerNumberFont" />
-            <FontString name="$parentCount" parentKey="count" inherits="VeneerNumberFontLarge" />
-          </Layer>
-        </Layers>
-      </Frame>
-    </Frames>
-  </Frame>
-
-  <Frame name="VeneerMixinScripts" virtual="true">
-    <Scripts>
-      <OnLoad method="OnLoad"  />
-      <OnEvent method="OnEvent" />
-      <OnUpdate method="OnUpdate" />
-    </Scripts>
-  </Frame>
 
   <Frame name="VeneerStatusBarTemplate" virtual="true" hidden="true" inherits="VeneerMixinScripts">
     <Scripts>
@@ -231,108 +193,6 @@
     </Layers>
   </Frame>
 
-  <Script file="Veneer.lua" />
-  <Script file="Modules\OrderHall.lua" />
 
-  <Frame name="VeneerWorldState" mixin="VeneerWorldStateMixin" parent="UIParent" inherits="VeneerMixinScripts">
-    <Anchors>
-      <Anchor point="TOP" />
-    </Anchors>
-    <Size x="600" y="24" />
-    <Frames>
-      <Frame name="$parentProgress" parentKey="Progress" mixin="VeneerWorldStateProgressMixin" inherits="VeneerMixinScripts">
-
-        <Anchors>
-          <Anchor point="TOPLEFT" />
-        </Anchors>
-        <Layers>
-          <Layer level="BORDER">
-            <Texture setAllPoints="true" parentKey="ProgressBG">
-              <Color r="0" g="0" b="0" a="0.5" />
-            </Texture>
-          </Layer>
-          <Layer level="ARTWORK">
-            <Texture parentKey="ProgressBar">
-              <Anchors>
-                <Anchor point="BOTTOMLEFT" />
-              </Anchors>
-              <Color r="1" g="1" b="1" a="0.8" />
-            </Texture>
-            <Texture parentKey="OverflowBar" hidden="true">
-              <Anchors>
-                <Anchor point="BOTTOMLEFT" />
-              </Anchors>
-              <Color a=".6" r="1" g="0" b=".5" />
-            </Texture>
-            <Texture parentKey="ProgressAdded" hidden="true">
-
-              <Color a="1" r="1" g="1" b="1" />
-            </Texture>
-          </Layer>
-          <Layer level="OVERLAY">
-            <FontString parentKey="Label" inherits="VeneerNumberFont">
-              <Anchors>
-                <Anchor point="CENTER" />
-              </Anchors>
-            </FontString>
-          </Layer>
-        </Layers>
-        <Animations>
-          <AnimationGroup parentKey="TransitionFadeOut" setToFinalAlpha="true">
-            <Alpha fromAlpha="1" toAlpha="0" duration="1.12" order="1" />
-            <Scripts>
-              <OnPlay>
-                --print('VnWorldState','fade out')
-              </OnPlay>
-              <OnFinished>
-                self:GetParent():Hide()
-                self:GetParent():Update()
-              </OnFinished>
-            </Scripts>
-          </AnimationGroup>
-          <AnimationGroup parentKey="TransitionFadeIn" setToFinalAlpha="true">
-            <Alpha fromAlpha="0" toAlpha="1" duration="0.15" order="1" />
-            <Scripts>
-              <OnPlay>
-                self:GetParent():ShowPanel()
-                self:GetParent().timeLived = 0
-                --print('VnWorldState', 'fade in')
-              </OnPlay>
-              <OnFinished>
-                self:GetParent().timeLived = 0
-              </OnFinished>
-            </Scripts>
-          </AnimationGroup>
-          <AnimationGroup parentKey="ProgressFlash" setToFinalAlpha="true">
-            <Alpha fromAlpha="0" toAlpha="1" duration="0.15" order="1" childKey="ProgressAdded" />
-            <Alpha fromAlpha="1" toAlpha="0" duration="0.45" order="2" childKey="ProgressAdded" />
-          </AnimationGroup>
-        </Animations>
-      </Frame>
-
-      <Frame name="$parentZoneCurrency" parentKey="ZoneCurrency" mixin="VeneerWorldStateCurrencyMixin" hidden="true" inherits="VeneerMixinScripts">
-        <Anchors>
-          <Anchor point="TOPRIGHT" />
-        </Anchors>
-        <Layers>
-          <Layer level="ARTWORK">
-            <Texture parentKey="Icon" >
-              <Size x="24" y="24" />
-              <Anchors>
-                <Anchor point="LEFT" />
-              </Anchors>
-            </Texture>
-          </Layer>
-          <Layer level="OVERLAY">
-            <FontString parentKey="Label" inherits="VeneerNumberFont">
-              <Anchors>
-                <Anchor point="LEFT" relativePoint="RIGHT" relativeKey="$parent.Icon" x="2" y="0" />
-              </Anchors>
-            </FontString>
-          </Layer>
-        </Layers>
-      </Frame>
-    </Frames>
-  </Frame>
 
 </Ui>
\ No newline at end of file