vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 FlyPaper
3 Functionality for sticking one frome to another frame
4  
5 Methods:
6 FlyPaper.Stick(frame, otherFrame, tolerance, xOff, yOff) - Attempts to attach <frame> to <otherFrame>
7 tolerance - how close the frames need to be to attach
8 xOff - how close, horizontally, the frames should be attached
9 yOff - how close, vertically, the frames should be attached
10  
11 FlyPaper.StickToPoint(frame, otherFrame, point, xOff, yOff) - attempts to anchor <frame> to a specific point on <otherFrame>
12 point - any non nil return value of FlyPaper.Stick;
13  
14 Version History:
15 6.7.19:
16 Fixed a bug causing a frame to think it was still stuck to another frame when it really wasn't
17 Added FlyPaper.StickToPoint for reloading settings
18 --]]
19  
20 local VERSION = "6.7.19";
21  
22 if(FlyPaper and FlyPaper.version >= VERSION) then return; end
23  
24 --returns true if <frame>, or one of the frames that <frame> is dependent on, is anchored to <otherFrame>. Returns false otherwise.
25 local function FrameIsDependentOnFrame(frame, otherFrame)
26 if(not (otherFrame and frame) ) then
27 return false;
28 end
29 if(frame == otherFrame) then
30 return true;
31 end
32  
33 local parent = frame.stuckTo;
34 while parent do
35 if(parent == otherFrame) then
36 return true;
37 end
38 parent = parent.stuckTo;
39 end
40 return false
41 end
42  
43 --returns true if its actually possible to attach the two frames without error
44 local function CanAttach(frame, otherFrame)
45 if( not (frame and otherFrame) ) then
46 return false;
47 elseif(frame:GetNumPoints() == 0 or otherFrame:GetNumPoints() == 0 ) then
48 return false;
49 elseif(frame:GetWidth() == 0 or frame:GetHeight() == 0 or otherFrame:GetWidth() == 0 or otherFrame:GetHeight() == 0) then
50 return false;
51 elseif( FrameIsDependentOnFrame(otherFrame, frame) ) then
52 return false;
53 end
54 return true;
55 end
56  
57 --[[ Attachment Functions ]]--
58 local function AttachToTop(frame, otherFrame, distLeft, distRight, distCenter, offset)
59 frame:ClearAllPoints();
60 --closest to the left
61 if(distLeft < distCenter and distLeft < distRight) then
62 frame:SetPoint("BOTTOMLEFT", otherFrame, "TOPLEFT", 0, offset);
63 return "TL";
64 --closest to the right
65 elseif(distRight < distCenter and distRight < distLeft ) then
66 frame:SetPoint("BOTTOMRIGHT", otherFrame, "TOPRIGHT", 0, offset);
67 return "TR";
68 --closest to the center
69 else
70 frame:SetPoint("BOTTOM", otherFrame, "TOP", 0, offset);
71 return "TC";
72 end
73 end
74  
75 local function AttachToBottom(frame, otherFrame, distLeft, distRight, distCenter, offset)
76 frame:ClearAllPoints();
77 --bottomleft
78 if(distLeft < distCenter and distLeft < distRight) then
79 frame:SetPoint("TOPLEFT", otherFrame, "BOTTOMLEFT", 0, -offset);
80 return "BL";
81 --bottomright
82 elseif(distRight < distCenter and distRight < distLeft) then
83 frame:SetPoint("TOPRIGHT", otherFrame, "BOTTOMRIGHT", 0, -offset);
84 return "BR";
85 --bottom
86 else
87 frame:SetPoint("TOP", otherFrame, "BOTTOM", 0, -offset);
88 return "BC";
89 end
90 end
91  
92 local function AttachToLeft(frame, otherFrame, distTop, distBottom, distCenter, offset)
93 frame:ClearAllPoints();
94 --bottomleft
95 if(distBottom < distTop and distBottom < distCenter) then
96 frame:SetPoint("BOTTOMRIGHT", otherFrame, "BOTTOMLEFT", -offset, 0);
97 return "LB";
98 --topleft
99 elseif(distTop < distBottom and distTop < distCenter) then
100 frame:SetPoint("TOPRIGHT", otherFrame, "TOPLEFT", -offset, 0);
101 return "LT";
102 --left
103 else
104 frame:SetPoint("RIGHT", otherFrame, "LEFT", -offset, 0);
105 return "LC";
106 end
107 end
108  
109 local function AttachToRight(frame, otherFrame, distTop, distBottom, distCenter, offset)
110 frame:ClearAllPoints();
111 --bottomright
112 if(distBottom < distTop and distBottom < distCenter) then
113 frame:SetPoint("BOTTOMLEFT", otherFrame, "BOTTOMRIGHT", offset, 0);
114 return "RB";
115 --topright
116 elseif(distTop < distBottom and distTop < distCenter) then
117 frame:SetPoint("TOPLEFT", otherFrame, "TOPRIGHT", offset, 0);
118 return "RT";
119 --right
120 else
121 frame:SetPoint("LEFT", otherFrame, "RIGHT", offset, 0);
122 return "RC";
123 end
124 end
125  
126 --[[ Usable Functions ]]--
127  
128 FlyPaper = {
129 version = VERSION,
130  
131 Stick = function(frame, otherFrame, tolerance, xOff, yOff)
132 if(not xOff) then
133 xOff = 0;
134 end
135 if(not yOff) then
136 yOff = 0;
137 end
138  
139 if(not CanAttach(frame, otherFrame) ) then
140 if(frame) then
141 frame.stuckTo = nil;
142 end
143 return false;
144 end
145  
146 --get anchoring points
147 local left = frame:GetLeft();
148 local right = frame:GetRight();
149 local top = frame:GetTop();
150 local bottom = frame:GetBottom();
151 local centerX, centerY = frame:GetCenter();
152  
153 if(left and right and top and bottom and centerX) then
154 local oScale = otherFrame:GetScale();
155 left = left / oScale;
156 right = right / oScale;
157 top = top / oScale;
158 bottom = bottom /oScale;
159 centerX = centerX / oScale;
160 centerY = centerY / oScale;
161 else
162 frame.stuckTo = nil;
163 return false;
164 end
165  
166 local oLeft = otherFrame:GetLeft();
167 local oRight = otherFrame:GetRight();
168 local oTop = otherFrame:GetTop();
169 local oBottom = otherFrame:GetBottom();
170 local oCenterX, oCenterY = otherFrame:GetCenter();
171  
172 if(oLeft and oRight and oTop and oBottom and oCenterX) then
173 local scale = frame:GetScale();
174 oCenterX = oCenterX / scale;
175 oCenterY = oCenterY / scale;
176 oLeft = oLeft / scale;
177 oRight = oRight / scale;
178 oTop = oTop / scale;
179 oBottom = oBottom / scale;
180 else
181 frame.stuckTo = nil;
182 return false;
183 end
184  
185 --[[ Start Attempting to Anchor <frame> to <otherFrame> ]]--
186  
187 if( (oLeft - tolerance <= left and oRight + tolerance >= right) or
188 (left - tolerance <= oLeft and right + tolerance >= oRight) ) then
189  
190 local distCenter = math.abs(oCenterX - centerX);
191 local distLeft = math.abs(oLeft - left);
192 local distRight = math.abs(right - oRight);
193  
194 --try to stick to the top if the distance is under the threshold distance to stick frames to each other (tolerance)
195 if( math.abs(oTop - bottom) <= tolerance ) then
196 local point = AttachToTop(frame, otherFrame, distLeft, distRight, distCenter, yOff);
197 frame.stuckTo = otherFrame;
198 return point;
199 --to the bottom
200 elseif( math.abs(oBottom - top) <= tolerance ) then
201 local point = AttachToBottom(frame, otherFrame, distLeft, distRight, distCenter, yOff);
202 frame.stuckTo = otherFrame;
203 return point;
204 end
205 end
206  
207  
208 if ( (oTop + tolerance >= top and oBottom - tolerance <= bottom) or
209 (top + tolerance >= oTop and bottom - tolerance <= oBottom) ) then
210  
211 local distCenter = math.abs(oCenterY - centerY);
212 local distTop = math.abs(oTop - top);
213 local distBottom = math.abs(oBottom - bottom);
214  
215 --to the left
216 if(math.abs(oLeft - right) <= tolerance ) then
217 local point = AttachToLeft(frame, otherFrame, distTop, distBottom, distCenter, xOff);
218 frame.stuckTo = otherFrame;
219 return point;
220 end
221  
222 --to the right
223 if(math.abs(oRight - left) <= tolerance ) then
224 local point = AttachToRight(frame, otherFrame, distTop, distBottom, distCenter, xOff);
225 frame.stuckTo = otherFrame;
226 return point;
227 end
228 end
229  
230 frame.stuckTo = nil;
231 return false;
232 end,
233  
234 StickToPoint = function(frame, otherFrame, point, xOff, yOff)
235 if(not xOff) then
236 xOff = 0;
237 end
238 if(not yOff) then
239 yOff = 0;
240 end
241  
242 --[[ Check to make sure we can anchor ]]--
243  
244 --check to make sure its actually possible to attach the frames
245 if(not (point and CanAttach(frame, otherFrame)) ) then
246 if(frame) then
247 frame.stuckTo = nil;
248 end
249 return nil;
250 end
251  
252 --check to make sure all anchoring points are valid
253 local left = frame:GetLeft();
254 local right = frame:GetRight();
255 local top = frame:GetTop();
256 local bottom = frame:GetBottom();
257 local centerX = frame:GetCenter();
258  
259 if( not (left and right and top and bottom and centerX) ) then
260 frame.stuckTo = nil;
261 return nil;
262 end
263  
264 local oLeft = otherFrame:GetLeft();
265 local oRight = otherFrame:GetRight();
266 local oTop = otherFrame:GetTop();
267 local oBottom = otherFrame:GetBottom();
268 local oCenterX = otherFrame:GetCenter();
269  
270 if(not (oLeft and oRight and oTop and oBottom and oCenterX) ) then
271 frame.stuckTo = nil;
272 return nil;
273 end
274  
275 --[[ Start Attempting to Anchor <frame> to <otherFrame> ]]--
276  
277 frame:ClearAllPoints();
278  
279 if( point == "TL" ) then
280 frame:SetPoint("BOTTOMLEFT", otherFrame, "TOPLEFT", 0, yOff);
281 frame.stuckTo = otherFrame;
282 return point;
283 elseif(point == "TC") then
284 frame:SetPoint("BOTTOM", otherFrame, "TOP", 0, yOff);
285 frame.stuckTo = otherFrame;
286 return point;
287 elseif(point == "TR") then
288 frame:SetPoint("BOTTOMRIGHT", otherFrame, "TOPRIGHT", 0, yOff);
289 frame.stuckTo = otherFrame;
290 return point;
291 end
292  
293 if( point == "BL" ) then
294 frame:SetPoint("TOPLEFT", otherFrame, "BOTTOMLEFT", 0, -yOff);
295 frame.stuckTo = otherFrame;
296 return point;
297 elseif(point == "BC") then
298 frame:SetPoint("TOP", otherFrame, "BOTTOM", 0, -yOff);
299 frame.stuckTo = otherFrame;
300 return point;
301 elseif(point == "BR") then
302 frame:SetPoint("TOPRIGHT", otherFrame, "BOTTOMRIGHT", 0, -yOff);
303 frame.stuckTo = otherFrame;
304 return point;
305 end
306  
307 --to the left
308 if( point == "LB" ) then
309 frame:SetPoint("BOTTOMRIGHT", otherFrame, "BOTTOMLEFT", -xOff, 0);
310 frame.stuckTo = otherFrame;
311 return point;
312 elseif(point == "LC") then
313 frame:SetPoint("RIGHT", otherFrame, "LEFT", -xOff, 0);
314 frame.stuckTo = otherFrame;
315 return point;
316 elseif(point == "LT") then
317 frame:SetPoint("TOPRIGHT", otherFrame, "TOPLEFT", -xOff, 0);
318 frame.stuckTo = otherFrame;
319 return point;
320 end
321  
322 --to the right
323 if( point == "RB" ) then
324 frame:SetPoint("BOTTOMLEFT", otherFrame, "BOTTOMRIGHT", xOff, 0);
325 frame.stuckTo = otherFrame;
326 return point;
327 elseif(point == "RC") then
328 frame:SetPoint("LEFT", otherFrame, "RIGHT", xOff, 0);
329 frame.stuckTo = otherFrame;
330 return point;
331 elseif(point == "RT") then
332 frame:SetPoint("TOPLEFT", otherFrame, "TOPRIGHT", xOff, 0);
333 frame.stuckTo = otherFrame;
334 return point;
335 end
336  
337 frame.stuckTo = nil;
338 return nil;
339 end,
340 }