Mercurial > wow > buffalo2
view BuffAnchors.lua @ 37:e84d645c8ab8
- revised the tracker update function to build its complete data list up front and use the values as points of comparison for determining possible out of place blocks, which will be iterated over afterward to remove what wasn't re-used
- also entailed revising the exact role of global event handlers and function hooks, limiting their directions of communication so one doesn't end up calling the other multiple or inifinity times
- schema handling polish
author | Nenue |
---|---|
date | Mon, 18 Apr 2016 07:56:23 -0400 |
parents | 66b927b46776 |
children |
line wrap: on
line source
--- ${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:EnableMouse(B.Conf.ConfigMode and B.Conf.ConfigMode or false) 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