flickerstreak@1
|
1
|
flickerstreak@1
|
2 -- private constants
|
flickerstreak@1
|
3 local insideFrame = 1
|
flickerstreak@1
|
4 local outsideFrame = 2
|
flickerstreak@1
|
5 local _G = getfenv(0) -- global variable table
|
flickerstreak@1
|
6
|
flickerstreak@1
|
7 local pointFindTable = {
|
flickerstreak@1
|
8 BOTTOMLEFT = function(f) return f:GetLeft(), f:GetBottom() end,
|
flickerstreak@1
|
9 BOTTOM = function(f) return nil, f:GetBottom() end,
|
flickerstreak@1
|
10 BOTTOMRIGHT = function(f) return f:GetRight(), f:GetBottom() end,
|
flickerstreak@1
|
11 RIGHT = function(f) return f:GetRight(), nil end,
|
flickerstreak@1
|
12 TOPRIGHT = function(f) return f:GetRight(), f:GetTop() end,
|
flickerstreak@1
|
13 TOP = function(f) return nil, f:GetTop() end,
|
flickerstreak@1
|
14 TOPLEFT = function(f) return f:GetLeft(), f:GetTop() end,
|
flickerstreak@1
|
15 LEFT = function(f) return f:GetLeft(), nil end,
|
flickerstreak@1
|
16 }
|
flickerstreak@1
|
17
|
flickerstreak@1
|
18 local oppositePointTable = {
|
flickerstreak@1
|
19 BOTTOMLEFT = "TOPRIGHT",
|
flickerstreak@1
|
20 BOTTOM = "TOP",
|
flickerstreak@1
|
21 BOTTOMRIGHT = "TOPLEFT",
|
flickerstreak@1
|
22 RIGHT = "LEFT",
|
flickerstreak@1
|
23 TOPRIGHT = "BOTTOMLEFT",
|
flickerstreak@1
|
24 TOP = "BOTTOM",
|
flickerstreak@1
|
25 TOPLEFT = "BOTTOMRIGHT",
|
flickerstreak@1
|
26 LEFT = "RIGHT"
|
flickerstreak@1
|
27 }
|
flickerstreak@1
|
28
|
flickerstreak@1
|
29 -- private variables
|
flickerstreak@1
|
30 local stickyTargets = {
|
flickerstreak@1
|
31 [UIParent] = insideFrame,
|
flickerstreak@1
|
32 [WorldFrame] = insideFrame
|
flickerstreak@1
|
33 }
|
flickerstreak@1
|
34
|
flickerstreak@1
|
35 -- ReBar is an Ace 2 class prototype object.
|
flickerstreak@1
|
36 ReBar = AceLibrary("AceOO-2.0").Class("AceEvent-2.0")
|
flickerstreak@1
|
37
|
flickerstreak@1
|
38 local dewdrop = AceLibrary("Dewdrop-2.0")
|
flickerstreak@1
|
39
|
flickerstreak@1
|
40 function ReBar.prototype:init( config, id )
|
flickerstreak@1
|
41 ReBar.super.prototype.init(self)
|
flickerstreak@1
|
42
|
flickerstreak@1
|
43 local buttonClass = config and config.btnConfig and config.btnConfig.type and _G[config.btnConfig.type]
|
flickerstreak@1
|
44 self.config = config
|
flickerstreak@1
|
45 self.barID = id
|
flickerstreak@1
|
46 self.class = { button = buttonClass }
|
flickerstreak@1
|
47 self.buttons = { }
|
flickerstreak@1
|
48
|
flickerstreak@1
|
49 -- create the bar and control widgets
|
flickerstreak@1
|
50 self.barFrame = CreateFrame("Frame", "ReBar_"..self.barID, UIParent, "ReBarTemplate")
|
flickerstreak@1
|
51 self.controlFrame = _G[self.barFrame:GetName().."Controls"]
|
flickerstreak@1
|
52 self.controlFrame.reBar = self
|
flickerstreak@1
|
53
|
flickerstreak@1
|
54 -- set the text label on the control widget
|
flickerstreak@1
|
55 _G[self.controlFrame:GetName().."LabelString"]:SetText(id)
|
flickerstreak@1
|
56
|
flickerstreak@1
|
57 -- initialize the bar layout
|
flickerstreak@1
|
58 self:ApplySize()
|
flickerstreak@1
|
59 self:ApplyAnchor()
|
flickerstreak@1
|
60 self:LayoutButtons()
|
flickerstreak@1
|
61 self:ApplyVisibility()
|
flickerstreak@1
|
62
|
flickerstreak@1
|
63 -- add bar to stickyTargets list
|
flickerstreak@1
|
64 stickyTargets[self.barFrame] = outsideFrame
|
flickerstreak@1
|
65
|
flickerstreak@1
|
66 -- initialize dewdrop menu
|
flickerstreak@1
|
67 dewdrop:Register(self.controlFrame, 'children', function()
|
flickerstreak@1
|
68 dewdrop:FeedAceOptionsTable(ReActionGlobalMenuOptions)
|
flickerstreak@1
|
69 dewdrop:FeedAceOptionsTable(GenerateReActionBarOptions(self))
|
flickerstreak@1
|
70 dewdrop:FeedAceOptionsTable(GenerateReActionButtonOptions(self))
|
flickerstreak@1
|
71 dewdrop:FeedAceOptionsTable(ReActionProfileMenuOptions)
|
flickerstreak@1
|
72 end,
|
flickerstreak@1
|
73 'cursorX', true,
|
flickerstreak@1
|
74 'cursorY', true
|
flickerstreak@1
|
75 )
|
flickerstreak@1
|
76 end
|
flickerstreak@1
|
77
|
flickerstreak@1
|
78
|
flickerstreak@1
|
79 function ReBar.prototype:Destroy()
|
flickerstreak@1
|
80 if self.barFrame == dewdrop:GetOpenedParent() then
|
flickerstreak@1
|
81 dewdrop:Close()
|
flickerstreak@1
|
82 dewdrop:Unregister(self.barFrame)
|
flickerstreak@1
|
83 end
|
flickerstreak@1
|
84
|
flickerstreak@1
|
85 self.barFrame:Hide()
|
flickerstreak@1
|
86 self.barFrame:ClearAllPoints()
|
flickerstreak@1
|
87 self.barFrame:SetParent(nil)
|
flickerstreak@1
|
88
|
flickerstreak@1
|
89 -- need to keep around self.config for dewdrop menus in the process of deleting self
|
flickerstreak@1
|
90
|
flickerstreak@1
|
91 while #self.buttons > 0 do
|
flickerstreak@1
|
92 self.class.button:release(table.remove(self.buttons))
|
flickerstreak@1
|
93 end
|
flickerstreak@1
|
94
|
flickerstreak@1
|
95 -- remove from sticky targets table
|
flickerstreak@1
|
96 stickyTargets[self.barFrame] = nil
|
flickerstreak@1
|
97
|
flickerstreak@1
|
98 -- remove from global table
|
flickerstreak@1
|
99 -- for some reason after a destroy/recreate the globals still reference
|
flickerstreak@1
|
100 -- the old frames
|
flickerstreak@1
|
101 setglobal(self.barFrame:GetName(), nil)
|
flickerstreak@1
|
102 setglobal(self.barFrame:GetName().."Controls", nil)
|
flickerstreak@1
|
103 setglobal(self.controlFrame:GetName().."LabelString", nil)
|
flickerstreak@1
|
104 end
|
flickerstreak@1
|
105
|
flickerstreak@1
|
106
|
flickerstreak@1
|
107 -- show/hide the control frame
|
flickerstreak@1
|
108 function ReBar.prototype:ShowControls()
|
flickerstreak@1
|
109 self.controlFrame:Show()
|
flickerstreak@1
|
110 end
|
flickerstreak@1
|
111
|
flickerstreak@1
|
112 function ReBar.prototype:HideControls()
|
flickerstreak@1
|
113 local b = self.barFrame
|
flickerstreak@1
|
114 if b.isMoving or b.resizing then
|
flickerstreak@1
|
115 b:StopMovingOrSizing()
|
flickerstreak@1
|
116 b:SetScript("OnUpdate",nil)
|
flickerstreak@1
|
117 end
|
flickerstreak@1
|
118 -- close any dewdrop menu owned by us
|
flickerstreak@1
|
119 if self.barFrame == dewdrop:GetOpenedParent() then
|
flickerstreak@1
|
120 dewdrop:Close()
|
flickerstreak@1
|
121 end
|
flickerstreak@1
|
122 self.controlFrame:Hide()
|
flickerstreak@1
|
123 end
|
flickerstreak@1
|
124
|
flickerstreak@1
|
125
|
flickerstreak@1
|
126
|
flickerstreak@1
|
127
|
flickerstreak@1
|
128 -- accessors
|
flickerstreak@1
|
129 function ReBar.prototype:GetVisibility()
|
flickerstreak@1
|
130 return self.config.visible
|
flickerstreak@1
|
131 end
|
flickerstreak@1
|
132
|
flickerstreak@1
|
133 function ReBar.prototype:ToggleVisibility()
|
flickerstreak@1
|
134 self.config.visible = not self.config.visible
|
flickerstreak@1
|
135 self:ApplyVisibility()
|
flickerstreak@1
|
136 end
|
flickerstreak@1
|
137
|
flickerstreak@1
|
138 function ReBar.prototype:GetOpacity()
|
flickerstreak@1
|
139 return self.config.opacity or 100
|
flickerstreak@1
|
140 end
|
flickerstreak@1
|
141
|
flickerstreak@1
|
142 function ReBar.prototype:SetOpacity( o )
|
flickerstreak@1
|
143 self.config.opacity = tonumber(o)
|
flickerstreak@1
|
144 self:ApplyVisibility()
|
flickerstreak@1
|
145 return self.config.opacity
|
flickerstreak@1
|
146 end
|
flickerstreak@1
|
147
|
flickerstreak@1
|
148
|
flickerstreak@1
|
149 -- layout methods
|
flickerstreak@1
|
150 function ReBar.prototype:ApplySize()
|
flickerstreak@1
|
151 local buttonSz = self.config.size or 36
|
flickerstreak@1
|
152 local spacing = self.config.spacing or 4
|
flickerstreak@1
|
153 local rows = self.config.rows or 1
|
flickerstreak@1
|
154 local columns = self.config.columns or 12
|
flickerstreak@1
|
155 local w = buttonSz * columns + spacing * (columns + 1)
|
flickerstreak@1
|
156 local h = buttonSz * rows + spacing * (rows + 1)
|
flickerstreak@1
|
157 local f = self.barFrame
|
flickerstreak@1
|
158
|
flickerstreak@1
|
159 -- +1: avoid resizing oddities caused by fractional UI scale setting
|
flickerstreak@1
|
160 f:SetMinResize(buttonSz + spacing*2 + 1, buttonSz + spacing*2 + 1)
|
flickerstreak@1
|
161 f:SetWidth(w + 1)
|
flickerstreak@1
|
162 f:SetHeight(h + 1)
|
flickerstreak@1
|
163 end
|
flickerstreak@1
|
164
|
flickerstreak@1
|
165 function ReBar.prototype:ApplyAnchor()
|
flickerstreak@1
|
166 local a = self.config.anchor
|
flickerstreak@1
|
167 local f = self.barFrame
|
flickerstreak@1
|
168 f:ClearAllPoints()
|
flickerstreak@1
|
169 f:SetPoint(a.point,getglobal(a.to),a.relPoint,a.x,a.y)
|
flickerstreak@1
|
170 end
|
flickerstreak@1
|
171
|
flickerstreak@1
|
172 function ReBar.prototype:ApplyVisibility()
|
flickerstreak@1
|
173 local v = self.config.visibility
|
flickerstreak@1
|
174 if type(v) == "table" then
|
flickerstreak@1
|
175 if v.class then
|
flickerstreak@1
|
176 local _, c = UnitClass("player")
|
flickerstreak@1
|
177 v = v.class[c]
|
flickerstreak@1
|
178 end
|
flickerstreak@1
|
179 elseif type(v) == "string" then
|
flickerstreak@1
|
180 local value = getglobal(v)
|
flickerstreak@1
|
181 v = value
|
flickerstreak@1
|
182 end
|
flickerstreak@1
|
183
|
flickerstreak@1
|
184 if self.config.opacity then
|
flickerstreak@1
|
185 self.barFrame:SetAlpha(self.config.opacity / 100)
|
flickerstreak@1
|
186 end
|
flickerstreak@1
|
187
|
flickerstreak@1
|
188 if v then
|
flickerstreak@1
|
189 self.barFrame:Show()
|
flickerstreak@1
|
190 else
|
flickerstreak@1
|
191 self.barFrame:Hide()
|
flickerstreak@1
|
192 end
|
flickerstreak@1
|
193 end
|
flickerstreak@1
|
194
|
flickerstreak@1
|
195 function ReBar.prototype:LayoutButtons()
|
flickerstreak@1
|
196 local r = self.config.rows
|
flickerstreak@1
|
197 local c = self.config.columns
|
flickerstreak@1
|
198 local n = r * c
|
flickerstreak@1
|
199 local sp = self.config.spacing
|
flickerstreak@1
|
200 local sz = self.config.size
|
flickerstreak@1
|
201 local gSize = sp + sz
|
flickerstreak@1
|
202
|
flickerstreak@1
|
203 for i = 1, n do
|
flickerstreak@1
|
204 if self.buttons[i] == nil then
|
flickerstreak@1
|
205 table.insert(self.buttons, self.class.button:acquire(self.barFrame, self.config.btnConfig, i))
|
flickerstreak@1
|
206 end
|
flickerstreak@1
|
207 local b = self.buttons[i]
|
flickerstreak@1
|
208 if b == nil then
|
flickerstreak@1
|
209 break -- handling for button types that support limited numbers
|
flickerstreak@1
|
210 end
|
flickerstreak@1
|
211 b:PlaceButton("TOPLEFT", sp + gSize * math.fmod(i-1,c), - (sp + gSize * math.floor((i-1)/c)), sz)
|
flickerstreak@1
|
212 end
|
flickerstreak@1
|
213
|
flickerstreak@1
|
214 -- b == nil, above, should always be the case if and only if i == n. ReBar never monkeys
|
flickerstreak@1
|
215 -- with buttons in the middle of the sequence: it always adds or removes on the array end
|
flickerstreak@1
|
216 while #self.buttons > n do
|
flickerstreak@1
|
217 self.class.button:release(table.remove(self.buttons))
|
flickerstreak@1
|
218 end
|
flickerstreak@1
|
219
|
flickerstreak@1
|
220 end
|
flickerstreak@1
|
221
|
flickerstreak@1
|
222
|
flickerstreak@1
|
223 function ReBar.prototype:StoreAnchor(f, p, rp, x, y)
|
flickerstreak@1
|
224 local name = f:GetName()
|
flickerstreak@1
|
225 -- no point if we can't store the name or the offsets are incomplete
|
flickerstreak@1
|
226 if name and x and y then
|
flickerstreak@1
|
227 self.config.anchor = {
|
flickerstreak@1
|
228 to = name,
|
flickerstreak@1
|
229 point = p,
|
flickerstreak@1
|
230 relPoint = rp or p,
|
flickerstreak@1
|
231 x = x,
|
flickerstreak@1
|
232 y = y
|
flickerstreak@1
|
233 }
|
flickerstreak@1
|
234 end
|
flickerstreak@1
|
235 end
|
flickerstreak@1
|
236
|
flickerstreak@1
|
237
|
flickerstreak@1
|
238
|
flickerstreak@1
|
239 -- mouse event handlers (clicking/dragging/resizing the bar)
|
flickerstreak@1
|
240 function ReBar.prototype:BeginDrag()
|
flickerstreak@1
|
241 local f = self.barFrame
|
flickerstreak@1
|
242 f:StartMoving()
|
flickerstreak@1
|
243 f.isMoving = true
|
flickerstreak@1
|
244 f:SetScript("OnUpdate", function() self:StickyIndicatorUpdate() end)
|
flickerstreak@1
|
245 end
|
flickerstreak@1
|
246
|
flickerstreak@1
|
247 function ReBar.prototype:FinishDrag()
|
flickerstreak@1
|
248 local f, p, rp, x, y
|
flickerstreak@1
|
249 local bf = self.barFrame
|
flickerstreak@1
|
250
|
flickerstreak@1
|
251 bf:StopMovingOrSizing()
|
flickerstreak@1
|
252 bf.isMoving = false
|
flickerstreak@1
|
253
|
flickerstreak@1
|
254 bf:SetScript("OnUpdate",nil)
|
flickerstreak@1
|
255 if IsShiftKeyDown() then
|
flickerstreak@1
|
256 f, p, rp, x, y = self:GetStickyAnchor()
|
flickerstreak@1
|
257 ReBarStickyIndicator1:Hide()
|
flickerstreak@1
|
258 ReBarStickyIndicator2:Hide()
|
flickerstreak@1
|
259 end
|
flickerstreak@1
|
260
|
flickerstreak@1
|
261 if f == nil then
|
flickerstreak@1
|
262 f = UIParent
|
flickerstreak@1
|
263 local _
|
flickerstreak@1
|
264 _, p,rp,x,y = self:GetClosestPointTo(f)
|
flickerstreak@1
|
265 end
|
flickerstreak@1
|
266
|
flickerstreak@1
|
267 if f then
|
flickerstreak@1
|
268 self:StoreAnchor(f,p,rp,x,y)
|
flickerstreak@1
|
269 self:ApplyAnchor()
|
flickerstreak@1
|
270 end
|
flickerstreak@1
|
271 end
|
flickerstreak@1
|
272
|
flickerstreak@1
|
273 function ReBar.prototype:BeginBarResize( sizingPoint )
|
flickerstreak@1
|
274 local f = self.barFrame
|
flickerstreak@1
|
275 f:StartSizing(sizingPoint)
|
flickerstreak@1
|
276 f.resizing = true
|
flickerstreak@1
|
277 f:SetScript("OnUpdate",function() self:ReflowButtons() end)
|
flickerstreak@1
|
278 end
|
flickerstreak@1
|
279
|
flickerstreak@1
|
280 function ReBar.prototype:BeginButtonResize( sizingPoint, mouseBtn )
|
flickerstreak@1
|
281 local f = self.barFrame
|
flickerstreak@1
|
282 f:StartSizing(sizingPoint)
|
flickerstreak@1
|
283 f.resizing = true
|
flickerstreak@1
|
284 local r = self.config.rows
|
flickerstreak@1
|
285 local c = self.config.columns
|
flickerstreak@1
|
286 local s = self.config.spacing
|
flickerstreak@1
|
287 local sz = self.config.size
|
flickerstreak@1
|
288 if mouseBtn == "LeftButton" then
|
flickerstreak@1
|
289 f:SetMinResize(c*(12 + 2*s) +1, r*(12 + 2*s) +1)
|
flickerstreak@1
|
290 f:SetScript("OnUpdate",function() self:DragSizeButtons() end)
|
flickerstreak@1
|
291 elseif mouseBtn == "RightButton" then
|
flickerstreak@1
|
292 f:SetMinResize(c*sz+1, r*sz+1)
|
flickerstreak@1
|
293 f:SetScript("OnUpdate",function() self:DragSizeSpacing() end)
|
flickerstreak@1
|
294 end
|
flickerstreak@1
|
295 end
|
flickerstreak@1
|
296
|
flickerstreak@1
|
297 function ReBar.prototype:FinishResize()
|
flickerstreak@1
|
298 local f = self.barFrame
|
flickerstreak@1
|
299 f:StopMovingOrSizing()
|
flickerstreak@1
|
300 f.resizing = false
|
flickerstreak@1
|
301 f:SetScript("OnUpdate",nil)
|
flickerstreak@1
|
302 self:ApplySize()
|
flickerstreak@1
|
303 end
|
flickerstreak@1
|
304
|
flickerstreak@1
|
305
|
flickerstreak@1
|
306
|
flickerstreak@1
|
307
|
flickerstreak@1
|
308 -- sticky anchoring functions
|
flickerstreak@1
|
309 function ReBar.prototype:StickyIndicatorUpdate()
|
flickerstreak@1
|
310 local si1 = ReBarStickyIndicator1
|
flickerstreak@1
|
311 local si2 = ReBarStickyIndicator2
|
flickerstreak@1
|
312 if IsShiftKeyDown() then
|
flickerstreak@1
|
313 local f, p, rp, x, y = self:GetStickyAnchor()
|
flickerstreak@1
|
314 if f then
|
flickerstreak@1
|
315 si1:ClearAllPoints()
|
flickerstreak@1
|
316 si2:ClearAllPoints()
|
flickerstreak@1
|
317 si1:SetPoint("CENTER",self.barFrame,p,0,0)
|
flickerstreak@1
|
318 si2:SetPoint("CENTER",f,rp,x,y)
|
flickerstreak@1
|
319 si1:Show()
|
flickerstreak@1
|
320 si2:Show()
|
flickerstreak@1
|
321 return nil
|
flickerstreak@1
|
322 end
|
flickerstreak@1
|
323 end
|
flickerstreak@1
|
324 si1:Hide()
|
flickerstreak@1
|
325 si2:Hide()
|
flickerstreak@1
|
326 si1:ClearAllPoints()
|
flickerstreak@1
|
327 si2:ClearAllPoints()
|
flickerstreak@1
|
328 end
|
flickerstreak@1
|
329
|
flickerstreak@1
|
330 function ReBar.prototype:CheckAnchorable(f)
|
flickerstreak@1
|
331 -- can't anchor to self or to a hidden frame
|
flickerstreak@1
|
332 if f == self.barFrame or not(f:IsShown()) then return false end
|
flickerstreak@1
|
333
|
flickerstreak@1
|
334 -- also can't anchor to frames that are anchored to self
|
flickerstreak@1
|
335 for i = 1, f:GetNumPoints() do
|
flickerstreak@1
|
336 local _, f2 = f:GetPoint(i)
|
flickerstreak@1
|
337 if f2 == self.barFrame then return false end
|
flickerstreak@1
|
338 end
|
flickerstreak@1
|
339
|
flickerstreak@1
|
340 return true
|
flickerstreak@1
|
341 end
|
flickerstreak@1
|
342
|
flickerstreak@1
|
343
|
flickerstreak@1
|
344 function ReBar.prototype:GetStickyAnchor()
|
flickerstreak@1
|
345 local snapRange = (self.config.size + self.config.spacing)
|
flickerstreak@1
|
346 local r2, f, p, rp, x, y = self:GetClosestAnchor()
|
flickerstreak@1
|
347
|
flickerstreak@1
|
348 if f and p then
|
flickerstreak@1
|
349 local xx, yy = pointFindTable[p](f)
|
flickerstreak@1
|
350 if r2 and r2 < (snapRange*snapRange) then
|
flickerstreak@1
|
351 if xx or math.abs(x) < snapRange then x = 0 end
|
flickerstreak@1
|
352 if yy or math.abs(y) < snapRange then y = 0 end
|
flickerstreak@1
|
353 elseif not(yy) and math.abs(x) < snapRange then
|
flickerstreak@1
|
354 x = 0
|
flickerstreak@1
|
355 elseif not(xx) and math.abs(y) < snapRange then
|
flickerstreak@1
|
356 y = 0
|
flickerstreak@1
|
357 else
|
flickerstreak@1
|
358 f = nil -- nothing in range
|
flickerstreak@1
|
359 end
|
flickerstreak@1
|
360 end
|
flickerstreak@1
|
361 return f, p, rp, x, y
|
flickerstreak@1
|
362 end
|
flickerstreak@1
|
363
|
flickerstreak@1
|
364 function ReBar.prototype:GetClosestAnchor()
|
flickerstreak@1
|
365 -- choose the closest anchor point on the list of target frames
|
flickerstreak@1
|
366 local range2, frame, point, relPoint, offsetX, offsetY
|
flickerstreak@1
|
367
|
flickerstreak@1
|
368 for f, tgtRegion in pairs(stickyTargets) do
|
flickerstreak@1
|
369 if self:CheckAnchorable(f) then
|
flickerstreak@1
|
370 local r2 ,p, rp, x, y = self:GetClosestPointTo(f,tgtRegion)
|
flickerstreak@1
|
371 if r2 then
|
flickerstreak@1
|
372 if not(range2 and range2 < r2) then
|
flickerstreak@1
|
373 range2, frame, point, relPoint, offsetX, offsetY = r2, f, p, rp, x, y
|
flickerstreak@1
|
374 end
|
flickerstreak@1
|
375 end
|
flickerstreak@1
|
376 end
|
flickerstreak@1
|
377 end
|
flickerstreak@1
|
378
|
flickerstreak@1
|
379 return range2, frame, point, relPoint, offsetX, offsetY
|
flickerstreak@1
|
380 end
|
flickerstreak@1
|
381
|
flickerstreak@1
|
382 function ReBar.prototype:GetClosestPointTo(f,inside)
|
flickerstreak@1
|
383 local range2, point, relPoint, offsetX, offsetY
|
flickerstreak@1
|
384 local pft = pointFindTable
|
flickerstreak@1
|
385 local cx, cy = self.barFrame:GetCenter()
|
flickerstreak@1
|
386 local fcx, fcy = f:GetCenter()
|
flickerstreak@1
|
387 local fh = f:GetHeight()
|
flickerstreak@1
|
388 local fw = f:GetWidth()
|
flickerstreak@1
|
389
|
flickerstreak@1
|
390 -- compute whether edge bisector intersects target edge
|
flickerstreak@1
|
391 local dcx = math.abs(cx-fcx) < fw/2 and (cx-fcx)
|
flickerstreak@1
|
392 local dcy = math.abs(cy-fcy) < fh/2 and (cy-fcy)
|
flickerstreak@1
|
393
|
flickerstreak@1
|
394 for p, func in pairs(pft) do
|
flickerstreak@1
|
395 local rp, x, y
|
flickerstreak@1
|
396 if inside == outsideFrame then
|
flickerstreak@1
|
397 rp = oppositePointTable[p]
|
flickerstreak@1
|
398 x, y = self:GetOffsetToPoint(f, func, pft[rp])
|
flickerstreak@1
|
399 else
|
flickerstreak@1
|
400 rp = p
|
flickerstreak@1
|
401 x, y = self:GetOffsetToPoint(f, func, func)
|
flickerstreak@1
|
402 end
|
flickerstreak@1
|
403
|
flickerstreak@1
|
404 -- if anchoring to an edge, only anchor if the center point overlaps the other edge
|
flickerstreak@1
|
405 if (x or dcx) and (y or dcy) then
|
flickerstreak@1
|
406 local r2 = (x or 0)^2 + (y or 0)^2
|
flickerstreak@1
|
407 if range2 == nil or r2 < range2 then
|
flickerstreak@1
|
408 range2, point, relPoint, offsetX, offsetY = r2, p, rp, x or dcx, y or dcy
|
flickerstreak@1
|
409 end
|
flickerstreak@1
|
410 end
|
flickerstreak@1
|
411 end
|
flickerstreak@1
|
412 return range2, point, relPoint, offsetX, offsetY
|
flickerstreak@1
|
413 end
|
flickerstreak@1
|
414
|
flickerstreak@1
|
415 function ReBar.prototype:GetOffsetToPoint(f,func,ffunc)
|
flickerstreak@1
|
416 local x, y = func(self.barFrame) -- coordinates of the point on this frame
|
flickerstreak@1
|
417 local fx, fy = ffunc(f) -- coordinates of the point on the target frame
|
flickerstreak@1
|
418 -- guarantees: if x then fx, if y then fy
|
flickerstreak@1
|
419 return x and (x-fx), y and (y-fy)
|
flickerstreak@1
|
420 end
|
flickerstreak@1
|
421
|
flickerstreak@1
|
422
|
flickerstreak@1
|
423
|
flickerstreak@1
|
424
|
flickerstreak@1
|
425
|
flickerstreak@1
|
426
|
flickerstreak@1
|
427 -- utility function to get the height, width, and button size attributes
|
flickerstreak@1
|
428 function ReBar.prototype:GetLayout()
|
flickerstreak@1
|
429 local c = self.config
|
flickerstreak@1
|
430 local f = self.barFrame
|
flickerstreak@1
|
431 return f:GetWidth(), f:GetHeight(), c.size, c.rows, c.columns, c.spacing
|
flickerstreak@1
|
432 end
|
flickerstreak@1
|
433
|
flickerstreak@1
|
434 -- add and remove buttons dynamically as the bar is resized
|
flickerstreak@1
|
435 function ReBar.prototype:ReflowButtons()
|
flickerstreak@1
|
436 local w, h, sz, r, c, sp = self:GetLayout()
|
flickerstreak@1
|
437
|
flickerstreak@1
|
438 self.config.rows = math.floor( (h - sp) / (sz + sp) )
|
flickerstreak@1
|
439 self.config.columns = math.floor( (w - sp) / (sz + sp) )
|
flickerstreak@1
|
440
|
flickerstreak@1
|
441 if self.config.rows ~= r or self.config.columns ~= c then
|
flickerstreak@1
|
442 self:LayoutButtons()
|
flickerstreak@1
|
443 end
|
flickerstreak@1
|
444 end
|
flickerstreak@1
|
445
|
flickerstreak@1
|
446
|
flickerstreak@1
|
447 -- change the size of buttons as the bar is resized
|
flickerstreak@1
|
448 function ReBar.prototype:DragSizeButtons()
|
flickerstreak@1
|
449 local w, h, sz, r, c, sp = self:GetLayout()
|
flickerstreak@1
|
450
|
flickerstreak@1
|
451 local newSzW = math.floor((w - (c+1)*sp)/c)
|
flickerstreak@1
|
452 local newSzH = math.floor((h - (r+1)*sp)/r)
|
flickerstreak@1
|
453
|
flickerstreak@1
|
454 self.config.size = math.max(12, math.min(newSzW, newSzH))
|
flickerstreak@1
|
455
|
flickerstreak@1
|
456 if self.config.size ~= sz then
|
flickerstreak@1
|
457 self:LayoutButtons()
|
flickerstreak@1
|
458 self:UpdateResizeTooltip()
|
flickerstreak@1
|
459 end
|
flickerstreak@1
|
460 end
|
flickerstreak@1
|
461
|
flickerstreak@1
|
462
|
flickerstreak@1
|
463 -- change the spacing of buttons as the bar is resized
|
flickerstreak@1
|
464 function ReBar.prototype:DragSizeSpacing()
|
flickerstreak@1
|
465 local w, h, sz, r, c, sp = self:GetLayout()
|
flickerstreak@1
|
466
|
flickerstreak@1
|
467 local newSpW = math.floor((w - c*sz)/(c+1))
|
flickerstreak@1
|
468 local newSpH = math.floor((h - r*sz)/(r+1))
|
flickerstreak@1
|
469
|
flickerstreak@1
|
470 self.config.spacing = math.max(0, math.min(newSpW, newSpH))
|
flickerstreak@1
|
471
|
flickerstreak@1
|
472 if self.config.spacing ~= sp then
|
flickerstreak@1
|
473 self:LayoutButtons()
|
flickerstreak@1
|
474 self:UpdateResizeTooltip()
|
flickerstreak@1
|
475 end
|
flickerstreak@1
|
476 end
|
flickerstreak@1
|
477
|
flickerstreak@1
|
478
|
flickerstreak@1
|
479 -- update the drag tooltip to indicate current sizes
|
flickerstreak@1
|
480 function ReBar.prototype:UpdateResizeTooltip()
|
flickerstreak@1
|
481 GameTooltipTextRight4:SetText(self.config.size)
|
flickerstreak@1
|
482 GameTooltipTextRight5:SetText(self.config.spacing)
|
flickerstreak@1
|
483 GameTooltip:Show()
|
flickerstreak@1
|
484 end
|
flickerstreak@1
|
485
|
flickerstreak@1
|
486 function ReBar.prototype:ShowTooltip()
|
flickerstreak@1
|
487 GameTooltip:SetOwner(self.barFrame, "ANCHOR_TOPRIGHT")
|
flickerstreak@1
|
488 GameTooltip:AddLine("Bar "..self.barID)
|
flickerstreak@1
|
489 GameTooltip:AddLine("Drag to move")
|
flickerstreak@1
|
490 GameTooltip:AddLine("Shift-drag for sticky mode")
|
flickerstreak@1
|
491 GameTooltip:AddLine("Right-click for options")
|
flickerstreak@1
|
492 GameTooltip:Show()
|
flickerstreak@1
|
493 end
|
flickerstreak@1
|
494
|
flickerstreak@1
|
495 function ReBar.prototype:ShowButtonResizeTooltip(point)
|
flickerstreak@1
|
496 GameTooltip:SetOwner(self.barFrame, "ANCHOR_"..point)
|
flickerstreak@1
|
497 GameTooltip:AddLine("Drag to resize buttons")
|
flickerstreak@1
|
498 GameTooltip:AddLine("Right-click-drag")
|
flickerstreak@1
|
499 GameTooltip:AddLine("to change spacing")
|
flickerstreak@1
|
500 GameTooltip:AddDoubleLine("Size: ", "0")
|
flickerstreak@1
|
501 GameTooltip:AddDoubleLine("Spacing: ", "0")
|
flickerstreak@1
|
502 self:UpdateResizeTooltip()
|
flickerstreak@1
|
503 end
|
flickerstreak@1
|
504
|
flickerstreak@1
|
505 function ReBar.prototype:ShowBarResizeTooltip(point)
|
flickerstreak@1
|
506 GameTooltip:SetOwner(self.barFrame, "ANCHOR_"..point)
|
flickerstreak@1
|
507 GameTooltip:AddLine("Drag to add/remove buttons")
|
flickerstreak@1
|
508 GameTooltip:Show()
|
flickerstreak@1
|
509 end
|