diff BuffAnchors.lua @ 0:3dbcad2b387d

initial push
author Nenue
date Wed, 30 Mar 2016 02:24:56 -0400
parents
children 66b927b46776
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BuffAnchors.lua	Wed Mar 30 02:24:56 2016 -0400
@@ -0,0 +1,302 @@
+--- ${PACKAGE_NAME}
+-- @file-author@
+-- @project-revision@ @project-hash@
+-- @file-revision@ @file-hash@
+-- Created: 3/22/2016 3:10 AM
+
+local MODULE = 'BuffFrame'
+local _, A = ...
+local B, _G = A.frame, _G
+local M = B:RegisterModule(MODULE)
+local type, unpack, select, pairs, ipairs, wipe = type, unpack, select, pairs, ipairs, table.wipe
+local min, ceil, mod, tonumber, tostring = min, ceil, mod, tonumber, tostring
+local CreateFrame = CreateFrame
+local print = B.print('Anchor')
+local fprint = B.fprint
+local bprint = B.print('AnchorFrame')
+
+local GetAnchorFrame = function(name)
+  local c = B.displays[name].conf
+  local anchorFrom, anchorParent, anchorTo, offsetX, offsetY = unpack(c.Anchor)
+  local print = bprint
+  if B.anchor[name] then
+    print('get', B.anchor[name]:GetName())
+    return B.anchor[name], anchorFrom, anchorParent, anchorTo, offsetX, offsetY
+  end
+  print('new frame', name)
+  local frame = CreateFrame('Frame', name..'Anchor', UIParent, B.displays[name].anchorTemplate)
+  frame.conf = c
+
+  local x, dx, y, dy
+  local Anchor_OnMouseDown =  function()
+    if c['Parent'] then
+      return
+    end
+
+    x = frame:GetLeft()
+    y = frame:GetTop()
+    frame:StartMoving()
+    frame.isMoving = true
+  end
+
+  local Anchor_OnMouseUp = function()
+    if c['Parent'] then
+      return
+    end
+
+    frame:StopMovingOrSizing()
+    dx = frame:GetLeft() - x
+    dy = frame:GetTop() - y
+    -- update config
+    print('|cFFFFFF00**changing', name, 'anchor by', dx, dy)
+    offsetX = offsetX + dx
+    offsetY = offsetY + dy
+    B.Conf[name .. 'Anchor'] = {anchorFrom, anchorParent, anchorTo, offsetX, offsetY }
+    frame:SetPoint(anchorFrom, _G[anchorParent], anchorTo, offsetX, offsetY)
+    frame.isMoving = nil
+  end
+
+  local AnchorButton_OnClick = function(self, anchor)
+    local point, parent, relative = anchor:GetPoint(1)
+    print('resetting anchors', point, parent:GetName(), relative)
+    B.Conf[name..'Point'] = {point, relative}
+    B.Conf[name..'RelativeX'] = (point:match('RIGHT')) and -1 or 1
+    B.Conf[name..'RelativeY'] = (point:match('TOP')) and -1 or 1
+    wipe(B.drawn[name])
+    B.UpdateBuffs(name)
+  end
+
+  frame.OnUpdate = function(self, elapsed)
+    print(self:GetName(), elapsed)
+    if self:IsMouseOver() then
+      for i, anchorButton in ipairs(frame.anchorButton) do
+        anchorButton:Show()
+      end
+    else
+      for i, anchorButton in ipairs(frame.anchorButton) do
+        anchorButton:Hide()
+      end
+    end
+  end
+
+  frame:SetScript('OnMouseDown', Anchor_OnMouseDown)
+  frame:SetScript("OnMouseUp", Anchor_OnMouseUp)
+  -- table addition
+  for i, anchorButton in ipairs(frame.anchorButton) do
+    anchorButton:SetScript('OnClick', AnchorButton_OnClick)
+  end
+
+  B.displays[name].anchor = frame
+  print(B.displays[name].anchor:GetName())
+  print(B.anchor[name]:GetName())
+  return frame, anchorFrom, anchorParent, anchorTo, offsetX, offsetY
+end
+
+--- Handles the preliminary positioning calculation for buff guide anchors
+M.UpdateAnchorFrames = function(name)
+  local print = fprint(name)
+  local c = B.displays[name].conf
+  local frame, anchorFrom, anchorParent, anchorTo, offsetX, offsetY = GetAnchorFrame(name)
+  print('got', frame:GetName())
+  frame.buffs = B.guides[name]
+  frame.heading:SetText(name)
+  B.SetConfigLayers(frame)
+
+  local buffMax = c['Max'] or 3
+  local perRow = c['PerRow'] or 2
+  local buffSpacing = c['Spacing']
+  local buffSize = c['Size']
+  local buffDurationSize = c['DurationSize']
+
+  if not frame.isMoving then
+    if not B.Conf[name .. 'Parent'] then
+      frame:SetPoint(anchorFrom, _G[anchorParent], anchorTo, offsetX, offsetY)
+    end
+  end
+
+  if frame.contains then buffMax = buffMax + 1 end
+  local cols, rows = min(perRow, buffMax), ceil(buffMax/perRow)
+  local spaces, breaks = (cols - 1), (rows - 1)
+  frame.columns = cols
+  frame.rows = rows
+  frame.spaces = cols - 1
+  frame.breaks = rows - 1
+
+  local width = cols*buffSize + spaces*buffSpacing
+  local height = rows * (buffSize + buffDurationSize) + (breaks * (buffSpacing))
+
+  frame:SetSize(width, height)
+  frame:Show()
+  print(frame:GetName(), frame:GetSize())
+  print(frame:GetPoint(1))
+end
+
+--- Handles placement of anchors embedded within anchors (consolidated buffs, maybe temp enchant)
+M.UpdateAnchorAnchors = function()
+  local print = fprint()
+  for buttonName, d in pairs(B.displays) do
+    local c = B.displays[buttonName].conf
+    local frame =  B.anchor[buttonName]
+    local parent, child = c.Parent, c.Position
+
+    frame.parent = nil
+    if B.Conf[buttonName .. 'Parent'] and _G[B.Conf[buttonName .. 'Parent']..'Anchor'] then
+
+      local anchorAnchor = _G[B.Conf[buttonName .. 'Parent']..'Anchor']
+      local anchorTarget = B.guides[parent][child]
+      if anchorTarget then
+        print('link', buttonName, 'to', parent, child)
+        print(parent, child, B.displays[parent].guides[child])
+        local ac = B.displays[parent].conf
+        local anchorFrom, anchorTo = unpack(ac.Point)
+        frame:ClearAllPoints()
+        frame:SetPoint(anchorFrom, anchorTarget, anchorTo)
+        frame.parent = anchorTarget
+        anchorTarget.contains = frame
+        anchorAnchor.contains = frame
+        anchorAnchor.containPosition = child
+      else
+        frame.parent = anchorAnchor
+        anchorAnchor.contains = frame
+        anchorAnchor.containPosition = nil
+      end
+    else
+      frame.parent = nil
+    end
+
+  end
+end
+
+-- if facing key direction, anchor point [1] to parent's point [2]
+local childFacing = {
+  ['TOP'] = {'TOP', 'BOTTOM'},
+  ['BOTTOM'] = {'BOTTOM', 'TOP'},
+  ['RIGHT'] = {'LEFT', 'RIGHT'},
+  ['LEFT'] = {'RIGHT', 'LEFT'},
+}
+-- if align in key position, concatenate value with facing point
+local childAlign = {
+  ['TOP'] = 'TOP%s',
+  ['BOTTOM'] = 'BOTTOM%s',
+  ['MIDDLE'] = '%s',
+  ['LEFT'] = '%sLEFT',
+  ['RIGHT'] = '%sRIGHT',
+  ['CENTER'] = '%s',
+}
+
+--- dep handlers
+B.UpdateAnchorChild = function (frame, child, c)
+  if frame.attached ~= child then
+    B.SetAnchorChild(frame, child, c)
+  end
+
+  print('positioning|cFFFF0088', child, '|r of |cFF00FF00', frame, '|r')
+
+  local frameAnchor = unpack(B.Conf[c.Parent.. 'Anchor'])
+  local childAnchor, childPoint = 'BOTTOMRIGHT', 'TOPRIGHT'
+  local direction, position = unpack(c.Anchor)
+  if direction and position then
+    childAnchor = childAlign[position]:format(childFacing[direction][2])
+    childPoint = childAlign[position]:format(childFacing[direction][1])
+    print('align toward', position,'on', direction, 'edge')
+  end
+
+  print(frameAnchor, direction, position)
+  local lX, lY, cX, cY = frame.outer_X, frame.outer_Y, frame.cutout_X, frame.cutout_Y
+  local mX, mY = 0, 0 -- alignment modifiers
+  local pX, pY = 0, 0 -- position value
+  print('|cFFFF0088PUSHOUTS|r:', lX, lY, '|cFFFF8800PULL-IN|r:', cX, cY)
+
+  -- if attachment is on a moving edge
+  if not frameAnchor:match(direction) then
+    print('  child anchors to a growing edge |cFFFF8800', direction,'|r')
+    if direction == 'BOTTOM' then
+      -- horizontal edge
+
+    else
+      -- vertical edge
+      pX = lX
+    end
+
+    if frameAnchor:match(position) then
+
+      print('close alignment', lX, cX)
+      if position == 'RIGHT' then
+        -- and far X val
+        pX = 0
+        lX = -lX
+        cX = -cX
+        pY = lY
+      else
+      end
+    else
+      print('far alignment', position)
+    end
+  else
+    print('  child anchors to a static edge |cFF0088FF', direction,'|r')
+    -- use no Y offset, position doesn't interfere
+    if direction == 'BOTTOM' or direction == 'TOP' then
+      pY = 0
+    else
+      pX = 0
+    end
+  end
+
+  local frameWidth = frame:GetWidth()
+  local frameHeight = frame:GetHeight()
+
+  local overlapY, overlapX
+
+  -- right and bottom anchors offsets need to be inverted
+  if direction == 'BOTTOM' then
+    print('inverting Y values for anchor on BOTTOM edge, options:', cY, lY, 'actual:', pY)
+    pY = frameHeight - pY
+    cY = frameHeight - cY
+    lY = frameHeight - lY
+    print('  new values:', cY, lY, pY)
+  elseif direction == 'RIGHT' then
+    pX = frameWidth -pX
+    cX = frameWidth-cX
+    lX = frameWidth-lX
+  end
+
+
+  print(child, '|cFFFFFF00', childAnchor, '|r', frame, '|cFFFF0088', childPoint, '|r', pX, pY)
+  child:ClearAllPoints()
+  child:SetPoint(childAnchor, frame, childPoint, pX, pY)
+  frame.attachPoint = {childAnchor, childPoint }
+
+  if Devian and Devian.InWorkspace() then
+    frame.alignedJoint:ClearAllPoints()
+    frame.poppingJointX:ClearAllPoints()
+    frame.poppingJointY:ClearAllPoints()
+    frame.cuttingJointX:ClearAllPoints()
+    frame.cuttingJointY:ClearAllPoints()
+    frame.childSpace:ClearAllPoints()
+
+    frame.alignedJoint:SetPoint(childAnchor, frame, childPoint, pX, pY)
+    frame.poppingJointY:SetPoint(childAnchor, frame, childPoint, lX, lY) -- should really only differ when rows exceed 1
+    frame.poppingJointX:SetPoint(childAnchor, frame, childPoint, lX, lY)
+    frame.cuttingJointY:SetPoint(childAnchor, frame, childPoint, cX, cY) -- should really only differ when rows exceed 1
+    frame.cuttingJointX:SetPoint(childAnchor, frame, childPoint, cX, cY)
+    frame.childSpace:SetAllPoints(child)
+
+    frame.alignedJoint:Show()
+    frame.poppingJointX:Show()
+    frame.poppingJointY:Show()
+    frame.cuttingJointX:Show()
+    frame.cuttingJointY:Show()
+    frame.childSpace:Show()
+
+    print('|cFFFF0000MIN  |r', childAnchor, childPoint, pX, pY)
+    print('|cFF00FFFFFAR  |r', childAnchor, childPoint, cX, cY)
+    print('|cFFFFFF00CLOSE|r', childAnchor, childPoint, lX, lY)
+
+  end
+end
+
+B.SetAnchorChild = function(frame, child, c)
+  print('linking', child)
+  frame.attached = child
+  frame.attachmentConf = c
+end
\ No newline at end of file