annotate classes/ReBar.lua @ 4:dfd829db3ad0

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