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