comparison Overlay.lua @ 257:920d17851a93 stable

Merge 1.1 beta 4 to stable
author Flick
date Tue, 12 Apr 2011 16:06:31 -0700
parents 65f2805957a0
children 2897480842dd
comparison
equal deleted inserted replaced
210:b2b105747466 257:920d17851a93
1 local addonName, addonTable = ...
2 local ReAction = addonTable.ReAction
3 local L = ReAction.L
4 local LKB = ReAction.LKB
5 local CreateFrame = CreateFrame
6 local InCombatLockdown = InCombatLockdown
7 local floor = math.floor
8 local min = math.min
9 local format = string.format
10 local GameTooltip = GameTooltip
11 local Bar = ReAction.Bar
12 local GetSize = Bar.GetSize
13 local SetSize = Bar.SetSize
14 local GetButtonSize = Bar.GetButtonSize
15 local GetButtonGrid = Bar.GetButtonGrid
16 local SetButtonSize = Bar.SetButtonSize
17 local SetButtonGrid = Bar.SetButtonGrid
18 local ApplyAnchor = Bar.ApplyAnchor
19 local GameTooltipTextRight1 = GameTooltipTextRight1
20 local GameTooltipTextRight2 = GameTooltipTextRight2
21 local GameTooltipTextRight3 = GameTooltipTextRight3
22
23 --
24 -- Wrap some of the bar manipulators to make them state-aware
25 --
26 local function SetAnchor( bar, point, frame, relPoint, x, y )
27 local state = bar:GetSecureState()
28 if state then
29 local anchorstate = bar:GetStateProperty(state, "anchorEnable")
30 if anchorstate then
31 bar:SetStateProperty(state, "anchorFrame", frame)
32 bar:SetStateProperty(state, "anchorPoint", point)
33 bar:SetStateProperty(state, "anchorRelPoint", relPoint)
34 bar:SetStateProperty(state, "anchorX", x or 0)
35 bar:SetStateProperty(state, "anchorY", y or 0)
36 bar:SetAnchor(bar:GetAnchor())
37 return
38 end
39 end
40 bar:SetAnchor(point, frame, relPoint, x, y)
41 end
42
43 local function GetStateScale( bar )
44 local state = bar:GetSecureState()
45 if state and bar:GetStateProperty(state, "enableScale") then
46 return bar:GetStateProperty(state, "scale")
47 end
48 end
49
50 local function SetStateScale( bar, scale )
51 local state = bar:GetSecureState()
52 if state and bar:GetStateProperty(state, "enableScale") then
53 bar:SetStateProperty(state, "scale", scale)
54 end
55 end
56
57
58 --
59 -- Bar config overlay
60 --
61
62 local function GetNormalTextColor()
63 return 1.0, 1.0, 1.0, 1.0
64 end
65
66 local function GetAnchoredTextColor()
67 return 1.0, 1.0, 1.0, 1.0
68 end
69
70 local function GetNormalBgColor()
71 return 0.7, 0.7, 1.0, 0.3
72 end
73
74 local function GetAnchoredBgColor()
75 return 0.9, 0.2, 0.7, 0.3
76 end
77
78 local function StoreSize(bar)
79 local f = bar:GetFrame()
80 SetSize( bar, f:GetWidth(), f:GetHeight() )
81 end
82
83 local function StoreExtents(bar)
84 local f = bar:GetFrame()
85 local p, fr, rp, x, y = f:GetPoint(1)
86 fr = fr and fr:GetName() or "UIParent"
87 SetAnchor( bar, p, fr, rp, x, y )
88 SetSize( bar, f:GetWidth(), f:GetHeight() )
89 end
90
91 local function RecomputeButtonSize(bar)
92 local w, h = GetSize(bar)
93 local bw, bh = GetButtonSize(bar)
94 local r, c, s = GetButtonGrid(bar)
95
96 local scaleW = (floor(w/c) - s) / bw
97 local scaleH = (floor(h/r) - s) / bh
98 local scale = min(scaleW, scaleH)
99
100 SetButtonSize(bar, scale * bw, scale * bh, s)
101 end
102
103 local function ComputeBarScale(bar, overlay)
104 local w, h = overlay:GetWidth() - 8, overlay:GetHeight() - 8
105 local bw, bh = GetButtonSize(bar)
106 local r, c, s = GetButtonGrid(bar)
107
108 local scaleW = w / (c*(bw+s))
109 local scaleH = h / (r*(bh+s))
110 local scale = min(scaleW, scaleH)
111
112 if scale > 2.5 then
113 scale = 2.5
114 elseif scale < 0.25 then
115 scale = 0.25
116 end
117
118 return scale
119 end
120
121 local function RecomputeButtonSpacing(bar)
122 local w, h = GetSize(bar)
123 local bw, bh = GetButtonSize(bar)
124 local r, c, s = GetButtonGrid(bar)
125
126 SetButtonGrid(bar,r,c,min(floor(w/c) - bw, floor(h/r) - bh))
127 end
128
129 local function RecomputeGrid(bar)
130 local w, h = GetSize(bar)
131 local bw, bh = GetButtonSize(bar)
132 local r, c, s = GetButtonGrid(bar)
133
134 SetButtonGrid(bar, floor(h/(bh+s)), floor(w/(bw+s)), s)
135 end
136
137 local function ClampToButtons(bar)
138 local bw, bh = GetButtonSize(bar)
139 local r, c, s = GetButtonGrid(bar)
140 SetSize(bar, (bw+s)*c + 1, (bh+s)*r + 1)
141 end
142
143 local function HideGameTooltip()
144 GameTooltip:Hide()
145 end
146
147 local anchorInside = { inside = true }
148 local anchorOutside = { outside = true }
149 local edges = { "BOTTOM", "TOP", "LEFT", "RIGHT" }
150 local oppositeEdges = {
151 TOP = "BOTTOM",
152 BOTTOM = "TOP",
153 LEFT = "RIGHT",
154 RIGHT = "LEFT"
155 }
156 local pointsOnEdge = {
157 BOTTOM = { "BOTTOM", "BOTTOMLEFT", "BOTTOMRIGHT", },
158 TOP = { "TOP", "TOPLEFT", "TOPRIGHT", },
159 RIGHT = { "RIGHT", "BOTTOMRIGHT", "TOPRIGHT", },
160 LEFT = { "LEFT", "BOTTOMLEFT", "TOPLEFT", },
161 }
162 local edgeSelector = {
163 BOTTOM = 1, -- select x of x,y
164 TOP = 1, -- select x of x,y
165 LEFT = 2, -- select y of x,y
166 RIGHT = 2, -- select y of x,y
167 }
168 local snapPoints = {
169 [anchorOutside] = {
170 BOTTOMLEFT = {"BOTTOMRIGHT","TOPLEFT","TOPRIGHT"},
171 BOTTOM = {"TOP"},
172 BOTTOMRIGHT = {"BOTTOMLEFT","TOPRIGHT","TOPLEFT"},
173 RIGHT = {"LEFT"},
174 TOPRIGHT = {"TOPLEFT","BOTTOMRIGHT","BOTTOMLEFT"},
175 TOP = {"BOTTOM"},
176 TOPLEFT = {"TOPRIGHT","BOTTOMLEFT","BOTTOMRIGHT"},
177 LEFT = {"RIGHT"},
178 CENTER = {"CENTER"}
179 },
180 [anchorInside] = {
181 BOTTOMLEFT = {"BOTTOMLEFT"},
182 BOTTOM = {"BOTTOM"},
183 BOTTOMRIGHT = {"BOTTOMRIGHT"},
184 RIGHT = {"RIGHT"},
185 TOPRIGHT = {"TOPRIGHT"},
186 TOP = {"TOP"},
187 TOPLEFT = {"TOPLEFT"},
188 LEFT = {"LEFT"},
189 CENTER = {"CENTER"}
190 }
191 }
192 local insidePointOffsetFuncs = {
193 BOTTOMLEFT = function(x, y) return x, y end,
194 BOTTOM = function(x, y) return 0, y end,
195 BOTTOMRIGHT = function(x, y) return -x, y end,
196 RIGHT = function(x, y) return -x, 0 end,
197 TOPRIGHT = function(x, y) return -x, -y end,
198 TOP = function(x, y) return 0, -y end,
199 TOPLEFT = function(x, y) return x, -y end,
200 LEFT = function(x, y) return x, 0 end,
201 CENTER = function(x, y) return x, y end,
202 }
203 local pointCoordFuncs = {
204 BOTTOMLEFT = function(f) return f:GetLeft(), f:GetBottom() end,
205 BOTTOM = function(f) return nil, f:GetBottom() end,
206 BOTTOMRIGHT = function(f) return f:GetRight(), f:GetBottom() end,
207 RIGHT = function(f) return f:GetRight(), nil end,
208 TOPRIGHT = function(f) return f:GetRight(), f:GetTop() end,
209 TOP = function(f) return nil, f:GetTop() end,
210 TOPLEFT = function(f) return f:GetLeft(), f:GetTop() end,
211 LEFT = function(f) return f:GetLeft(), nil end,
212 CENTER = function(f) return f:GetCenter() end,
213 }
214 local edgeBoundsFuncs = {
215 BOTTOM = function(f) return f:GetLeft(), f:GetRight() end,
216 LEFT = function(f) return f:GetBottom(), f:GetTop() end
217 }
218 edgeBoundsFuncs.TOP = edgeBoundsFuncs.BOTTOM
219 edgeBoundsFuncs.RIGHT = edgeBoundsFuncs.LEFT
220 local cornerTexCoords = {
221 -- ULx, ULy, LLx, LLy, URx, URy, LRx, LRy
222 TOPLEFT = { 1, 1, 1, 0, 0, 1, 0, 0 },
223 TOPRIGHT = { 1, 0, 0, 0, 1, 1, 0, 1 },
224 BOTTOMLEFT = { 0, 1, 1, 1, 0, 0, 1, 0 },
225 BOTTOMRIGHT = { 0, 0, 0, 1, 1, 0, 1, 1 },
226 }
227
228 -- Returns absolute coordinates x,y of the named point 'p' of frame 'f'
229 local function GetPointCoords( f, p )
230 local x, y = pointCoordFuncs[p](f)
231 if not(x and y) then
232 local cx, cy = f:GetCenter()
233 x = x or cx
234 y = y or cy
235 end
236 return x, y
237 end
238
239
240 -- Returns true if frame 'f1' can be anchored to frame 'f2'
241 local function CheckAnchorable( f1, f2 )
242 -- can't anchor a frame to itself or to nil
243 if f1 == f2 or f2 == nil then
244 return false
245 end
246
247 -- can always anchor to UIParent
248 if f2 == UIParent then
249 return true
250 end
251
252 -- also can't do circular anchoring of frames
253 -- walk the anchor chain, which generally shouldn't be that expensive
254 -- (who nests draggables that deep anyway?)
255 for i = 1, f2:GetNumPoints() do
256 local _, f = f2:GetPoint(i)
257 if not f then f = f2:GetParent() end
258 return CheckAnchorable(f1,f)
259 end
260
261 return true
262 end
263
264 -- Returns true if frames f1 and f2 specified edges overlap
265 local function CheckEdgeOverlap( f1, f2, e )
266 local l1, u1 = edgeBoundsFuncs[e](f1)
267 local l2, u2 = edgeBoundsFuncs[e](f2)
268 return l1 <= l2 and l2 <= u1 or l2 <= l1 and l1 <= u2
269 end
270
271 -- Returns true if point p1 on frame f1 overlaps edge e2 on frame f2
272 local function CheckPointEdgeOverlap( f1, p1, f2, e2 )
273 local l, u = edgeBoundsFuncs[e2](f2)
274 local x, y = GetPointCoords(f1,p1)
275 x = select(edgeSelector[e2], x, y)
276 return l <= x and x <= u
277 end
278
279 -- Returns the distance between corresponding edges. It is
280 -- assumed that the passed in edges e1 and e2 are the same or opposites
281 local function GetEdgeDistance( f1, f2, e1, e2 )
282 local x1, y1 = pointCoordFuncs[e1](f1)
283 local x2, y2 = pointCoordFuncs[e2](f2)
284 return math.abs((x1 or y1) - (x2 or y2))
285 end
286
287 local globalSnapTargets = { [UIParent] = anchorInside }
288
289 local function GetClosestFrameEdge(f1,f2,a)
290 local dist, edge, opp
291 if f2:IsVisible() and CheckAnchorable(f1,f2) then
292 for _, e in pairs(edges) do
293 local o = a.inside and e or oppositeEdges[e]
294 if CheckEdgeOverlap(f1,f2,e) then
295 local d = GetEdgeDistance(f1, f2, e, o)
296 if not dist or (d < dist) then
297 dist, edge, opp = d, e, o
298 end
299 end
300 end
301 end
302 return dist, edge, opp
303 end
304
305 local function GetClosestVisibleEdge( f )
306 local r, o, e1, e2
307 local a = anchorOutside
308 for _, b in ReAction:IterateBars() do
309 local d, e, opp = GetClosestFrameEdge(f,b:GetFrame(),a)
310 if d and (not r or d < r) then
311 r, o, e1, e2 = d, b:GetFrame(), e, opp
312 end
313 end
314 for f2, a2 in pairs(globalSnapTargets) do
315 local d, e, opp = GetClosestFrameEdge(f,f2,a2)
316 if d and (not r or d < r) then
317 r, o, e1, e2, a = d, f2, e, opp, a2
318 end
319 end
320 return o, e1, e2, a
321 end
322
323 local function GetClosestVisiblePoint(f1)
324 local f2, e1, e2, a = GetClosestVisibleEdge(f1)
325 if f2 then
326 local rsq, p, rp, x, y
327 -- iterate pointsOnEdge in order and use < to prefer edge centers to corners
328 for _, p1 in ipairs(pointsOnEdge[e1]) do
329 if CheckPointEdgeOverlap(f1,p1,f2,e2) then
330 for _, p2 in pairs(snapPoints[a][p1]) do
331 local x1, y1 = GetPointCoords(f1,p1)
332 local x2, y2 = GetPointCoords(f2,p2)
333 local dx = x1 - x2
334 local dy = y1 - y2
335 local rsq2 = dx*dx + dy*dy
336 if not rsq or rsq2 < rsq then
337 rsq, p, rp, x, y = rsq2, p1, p2, dx, dy
338 end
339 end
340 end
341 end
342 return f2, p, rp, x, y
343 end
344 end
345
346 local function GetClosestPointSnapped(f1, rx, ry, xOff, yOff)
347 local o, p, rp, x, y = GetClosestVisiblePoint(f1)
348 local s = false
349
350 local insideOffsetFunc = p and insidePointOffsetFuncs[p]
351 local coordFunc = p and pointCoordFuncs[p]
352 if not insideOffsetFunc or not coordFunc then
353 return
354 end
355
356 local sx, sy = insideOffsetFunc(xOff or 0, yOff or 0)
357 local xx, yy = coordFunc(f1)
358 if xx and yy then
359 if math.abs(x) <= rx then
360 if math.abs(y) <= ry then
361 x = sx
362 y = sy
363 s = true
364 elseif CheckEdgeOverlap(f1,o,"LEFT") then
365 x = sx
366 s = true
367 end
368 elseif math.abs(y) <= ry and CheckEdgeOverlap(f1,o,"TOP") then
369 y = sy
370 s = true
371 end
372 elseif xx then
373 if math.abs(x) <= rx then
374 x = sx
375 s = true
376 if math.abs(y) <= ry then
377 y = sy
378 end
379 end
380 elseif yy then
381 if math.abs(y) <= ry then
382 y = sy
383 s = true
384 if math.abs(x) <= rx then
385 x = sx
386 end
387 end
388 end
389
390 -- correct for some Lua oddities with doubles
391 if x == -0 then x = 0 end
392 if y == -0 then y = 0 end
393
394 if s then
395 return o, p, rp, math.floor(x), math.floor(y)
396 end
397 end
398
399 local function CreateSnapIndicator()
400 local si = CreateFrame("Frame",nil,UIParent)
401 si:SetFrameStrata("HIGH")
402 si:SetHeight(16)
403 si:SetWidth(16)
404 local tex = si:CreateTexture()
405 tex:SetAllPoints()
406 tex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock")
407 tex:SetBlendMode("ADD")
408 tex:SetDrawLayer("OVERLAY")
409 return si
410 end
411
412 local si1 = CreateSnapIndicator()
413 local si2 = CreateSnapIndicator()
414
415 local function DisplaySnapIndicator( f, rx, ry, xOff, yOff )
416 local o, p, rp, x, y, snap = GetClosestPointSnapped(f, rx, ry, xOff, yOff)
417 if o then
418 si1:ClearAllPoints()
419 si2:ClearAllPoints()
420 si1:SetPoint("CENTER", f, p, 0, 0)
421 local xx, yy = pointCoordFuncs[rp](o)
422 x = math.abs(x) <=rx and xx and 0 or x
423 y = math.abs(y) <=ry and yy and 0 or y
424 si2:SetPoint("CENTER", o, rp, x, y)
425 si1:Show()
426 si2:Show()
427 else
428 if si1:IsVisible() then
429 si1:Hide()
430 si2:Hide()
431 end
432 end
433 return o, p
434 end
435
436 local function HideSnapIndicator()
437 if si1:IsVisible() then
438 si1:Hide()
439 si2:Hide()
440 end
441 end
442
443 local function UpdateLabelString(overlay)
444 local label = overlay.labelString
445 if label then
446 local name = overlay.labelName
447 if name and overlay.labelSubtext then
448 name = format("%s (%s)", name, overlay.labelSubtext)
449 end
450 label:SetText(name or "")
451 end
452 end
453
454 local function CreateControls(bar)
455 local f = bar:GetFrame()
456
457 f:SetMovable(true)
458 f:SetResizable(true)
459
460 -- child of UIParent so that alpha and scale doesn't propagate to it
461 local overlay = CreateFrame("Button", nil, UIParent)
462 overlay:EnableMouse(true)
463 overlay:SetFrameLevel(10) -- set it above the buttons
464 overlay:SetPoint("TOPLEFT", f, "TOPLEFT", -4, 4)
465 overlay:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 4, -4)
466 overlay:SetBackdrop({
467 edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
468 tile = true,
469 tileSize = 16,
470 edgeSize = 16,
471 insets = { left = 0, right = 0, top = 0, bottom = 0 },
472 })
473
474 -- textures
475 local bgTex = overlay:CreateTexture(nil,"BACKGROUND")
476 bgTex:SetTexture(0.7,0.7,1.0,0.2)
477 bgTex:SetPoint("TOPLEFT",4,-4)
478 bgTex:SetPoint("BOTTOMRIGHT",-4,4)
479 local hTex = overlay:CreateTexture(nil,"HIGHLIGHT")
480 hTex:SetTexture(0.7,0.7,1.0,0.2)
481 hTex:SetPoint("TOPLEFT",4,-4)
482 hTex:SetPoint("BOTTOMRIGHT",-4,4)
483 hTex:SetBlendMode("ADD")
484 local aTex = overlay:CreateTexture(nil,"ARTWORK")
485 aTex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock")
486 aTex:SetWidth(16)
487 aTex:SetHeight(16)
488 aTex:Hide()
489
490 -- label
491 local label = overlay:CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
492 label:SetAllPoints()
493 label:SetJustifyH("CENTER")
494 label:SetShadowColor(0,0,0,1)
495 label:SetShadowOffset(3,-3)
496 label:SetTextColor(GetNormalTextColor())
497 label:SetText(bar:GetName())
498 label:Show()
499 overlay.labelString = label
500 overlay.labelName = bar:GetName()
501
502 local function UpdateAnchorDecoration()
503 local point, anchor, relPoint, x, y = f:GetPoint(1)
504 if point then
505 local ofsx, ofsy = insidePointOffsetFuncs[point](x,y)
506 if (anchor and anchor ~= UIParent) or (ofsx == 0 and ofsy == 0) then
507 bgTex:SetTexture( GetAnchoredBgColor() )
508 hTex:SetTexture( GetAnchoredBgColor() )
509 label:SetTextColor( GetAnchoredTextColor() )
510 aTex:ClearAllPoints()
511 aTex:SetPoint(point)
512 aTex:Show()
513 return
514 end
515 end
516 bgTex:SetTexture( GetNormalBgColor() )
517 hTex:SetTexture( GetNormalBgColor() )
518 label:SetTextColor( GetNormalTextColor() )
519 aTex:Hide()
520 end
521
522 local function StopResize()
523 f:StopMovingOrSizing()
524 f.isMoving = false
525 f:SetScript("OnUpdate",nil)
526 StoreSize(bar)
527 ClampToButtons(bar)
528 ReAction:RefreshEditor()
529 end
530
531 local function CornerUpdate()
532 local bw, bh = GetButtonSize(bar)
533 local r, c, s = GetButtonGrid(bar)
534 local ss = GetStateScale(bar)
535 if IsShiftKeyDown() then
536 if ss then
537 f:SetMinResize( ((s+bw)*c*0.25)/ss, ((s+bh)*r*0.25)/ss )
538 f:SetMaxResize( ((s+bw)*c*2.5 + 1)/ss, ((s+bh)*r*2.5 + 1)/ss )
539 scale = ComputeBarScale(bar, overlay)
540 else
541 f:SetMinResize( (s+12)*c+1, (s+12)*r+1 )
542 f:SetMaxResize( (s+128)*c+1, (s+128)*r+1 )
543 RecomputeButtonSize(bar)
544 end
545 elseif not ss and IsAltKeyDown() then
546 f:SetMinResize( bw*c, bh*r )
547 f:SetMaxResize( 2*bw*c, 2*bh*r )
548 RecomputeButtonSpacing(bar)
549 else
550 f:SetMinResize( bw+s+1, bh+s+1 )
551 f:SetMaxResize( 50*(bw+s)+1, 50*(bh+s)+1 )
552 RecomputeGrid(bar)
553 end
554 GameTooltipTextRight2:SetText(format("%d x %d",r,c))
555
556 local ss = GetStateScale(bar)
557 if ss then
558 GameTooltipTextRight4:SetText(format("%d%%", scale*100))
559 else
560 local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh)
561 GameTooltipTextRight3:SetText(size)
562 GameTooltipTextRight4:SetText(tostring(s))
563 end
564 end
565
566 -- corner drag handles
567 for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do
568 local corner = CreateFrame("Frame",nil,overlay)
569 corner:EnableMouse(true)
570 corner:SetWidth(16)
571 corner:SetHeight(16)
572 corner:SetPoint(point)
573
574 local tex = corner:CreateTexture(nil,"HIGHLIGHT")
575 tex:SetTexture("Interface\\AddOns\\ReAction\\img\\corner")
576 tex:SetTexCoord(unpack(cornerTexCoords[point]))
577 tex:SetBlendMode("ADD")
578 tex:SetAlpha(0.6)
579 tex:SetAllPoints()
580
581 corner:SetScript("OnMouseDown",
582 function(_,btn)
583 f:SetScript("OnUpdate", CornerUpdate)
584 f:StartSizing(point)
585 end
586 )
587 corner:SetScript("OnMouseUp",
588 function()
589 local ss = GetStateScale(bar)
590 if ss then
591 SetStateScale(bar, ComputeBarScale(bar, overlay))
592 end
593 StopResize()
594 end)
595 corner:SetScript("OnEnter",
596 function()
597 local bw, bh = GetButtonSize(bar)
598 local r, c, s = bar:GetButtonGrid()
599 local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh)
600 local ss = GetStateScale(bar)
601 local state = bar:GetSecureState()
602 GameTooltip:SetOwner(f, "ANCHOR_"..point)
603 if ss then
604 GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state))
605 else
606 GameTooltip:AddLine(bar:GetName())
607 end
608 GameTooltip:AddDoubleLine(format("|cffcccccc%s|r %s",L["Drag"],L["to add/remove buttons:"]), format("%d x %d",r,c))
609 if ss then
610 GameTooltip:AddLine(L["State Scale Override"])
611 GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to change scale:"]), format("%d%%", bar:GetStateProperty(state,"scale")*100))
612 else
613 GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to resize buttons:"]), tostring(floor(size)))
614 GameTooltip:AddDoubleLine(format("|cff0033cc%s|r %s",L["Hold Alt"], L["to change spacing:"]), tostring(floor(s)))
615 end
616 GameTooltip:Show()
617 end
618 )
619 corner:SetScript("OnLeave",
620 function()
621 GameTooltip:Hide()
622 f:SetScript("OnUpdate",nil)
623 end
624 )
625 end
626
627 overlay:RegisterForDrag("LeftButton")
628 overlay:RegisterForClicks("RightButtonUp")
629
630 overlay:SetScript("OnDragStart",
631 function()
632 f:StartMoving()
633 f.isMoving = true
634 local w,h = bar:GetButtonSize()
635 f:ClearAllPoints()
636 UpdateAnchorDecoration()
637 f:SetScript("OnUpdate", function()
638 if IsShiftKeyDown() then
639 local f, p = DisplaySnapIndicator(f,w,h)
640 else
641 HideSnapIndicator()
642 end
643 end)
644 end
645 )
646
647 local function UpdateDragTooltip()
648 GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT")
649 local ss = GetStateScale(bar)
650 local state = bar:GetSecureState()
651 if ss then
652 GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state))
653 else
654 GameTooltip:AddLine(bar:GetName())
655 end
656 GameTooltip:AddLine(format("|cffcccccc%s|r %s",L["Drag"],L["to move"]))
657 GameTooltip:AddLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to anchor to nearby frames"]))
658 GameTooltip:AddLine(format("|cff00cccc%s|r %s",L["Right-click"],L["for options..."]))
659 local point, frame, relpoint, x, y = bar:GetFrame():GetPoint(1)
660 if point then
661 local ofsx, ofsy = insidePointOffsetFuncs[point](x,y)
662 if (frame and frame ~= UIParent) or (ofsx == 0 and ofsy == 0) then
663 frame = frame or UIParent
664 GameTooltip:AddLine(format("%s <%s>",L["Currently anchored to"],frame:GetName()))
665 end
666 end
667 GameTooltip:Show()
668 end
669
670 overlay:SetScript("OnDragStop",
671 function()
672 f:StopMovingOrSizing()
673 f.isMoving = false
674 f:SetScript("OnUpdate",nil)
675
676 if IsShiftKeyDown() then
677 local w, h = bar:GetButtonSize()
678 local a, p, rp, x, y = GetClosestPointSnapped(f,w,h)
679 if a then
680 f:ClearAllPoints()
681 f:SetPoint(p,a,rp,x,y)
682 end
683 HideSnapIndicator()
684 end
685
686 StoreExtents(bar)
687 ReAction:RefreshEditor()
688 UpdateDragTooltip()
689 UpdateAnchorDecoration()
690 end
691 )
692
693 overlay:SetScript("OnEnter",
694 function()
695 UpdateDragTooltip()
696 end
697 )
698
699 overlay:SetScript("OnLeave", HideGameTooltip)
700
701 overlay:SetScript("OnClick",
702 function()
703 ReAction:ShowEditor(bar)
704 end
705 )
706
707 function overlay:RefreshControls()
708 UpdateAnchorDecoration()
709 end
710
711 overlay:SetScript("OnShow", overlay.RefreshControls)
712
713 if ReAction:GetKeybindMode() then
714 overlay:SetFrameLevel(1)
715 end
716
717 UpdateLabelString(overlay)
718 UpdateAnchorDecoration()
719
720 return overlay
721 end
722
723
724 -- export methods to the Bar prototype
725 Bar.Overlay = { }
726 function Bar.Overlay:New( bar )
727 return setmetatable( {frame = CreateControls(bar)}, {__index=self} )
728 end
729
730 function Bar.Overlay:SetLabel(name)
731 self.frame.labelName = name
732 UpdateLabelString(self.frame)
733 end
734
735 function Bar.Overlay:SetLabelSubtext(text)
736 self.frame.labelSubtext = text
737 UpdateLabelString(self.frame)
738 end
739
740 function Bar.Overlay:Show()
741 self.frame:Show()
742 end
743
744 function Bar.Overlay:Hide()
745 self.frame:Hide()
746 end
747
748 function Bar.Overlay:IsShown()
749 return self.frame:IsShown()
750 end
751
752 function Bar.Overlay:RefreshControls()
753 self.frame:RefreshControls()
754 end