Mercurial > wow > reaction
comparison modules/ReAction_ConfigUI/ReAction_ConfigUI.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 | 11ddb9610770 |
comparison
equal
deleted
inserted
replaced
| 32:821b2b7edff1 | 33:c54c481ad0ed |
|---|---|
| 1 --[[ | 1 --[[ |
| 2 ReAction Configuration UI module | 2 ReAction Configuration UI module |
| 3 | 3 |
| 4 This modules creates and manages ReAction configuration | 4 Hooks into Blizzard Interface Options AddOns panel |
| 5 elements, including: | |
| 6 | |
| 7 - Interface Options panel | |
| 8 - bar dragging and resizing control overlays | |
| 9 - contextual menus | |
| 10 | |
| 11 Individual modules are responsible for populating these | |
| 12 configuration elements via ReAction:RegisterOptions(). The | |
| 13 valid values of 'context' are: | |
| 14 | |
| 15 - 'global' : added to the Global Settings tab | |
| 16 - 'module' : added to the Module Settings tab | |
| 17 - 'bar' : added to the Bar Settings tab | |
| 18 - 'barMenu' : shown on the bar contextual menu | |
| 19 | |
| 20 --]] | 5 --]] |
| 21 | 6 |
| 22 -- local imports | 7 -- local imports |
| 23 local ReAction = ReAction | 8 local ReAction = ReAction |
| 24 local L = ReAction.L | 9 local L = ReAction.L |
| 25 local _G = _G | |
| 26 local InCombatLockdown = InCombatLockdown | |
| 27 | |
| 28 local Dewdrop = AceLibrary("Dewdrop-2.0") | |
| 29 | 10 |
| 30 -- module declaration | 11 -- module declaration |
| 31 local moduleID = "ConfigUI" | 12 local moduleID = "ConfigUI" |
| 32 local module = ReAction:NewModule( moduleID, | 13 local module = ReAction:NewModule( moduleID ) |
| 33 "AceEvent-3.0" | |
| 34 ) | |
| 35 | 14 |
| 15 -- options table basic layer | |
| 36 module.configOptions = { | 16 module.configOptions = { |
| 37 type = "group", | 17 type = "group", |
| 38 childGroups = "tab", | 18 childGroups = "tab", |
| 39 args = { | 19 args = { |
| 40 desc = { | 20 desc = { |
| 92 self.db = ReAction.db:RegisterNamespace( moduleID, | 72 self.db = ReAction.db:RegisterNamespace( moduleID, |
| 93 { | 73 { |
| 94 profile = { } | 74 profile = { } |
| 95 } | 75 } |
| 96 ) | 76 ) |
| 97 self:InitializeOptions() | |
| 98 LibStub("AceConfig-3.0"):RegisterOptionsTable("ReAction",self.configOptions) | |
| 99 LibStub("AceConfigDialog-3.0"):AddToBlizOptions("ReAction", "ReAction") | |
| 100 self:RegisterEvent("PLAYER_REGEN_DISABLED") | |
| 101 end | |
| 102 | 77 |
| 103 function module:InitializeOptions() | |
| 104 for _, m in pairs(ReAction:GetOptions("global")) do | 78 for _, m in pairs(ReAction:GetOptions("global")) do |
| 105 for k, v in pairs(m) do | 79 for k, v in pairs(m) do |
| 106 self.configOptions.args.global.args[k] = v | 80 self.configOptions.args.global.args[k] = v |
| 107 end | 81 end |
| 108 end | 82 end |
| 83 | |
| 84 self.configOptions.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(ReAction.db) | |
| 85 self.configOptions.args.profile.order = -2 | |
| 86 | |
| 87 LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable("ReAction",self.configOptions) | |
| 88 LibStub("AceConfigDialog-3.0"):AddToBlizOptions("ReAction", "ReAction") | |
| 109 ReAction.RegisterCallback(self,"OnOptionsRegistered") | 89 ReAction.RegisterCallback(self,"OnOptionsRegistered") |
| 90 ReAction.RegisterCallback(self,"OnOptionsRefreshed") | |
| 110 end | 91 end |
| 111 | 92 |
| 112 function module:OnOptionsRegistered(evt, context, module, opts) | 93 function module:OnOptionsRegistered(evt, context, module, opts) |
| 113 if context == "global" then | 94 if context == "global" then |
| 114 for k, v in pairs(opts) do | 95 for k, v in pairs(opts) do |
| 123 elseif context == "barMenu" then | 104 elseif context == "barMenu" then |
| 124 | 105 |
| 125 end | 106 end |
| 126 end | 107 end |
| 127 | 108 |
| 128 function module:PLAYER_REGEN_DISABLED() | 109 function module:OnOptionsRefreshed(evt) |
| 129 if self.configMode == true then | 110 -- TODO: refresh options frame (just OpenConfig again?) |
| 130 UIErrorsFrame:AddMessage(L["ReAction config mode disabled during combat."]) | |
| 131 self:SetConfigMode(false) | |
| 132 end | |
| 133 end | |
| 134 | |
| 135 function module:SetConfigMode( mode ) | |
| 136 ReAction:CallMethodOnAllBars("ShowControls",mode) | |
| 137 ReAction:CallMethodOnAllModules("ApplyConfigMode",mode,ReAction.bars) | |
| 138 self.configMode = mode | |
| 139 end | |
| 140 | |
| 141 function module:ApplyConfigMode( mode, bars ) | |
| 142 if not(mode) then | |
| 143 -- close open dewdrop menu | |
| 144 local p = Dewdrop:GetOpenedParent() | |
| 145 if p then | |
| 146 for _, bar in pairs(bars) do | |
| 147 if bar then | |
| 148 if p == bar.controlFrame then | |
| 149 Dewdrop:Close() | |
| 150 end | |
| 151 end | |
| 152 end | |
| 153 end | |
| 154 end | |
| 155 end | |
| 156 | |
| 157 local function safecall(module, method, ...) | |
| 158 if module and type(module[method]) == "function" then | |
| 159 return module[method](method, ...) | |
| 160 end | |
| 161 end | 111 end |
| 162 | 112 |
| 163 function module:OpenConfig(bar) | 113 function module:OpenConfig(bar) |
| 164 Dewdrop:Close() | |
| 165 InterfaceOptionsFrame_OpenToFrame("ReAction") | 114 InterfaceOptionsFrame_OpenToFrame("ReAction") |
| 166 end | 115 if bar then |
| 167 | 116 -- TODO: select the correct bar pane |
| 168 function module:ApplyToBar(bar) | |
| 169 if self.configMode then | |
| 170 bar:ShowControls(self.configMode) | |
| 171 end | 117 end |
| 172 end | 118 end |
| 173 | |
| 174 function module:RemoveFromBar(bar) | |
| 175 if bar.controlFrame then | |
| 176 bar.controlFrame:SetParent(UIParent) | |
| 177 bar.controlFrame:ClearAllPoints() | |
| 178 bar.controlFrame:Hide() | |
| 179 bar.controlFrame = nil | |
| 180 end | |
| 181 end | |
| 182 | |
| 183 | |
| 184 | |
| 185 | |
| 186 | |
| 187 -- | |
| 188 -- Bar config overlay | |
| 189 -- | |
| 190 -- import some of these for small OnUpdate performance boost | |
| 191 local Bar = ReAction.Bar.prototype | |
| 192 local GetSize = Bar.GetSize | |
| 193 local GetButtonSize = Bar.GetButtonSize | |
| 194 local GetButtonGrid = Bar.GetButtonGrid | |
| 195 local SetSize = Bar.SetSize | |
| 196 local SetButtonSize = Bar.SetButtonSize | |
| 197 local SetButtonGrid = Bar.SetButtonGrid | |
| 198 local ApplyAnchor = Bar.ApplyAnchor | |
| 199 local floor = math.floor | |
| 200 local min = math.min | |
| 201 local format = string.format | |
| 202 local GameTooltip = GameTooltip | |
| 203 | |
| 204 local function StoreExtents(bar) | |
| 205 local f = bar.frame | |
| 206 local point, relativeTo, relativePoint, x, y = f:GetPoint(1) | |
| 207 relativeTo = relativeTo or f:GetParent() | |
| 208 local anchorTo | |
| 209 for name, b in pairs(ReAction.bars) do | |
| 210 if b then | |
| 211 if b:GetFrame() == relativeTo then | |
| 212 anchorTo = name | |
| 213 break | |
| 214 end | |
| 215 end | |
| 216 end | |
| 217 anchorTo = anchorTo or relativeTo:GetName() | |
| 218 local c = bar.config | |
| 219 c.anchor = point | |
| 220 c.anchorTo = anchorTo | |
| 221 c.relativePoint = relativePoint | |
| 222 c.x = x | |
| 223 c.y = y | |
| 224 c.width, c.height = f:GetWidth(), f:GetHeight() | |
| 225 end | |
| 226 | |
| 227 local function RecomputeButtonSize(bar) | |
| 228 local w, h = GetSize(bar) | |
| 229 local bw, bh = GetButtonSize(bar) | |
| 230 local r, c, s = GetButtonGrid(bar) | |
| 231 | |
| 232 local scaleW = (floor(w/c) - s) / bw | |
| 233 local scaleH = (floor(h/r) - s) / bh | |
| 234 local scale = min(scaleW, scaleH) | |
| 235 | |
| 236 SetButtonSize(bar, scale * bw, scale * bh, s) | |
| 237 end | |
| 238 | |
| 239 local function RecomputeButtonSpacing(bar) | |
| 240 local w, h = GetSize(bar) | |
| 241 local bw, bh = GetButtonSize(bar) | |
| 242 local r, c, s = GetButtonGrid(bar) | |
| 243 | |
| 244 SetButtonGrid(bar,r,c,min(floor(w/c) - bw, floor(h/r) - bh)) | |
| 245 end | |
| 246 | |
| 247 local function RecomputeGrid(bar) | |
| 248 local w, h = GetSize(bar) | |
| 249 local bw, bh = GetButtonSize(bar) | |
| 250 local r, c, s = GetButtonGrid(bar) | |
| 251 | |
| 252 SetButtonGrid(bar, floor(h/(bh+s)), floor(w/(bw+s)), s) | |
| 253 end | |
| 254 | |
| 255 local function ClampToButtons(bar) | |
| 256 local bw, bh = GetButtonSize(bar) | |
| 257 local r, c, s = GetButtonGrid(bar) | |
| 258 SetSize(bar, (bw+s)*c, (bh+s)*r ) | |
| 259 end | |
| 260 | |
| 261 local function HideGameTooltip() | |
| 262 GameTooltip:Hide() | |
| 263 end | |
| 264 | |
| 265 local function CreateControls(bar) | |
| 266 local f = bar.frame | |
| 267 | |
| 268 f:SetMovable(true) | |
| 269 f:SetResizable(true) | |
| 270 f:SetClampedToScreen(true) | |
| 271 | |
| 272 -- buttons on the bar should be direct children of the bar frame. | |
| 273 -- The control elements need to float on top of this, which we could | |
| 274 -- do with SetFrameLevel() or Raise(), but it's more reliable to do it | |
| 275 -- via frame nesting, hence good old foo's appearance here. | |
| 276 local foo = CreateFrame("Frame",nil,f) | |
| 277 foo:SetAllPoints() | |
| 278 | |
| 279 local control = CreateFrame("Button", nil, foo) | |
| 280 control:EnableMouse(true) | |
| 281 control:SetToplevel(true) | |
| 282 control:SetPoint("TOPLEFT", -4, 4) | |
| 283 control:SetPoint("BOTTOMRIGHT", 4, -4) | |
| 284 control:SetBackdrop({ | |
| 285 edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", | |
| 286 tile = true, | |
| 287 tileSize = 16, | |
| 288 edgeSize = 16, | |
| 289 insets = { left = 0, right = 0, top = 0, bottom = 0 }, | |
| 290 }) | |
| 291 | |
| 292 -- textures | |
| 293 local bgTex = control:CreateTexture(nil,"BACKGROUND") | |
| 294 bgTex:SetTexture(0.7,0.7,1.0,0.2) | |
| 295 bgTex:SetPoint("TOPLEFT",4,-4) | |
| 296 bgTex:SetPoint("BOTTOMRIGHT",-4,4) | |
| 297 local hTex = control:CreateTexture(nil,"HIGHLIGHT") | |
| 298 hTex:SetTexture(0.7,0.7,1.0,0.2) | |
| 299 hTex:SetPoint("TOPLEFT",4,-4) | |
| 300 hTex:SetPoint("BOTTOMRIGHT",-4,4) | |
| 301 hTex:SetBlendMode("ADD") | |
| 302 | |
| 303 -- label | |
| 304 local label = control:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") | |
| 305 label:SetAllPoints() | |
| 306 label:SetJustifyH("CENTER") | |
| 307 label:SetShadowColor(0,0,0,1) | |
| 308 label:SetShadowOffset(2,-2) | |
| 309 label:SetTextColor(1,1,1,1) | |
| 310 label:SetText(bar:GetName()) | |
| 311 label:Show() | |
| 312 bar.controlLabelString = label -- so that bar:SetName() can update it | |
| 313 | |
| 314 local StopResize = function() | |
| 315 f:StopMovingOrSizing() | |
| 316 f.isMoving = false | |
| 317 f:SetScript("OnUpdate",nil) | |
| 318 StoreExtents(bar) | |
| 319 ClampToButtons(bar) | |
| 320 ApplyAnchor(bar) | |
| 321 end | |
| 322 | |
| 323 -- edge drag handles | |
| 324 for _, point in pairs({"LEFT","TOP","RIGHT","BOTTOM"}) do | |
| 325 local edge = CreateFrame("Frame",nil,control) | |
| 326 edge:EnableMouse(true) | |
| 327 edge:SetWidth(8) | |
| 328 edge:SetHeight(8) | |
| 329 if point == "TOP" or point == "BOTTOM" then | |
| 330 edge:SetPoint(point.."LEFT") | |
| 331 edge:SetPoint(point.."RIGHT") | |
| 332 else | |
| 333 edge:SetPoint("TOP"..point) | |
| 334 edge:SetPoint("BOTTOM"..point) | |
| 335 end | |
| 336 local tex = edge:CreateTexture(nil,"HIGHLIGHT") | |
| 337 tex:SetTexture(1.0,0.82,0,0.7) | |
| 338 tex:SetBlendMode("ADD") | |
| 339 tex:SetAllPoints() | |
| 340 edge:RegisterForDrag("LeftButton") | |
| 341 edge:SetScript("OnMouseDown", | |
| 342 function() | |
| 343 local bw, bh = GetButtonSize(bar) | |
| 344 local r, c, s = GetButtonGrid(bar) | |
| 345 f:SetMinResize( bw+s+1, bh+s+1 ) | |
| 346 f:StartSizing(point) | |
| 347 f:SetScript("OnUpdate", | |
| 348 function() | |
| 349 RecomputeGrid(bar) | |
| 350 bar:RefreshLayout() | |
| 351 end | |
| 352 ) | |
| 353 end | |
| 354 ) | |
| 355 edge:SetScript("OnMouseUp", StopResize) | |
| 356 edge:SetScript("OnEnter", | |
| 357 function() | |
| 358 GameTooltip:SetOwner(f, "ANCHOR_"..point) | |
| 359 GameTooltip:AddLine(L["Drag to add/remove buttons"]) | |
| 360 GameTooltip:Show() | |
| 361 end | |
| 362 ) | |
| 363 edge:SetScript("OnLeave", HideGameTooltip) | |
| 364 edge:Show() | |
| 365 end | |
| 366 | |
| 367 -- corner drag handles, again nested in an anonymous frame so that they are on top | |
| 368 local foo2 = CreateFrame("Frame",nil,control) | |
| 369 foo2:SetAllPoints(true) | |
| 370 for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do | |
| 371 local corner = CreateFrame("Frame",nil,foo2) | |
| 372 corner:EnableMouse(true) | |
| 373 corner:SetWidth(12) | |
| 374 corner:SetHeight(12) | |
| 375 corner:SetPoint(point) | |
| 376 local tex = corner:CreateTexture(nil,"HIGHLIGHT") | |
| 377 tex:SetTexture(1.0,0.82,0,0.7) | |
| 378 tex:SetBlendMode("ADD") | |
| 379 tex:SetAllPoints() | |
| 380 corner:RegisterForDrag("LeftButton","RightButton") | |
| 381 local updateTooltip = function() | |
| 382 local size, size2 = bar:GetButtonSize() | |
| 383 local rows, cols, spacing = bar:GetButtonGrid() | |
| 384 size = (size == size2) and tostring(size) or format("%dx%d",size,size2) | |
| 385 GameTooltipTextRight4:SetText(size) | |
| 386 GameTooltipTextRight5:SetText(tostring(spacing)) | |
| 387 end | |
| 388 corner:SetScript("OnMouseDown", | |
| 389 function(_,btn) | |
| 390 local bw, bh = GetButtonSize(bar) | |
| 391 local r, c, s = GetButtonGrid(bar) | |
| 392 if btn == "LeftButton" then -- button resize | |
| 393 f:SetMinResize( (s+12)*c+1, (s+12)*r+1 ) | |
| 394 f:SetScript("OnUpdate", | |
| 395 function() | |
| 396 RecomputeButtonSize(bar) | |
| 397 bar:RefreshLayout() | |
| 398 updateTooltip() | |
| 399 end | |
| 400 ) | |
| 401 elseif btn == "RightButton" then -- spacing resize | |
| 402 f:SetMinResize( bw*c, bh*r ) | |
| 403 f:SetScript("OnUpdate", | |
| 404 function() | |
| 405 RecomputeButtonSpacing(bar) | |
| 406 bar:RefreshLayout() | |
| 407 updateTooltip() | |
| 408 end | |
| 409 ) | |
| 410 end | |
| 411 f:StartSizing(point) | |
| 412 end | |
| 413 ) | |
| 414 corner:SetScript("OnMouseUp",StopResize) | |
| 415 corner:SetScript("OnEnter", | |
| 416 function() | |
| 417 GameTooltip:SetOwner(f, "ANCHOR_"..point) | |
| 418 GameTooltip:AddLine(L["Drag to resize buttons"]) | |
| 419 GameTooltip:AddLine(L["Right-click-drag"]) | |
| 420 GameTooltip:AddLine(L["to change spacing"]) | |
| 421 local size, size2 = bar:GetButtonSize() | |
| 422 local rows, cols, spacing = bar:GetButtonGrid() | |
| 423 size = (size == size2) and tostring(size) or format("%dx%d",size,size2) | |
| 424 GameTooltip:AddDoubleLine(L["Size:"], size) | |
| 425 GameTooltip:AddDoubleLine(L["Spacing:"], tostring(spacing)) | |
| 426 GameTooltip:Show() | |
| 427 end | |
| 428 ) | |
| 429 corner:SetScript("OnLeave", | |
| 430 function() | |
| 431 GameTooltip:Hide() | |
| 432 f:SetScript("OnUpdate",nil) | |
| 433 end | |
| 434 ) | |
| 435 | |
| 436 end | |
| 437 | |
| 438 control:RegisterForDrag("LeftButton") | |
| 439 control:RegisterForClicks("RightButtonDown") | |
| 440 | |
| 441 control:SetScript("OnDragStart", | |
| 442 function() | |
| 443 f:StartMoving() | |
| 444 f.isMoving = true | |
| 445 -- TODO: snap indicator update install | |
| 446 end | |
| 447 ) | |
| 448 | |
| 449 control:SetScript("OnDragStop", | |
| 450 function() | |
| 451 f:StopMovingOrSizing() | |
| 452 f.isMoving = false | |
| 453 f:SetScript("OnUpdate",nil) | |
| 454 -- TODO: snap frame here | |
| 455 StoreExtents(bar) | |
| 456 end | |
| 457 ) | |
| 458 | |
| 459 control:SetScript("OnEnter", | |
| 460 function() | |
| 461 -- add bar type and status information to name | |
| 462 local name = bar.name | |
| 463 for _, m in ReAction:IterateModules() do | |
| 464 local suffix = safecall(m,"GetBarNameModifier",bar) | |
| 465 if suffix then | |
| 466 name = ("%s %s"):format(name,suffix) | |
| 467 end | |
| 468 end | |
| 469 | |
| 470 GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT") | |
| 471 GameTooltip:AddLine(name) | |
| 472 GameTooltip:AddLine(L["Drag to move"]) | |
| 473 --GameTooltip:AddLine(L["Shift-drag for sticky mode"]) | |
| 474 GameTooltip:AddLine(L["Right-click for options"]) | |
| 475 GameTooltip:Show() | |
| 476 end | |
| 477 ) | |
| 478 | |
| 479 control:SetScript("OnLeave", HideGameTooltip) | |
| 480 | |
| 481 control:SetScript("OnClick", | |
| 482 function() | |
| 483 bar:ShowMenu() | |
| 484 end | |
| 485 ) | |
| 486 | |
| 487 return control | |
| 488 end | |
| 489 | |
| 490 function Bar:ShowControls(show) | |
| 491 if show then | |
| 492 if not self.controlFrame then | |
| 493 self.controlFrame = CreateControls(self) | |
| 494 end | |
| 495 self.controlFrame:Show() | |
| 496 elseif self.controlFrame then | |
| 497 self.controlFrame:Hide() | |
| 498 end | |
| 499 end | |
| 500 | |
| 501 function Bar:ShowMenu() | |
| 502 if not self.menuOpts then | |
| 503 self.menuOpts = { | |
| 504 type = "group", | |
| 505 args = { | |
| 506 openConfig = { | |
| 507 type = "execute", | |
| 508 name = L["Configure..."], | |
| 509 desc = L["Open the configuration dialogue for this bar"], | |
| 510 func = function() module:OpenConfig(self) end, | |
| 511 disabled = InCombatLockdown, | |
| 512 order = 1 | |
| 513 }, | |
| 514 delete = { | |
| 515 type = "execute", | |
| 516 name = L["Delete Bar"], | |
| 517 desc = L["Remove the bar from the current profile"], | |
| 518 func = function() ReAction:EraseBar(self) end, | |
| 519 order = 2 | |
| 520 }, | |
| 521 } | |
| 522 } | |
| 523 end | |
| 524 if self.modMenuOpts == nil then | |
| 525 self.modMenuOpts = { } | |
| 526 end | |
| 527 for _, m in ReAction:IterateModules() do | |
| 528 local opts = safecall(m,"GetBarMenuOptions",self,module) | |
| 529 if opts then | |
| 530 for k, v in pairs(opts) do | |
| 531 self.menuOpts.args[k] = v | |
| 532 end | |
| 533 end | |
| 534 end | |
| 535 Dewdrop:Open(self.controlFrame, "children", self.menuOpts, "cursorX", true, "cursorY", true) | |
| 536 end | |
| 537 | |
| 538 local Bar_SuperSetName = Bar.SetName | |
| 539 function Bar:SetName(name) | |
| 540 Bar_SuperSetName(self,name) | |
| 541 if self.controlLabelString then | |
| 542 self.controlLabelString:SetText(self.name) | |
| 543 end | |
| 544 end |
