changeset 93:f6fae1a4c66c v2.2.95-rc1

- revision and simplification dock layout - fixed character-specific addon choices getting erroneously toggled The XML template was missing header information; that has been filled in, and it should be easier to catch problems arising from that area.
author Nenue
date Wed, 19 Oct 2016 16:47:38 -0400
parents 4370eefcecdd
children c3511ea79774
files Devian.lua Devian.toc Devian.xml Dock.lua UI.lua
diffstat 5 files changed, 251 insertions(+), 208 deletions(-) [+]
line wrap: on
line diff
--- a/Devian.lua	Wed Aug 10 07:12:43 2016 -0400
+++ b/Devian.lua	Wed Oct 19 16:47:38 2016 -0400
@@ -21,7 +21,7 @@
 local playerName = UnitName("player")
 local playerRealm = playerName .. '-' .. GetRealmName()
 local num_dock_tabs = 0
-
+local charStates ={}
 
 DevianLoadMessage = setmetatable({}, {
   __call = function(t, msg)
@@ -43,7 +43,7 @@
   if D.debugmode then
     return print('Dvn', ...)
   else
-    return function() end
+    return nop
   end
 end
 local print = D.print
@@ -169,7 +169,7 @@
 
   for k,v in pairs(src) do
     if not dest[k] then
-      oldprint('Rebuilding conf value', k)
+      --oldprint('Rebuilding conf value', k)
       if type(v) == 'table' then
         dest[k] = {}
         D.DeepCopy(v, dest[k], ...)
@@ -232,8 +232,8 @@
     setprinthandler(D.Message)
   else
     DEVIAN_WORKSPACE = false
-    DEVIAN_PNAME = ''
-    print = function() end
+    DEVIAN_PNAME = nil
+    print = nop
   end
   DEVIAN_PID =id
 
@@ -274,17 +274,20 @@
 
   -- no args, toggle ui
   if mode == 'rc' then
-    return D.ResetChannels(self, tag)
+    return D:ResetChannels(tag)
   elseif  mode == 'stack' then
     return D:StackFrames()
   elseif mode == 'grid' then
     return D:DistributeFrames()
   elseif mode == 'tag' then -- tagging
-    return D.Tag(self, tag, dest)
+    return D:Tag(tag, dest)
   elseif mode == 'new' then
-    return D.New(self, tag)
+    return D:New(tag)
+  elseif mode == 'dock' then
+    D.db.dockPoint = tag
+    return D:UpdateDock()
   elseif mode == 'remove' then
-    return D.Remove(self, tag)
+    return D:Remove(tag)
   elseif mode ~= nil then
     -- profile selector or save command
     if mode == 'save' then
@@ -363,6 +366,7 @@
 
 
   if scan_func then
+    wipe(charStates)
     for id, name, enableState, globalState in D.Addons() do
       scan_func(id, name, enableState, globalState)
     end
@@ -370,7 +374,32 @@
 
   if scan_func == D.Load then
     _G.ReloadUI()
+    if AddonList_Update then
+      AddonList_Update()
+    end
+  elseif (scan_func == D.Save) then
+    print('reckoning')
+    local updated = {}
+    for addon, newState in pairs(charStates) do
+      for character, addons in pairs(db.profiles[list_id].char) do
+        if addons[addon] then
+          print(addon, addons[addon], '::', newState)
+          if (addons[addon] ~= newState) then
+            addons[addon] = newState
+            updated[character] = (updated[character] or 0) + 1
+          end
+
+        end
+
+      end
+    end
+    for character, numAddons in pairs(updated) do
+      print(character, numAddons, 'settings')
+    end
+
   end
+
+
   D.Profile(db.current_profile)
 end
 
@@ -389,27 +418,36 @@
 end
 
 D.Load = function(id, name, charState, globalState)
-  if targetChar[name] or targetGlobal[name] then
-    if targetGlobal[name] == 2 then
-      EnableAddOn(id, true)
-    elseif targetChar[name] == 2 then
-      EnableAddOn(id, playerName)
-    else
-      if targetChar[name] == 2 and targetGlobal[name] ~= 2 then
-        DisableAddOn(id)
-      else
-        DisableAddOn(id, true)
-      end
-    end
-    --print('load', name, 'global =', targetGlobal[name], 'char =', targetChar[name])
-  else
+  print('load', tostring(name), tostring(charState), tostring(globalState))
+  if targetGlobal[name] == 2 then
+    EnableAddOn(id, true)
+  elseif targetChar[name] == 2 then
+    EnableAddOn(id, playerName)
+  elseif targetGlobal[name] == 0 then
+    DisableAddOn(id, true)
+  elseif targetChar[name] == 0 then
+    DisableAddOn(id, playerName)
+  end
+
+  if not (targetChar[name] or targetGlobal[name]) then
     tinsert(D.unlisted, name)
   end
+
 end
+
+
 D.Save = function(id, name, charState, globalState)
-  --print('save', id, name, charState, globalState)
+  if (charState ~= 0) or (globalState ~= 0) then
+    print('save', id, name, playerRealm .. ': '.. charState, 'All: '.. globalState)
+  end
+
   targetGlobal[name] = globalState
   targetChar[name] = charState
+
+  -- if enabling/disabling globally
+  if globalState ~= 1 then
+    charStates[name] = globalState
+  end
 end
 
 D.Tag = function(self, tag, dest)
@@ -492,7 +530,7 @@
     D.console[dest]:Hide()
     D.channels[dest] = nil
     tremove(D.console, dest)
-    tremove(D.dock.buttons, dest)
+    D.dock.buttons[dest]:SetShown(false)
     D:UpdateDock()
     D:Print('Removed channel #'..dest)
   end
@@ -589,9 +627,10 @@
     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.buttons[id].newMessage then
-      D.dock.buttons[id].newMessage = true
-      D.UpdateBeacon(D.dock.buttons[id])
+    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()
     end
   end
   wipe(buffer)
@@ -677,10 +716,10 @@
     _G['SLASH_' .. CMD .. '1'] = "/"..cmd
 
     if type(func == 'string') then
-      print('SLASH_' .. CMD .. '1','/'.. cmd, func)
+      --print('SLASH_' .. CMD .. '1','/'.. cmd, func)
       SlashCmdList[CMD] = D[func]
     else
-      print('SLASH_' .. CMD .. '1','/'.. cmd, func)
+      --print('SLASH_' .. CMD .. '1','/'.. cmd, func)
       SlashCmdList[CMD] = func
     end
   end
--- a/Devian.toc	Wed Aug 10 07:12:43 2016 -0400
+++ b/Devian.toc	Wed Oct 19 16:47:38 2016 -0400
@@ -2,9 +2,14 @@
 ## Title: !|cFF00FFFFDevian|r
 ## Notes: AddOn Development Workspace
 ## Author: Krakyn
-## Version: 2.0 @project-revision@
+## Version: 2.2 @project-revision@
 ## SavedVariables: DevianDB, DevianLoadMessage
 ## OptionalDeps: Ace3
+Libs\LibStub\LibStub.lua
+Libs\AceAddon-3.0\AceAddon-3.0.xml
+Libs\AceConsole-3.0\AceConsole-3.0.xml
+Libs\CallbackHandler-1.0\CallbackHandler-1.0.lua
+Libs\AceEvent-3.0\AceEvent-3.0.xml
 Devian.xml
 Devian.lua
 Locale.lua
--- a/Devian.xml	Wed Aug 10 07:12:43 2016 -0400
+++ b/Devian.xml	Wed Oct 19 16:47:38 2016 -0400
@@ -1,4 +1,5 @@
-<Ui>
+<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" />
@@ -34,6 +35,7 @@
           <Color a="1" r="1" g="1" b="1" />
           <TexCoords top="0.47" left="0" bottom="0.9" right="1" />
         </Texture>
+
       </Layer>
     </Layers>
   </Button>
@@ -46,6 +48,8 @@
     </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" />
@@ -233,16 +237,10 @@
       hidden="true"
       frameStrata="LOW">
     <Scripts>
-      <OnEnter>
-        Devian.DockHighlight(self)
-      </OnEnter>
-      <OnLeave>
-        Devian.DockHighlight(self)
-      </OnLeave>
+      <OnMouseWheel>
+        Devian.Dock_OnMouseWheel(self, delta)
+      </OnMouseWheel>
     </Scripts>
-    <Anchors>
-      <Anchor point="TOP" relativePoint="TOP" x="0" y="1" />
-    </Anchors>
     <Size x="32" y="20" />
     <Layers>
       <Layer level="ARTWORK">
@@ -286,70 +284,56 @@
     </Layers>
   </Button>
 
-  <Button name="DevianBeacon" hidden="true" inherits="DevianButton" virtual="true" enableMouse="true" alpha="1" frameStrata="MEDIUM">
-    <Size x="64" y="32" />
+  <Button name="DevianBeacon" hidden="true" virtual="true" enableMouse="true" alpha="1" frameStrata="MEDIUM" mixin="DevianDockButtonMixin">
+    <Size x="64" y="24" />
 
     <Scripts>
-      <OnShow>
-        Devian.UpdateBeacon(self)
-      </OnShow>
-      <OnMouseDown>
-        --print("click", self:GetName(), button, self.console.index)
-        if button == "LeftButton" then
-          if IsShiftKeyDown() then
-            Devian:Console_Toggle(self.console.index, 0)
-          else
-            if self.console.index == Devian.currentProfile.current_channel or (not self.console.enabled) then
-              Devian:Console_Toggle(self.console.index)
-              if self.console.enabled then
-                if self.console.minimized then
-                  self.console:MinMax()
-                end
-                self.console:ToFront()
-              end
-            else
-              self.console:ToFront()
-            end
-          end
-        elseif button == "RightButton" then
-          self.console:MinMax()
-        end
-        self.console:Save()
-      </OnMouseDown>
-      <OnEnter>
-        --print(self:GetName(),'got mouse')
-        Devian.DockHighlight(self)
-      </OnEnter>
+      <OnShow method="OnShow" />
+      <OnEnter method="OnEnter" />
+      <OnMouseDown method="OnMouseDown" />
+      <OnClick method="Select" />
     </Scripts>
     <Layers>
+      <Layer level="BACKGROUND">
+        <Texture parentKey="Background" setAllPoints="true">
+          <Color a="0.5" r="0" g="0" b="0" />
+        </Texture>
+      </Layer>
       <Layer level="OVERLAY">
+        <Texture parentKey="Stripe">
+          <Anchors>
+            <Anchor point="TOPLEFT" />
+            <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT" x="0" y="-3" />
+          </Anchors>
+        </Texture>
       </Layer>
     </Layers>
     <Frames>
-      <Frame name="$parentText" parentKey="caption" alpha="0" blendMode="BLEND" enableMouse="false">
-        <Size x="100" y="30" />
+      <Frame name="$parentText" parentKey="caption" alpha="1" blendMode="BLEND" enableMouse="false">
+        <Size x="64" y="24" />
         <Anchors>
           <Anchor point="BOTTOM" relativePoint="BOTTOM" x="0" y="0" />
         </Anchors>
         <Layers>
           <Layer level="OVERLAY">
-            <FontString text="Test String" inherits="DevianText" parentKey="name" setAllPoints="true">
+            <FontString text="Test String" inherits="DevianDockHeader" parentKey="name" wordwrap="false" setAllPoints="true">
+              <Anchors>
+                <Anchor point="BOTTOM" />
+              </Anchors>
               <Color r="1" g="1" b="1" a="1" />
               <Shadow>
                 <Color r="0" g="0" b="0" a="1" />
                 <Offset x="0" y="-2" />
               </Shadow>
-              <Animations>
-                <AnimationGroup>
-                  <Scale scaleX="1.4" scaleY="1.4" looping="NONE">
-                    <Origin point="CENTER" x="0" y="0" />
-
-                  </Scale>
-                </AnimationGroup>
-              </Animations>
             </FontString>
           </Layer>
         </Layers>
+        <Animations>
+          <AnimationGroup parentKey="pulse" looping="BOUNCE" setToFinalAlpha="false">
+            <Alpha fromAlpha=".5" toAlpha="1" duration="0.4" endDelay="0.6" order="1" childKey="name" />
+
+          </AnimationGroup>
+        </Animations>
       </Frame>
     </Frames>
   </Button>
--- a/Dock.lua	Wed Aug 10 07:12:43 2016 -0400
+++ b/Dock.lua	Wed Oct 19 16:47:38 2016 -0400
@@ -8,6 +8,112 @@
 local ceil, floor, sqrt, pairs, GetScreenWidth, GetScreenHeight =  math.ceil, math.floor, math.sqrt, pairs, GetScreenWidth, GetScreenHeight
 local db
 local print = D.print
+local DOCK_BUTTON_PADDING = 6
+
+DevianDockButtonMixin = {}
+
+--- Updates region visibility as needed
+local getFadeInArgs = function(sign, region)
+  --print('Dvn', region)
+  local db = D.db
+  local alph = region:GetAlpha()
+  local a = (db[sign..'_alpha_on'] - alph)
+  local b = (db[sign..'_alpha_on']-db[sign..'_alpha_off'])
+  local dur = (a / b) * db[sign..'_fade_in']
+  return dur, alph, db[sign..'_alpha_on']
+end
+
+local getFadeOutArgs = function(sign, region)
+  local db = D.db
+  local alph = region:GetAlpha()
+  local a = (alph  - db[sign..'_alpha_off'])
+  local b = (db[sign..'_alpha_on']-db[sign..'_alpha_off'])
+  local dur = (a / b) * db[sign..'_fade_out']
+  return dur, alph, db[sign..'_alpha_off']
+end
+
+local function queueFade (self, duration, from, to)
+  self:SetAlpha(to)
+end
+
+local numBeacons = 0
+function D:GetDockButton(console)
+  self.dock.usedButtons = self.dock.usedButtons or {}
+
+  local button = self.dock.usedButtons[console.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)
+  end
+  button.index = console.index
+  button.caption.name:SetText(console.signature)
+  button:SetShown(true)
+  return button
+end
+
+function DevianDockButtonMixin:OnMouseDown(button)
+  --print("click", self:GetName(), button, self.console.index)
+  if button == "LeftButton" then
+    if IsShiftKeyDown() then
+      D:Console_Toggle(self.console.index, 0)
+    else
+      if self.console.index == D.currentProfile.current_channel or (not self.console.enabled) then
+        D:Console_Toggle(self.console.index)
+        if self.console.enabled then
+          if self.console.minimized then
+            self.console:MinMax()
+          end
+          self.console:ToFront()
+        end
+      else
+        self.console:ToFront()
+      end
+    end
+  elseif button == "RightButton" then
+    self.console:MinMax()
+  end
+  self.console:Save()
+end
+function DevianDockButtonMixin:OnShow()
+  self:Update()
+end
+function DevianDockButtonMixin:OnEnter()
+end
+function DevianDockButtonMixin:Update()
+  local db = D.db
+  local isActive = (self.raised or self.selected or self.newMessage)
+
+  if (self.showName or isActive) then
+    self.caption:SetAlpha(1)
+  else
+    self.caption:SetAlpha(0.5)
+  end
+
+  if self.selected then
+    self.Background:SetColorTexture(0.4,0.4,0.4,1)
+  else
+    self.Background:SetColorTexture(0,0,0,.5)
+  end
+
+  if (not self.showName) and (not isActive) then
+    --print(self:GetName(), 'no name no active, fade out')
+    self:SetAlpha(0.5)
+  else
+    self:SetAlpha(1)
+  end
+
+  self:SetWidth(self.caption.name:GetStringWidth() + DOCK_BUTTON_PADDING)
+end
+
+function DevianDockButtonMixin:Select()
+  self.caption.pulse:Stop()
+  self:Update()
+end
 
 --- Spaces each frame evenly across the screen.
 function D:DistributeFrames() --
@@ -42,132 +148,45 @@
   end
 end
 
+function D:Dock_OnMouseWheel(delta)
+  if delta >= 1 then
+    D.dockScale = (D.dockScale or 1) - 0.1
+  else
+    D.dockScale = (D.dockScale or 1) + 0.1
+  end
+  D:UpdateDock()
+end
 
 --- Space everything and set the dock size
 function D:UpdateDock()
   local pad_offset = 12
-  local draw_offset = pad_offset
+  local drawWidth = 0
+  local lastButton
+  local numButtons = 0
+  for i, d in ipairs(self.dock.buttons) do
+    if d and d:IsShown() then
+      d:SetScale(D.dockScale or 1)
+      if lastButton then
+        d:SetPoint('TOPLEFT', lastButton, 'TOPRIGHT', pad_offset, 0)
+      else
+        d:SetPoint('TOPLEFT',  DevianDock, 'TOPLEFT', pad_offset, 0)
+      end
 
-  local dockn = 1
-  for i, d in pairs(self.dock.buttons) do
-    dockn = max(i, dockn)
-  end
-  for i = 1, dockn do
-    local d = self.dock.buttons[i]
-    if d then
-      d:SetPoint('TOPLEFT',  DevianDock, 'TOPLEFT', draw_offset, 0)
-      draw_offset=  draw_offset + d:GetWidth() + pad_offset
+      drawWidth =  drawWidth + d:GetWidth() + pad_offset
+      lastButton = d
+      numButtons = numButtons + 1
+      print(numButtons)
     end
   end
-  self.dock:SetWidth(draw_offset)
+  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)
 end
 
---- Updates region visibility as needed
-local getFadeInArgs = function(sign, region)
-  --print('Dvn', region)
-  local db = D.db
-  local alph = region:GetAlpha()
-  local a = (db[sign..'_alpha_on'] - alph)
-  local b = (db[sign..'_alpha_on']-db[sign..'_alpha_off'])
-  local dur = (a / b) * db[sign..'_fade_in']
-  return dur, alph, db[sign..'_alpha_on']
-end
-
-local getFadeOutArgs = function(sign, region)
-  local db = D.db
-  local alph = region:GetAlpha()
-  local a = (alph  - db[sign..'_alpha_off'])
-  local b = (db[sign..'_alpha_on']-db[sign..'_alpha_off'])
-  local dur = (a / b) * db[sign..'_fade_out']
-  return dur, alph, db[sign..'_alpha_off']
-end
-
-local function queueFade (self, duration, from, to)
-  self:SetAlpha(to)
-end
-
-function D.UpdateBeacon(beacon)
-  local db = D.db
-  local isActive = (beacon.raised or beacon.selected or beacon.newMessage)
-  if isActive then
-    --print(beacon:GetName(), 'active, fade in')
-    queueFade(beacon, getFadeInArgs('dock_button', beacon))
-  end
-
-  if beacon.showName or isActive then
-    --print(beacon:GetName(), 'show name, fade in name')
-    queueFade(beacon.caption, getFadeInArgs('dock_button', beacon.caption))
-  end
-
-  if not isActive then
-    queueFade(beacon, getFadeOutArgs('dock_button', beacon))
-  end
-
-  if (not beacon.showName) and (not isActive) then
-    --print(beacon:GetName(), 'no name no active, fade out')
-    queueFade(beacon.caption,getFadeOutArgs('dock_button', beacon.caption))
-  end
-end
 
 local function FrameFade(frame)
   if not D.fader then
     D.fader = CreateFrame('Frame', 'DevianFaderFrame', UIParent):CreateAnimationGroup('fader'):CreateAnimation('Alpha', 'FadeIn')
   end
-end
-
---- Dock interaction framescript
-function D.DockHighlight(beacon)
-  db = D.db
-  local self = D.dock
-  local mouseOverDock = false
-  if self:IsMouseOver() then
-    mouseOverDock = true
-  end
-
-  if beacon then
-    --print(beacon:GetName(), ' highlighter got beacon')
-    mouseOverDock = true
-    if not beacon.raised then
-      --print(beacon:GetName(), '  beacon not raised')
-      beacon.raised = true
-      D.UpdateBeacon(beacon)
-
-      -- IsMouseOver can still return false during its frame's OnEnter
-      beacon.inc = 0
-      beacon:SetScript('OnUpdate', function(self)
-        if not self:IsMouseOver() then
-          self.inc = self.inc + 1
-          --print(self:GetName(),self.inc)
-          if self.inc > 10 then
-          --print(self:GetName(), 'lost mouseover, terminating OnUpdate')
-          self.raised = nil
-          D.UpdateBeacon(self)
-          self:SetScript('OnUpdate', nil)
-            end
-        end
-      end)
-    end
-  elseif beacon.raised and beacon.index ~= db.current_channel then
-    beacon.raised = nil
-    D.UpdateBeacon(beacon)
-    --beacon:SetScript('OnUpdate', nil)
-  end
-
-  if mouseOverDock then
-    -- Raise it up
-    if not self.raised then
-
-      self.raised = true
-      queueFade(self, getFadeInArgs('dock', self))
-    end
-  elseif  self.raised then
-    -- Drop it down
-    self.raised = nil
-    queueFade(self, getFadeOutArgs('dock', self))
-    for k, v in pairs(self.buttons) do
-      v.raised = nil
-      D.UpdateBeacon(v)
-    end
-  end
-
 end
\ No newline at end of file
--- a/UI.lua	Wed Aug 10 07:12:43 2016 -0400
+++ b/UI.lua	Wed Oct 19 16:47:38 2016 -0400
@@ -108,10 +108,10 @@
 
 
   -- update dock buttons
-  local beacon = D.dock.buttons[c.index]
+  local beacon = c.dockButton
   beacon.selected = true
   beacon.newMessage = nil
-  D.UpdateBeacon(beacon)
+  beacon:Update()
 
   for _, part in pairs(c.border) do
     part:SetColorTexture(unpack(db.frontborder))
@@ -126,11 +126,11 @@
       bc.dropmenu.icon:SetVertexColor(unpack(db.backheader))
       bc.title:SetTextColor(unpack(db.backborder))
 
-      local beacon = D.dock.buttons[bc.index]
+      local beacon = D.dock.usedButtons[bc.index]
       beacon.raised = nil
       beacon.showName = nil
       beacon.selected = nil
-      D.UpdateBeacon(beacon)
+      beacon:Update()
 
       for _, part in pairs(bc.border) do
         part:SetColorTexture(unpack(db.backborder))
@@ -236,12 +236,8 @@
     f:SetScript('OnEvent', Console_OnMovementChanged)
   end
 
-  D.dock.buttons[i] = CreateFrame('Button', 'Channel'..i..'Beacon', UIParent, 'DevianBeacon')
-  D.dock.buttons[i].icon:SetVertexColor(math.random(),math.random(),math.random())
-  D.dock.buttons[i].console = f
-  D.dock.buttons[i].index = i
-  D.dock.buttons[i].caption.name:SetText(vars.signature)
-  D.dock.buttons[i]:Show()
+  f.dockButton = D:GetDockButton(f)
+
 
   if vars.minimized then
     f:Minimize()