Nenue@0
|
1 --- ${PACKAGE_NAME}
|
Nenue@0
|
2 -- @file-author@
|
Nenue@0
|
3 -- @project-revision@ @project-hash@
|
Nenue@0
|
4 -- @file-revision@ @file-hash@
|
Nenue@0
|
5 -- Created: 3/22/2016 3:10 AM
|
Nenue@0
|
6
|
Nenue@0
|
7 local MODULE = 'BuffFrame'
|
Nenue@0
|
8 local _, A = ...
|
Nenue@0
|
9 local B, _G = A.frame, _G
|
Nenue@47
|
10 local buffFrame = B:RegisterModule(MODULE)
|
Nenue@0
|
11 local type, unpack, select, pairs, ipairs, wipe = type, unpack, select, pairs, ipairs, table.wipe
|
Nenue@0
|
12 local min, ceil, mod, tonumber, tostring = min, ceil, mod, tonumber, tostring
|
Nenue@0
|
13 local CreateFrame = CreateFrame
|
Nenue@0
|
14 local print = B.print('Anchor')
|
Nenue@0
|
15 local fprint = B.fprint
|
Nenue@0
|
16 local bprint = B.print('AnchorFrame')
|
Nenue@0
|
17
|
Nenue@0
|
18 local GetAnchorFrame = function(name)
|
Nenue@48
|
19 local c = buffFrame.displays[name].conf
|
Nenue@48
|
20 local anchors = buffFrame.anchors
|
Nenue@0
|
21 local anchorFrom, anchorParent, anchorTo, offsetX, offsetY = unpack(c.Anchor)
|
Nenue@0
|
22 local print = bprint
|
Nenue@48
|
23 if anchors[name] and anchors[name].GetName then
|
Nenue@48
|
24 print('get', buffFrame.anchors[name]:GetName())
|
Nenue@48
|
25 return buffFrame.anchors[name], anchorFrom, anchorParent, anchorTo, offsetX, offsetY
|
Nenue@0
|
26 end
|
Nenue@0
|
27 print('new frame', name)
|
Nenue@48
|
28 local frame = CreateFrame('Frame', name..'Anchor', UIParent, buffFrame.displays[name].anchorTemplate)
|
Nenue@0
|
29 frame.conf = c
|
Nenue@0
|
30
|
Nenue@0
|
31 local x, dx, y, dy
|
Nenue@0
|
32 local Anchor_OnMouseDown = function()
|
Nenue@0
|
33 if c['Parent'] then
|
Nenue@0
|
34 return
|
Nenue@0
|
35 end
|
Nenue@0
|
36
|
Nenue@0
|
37 x = frame:GetLeft()
|
Nenue@0
|
38 y = frame:GetTop()
|
Nenue@0
|
39 frame:StartMoving()
|
Nenue@0
|
40 frame.isMoving = true
|
Nenue@0
|
41 end
|
Nenue@0
|
42
|
Nenue@0
|
43 local Anchor_OnMouseUp = function()
|
Nenue@0
|
44 if c['Parent'] then
|
Nenue@0
|
45 return
|
Nenue@0
|
46 end
|
Nenue@0
|
47
|
Nenue@0
|
48 frame:StopMovingOrSizing()
|
Nenue@0
|
49 dx = frame:GetLeft() - x
|
Nenue@0
|
50 dy = frame:GetTop() - y
|
Nenue@0
|
51 -- update config
|
Nenue@0
|
52 print('|cFFFFFF00**changing', name, 'anchor by', dx, dy)
|
Nenue@0
|
53 offsetX = offsetX + dx
|
Nenue@0
|
54 offsetY = offsetY + dy
|
Nenue@48
|
55 buffFrame.Conf[name .. 'Anchor'] = {anchorFrom, anchorParent, anchorTo, offsetX, offsetY }
|
Nenue@0
|
56 frame:SetPoint(anchorFrom, _G[anchorParent], anchorTo, offsetX, offsetY)
|
Nenue@0
|
57 frame.isMoving = nil
|
Nenue@0
|
58 end
|
Nenue@0
|
59
|
Nenue@0
|
60 local AnchorButton_OnClick = function(self, anchor)
|
Nenue@0
|
61 local point, parent, relative = anchor:GetPoint(1)
|
Nenue@0
|
62 print('resetting anchors', point, parent:GetName(), relative)
|
Nenue@48
|
63 buffFrame.Conf[name..'Point'] = {point, relative}
|
Nenue@48
|
64 buffFrame.Conf[name..'RelativeX'] = (point:match('RIGHT')) and -1 or 1
|
Nenue@48
|
65 buffFrame.Conf[name..'RelativeY'] = (point:match('TOP')) and -1 or 1
|
Nenue@48
|
66 wipe(buffFrame.drawn[name])
|
Nenue@48
|
67 buffFrame.UpdateBuffs(name)
|
Nenue@0
|
68 end
|
Nenue@0
|
69
|
Nenue@0
|
70 frame.OnUpdate = function(self, elapsed)
|
Nenue@0
|
71 print(self:GetName(), elapsed)
|
Nenue@0
|
72 if self:IsMouseOver() then
|
Nenue@0
|
73 for i, anchorButton in ipairs(frame.anchorButton) do
|
Nenue@0
|
74 anchorButton:Show()
|
Nenue@0
|
75 end
|
Nenue@0
|
76 else
|
Nenue@0
|
77 for i, anchorButton in ipairs(frame.anchorButton) do
|
Nenue@0
|
78 anchorButton:Hide()
|
Nenue@0
|
79 end
|
Nenue@0
|
80 end
|
Nenue@0
|
81 end
|
Nenue@0
|
82
|
Nenue@24
|
83 frame:EnableMouse(B.Conf.ConfigMode and B.Conf.ConfigMode or false)
|
Nenue@0
|
84 frame:SetScript('OnMouseDown', Anchor_OnMouseDown)
|
Nenue@0
|
85 frame:SetScript("OnMouseUp", Anchor_OnMouseUp)
|
Nenue@0
|
86 -- table addition
|
Nenue@0
|
87 for i, anchorButton in ipairs(frame.anchorButton) do
|
Nenue@0
|
88 anchorButton:SetScript('OnClick', AnchorButton_OnClick)
|
Nenue@0
|
89 end
|
Nenue@0
|
90
|
Nenue@48
|
91 buffFrame.displays[name].anchor = frame
|
Nenue@48
|
92 print('displays[name].anchor', buffFrame.displays[name].anchor:GetName())
|
Nenue@48
|
93 print('anchors[name]', buffFrame.anchors[name]:GetName())
|
Nenue@0
|
94 return frame, anchorFrom, anchorParent, anchorTo, offsetX, offsetY
|
Nenue@0
|
95 end
|
Nenue@0
|
96
|
Nenue@0
|
97 --- Handles the preliminary positioning calculation for buff guide anchors
|
Nenue@47
|
98 buffFrame.UpdateAnchorFrames = function(name)
|
Nenue@0
|
99 local print = fprint(name)
|
Nenue@48
|
100 local c = buffFrame.displays[name].conf
|
Nenue@0
|
101 local frame, anchorFrom, anchorParent, anchorTo, offsetX, offsetY = GetAnchorFrame(name)
|
Nenue@0
|
102 print('got', frame:GetName())
|
Nenue@48
|
103 frame.buffs = buffFrame.guides[name]
|
Nenue@0
|
104 frame.heading:SetText(name)
|
Nenue@0
|
105 B.SetConfigLayers(frame)
|
Nenue@0
|
106
|
Nenue@0
|
107 local buffMax = c['Max'] or 3
|
Nenue@0
|
108 local perRow = c['PerRow'] or 2
|
Nenue@0
|
109 local buffSpacing = c['Spacing']
|
Nenue@0
|
110 local buffSize = c['Size']
|
Nenue@0
|
111 local buffDurationSize = c['DurationSize']
|
Nenue@0
|
112
|
Nenue@0
|
113 if not frame.isMoving then
|
Nenue@0
|
114 if not B.Conf[name .. 'Parent'] then
|
Nenue@0
|
115 frame:SetPoint(anchorFrom, _G[anchorParent], anchorTo, offsetX, offsetY)
|
Nenue@0
|
116 end
|
Nenue@0
|
117 end
|
Nenue@0
|
118
|
Nenue@0
|
119 if frame.contains then buffMax = buffMax + 1 end
|
Nenue@0
|
120 local cols, rows = min(perRow, buffMax), ceil(buffMax/perRow)
|
Nenue@0
|
121 local spaces, breaks = (cols - 1), (rows - 1)
|
Nenue@0
|
122 frame.columns = cols
|
Nenue@0
|
123 frame.rows = rows
|
Nenue@0
|
124 frame.spaces = cols - 1
|
Nenue@0
|
125 frame.breaks = rows - 1
|
Nenue@0
|
126
|
Nenue@0
|
127 local width = cols*buffSize + spaces*buffSpacing
|
Nenue@0
|
128 local height = rows * (buffSize + buffDurationSize) + (breaks * (buffSpacing))
|
Nenue@0
|
129
|
Nenue@0
|
130 frame:SetSize(width, height)
|
Nenue@0
|
131 frame:Show()
|
Nenue@0
|
132 print(frame:GetName(), frame:GetSize())
|
Nenue@0
|
133 print(frame:GetPoint(1))
|
Nenue@0
|
134 end
|
Nenue@0
|
135
|
Nenue@0
|
136 --- Handles placement of anchors embedded within anchors (consolidated buffs, maybe temp enchant)
|
Nenue@47
|
137 buffFrame.UpdateAnchorAnchors = function()
|
Nenue@48
|
138 local displays = buffFrame.displays
|
Nenue@48
|
139 local c = buffFrame.Conf
|
Nenue@48
|
140 local guides = buffFrame.guides
|
Nenue@0
|
141 local print = fprint()
|
Nenue@48
|
142 for buttonName, d in pairs(displays) do
|
Nenue@48
|
143 local c = displays[buttonName].conf
|
Nenue@48
|
144 local frame = buffFrame.anchors[buttonName]
|
Nenue@0
|
145 local parent, child = c.Parent, c.Position
|
Nenue@0
|
146
|
Nenue@0
|
147 frame.parent = nil
|
Nenue@48
|
148 if c[buttonName .. 'Parent'] and _G[c[buttonName .. 'Parent']..'Anchor'] then
|
Nenue@0
|
149
|
Nenue@48
|
150 local anchorAnchor = _G[c[buttonName .. 'Parent']..'Anchor']
|
Nenue@48
|
151 local anchorTarget = guides[parent][child]
|
Nenue@0
|
152 if anchorTarget then
|
Nenue@0
|
153 print('link', buttonName, 'to', parent, child)
|
Nenue@48
|
154 print(parent, child, displays[parent].guides[child])
|
Nenue@48
|
155 local ac = displays[parent].conf
|
Nenue@0
|
156 local anchorFrom, anchorTo = unpack(ac.Point)
|
Nenue@0
|
157 frame:ClearAllPoints()
|
Nenue@0
|
158 frame:SetPoint(anchorFrom, anchorTarget, anchorTo)
|
Nenue@0
|
159 frame.parent = anchorTarget
|
Nenue@0
|
160 anchorTarget.contains = frame
|
Nenue@0
|
161 anchorAnchor.contains = frame
|
Nenue@0
|
162 anchorAnchor.containPosition = child
|
Nenue@0
|
163 else
|
Nenue@0
|
164 frame.parent = anchorAnchor
|
Nenue@0
|
165 anchorAnchor.contains = frame
|
Nenue@0
|
166 anchorAnchor.containPosition = nil
|
Nenue@0
|
167 end
|
Nenue@0
|
168 else
|
Nenue@0
|
169 frame.parent = nil
|
Nenue@0
|
170 end
|
Nenue@0
|
171
|
Nenue@0
|
172 end
|
Nenue@0
|
173 end
|
Nenue@0
|
174
|
Nenue@0
|
175 -- if facing key direction, anchor point [1] to parent's point [2]
|
Nenue@0
|
176 local childFacing = {
|
Nenue@0
|
177 ['TOP'] = {'TOP', 'BOTTOM'},
|
Nenue@0
|
178 ['BOTTOM'] = {'BOTTOM', 'TOP'},
|
Nenue@0
|
179 ['RIGHT'] = {'LEFT', 'RIGHT'},
|
Nenue@0
|
180 ['LEFT'] = {'RIGHT', 'LEFT'},
|
Nenue@0
|
181 }
|
Nenue@0
|
182 -- if align in key position, concatenate value with facing point
|
Nenue@0
|
183 local childAlign = {
|
Nenue@0
|
184 ['TOP'] = 'TOP%s',
|
Nenue@0
|
185 ['BOTTOM'] = 'BOTTOM%s',
|
Nenue@0
|
186 ['MIDDLE'] = '%s',
|
Nenue@0
|
187 ['LEFT'] = '%sLEFT',
|
Nenue@0
|
188 ['RIGHT'] = '%sRIGHT',
|
Nenue@0
|
189 ['CENTER'] = '%s',
|
Nenue@0
|
190 }
|
Nenue@0
|
191
|
Nenue@0
|
192 --- dep handlers
|
Nenue@0
|
193 B.UpdateAnchorChild = function (frame, child, c)
|
Nenue@0
|
194 if frame.attached ~= child then
|
Nenue@0
|
195 B.SetAnchorChild(frame, child, c)
|
Nenue@0
|
196 end
|
Nenue@0
|
197
|
Nenue@0
|
198 print('positioning|cFFFF0088', child, '|r of |cFF00FF00', frame, '|r')
|
Nenue@0
|
199
|
Nenue@0
|
200 local frameAnchor = unpack(B.Conf[c.Parent.. 'Anchor'])
|
Nenue@0
|
201 local childAnchor, childPoint = 'BOTTOMRIGHT', 'TOPRIGHT'
|
Nenue@0
|
202 local direction, position = unpack(c.Anchor)
|
Nenue@0
|
203 if direction and position then
|
Nenue@0
|
204 childAnchor = childAlign[position]:format(childFacing[direction][2])
|
Nenue@0
|
205 childPoint = childAlign[position]:format(childFacing[direction][1])
|
Nenue@0
|
206 print('align toward', position,'on', direction, 'edge')
|
Nenue@0
|
207 end
|
Nenue@0
|
208
|
Nenue@0
|
209 print(frameAnchor, direction, position)
|
Nenue@0
|
210 local lX, lY, cX, cY = frame.outer_X, frame.outer_Y, frame.cutout_X, frame.cutout_Y
|
Nenue@0
|
211 local mX, mY = 0, 0 -- alignment modifiers
|
Nenue@0
|
212 local pX, pY = 0, 0 -- position value
|
Nenue@0
|
213 print('|cFFFF0088PUSHOUTS|r:', lX, lY, '|cFFFF8800PULL-IN|r:', cX, cY)
|
Nenue@0
|
214
|
Nenue@0
|
215 -- if attachment is on a moving edge
|
Nenue@0
|
216 if not frameAnchor:match(direction) then
|
Nenue@0
|
217 print(' child anchors to a growing edge |cFFFF8800', direction,'|r')
|
Nenue@0
|
218 if direction == 'BOTTOM' then
|
Nenue@0
|
219 -- horizontal edge
|
Nenue@0
|
220
|
Nenue@0
|
221 else
|
Nenue@0
|
222 -- vertical edge
|
Nenue@0
|
223 pX = lX
|
Nenue@0
|
224 end
|
Nenue@0
|
225
|
Nenue@0
|
226 if frameAnchor:match(position) then
|
Nenue@0
|
227
|
Nenue@0
|
228 print('close alignment', lX, cX)
|
Nenue@0
|
229 if position == 'RIGHT' then
|
Nenue@0
|
230 -- and far X val
|
Nenue@0
|
231 pX = 0
|
Nenue@0
|
232 lX = -lX
|
Nenue@0
|
233 cX = -cX
|
Nenue@0
|
234 pY = lY
|
Nenue@0
|
235 else
|
Nenue@0
|
236 end
|
Nenue@0
|
237 else
|
Nenue@0
|
238 print('far alignment', position)
|
Nenue@0
|
239 end
|
Nenue@0
|
240 else
|
Nenue@0
|
241 print(' child anchors to a static edge |cFF0088FF', direction,'|r')
|
Nenue@0
|
242 -- use no Y offset, position doesn't interfere
|
Nenue@0
|
243 if direction == 'BOTTOM' or direction == 'TOP' then
|
Nenue@0
|
244 pY = 0
|
Nenue@0
|
245 else
|
Nenue@0
|
246 pX = 0
|
Nenue@0
|
247 end
|
Nenue@0
|
248 end
|
Nenue@0
|
249
|
Nenue@0
|
250 local frameWidth = frame:GetWidth()
|
Nenue@0
|
251 local frameHeight = frame:GetHeight()
|
Nenue@0
|
252
|
Nenue@0
|
253 local overlapY, overlapX
|
Nenue@0
|
254
|
Nenue@0
|
255 -- right and bottom anchors offsets need to be inverted
|
Nenue@0
|
256 if direction == 'BOTTOM' then
|
Nenue@0
|
257 print('inverting Y values for anchor on BOTTOM edge, options:', cY, lY, 'actual:', pY)
|
Nenue@0
|
258 pY = frameHeight - pY
|
Nenue@0
|
259 cY = frameHeight - cY
|
Nenue@0
|
260 lY = frameHeight - lY
|
Nenue@0
|
261 print(' new values:', cY, lY, pY)
|
Nenue@0
|
262 elseif direction == 'RIGHT' then
|
Nenue@0
|
263 pX = frameWidth -pX
|
Nenue@0
|
264 cX = frameWidth-cX
|
Nenue@0
|
265 lX = frameWidth-lX
|
Nenue@0
|
266 end
|
Nenue@0
|
267
|
Nenue@0
|
268
|
Nenue@0
|
269 print(child, '|cFFFFFF00', childAnchor, '|r', frame, '|cFFFF0088', childPoint, '|r', pX, pY)
|
Nenue@0
|
270 child:ClearAllPoints()
|
Nenue@0
|
271 child:SetPoint(childAnchor, frame, childPoint, pX, pY)
|
Nenue@0
|
272 frame.attachPoint = {childAnchor, childPoint }
|
Nenue@0
|
273
|
Nenue@0
|
274 if Devian and Devian.InWorkspace() then
|
Nenue@0
|
275 frame.alignedJoint:ClearAllPoints()
|
Nenue@0
|
276 frame.poppingJointX:ClearAllPoints()
|
Nenue@0
|
277 frame.poppingJointY:ClearAllPoints()
|
Nenue@0
|
278 frame.cuttingJointX:ClearAllPoints()
|
Nenue@0
|
279 frame.cuttingJointY:ClearAllPoints()
|
Nenue@0
|
280 frame.childSpace:ClearAllPoints()
|
Nenue@0
|
281
|
Nenue@0
|
282 frame.alignedJoint:SetPoint(childAnchor, frame, childPoint, pX, pY)
|
Nenue@0
|
283 frame.poppingJointY:SetPoint(childAnchor, frame, childPoint, lX, lY) -- should really only differ when rows exceed 1
|
Nenue@0
|
284 frame.poppingJointX:SetPoint(childAnchor, frame, childPoint, lX, lY)
|
Nenue@0
|
285 frame.cuttingJointY:SetPoint(childAnchor, frame, childPoint, cX, cY) -- should really only differ when rows exceed 1
|
Nenue@0
|
286 frame.cuttingJointX:SetPoint(childAnchor, frame, childPoint, cX, cY)
|
Nenue@0
|
287 frame.childSpace:SetAllPoints(child)
|
Nenue@0
|
288
|
Nenue@0
|
289 frame.alignedJoint:Show()
|
Nenue@0
|
290 frame.poppingJointX:Show()
|
Nenue@0
|
291 frame.poppingJointY:Show()
|
Nenue@0
|
292 frame.cuttingJointX:Show()
|
Nenue@0
|
293 frame.cuttingJointY:Show()
|
Nenue@0
|
294 frame.childSpace:Show()
|
Nenue@0
|
295
|
Nenue@0
|
296 print('|cFFFF0000MIN |r', childAnchor, childPoint, pX, pY)
|
Nenue@0
|
297 print('|cFF00FFFFFAR |r', childAnchor, childPoint, cX, cY)
|
Nenue@0
|
298 print('|cFFFFFF00CLOSE|r', childAnchor, childPoint, lX, lY)
|
Nenue@0
|
299
|
Nenue@0
|
300 end
|
Nenue@0
|
301 end
|
Nenue@0
|
302
|
Nenue@0
|
303 B.SetAnchorChild = function(frame, child, c)
|
Nenue@0
|
304 print('linking', child)
|
Nenue@0
|
305 frame.attached = child
|
Nenue@0
|
306 frame.attachmentConf = c
|
Nenue@0
|
307 end |