Mercurial > wow > reaction
comparison Bar.lua @ 33:c54c481ad0ed
- Moved bar control frame from ConfigUI to Bar
- Added LICENSE.txt
- added profile management options
- other minor cleanup
| author | Flick <flickerstreak@gmail.com> |
|---|---|
| date | Thu, 03 Apr 2008 20:25:40 +0000 |
| parents | 0d95ce7a9ec2 |
| children | c3c64e2def50 |
comparison
equal
deleted
inserted
replaced
| 32:821b2b7edff1 | 33:c54c481ad0ed |
|---|---|
| 1 local ReAction = ReAction | 1 local ReAction = ReAction |
| 2 local L = ReAction.L | 2 local L = ReAction.L |
| 3 local _G = _G | 3 local _G = _G |
| 4 local CreateFrame = CreateFrame | 4 local CreateFrame = CreateFrame |
| 5 local InCombatLockdown = InCombatLockdown | |
| 6 local floor = math.floor | |
| 7 local min = math.min | |
| 8 local format = string.format | |
| 9 local GameTooltip = GameTooltip | |
| 10 | |
| 11 | |
| 5 | 12 |
| 6 -- update ReAction revision if this file is newer | 13 -- update ReAction revision if this file is newer |
| 7 local revision = tonumber(("$Revision: 1 $"):match("%d+")) | 14 local revision = tonumber(("$Revision$"):match("%d+")) |
| 8 if revision > ReAction.revision then | 15 if revision > ReAction.revision then |
| 9 Reaction.revision = revision | 16 Reaction.revision = revision |
| 10 end | 17 end |
| 11 | 18 |
| 12 ------ BAR CLASS ------ | 19 ------ BAR CLASS ------ |
| 110 | 117 |
| 111 function Bar:GetName() | 118 function Bar:GetName() |
| 112 return self.name | 119 return self.name |
| 113 end | 120 end |
| 114 | 121 |
| 122 function Bar:SetName(name) | |
| 123 self.name = name | |
| 124 if self.controlLabelString then | |
| 125 self.controlLabelString:SetText(self.name) | |
| 126 end | |
| 127 end | |
| 128 | |
| 115 function Bar:PlaceButton(f, idx, baseW, baseH) | 129 function Bar:PlaceButton(f, idx, baseW, baseH) |
| 116 local r, c, s = self:GetButtonGrid() | 130 local r, c, s = self:GetButtonGrid() |
| 117 local bh, bw = self:GetButtonSize() | 131 local bh, bw = self:GetButtonSize() |
| 118 local row, col = floor((idx-1)/c), mod((idx-1),c) -- zero-based | 132 local row, col = floor((idx-1)/c), mod((idx-1),c) -- zero-based |
| 119 local x, y = col*bw + (col+0.5)*s, row*bh + (row+0.5)*s | 133 local x, y = col*bw + (col+0.5)*s, row*bh + (row+0.5)*s |
| 125 -- f:Show() | 139 -- f:Show() |
| 126 end | 140 end |
| 127 | 141 |
| 128 | 142 |
| 129 | 143 |
| 144 | |
| 145 | |
| 146 | |
| 147 | |
| 148 -- | |
| 149 -- Bar config overlay | |
| 150 -- | |
| 151 local StoreExtents, RecomputeButtonSize, RecomputeButtonSpacing, RecomputeGrid, ClampToButtons, HideGameTooltip, CreateControls | |
| 152 | |
| 153 do | |
| 154 -- upvalue some of these for small OnUpdate performance boost | |
| 155 local GetSize = Bar.GetSize | |
| 156 local GetButtonSize = Bar.GetButtonSize | |
| 157 local GetButtonGrid = Bar.GetButtonGrid | |
| 158 local SetSize = Bar.SetSize | |
| 159 local SetButtonSize = Bar.SetButtonSize | |
| 160 local SetButtonGrid = Bar.SetButtonGrid | |
| 161 local ApplyAnchor = Bar.ApplyAnchor | |
| 162 | |
| 163 StoreExtents = function(bar) | |
| 164 local f = bar.frame | |
| 165 local point, relativeTo, relativePoint, x, y = f:GetPoint(1) | |
| 166 relativeTo = relativeTo or f:GetParent() | |
| 167 local anchorTo | |
| 168 for name, b in pairs(ReAction.bars) do | |
| 169 if b then | |
| 170 if b:GetFrame() == relativeTo then | |
| 171 anchorTo = name | |
| 172 break | |
| 173 end | |
| 174 end | |
| 175 end | |
| 176 anchorTo = anchorTo or relativeTo:GetName() | |
| 177 local c = bar.config | |
| 178 c.anchor = point | |
| 179 c.anchorTo = anchorTo | |
| 180 c.relativePoint = relativePoint | |
| 181 c.x = x | |
| 182 c.y = y | |
| 183 c.width, c.height = f:GetWidth(), f:GetHeight() | |
| 184 end | |
| 185 | |
| 186 RecomputeButtonSize = function(bar) | |
| 187 local w, h = GetSize(bar) | |
| 188 local bw, bh = GetButtonSize(bar) | |
| 189 local r, c, s = GetButtonGrid(bar) | |
| 190 | |
| 191 local scaleW = (floor(w/c) - s) / bw | |
| 192 local scaleH = (floor(h/r) - s) / bh | |
| 193 local scale = min(scaleW, scaleH) | |
| 194 | |
| 195 SetButtonSize(bar, scale * bw, scale * bh, s) | |
| 196 end | |
| 197 | |
| 198 RecomputeButtonSpacing = function(bar) | |
| 199 local w, h = GetSize(bar) | |
| 200 local bw, bh = GetButtonSize(bar) | |
| 201 local r, c, s = GetButtonGrid(bar) | |
| 202 | |
| 203 SetButtonGrid(bar,r,c,min(floor(w/c) - bw, floor(h/r) - bh)) | |
| 204 end | |
| 205 | |
| 206 RecomputeGrid = function(bar) | |
| 207 local w, h = GetSize(bar) | |
| 208 local bw, bh = GetButtonSize(bar) | |
| 209 local r, c, s = GetButtonGrid(bar) | |
| 210 | |
| 211 SetButtonGrid(bar, floor(h/(bh+s)), floor(w/(bw+s)), s) | |
| 212 end | |
| 213 | |
| 214 ClampToButtons = function(bar) | |
| 215 local bw, bh = GetButtonSize(bar) | |
| 216 local r, c, s = GetButtonGrid(bar) | |
| 217 SetSize(bar, (bw+s)*c, (bh+s)*r ) | |
| 218 end | |
| 219 | |
| 220 HideGameTooltip = function() | |
| 221 GameTooltip:Hide() | |
| 222 end | |
| 223 | |
| 224 CreateControls = function(bar) | |
| 225 local f = bar.frame | |
| 226 | |
| 227 f:SetMovable(true) | |
| 228 f:SetResizable(true) | |
| 229 f:SetClampedToScreen(true) | |
| 230 | |
| 231 -- buttons on the bar should be direct children of the bar frame. | |
| 232 -- The control elements need to float on top of this, which we could | |
| 233 -- do with SetFrameLevel() or Raise(), but it's more reliable to do it | |
| 234 -- via frame nesting, hence good old foo's appearance here. | |
| 235 local foo = CreateFrame("Frame",nil,f) | |
| 236 foo:SetAllPoints() | |
| 237 | |
| 238 local control = CreateFrame("Button", nil, foo) | |
| 239 control:EnableMouse(true) | |
| 240 control:SetToplevel(true) | |
| 241 control:SetPoint("TOPLEFT", -4, 4) | |
| 242 control:SetPoint("BOTTOMRIGHT", 4, -4) | |
| 243 control:SetBackdrop({ | |
| 244 edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", | |
| 245 tile = true, | |
| 246 tileSize = 16, | |
| 247 edgeSize = 16, | |
| 248 insets = { left = 0, right = 0, top = 0, bottom = 0 }, | |
| 249 }) | |
| 250 | |
| 251 -- textures | |
| 252 local bgTex = control:CreateTexture(nil,"BACKGROUND") | |
| 253 bgTex:SetTexture(0.7,0.7,1.0,0.2) | |
| 254 bgTex:SetPoint("TOPLEFT",4,-4) | |
| 255 bgTex:SetPoint("BOTTOMRIGHT",-4,4) | |
| 256 local hTex = control:CreateTexture(nil,"HIGHLIGHT") | |
| 257 hTex:SetTexture(0.7,0.7,1.0,0.2) | |
| 258 hTex:SetPoint("TOPLEFT",4,-4) | |
| 259 hTex:SetPoint("BOTTOMRIGHT",-4,4) | |
| 260 hTex:SetBlendMode("ADD") | |
| 261 | |
| 262 -- label | |
| 263 local label = control:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") | |
| 264 label:SetAllPoints() | |
| 265 label:SetJustifyH("CENTER") | |
| 266 label:SetShadowColor(0,0,0,1) | |
| 267 label:SetShadowOffset(2,-2) | |
| 268 label:SetTextColor(1,1,1,1) | |
| 269 label:SetText(bar:GetName()) | |
| 270 label:Show() | |
| 271 bar.controlLabelString = label -- so that bar:SetName() can update it | |
| 272 | |
| 273 local StopResize = function() | |
| 274 f:StopMovingOrSizing() | |
| 275 f.isMoving = false | |
| 276 f:SetScript("OnUpdate",nil) | |
| 277 StoreExtents(bar) | |
| 278 ClampToButtons(bar) | |
| 279 ApplyAnchor(bar) | |
| 280 end | |
| 281 | |
| 282 -- edge drag handles | |
| 283 for _, point in pairs({"LEFT","TOP","RIGHT","BOTTOM"}) do | |
| 284 local edge = CreateFrame("Frame",nil,control) | |
| 285 edge:EnableMouse(true) | |
| 286 edge:SetWidth(8) | |
| 287 edge:SetHeight(8) | |
| 288 if point == "TOP" or point == "BOTTOM" then | |
| 289 edge:SetPoint(point.."LEFT") | |
| 290 edge:SetPoint(point.."RIGHT") | |
| 291 else | |
| 292 edge:SetPoint("TOP"..point) | |
| 293 edge:SetPoint("BOTTOM"..point) | |
| 294 end | |
| 295 local tex = edge:CreateTexture(nil,"HIGHLIGHT") | |
| 296 tex:SetTexture(1.0,0.82,0,0.7) | |
| 297 tex:SetBlendMode("ADD") | |
| 298 tex:SetAllPoints() | |
| 299 edge:RegisterForDrag("LeftButton") | |
| 300 edge:SetScript("OnMouseDown", | |
| 301 function() | |
| 302 local bw, bh = GetButtonSize(bar) | |
| 303 local r, c, s = GetButtonGrid(bar) | |
| 304 f:SetMinResize( bw+s+1, bh+s+1 ) | |
| 305 f:StartSizing(point) | |
| 306 f:SetScript("OnUpdate", | |
| 307 function() | |
| 308 RecomputeGrid(bar) | |
| 309 bar:RefreshLayout() | |
| 310 end | |
| 311 ) | |
| 312 end | |
| 313 ) | |
| 314 edge:SetScript("OnMouseUp", StopResize) | |
| 315 edge:SetScript("OnEnter", | |
| 316 function() | |
| 317 GameTooltip:SetOwner(f, "ANCHOR_"..point) | |
| 318 GameTooltip:AddLine(L["Drag to add/remove buttons"]) | |
| 319 GameTooltip:Show() | |
| 320 end | |
| 321 ) | |
| 322 edge:SetScript("OnLeave", HideGameTooltip) | |
| 323 edge:Show() | |
| 324 end | |
| 325 | |
| 326 -- corner drag handles, again nested in an anonymous frame so that they are on top | |
| 327 local foo2 = CreateFrame("Frame",nil,control) | |
| 328 foo2:SetAllPoints(true) | |
| 329 for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do | |
| 330 local corner = CreateFrame("Frame",nil,foo2) | |
| 331 corner:EnableMouse(true) | |
| 332 corner:SetWidth(12) | |
| 333 corner:SetHeight(12) | |
| 334 corner:SetPoint(point) | |
| 335 local tex = corner:CreateTexture(nil,"HIGHLIGHT") | |
| 336 tex:SetTexture(1.0,0.82,0,0.7) | |
| 337 tex:SetBlendMode("ADD") | |
| 338 tex:SetAllPoints() | |
| 339 corner:RegisterForDrag("LeftButton","RightButton") | |
| 340 local updateTooltip = function() | |
| 341 local size, size2 = bar:GetButtonSize() | |
| 342 local rows, cols, spacing = bar:GetButtonGrid() | |
| 343 size = (size == size2) and tostring(size) or format("%dx%d",size,size2) | |
| 344 GameTooltipTextRight4:SetText(size) | |
| 345 GameTooltipTextRight5:SetText(tostring(spacing)) | |
| 346 end | |
| 347 corner:SetScript("OnMouseDown", | |
| 348 function(_,btn) | |
| 349 local bw, bh = GetButtonSize(bar) | |
| 350 local r, c, s = GetButtonGrid(bar) | |
| 351 if btn == "LeftButton" then -- button resize | |
| 352 f:SetMinResize( (s+12)*c+1, (s+12)*r+1 ) | |
| 353 f:SetScript("OnUpdate", | |
| 354 function() | |
| 355 RecomputeButtonSize(bar) | |
| 356 bar:RefreshLayout() | |
| 357 updateTooltip() | |
| 358 end | |
| 359 ) | |
| 360 elseif btn == "RightButton" then -- spacing resize | |
| 361 f:SetMinResize( bw*c, bh*r ) | |
| 362 f:SetScript("OnUpdate", | |
| 363 function() | |
| 364 RecomputeButtonSpacing(bar) | |
| 365 bar:RefreshLayout() | |
| 366 updateTooltip() | |
| 367 end | |
| 368 ) | |
| 369 end | |
| 370 f:StartSizing(point) | |
| 371 end | |
| 372 ) | |
| 373 corner:SetScript("OnMouseUp",StopResize) | |
| 374 corner:SetScript("OnEnter", | |
| 375 function() | |
| 376 GameTooltip:SetOwner(f, "ANCHOR_"..point) | |
| 377 GameTooltip:AddLine(L["Drag to resize buttons"]) | |
| 378 GameTooltip:AddLine(L["Right-click-drag"]) | |
| 379 GameTooltip:AddLine(L["to change spacing"]) | |
| 380 local size, size2 = bar:GetButtonSize() | |
| 381 local rows, cols, spacing = bar:GetButtonGrid() | |
| 382 size = (size == size2) and tostring(size) or format("%dx%d",size,size2) | |
| 383 GameTooltip:AddDoubleLine(L["Size:"], size) | |
| 384 GameTooltip:AddDoubleLine(L["Spacing:"], tostring(spacing)) | |
| 385 GameTooltip:Show() | |
| 386 end | |
| 387 ) | |
| 388 corner:SetScript("OnLeave", | |
| 389 function() | |
| 390 GameTooltip:Hide() | |
| 391 f:SetScript("OnUpdate",nil) | |
| 392 end | |
| 393 ) | |
| 394 | |
| 395 end | |
| 396 | |
| 397 control:RegisterForDrag("LeftButton") | |
| 398 control:RegisterForClicks("RightButtonDown") | |
| 399 | |
| 400 control:SetScript("OnDragStart", | |
| 401 function() | |
| 402 f:StartMoving() | |
| 403 f.isMoving = true | |
| 404 -- TODO: snap indicator update install | |
| 405 end | |
| 406 ) | |
| 407 | |
| 408 control:SetScript("OnDragStop", | |
| 409 function() | |
| 410 f:StopMovingOrSizing() | |
| 411 f.isMoving = false | |
| 412 f:SetScript("OnUpdate",nil) | |
| 413 -- TODO: snap frame here | |
| 414 StoreExtents(bar) | |
| 415 end | |
| 416 ) | |
| 417 | |
| 418 control:SetScript("OnEnter", | |
| 419 function() | |
| 420 -- add bar type and status information to name | |
| 421 local name = bar.name | |
| 422 for _, m in ReAction:IterateModules() do | |
| 423 --[[ | |
| 424 local suffix = safecall(m,"GetBarNameModifier",bar) | |
| 425 if suffix then | |
| 426 name = ("%s %s"):format(name,suffix) | |
| 427 end | |
| 428 --]] | |
| 429 end | |
| 430 | |
| 431 GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT") | |
| 432 GameTooltip:AddLine(name) | |
| 433 GameTooltip:AddLine(L["Drag to move"]) | |
| 434 --GameTooltip:AddLine(L["Shift-drag for sticky mode"]) | |
| 435 GameTooltip:AddLine(L["Right-click for options"]) | |
| 436 GameTooltip:Show() | |
| 437 end | |
| 438 ) | |
| 439 | |
| 440 control:SetScript("OnLeave", HideGameTooltip) | |
| 441 | |
| 442 control:SetScript("OnClick", | |
| 443 function() | |
| 444 bar:ShowMenu() | |
| 445 end | |
| 446 ) | |
| 447 | |
| 448 return control | |
| 449 end | |
| 450 end | |
| 451 | |
| 452 | |
| 453 local OpenMenu, CloseMenu | |
| 454 do | |
| 455 -- Looking for a lightweight AceConfig3-struct-compatible | |
| 456 -- replacement for Dewdrop, encapsulate here | |
| 457 -- Considering Blizzard's EasyMenu/UIDropDownMenu, but that's | |
| 458 -- a bit tricky to convert from AceConfig3-struct | |
| 459 local Dewdrop = AceLibrary("Dewdrop-2.0") | |
| 460 OpenMenu = function(frame, opts) | |
| 461 Dewdrop:Open(frame, "children", opts, "cursorX", true, "cursorY", true) | |
| 462 end | |
| 463 CloseMenu = function(frame) | |
| 464 if Dewdrop:GetOpenedParent() == frame then | |
| 465 Dewdrop:Close() | |
| 466 end | |
| 467 end | |
| 468 end | |
| 469 | |
| 470 | |
| 471 function Bar:ShowControls(show) | |
| 472 if show then | |
| 473 if not self.controlFrame then | |
| 474 self.controlFrame = CreateControls(self) | |
| 475 end | |
| 476 self.controlFrame:Show() | |
| 477 elseif self.controlFrame then | |
| 478 CloseMenu(self.controlFrame) | |
| 479 self.controlFrame:Hide() | |
| 480 end | |
| 481 end | |
| 482 | |
| 483 function Bar:ShowMenu() | |
| 484 if not self.menuOpts then | |
| 485 self.menuOpts = { | |
| 486 type = "group", | |
| 487 args = { | |
| 488 --[[ | |
| 489 openConfig = { | |
| 490 type = "execute", | |
| 491 name = L["Configure..."], | |
| 492 desc = L["Open the configuration dialogue for this bar"], | |
| 493 func = function() CloseMenu(self.controlFrame); module:OpenConfig(self) end, | |
| 494 disabled = InCombatLockdown, | |
| 495 order = 1 | |
| 496 }, | |
| 497 --]] | |
| 498 delete = { | |
| 499 type = "execute", | |
| 500 name = L["Delete Bar"], | |
| 501 desc = L["Remove the bar from the current profile"], | |
| 502 func = function() ReAction:EraseBar(self) end, | |
| 503 order = 2 | |
| 504 }, | |
| 505 } | |
| 506 } | |
| 507 end | |
| 508 if self.modMenuOpts == nil then | |
| 509 self.modMenuOpts = { } | |
| 510 end | |
| 511 OpenMenu(self.controlFrame, self.menuOpts) | |
| 512 end | |
| 513 | |
| 514 | |
| 515 | |
| 130 ------ Export as a class-factory ------ | 516 ------ Export as a class-factory ------ |
| 131 ReAction.Bar = { | 517 ReAction.Bar = { |
| 132 prototype = Bar, | 518 prototype = Bar, |
| 133 | 519 |
| 134 IsInstance = function(self, x) | 520 IsInstance = function(self, x) |
