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