annotate Editor.lua @ 308:08bd2dec1f01 stable tip

Merge 1.1 beta 13 to stable
author Flick
date Wed, 14 Nov 2012 20:32:03 -0800
parents 6fbb55e5c624
children
rev   line source
Flick@276 1 local _, ns = ...
Flick@276 2 local ReAction = ns.ReAction
flickerstreak@109 3 local L = ReAction.L
flickerstreak@109 4 local _G = _G
flickerstreak@185 5 local wipe = wipe
Flick@244 6 local format = string.format
Flick@244 7 local InCombatLockdown = InCombatLockdown
Flick@276 8 local tfetch = ns.tfetch
Flick@276 9 local tbuild = ns.tbuild
flickerstreak@185 10
flickerstreak@109 11 local AceConfigReg = LibStub("AceConfigRegistry-3.0")
flickerstreak@109 12 local AceConfigDialog = LibStub("AceConfigDialog-3.0")
flickerstreak@109 13
flickerstreak@109 14
flickerstreak@185 15 local pointTable = {
Flick@244 16 NONE = " ",
flickerstreak@185 17 CENTER = L["Center"],
flickerstreak@185 18 LEFT = L["Left"],
flickerstreak@185 19 RIGHT = L["Right"],
flickerstreak@185 20 TOP = L["Top"],
flickerstreak@185 21 BOTTOM = L["Bottom"],
flickerstreak@185 22 TOPLEFT = L["Top Left"],
flickerstreak@185 23 TOPRIGHT = L["Top Right"],
flickerstreak@185 24 BOTTOMLEFT = L["Bottom Left"],
flickerstreak@185 25 BOTTOMRIGHT = L["Bottom Right"],
flickerstreak@185 26 }
flickerstreak@109 27
Flick@237 28 local Editor = {
Flick@237 29 buttonHandlers = { }
Flick@237 30 }
flickerstreak@109 31
flickerstreak@185 32 function Editor:New()
flickerstreak@185 33 -- create new self
flickerstreak@185 34 self = setmetatable( { }, { __index = self } )
flickerstreak@109 35
flickerstreak@185 36 self.barOptMap = setmetatable({},{__mode="v"})
flickerstreak@185 37 self.tmp = { }
flickerstreak@185 38 self.configID = "ReAction-Editor"
flickerstreak@109 39
flickerstreak@185 40 self.gui = LibStub("AceGUI-3.0"):Create("Frame")
flickerstreak@185 41
flickerstreak@185 42 local frame = self.gui.frame
flickerstreak@109 43 frame:SetClampedToScreen(true)
flickerstreak@109 44 frame:Hide()
flickerstreak@185 45
flickerstreak@195 46 self.title = ("%s - %s"):format(L["ReAction"],L["Bar Editor"])
flickerstreak@195 47 self.gui:SetTitle(self.title)
flickerstreak@195 48
flickerstreak@185 49 self.options = {
flickerstreak@109 50 type = "group",
flickerstreak@195 51 name = self.title,
flickerstreak@185 52 handler = self,
flickerstreak@185 53 childGroups = "select",
flickerstreak@109 54 args = {
flickerstreak@109 55 launchConfig = {
flickerstreak@109 56 type = "execute",
flickerstreak@109 57 name = L["Global Config"],
flickerstreak@109 58 desc = L["Opens ReAction global configuration settings panel"],
Flick@250 59 func = function()
Flick@250 60 -- AceConfigDialog calls :Open() after every selection, making it
Flick@250 61 -- generally not possible to cleanly close from a menu item.
Flick@250 62 -- If you don't use a custom frame, you can use ACD:Close(), but since
Flick@250 63 -- we're using a custom frame, we have to do the work of closing later in an
Flick@250 64 -- OnUpdate script.
Flick@250 65 ReAction:ShowOptions();
Flick@250 66 frame:SetScript("OnUpdate",
Flick@250 67 function()
Flick@250 68 self:Close()
Flick@250 69 frame:SetScript("OnUpdate",nil)
Flick@250 70 end)
Flick@250 71 end,
flickerstreak@185 72 order = 1
flickerstreak@109 73 },
flickerstreak@185 74 desc = {
flickerstreak@185 75 type = "description",
flickerstreak@185 76 name = L["Use the mouse to arrange and resize the bars on screen. Tooltips on bars indicate additional functionality."],
flickerstreak@195 77 order = 2,
flickerstreak@195 78 },
flickerstreak@195 79 hdr = {
flickerstreak@195 80 type = "header",
flickerstreak@195 81 name = L["Select Bar"],
flickerstreak@194 82 order = 3,
flickerstreak@185 83 },
flickerstreak@185 84 _new = {
flickerstreak@109 85 type = "group",
flickerstreak@109 86 name = L["New Bar..."],
flickerstreak@194 87 order = 4,
flickerstreak@109 88 args = {
flickerstreak@109 89 desc = {
flickerstreak@109 90 type = "description",
flickerstreak@109 91 name = L["Choose a name, type, and initial grid for your new action bar:"],
flickerstreak@109 92 order = 1,
flickerstreak@109 93 },
flickerstreak@109 94 name = {
flickerstreak@109 95 type = "input",
flickerstreak@109 96 name = L["Bar Name"],
flickerstreak@109 97 desc = L["Enter a name for your new action bar"],
flickerstreak@185 98 get = function() return self.tmp.barName or "" end,
flickerstreak@185 99 set = function(info, val) self.tmp.barName = val end,
flickerstreak@109 100 order = 2,
flickerstreak@109 101 },
flickerstreak@109 102 type = {
flickerstreak@109 103 type = "select",
flickerstreak@109 104 name = L["Button Type"],
flickerstreak@185 105 get = function() return self.tmp.barType or ReAction:GetDefaultBarType() or "" end,
flickerstreak@109 106 set = function(info, val)
flickerstreak@218 107 local c = ReAction:GetDefaultBarConfig(val)
flickerstreak@185 108 self.tmp.barType = val
flickerstreak@218 109 self.tmp.barSize = c.btnWidth or self.tmp.barSize
flickerstreak@218 110 self.tmp.barRows = c.btnRows or self.tmp.barRows
flickerstreak@218 111 self.tmp.barCols = c.btnColumns or self.tmp.barCols
flickerstreak@218 112 self.tmp.barSpacing = c.spacing or self.tmp.barSpacing
flickerstreak@109 113 end,
flickerstreak@109 114 values = "GetBarTypes",
flickerstreak@109 115 order = 3,
flickerstreak@109 116 },
flickerstreak@185 117 go = {
flickerstreak@185 118 type = "execute",
flickerstreak@185 119 name = L["Create Bar"],
flickerstreak@185 120 func = "CreateBar",
flickerstreak@185 121 order = 4,
flickerstreak@185 122 },
flickerstreak@109 123 grid = {
flickerstreak@109 124 type = "group",
flickerstreak@109 125 name = L["Button Grid"],
flickerstreak@109 126 inline = true,
flickerstreak@185 127 order = 5,
flickerstreak@109 128 args = {
flickerstreak@109 129 rows = {
flickerstreak@109 130 type = "range",
flickerstreak@109 131 name = L["Rows"],
flickerstreak@185 132 get = function() return self.tmp.barRows or 1 end,
flickerstreak@185 133 set = function(info, val) self.tmp.barRows = val end,
Flick@269 134 width = "double",
flickerstreak@109 135 min = 1,
flickerstreak@109 136 max = 32,
flickerstreak@109 137 step = 1,
flickerstreak@109 138 order = 2,
flickerstreak@109 139 },
flickerstreak@109 140 cols = {
flickerstreak@109 141 type = "range",
flickerstreak@109 142 name = L["Columns"],
flickerstreak@185 143 get = function() return self.tmp.barCols or 12 end,
flickerstreak@185 144 set = function(info, val) self.tmp.barCols = val end,
Flick@269 145 width = "double",
flickerstreak@109 146 min = 1,
flickerstreak@109 147 max = 32,
flickerstreak@109 148 step = 1,
flickerstreak@109 149 order = 3,
flickerstreak@109 150 },
flickerstreak@109 151 sz = {
flickerstreak@109 152 type = "range",
flickerstreak@109 153 name = L["Size"],
flickerstreak@185 154 get = function() return self.tmp.barSize or 36 end,
flickerstreak@185 155 set = function(info, val) self.tmp.barSize = val end,
Flick@269 156 width = "double",
flickerstreak@109 157 min = 10,
flickerstreak@109 158 max = 72,
flickerstreak@109 159 step = 1,
flickerstreak@109 160 order = 4,
flickerstreak@109 161 },
flickerstreak@109 162 spacing = {
flickerstreak@109 163 type = "range",
flickerstreak@109 164 name = L["Spacing"],
flickerstreak@185 165 get = function() return self.tmp.barSpacing or 3 end,
flickerstreak@185 166 set = function(info, val) self.tmp.barSpacing = val end,
Flick@269 167 width = "double",
flickerstreak@109 168 min = 0,
flickerstreak@109 169 max = 24,
flickerstreak@109 170 step = 1,
flickerstreak@109 171 order = 5,
flickerstreak@109 172 }
flickerstreak@195 173 }
flickerstreak@195 174 }
flickerstreak@109 175 }
flickerstreak@109 176 }
flickerstreak@195 177 }
flickerstreak@109 178 }
flickerstreak@109 179
flickerstreak@185 180 self.gui:SetCallback("OnClose",
flickerstreak@185 181 function()
flickerstreak@185 182 ReAction:SetConfigMode(false)
flickerstreak@185 183 end )
flickerstreak@185 184
flickerstreak@185 185 AceConfigReg:RegisterOptionsTable(self.configID, self.options)
flickerstreak@185 186 AceConfigDialog:SetDefaultSize(self.configID, 700, 540)
flickerstreak@185 187
flickerstreak@185 188 ReAction.RegisterCallback(self,"OnCreateBar")
flickerstreak@185 189 ReAction.RegisterCallback(self,"OnDestroyBar")
flickerstreak@185 190 ReAction.RegisterCallback(self,"OnRenameBar")
flickerstreak@185 191
flickerstreak@216 192 self:RefreshBarOptions()
flickerstreak@109 193
flickerstreak@185 194 return self
flickerstreak@109 195 end
flickerstreak@109 196
flickerstreak@109 197
flickerstreak@185 198 function Editor:Open(bar, ...)
flickerstreak@185 199 if bar then
flickerstreak@185 200 AceConfigDialog:SelectGroup(self.configID, self.barOptMap[bar:GetName()], ...)
flickerstreak@185 201 end
flickerstreak@185 202 AceConfigDialog:Open(self.configID,self.gui)
flickerstreak@185 203 self.gui:SetTitle(self.title)
flickerstreak@185 204 end
flickerstreak@185 205
flickerstreak@185 206 function Editor:Close()
flickerstreak@185 207 if self.gui then
flickerstreak@185 208 self.gui:ReleaseChildren()
flickerstreak@185 209 self.gui:Hide()
flickerstreak@109 210 end
flickerstreak@109 211 end
flickerstreak@109 212
flickerstreak@185 213 function Editor:Refresh()
flickerstreak@185 214 AceConfigReg:NotifyChange(self.configID)
flickerstreak@185 215 end
flickerstreak@185 216
flickerstreak@216 217 function Editor:UpdateBarOptions(bar)
flickerstreak@185 218 local name = bar:GetName()
flickerstreak@216 219 local key = self.barOptMap[name]
flickerstreak@185 220 local args = self.options.args
flickerstreak@216 221
flickerstreak@216 222 if not key then
flickerstreak@216 223 -- AceConfig doesn't allow spaces, etc, in arg key names, and they must be
flickerstreak@216 224 -- unique strings. So generate a unique key (it can be whatever) for the bar
flickerstreak@216 225 local i = 1
flickerstreak@216 226 repeat
flickerstreak@216 227 key = ("bar%s"):format(i)
flickerstreak@216 228 i = i+1
flickerstreak@216 229 until args[key] == nil
flickerstreak@216 230 self.barOptMap[name] = key
flickerstreak@216 231
flickerstreak@216 232 args[key] = {
flickerstreak@216 233 type = "group",
flickerstreak@216 234 name = name,
flickerstreak@216 235 childGroups = "tab",
flickerstreak@216 236 order = i+100,
flickerstreak@216 237 args = {
flickerstreak@216 238 general = {
flickerstreak@216 239 type = "group",
flickerstreak@216 240 name = L["General"],
flickerstreak@216 241 order = 1,
flickerstreak@216 242 args = {
flickerstreak@216 243 name = {
flickerstreak@216 244 type = "input",
flickerstreak@216 245 name = L["Rename Bar"],
flickerstreak@216 246 get = function() return bar:GetName() end,
flickerstreak@216 247 set = function(info, value) return ReAction:RenameBar(bar, value) end,
flickerstreak@216 248 order = 1,
flickerstreak@216 249 },
flickerstreak@216 250 delete = {
flickerstreak@216 251 type = "execute",
flickerstreak@216 252 name = L["Delete Bar"],
flickerstreak@216 253 desc = function() return bar:GetName() end,
flickerstreak@216 254 confirm = true,
flickerstreak@216 255 func = function() ReAction:EraseBar(bar) end,
flickerstreak@216 256 order = 2
flickerstreak@216 257 },
Flick@269 258 optionsHdr = {
Flick@269 259 type = "header",
Flick@269 260 name = "",
Flick@269 261 order = 3,
Flick@269 262 },
Flick@259 263 clickDown = {
Flick@259 264 type = "toggle",
Flick@259 265 name = L["Activate on Down"],
Flick@259 266 desc = L["Activate the button when the key or mouse button is pressed down instead of when it is released"],
Flick@269 267 order = 4,
Flick@269 268 width = "full",
Flick@261 269 set = function(info, value) bar:GetConfig().clickDown = value; ReAction:RebuildAll() end,
Flick@259 270 get = function() return bar:GetConfig().clickDown end,
Flick@259 271 },
Flick@269 272 alpha = {
Flick@269 273 type = "range",
Flick@269 274 name = L["Transparency"],
Flick@269 275 get = function() return bar:GetAlpha() end,
Flick@269 276 set = function(info, val) bar:SetAlpha(val) end,
Flick@269 277 min = 0,
Flick@269 278 max = 1,
Flick@269 279 isPercent = true,
Flick@269 280 step = 0.01,
Flick@269 281 bigStep = 0.05,
Flick@269 282 order = 5,
Flick@269 283 },
Flick@283 284 grid = {
Flick@283 285 type = "group",
Flick@283 286 name = L["Button Grid"],
Flick@283 287 inline = true,
Flick@283 288 order = 6,
Flick@283 289 args = {
Flick@283 290 rows = {
Flick@283 291 type = "range",
Flick@283 292 name = L["Rows"],
Flick@283 293 get = function() return select(1,bar:GetButtonGrid()) end,
Flick@283 294 set = function(info, val) bar:SetButtonGrid(val) end,
Flick@283 295 width = "double",
Flick@283 296 min = 1,
Flick@283 297 max = 32,
Flick@283 298 step = 1,
Flick@283 299 order = 2,
Flick@283 300 },
Flick@283 301 cols = {
Flick@283 302 type = "range",
Flick@283 303 name = L["Columns"],
Flick@283 304 get = function() return select(2,bar:GetButtonGrid()) end,
Flick@283 305 set = function(info, val) bar:SetButtonGrid(nil,val) end,
Flick@283 306 width = "double",
Flick@283 307 min = 1,
Flick@283 308 max = 32,
Flick@283 309 step = 1,
Flick@283 310 order = 3,
Flick@283 311 },
Flick@283 312 sz = {
Flick@283 313 type = "range",
Flick@283 314 name = L["Size"],
Flick@283 315 get = function() return select(1,bar:GetButtonSize()) end,
Flick@283 316 set = function(info, val) bar:SetButtonSize(val,val) end,
Flick@283 317 width = "double",
Flick@283 318 min = 10,
Flick@283 319 max = 72,
Flick@283 320 step = 1,
Flick@283 321 order = 4,
Flick@283 322 },
Flick@283 323 spacing = {
Flick@283 324 type = "range",
Flick@283 325 name = L["Spacing"],
Flick@283 326 get = function() return select(3,bar:GetButtonGrid()) end,
Flick@283 327 set = function(info, val) bar:SetButtonGrid(nil,nil,val) end,
Flick@283 328 width = "double",
Flick@283 329 min = 0,
Flick@283 330 max = 24,
Flick@283 331 step = 1,
Flick@283 332 order = 5,
Flick@283 333 }
Flick@283 334 }
Flick@283 335 },
flickerstreak@216 336 anchor = {
flickerstreak@216 337 type = "group",
flickerstreak@216 338 name = L["Anchor"],
flickerstreak@216 339 inline = true,
Flick@283 340 order = 7,
flickerstreak@216 341 args = {
flickerstreak@216 342 frame = {
flickerstreak@216 343 type = "input",
flickerstreak@216 344 name = L["Frame"],
flickerstreak@216 345 desc = L["The frame that the bar is anchored to"],
flickerstreak@216 346 get = function() local _, f = bar:GetAnchor(); return f end,
flickerstreak@216 347 set = function(info, val) bar:SetAnchor(nil,val) end,
flickerstreak@216 348 validate = function(info, name)
flickerstreak@216 349 if name then
flickerstreak@216 350 local f = ReAction:GetBar(name)
flickerstreak@216 351 if f then
flickerstreak@216 352 return true
flickerstreak@216 353 else
flickerstreak@216 354 f = _G[name]
flickerstreak@216 355 if f and type(f) == "table" and f.IsObjectType and f:IsObjectType("Frame") then
flickerstreak@216 356 local _, explicit = f:IsProtected()
flickerstreak@216 357 return explicit
flickerstreak@216 358 end
flickerstreak@185 359 end
flickerstreak@185 360 end
flickerstreak@216 361 return false
flickerstreak@216 362 end,
flickerstreak@216 363 width = "double",
flickerstreak@216 364 order = 1
flickerstreak@216 365 },
flickerstreak@216 366 point = {
flickerstreak@216 367 type = "select",
flickerstreak@216 368 name = L["Point"],
flickerstreak@216 369 desc = L["Anchor point on the bar frame"],
flickerstreak@216 370 style = "dropdown",
flickerstreak@216 371 get = function() return bar:GetAnchor() end,
flickerstreak@216 372 set = function(info, val) bar:SetAnchor(val) end,
flickerstreak@216 373 values = pointTable,
flickerstreak@216 374 order = 2,
flickerstreak@216 375 },
flickerstreak@216 376 relativePoint = {
flickerstreak@216 377 type = "select",
flickerstreak@216 378 name = L["Relative Point"],
flickerstreak@216 379 desc = L["Anchor point on the target frame"],
flickerstreak@216 380 style = "dropdown",
flickerstreak@216 381 get = function() local p,f,r = bar:GetAnchor(); return r end,
flickerstreak@216 382 set = function(info, val) bar:SetAnchor(nil,nil,val) end,
flickerstreak@216 383 values = pointTable,
flickerstreak@216 384 order = 3,
flickerstreak@216 385 },
flickerstreak@216 386 x = {
flickerstreak@216 387 type = "input",
flickerstreak@216 388 pattern = "\-?%d+",
flickerstreak@216 389 name = L["X offset"],
flickerstreak@216 390 get = function() local p,f,r,x = bar:GetAnchor(); return ("%d"):format(x) end,
flickerstreak@216 391 set = function(info,val) bar:SetAnchor(nil,nil,nil,val) end,
flickerstreak@216 392 order = 4
flickerstreak@216 393 },
flickerstreak@216 394 y = {
flickerstreak@216 395 type = "input",
flickerstreak@216 396 pattern = "\-?%d+",
flickerstreak@216 397 name = L["Y offset"],
flickerstreak@216 398 get = function() local p,f,r,x,y = bar:GetAnchor(); return ("%d"):format(y) end,
flickerstreak@216 399 set = function(info,val) bar:SetAnchor(nil,nil,nil,nil,val) end,
flickerstreak@216 400 order = 5
flickerstreak@216 401 },
flickerstreak@185 402 },
flickerstreak@185 403 },
flickerstreak@185 404 },
flickerstreak@185 405 },
Flick@244 406 buttonOpts = self:CreateButtonOptions(bar),
Flick@244 407 stateOpts = self:CreateStateOptions(bar)
Flick@244 408 }
flickerstreak@185 409 }
flickerstreak@216 410 end
flickerstreak@216 411
flickerstreak@185 412 end
flickerstreak@185 413
Flick@237 414 function Editor:CreateButtonOptions(bar)
Flick@237 415 local buttonClass = bar:GetButtonClass()
Flick@237 416 local classID = buttonClass:GetButtonTypeID()
Flick@237 417 local handler = self.buttonHandlers[classID]
Flick@237 418
Flick@237 419 if handler then
Flick@237 420 local h = handler:New(bar)
Flick@237 421 return h:GetOptions()
Flick@237 422 end
Flick@237 423 end
Flick@237 424
flickerstreak@185 425 function Editor:RefreshBarOptions()
flickerstreak@219 426 for name, key in pairs(self.barOptMap) do
flickerstreak@216 427 if not ReAction:GetBar(name) then
flickerstreak@219 428 self.barOptMap[name] = nil
flickerstreak@219 429 self.options.args[key] = nil
flickerstreak@185 430 end
flickerstreak@185 431 end
flickerstreak@216 432 for name, bar in ReAction:IterateBars() do
flickerstreak@216 433 self:UpdateBarOptions(bar)
flickerstreak@216 434 end
flickerstreak@216 435 self:Refresh()
flickerstreak@185 436 end
flickerstreak@185 437
flickerstreak@185 438 function Editor:OnCreateBar(evt, bar)
flickerstreak@216 439 self:UpdateBarOptions(bar)
flickerstreak@216 440 self:Refresh()
flickerstreak@185 441 end
flickerstreak@185 442
flickerstreak@185 443 function Editor:OnDestroyBar(evt, bar, name)
flickerstreak@185 444 local key = self.barOptMap[name]
flickerstreak@185 445 if key then
flickerstreak@216 446 self.barOptMap[name] = nil
flickerstreak@185 447 self.options.args[key] = nil
flickerstreak@185 448 self:Refresh()
flickerstreak@185 449 end
flickerstreak@185 450 end
flickerstreak@185 451
flickerstreak@185 452 function Editor:OnRenameBar(evt, bar, oldname, newname)
flickerstreak@185 453 local key = self.barOptMap[oldname]
flickerstreak@185 454 if key then
flickerstreak@216 455 self.barOptMap[oldname], self.barOptMap[newname] = nil, key
flickerstreak@185 456 self.options.args[key].name = newname
flickerstreak@185 457 self:Refresh()
flickerstreak@185 458 end
flickerstreak@185 459 end
flickerstreak@185 460
flickerstreak@185 461 local _scratch = { }
flickerstreak@185 462 function Editor:GetBarTypes()
flickerstreak@185 463 wipe(_scratch)
flickerstreak@185 464 return ReAction:GetBarTypeOptions(_scratch)
flickerstreak@185 465 end
flickerstreak@185 466
flickerstreak@185 467 function Editor:CreateBar()
flickerstreak@185 468 if self.tmp.barName and self.tmp.barName ~= "" then
flickerstreak@185 469 local bar = ReAction:CreateBar(self.tmp.barName, self.tmp.barType or ReAction:GetDefaultBarType(), self.tmp.barRows, self.tmp.barCols, self.tmp.barSize, self.tmp.barSpacing)
flickerstreak@185 470 if bar then
flickerstreak@185 471 AceConfigDialog:SelectGroup(self.configID, self.barOptMap[self.tmp.barName])
flickerstreak@185 472 self.tmp.barName = nil
flickerstreak@185 473 end
flickerstreak@185 474 end
flickerstreak@185 475 end
flickerstreak@185 476
Flick@237 477 -------------------------------
Flick@237 478 ---- Action button handler ----
Flick@237 479 -------------------------------
Flick@237 480
Flick@237 481 do
Flick@237 482 local ActionHandler = {
Flick@237 483 buttonClass = ReAction.Button.Action,
Flick@237 484 options = {
Flick@237 485 pages = {
Flick@237 486 name = L["# Pages"],
Flick@237 487 desc = L["Use the Dynamic State tab to specify page transitions"],
Flick@269 488 order = 1,
Flick@237 489 type = "range",
Flick@237 490 min = 1,
Flick@237 491 max = 10,
Flick@237 492 step = 1,
Flick@237 493 get = "GetNumPages",
Flick@237 494 set = "SetNumPages",
Flick@237 495 },
Flick@237 496 mindcontrol = {
Flick@300 497 name = L["Override Button Support"],
Flick@300 498 desc = L["Override the first 12 buttons on this bar with abilities gained from certain game quests and events."],
Flick@269 499 order = 2,
Flick@237 500 type = "toggle",
Flick@300 501 set = "SetMindControl", -- called 'mind control' for legacy reasons
Flick@300 502 get = "GetMindControl", -- called 'mind control' for legacy reasons
Flick@237 503 },
Flick@237 504 vehicle = {
Flick@237 505 name = L["Vehicle Support"],
Flick@237 506 desc = L["When on a vehicle, map the first 6 buttons of this bar to the vehicle actions. The vehicle-exit button is mapped to the 7th button. Pitch controls are not supported."],
Flick@269 507 order = 3,
Flick@237 508 type = "toggle",
Flick@237 509 get = "GetVehicle",
Flick@237 510 set = "SetVehicle",
Flick@237 511 },
Flick@269 512 hideEmpty = {
Flick@269 513 name = L["Hide Empty Buttons"],
Flick@269 514 order = 4,
Flick@269 515 type = "toggle",
Flick@269 516 width = "full",
Flick@269 517 get = "GetHideEmpty",
Flick@269 518 set = "SetHideEmpty",
Flick@269 519 },
Flick@269 520 lockButtons = {
Flick@269 521 name = L["Lock Buttons"],
Flick@269 522 desc = L["Prevents picking up/dragging actions (use SHIFT to override this behavior)"],
Flick@269 523 order = 5,
Flick@269 524 width = "full",
Flick@269 525 type = "toggle",
Flick@269 526 get = "GetLockButtons",
Flick@269 527 set = "SetLockButtons",
Flick@269 528 },
Flick@269 529 lockOnlyCombat = {
Flick@269 530 name = L["Only in Combat"],
Flick@269 531 desc = L["Only lock the buttons when in combat"],
Flick@269 532 order = 6,
Flick@269 533 width = "full",
Flick@269 534 type = "toggle",
Flick@269 535 disabled = "LockButtonsCombatDisabled",
Flick@269 536 get = "GetLockButtonsCombat",
Flick@269 537 set = "SetLockButtonsCombat",
Flick@269 538 },
Flick@237 539 actions = {
Flick@237 540 name = L["Edit Action IDs"],
Flick@237 541 order = 7,
Flick@237 542 type = "group",
Flick@237 543 inline = true,
Flick@237 544 args = {
Flick@237 545 method = {
Flick@237 546 name = L["Assign"],
Flick@237 547 order = 1,
Flick@237 548 type = "select",
Flick@269 549 width = "full",
Flick@237 550 values = { [0] = L["Choose Method..."],
Flick@237 551 [1] = L["Individually"],
Flick@237 552 [2] = L["All at Once"], },
Flick@237 553 get = "GetActionEditMethod",
Flick@237 554 set = "SetActionEditMethod",
Flick@237 555 },
Flick@237 556 rowSelect = {
Flick@237 557 name = L["Row"],
Flick@237 558 desc = L["Rows are numbered top to bottom"],
Flick@237 559 order = 2,
Flick@237 560 type = "select",
Flick@237 561 width = "half",
Flick@237 562 hidden = "IsButtonSelectHidden",
Flick@237 563 values = "GetRowList",
Flick@237 564 get = "GetSelectedRow",
Flick@237 565 set = "SetSelectedRow",
Flick@237 566 },
Flick@237 567 colSelect = {
Flick@237 568 name = L["Col"],
Flick@237 569 desc = L["Columns are numbered left to right"],
Flick@237 570 order = 3,
Flick@237 571 type = "select",
Flick@237 572 width = "half",
Flick@237 573 hidden = "IsButtonSelectHidden",
Flick@237 574 values = "GetColumnList",
Flick@237 575 get = "GetSelectedColumn",
Flick@237 576 set = "SetSelectedColumn",
Flick@237 577 },
Flick@237 578 pageSelect = {
Flick@237 579 name = L["Page"],
Flick@237 580 order = 4,
Flick@237 581 type = "select",
Flick@237 582 width = "half",
Flick@237 583 hidden = "IsPageSelectHidden",
Flick@237 584 values = "GetPageList",
Flick@237 585 get = "GetSelectedPage",
Flick@237 586 set = "SetSelectedPage",
Flick@237 587 },
Flick@237 588 single = {
Flick@237 589 name = L["Action ID"],
Flick@237 590 usage = L["Specify ID 1-120"],
Flick@237 591 order = 5,
Flick@237 592 type = "input",
Flick@237 593 width = "half",
Flick@237 594 hidden = "IsButtonSelectHidden",
Flick@237 595 get = "GetActionID",
Flick@237 596 set = "SetActionID",
Flick@237 597 validate = "ValidateActionID",
Flick@237 598 },
Flick@237 599 multi = {
Flick@237 600 name = L["ID List"],
Flick@237 601 usage = L["Specify a comma-separated list of IDs for each button in the bar (in order). Separate multiple pages with semicolons (;)"],
Flick@237 602 order = 6,
Flick@237 603 type = "input",
Flick@237 604 multiline = true,
Flick@237 605 width = "double",
Flick@237 606 hidden = "IsMultiIDHidden",
Flick@237 607 get = "GetMultiID",
Flick@237 608 set = "SetMultiID",
Flick@237 609 validate = "ValidateMultiID",
Flick@237 610 },
Flick@237 611 },
Flick@237 612 },
Flick@237 613 }
Flick@237 614 }
Flick@237 615
Flick@237 616 Editor.buttonHandlers[ActionHandler.buttonClass:GetButtonTypeID()] = ActionHandler
Flick@237 617
Flick@237 618 local meta = { __index = ActionHandler }
Flick@237 619
Flick@237 620 function ActionHandler:New( bar )
Flick@237 621 return setmetatable(
Flick@237 622 {
Flick@237 623 bar = bar,
Flick@237 624 config = bar:GetConfig(),
Flick@237 625 },
Flick@237 626 meta)
Flick@237 627 end
Flick@237 628
Flick@237 629 function ActionHandler:Refresh()
Flick@237 630 self.buttonClass:SetupBar(self.bar)
Flick@237 631 end
Flick@237 632
Flick@237 633 function ActionHandler:UpdateButtonLock()
Flick@237 634 self.buttonClass:SetButtonLock(self.bar, self.config.lockButtons, self.config.lockButtonsCombat)
Flick@237 635 end
Flick@237 636
Flick@237 637 function ActionHandler:GetLastButton()
Flick@237 638 return self.bar:GetButton(self.bar:GetNumButtons())
Flick@237 639 end
Flick@237 640
Flick@237 641 -- options handlers
Flick@237 642 function ActionHandler:GetOptions()
Flick@237 643 return {
Flick@237 644 type = "group",
Flick@237 645 name = L["Action Buttons"],
Flick@237 646 handler = self,
Flick@237 647 order = 2,
Flick@237 648 args = self.options
Flick@237 649 }
Flick@237 650 end
Flick@237 651
Flick@237 652 function ActionHandler:SetHideEmpty(info, value)
Flick@237 653 if value ~= self.config.hideEmpty then
Flick@237 654 self.config.hideEmpty = value
Flick@237 655 for _, b in self.bar:IterateButtons() do
Flick@237 656 b:ShowGrid(not value)
Flick@237 657 end
Flick@237 658 end
Flick@237 659 end
Flick@237 660
Flick@237 661 function ActionHandler:GetHideEmpty()
Flick@237 662 return self.config.hideEmpty
Flick@237 663 end
Flick@237 664
Flick@237 665 function ActionHandler:GetLockButtons()
Flick@237 666 return self.config.lockButtons
Flick@237 667 end
Flick@237 668
Flick@237 669 function ActionHandler:SetLockButtons(info, value)
Flick@237 670 self.config.lockButtons = value
Flick@237 671 self:UpdateButtonLock()
Flick@237 672 end
Flick@237 673
Flick@237 674 function ActionHandler:GetLockButtonsCombat()
Flick@237 675 return self.config.lockButtonsCombat
Flick@237 676 end
Flick@237 677
Flick@237 678 function ActionHandler:SetLockButtonsCombat(info, value)
Flick@237 679 self.config.lockButtonsCombat = value
Flick@237 680 self:UpdateButtonLock()
Flick@237 681 end
Flick@237 682
Flick@237 683 function ActionHandler:LockButtonsCombatDisabled()
Flick@237 684 return not self.config.lockButtons
Flick@237 685 end
Flick@237 686
Flick@237 687 function ActionHandler:GetNumPages()
Flick@237 688 return self.config.nPages
Flick@237 689 end
Flick@237 690
Flick@237 691 function ActionHandler:SetNumPages(info, value)
Flick@237 692 self.config.nPages = value
Flick@237 693 self:Refresh()
Flick@237 694 end
Flick@237 695
Flick@237 696 function ActionHandler:GetMindControl()
Flick@237 697 return self.config.mindcontrol
Flick@237 698 end
Flick@237 699
Flick@237 700 function ActionHandler:SetMindControl(info, value)
Flick@237 701 self.config.mindcontrol = value
Flick@237 702 self:Refresh()
Flick@237 703 end
Flick@237 704
Flick@237 705 function ActionHandler:GetVehicle()
Flick@237 706 return self.config.vehicle
Flick@237 707 end
Flick@237 708
Flick@237 709 function ActionHandler:SetVehicle(info, value)
Flick@237 710 self.config.vehicle = value
Flick@237 711 self:Refresh()
Flick@237 712 end
Flick@237 713
Flick@237 714 function ActionHandler:GetActionEditMethod()
Flick@237 715 return self.editMethod or 0
Flick@237 716 end
Flick@237 717
Flick@237 718 function ActionHandler:SetActionEditMethod(info, value)
Flick@237 719 self.editMethod = value
Flick@237 720 end
Flick@237 721
Flick@237 722 function ActionHandler:IsButtonSelectHidden()
Flick@237 723 return self.editMethod ~= 1
Flick@237 724 end
Flick@237 725
Flick@237 726 function ActionHandler:GetRowList()
Flick@237 727 local r,c = self.bar:GetButtonGrid()
Flick@237 728 if self.rowList == nil or #self.rowList ~= r then
Flick@237 729 local list = { }
Flick@237 730 for i = 1, r do
Flick@237 731 table.insert(list,i)
Flick@237 732 end
Flick@237 733 self.rowList = list
Flick@237 734 end
Flick@237 735 return self.rowList
Flick@237 736 end
Flick@237 737
Flick@237 738 function ActionHandler:GetSelectedRow()
Flick@237 739 local r, c = self.bar:GetButtonGrid()
Flick@237 740 local row = self.selectedRow or 1
Flick@237 741 if row > r then
Flick@237 742 row = 1
Flick@237 743 end
Flick@237 744 self.selectedRow = row
Flick@237 745 return row
Flick@237 746 end
Flick@237 747
Flick@237 748 function ActionHandler:SetSelectedRow(info, value)
Flick@237 749 self.selectedRow = value
Flick@237 750 end
Flick@237 751
Flick@237 752 function ActionHandler:GetColumnList()
Flick@237 753 local r,c = self.bar:GetButtonGrid()
Flick@237 754 if self.columnList == nil or #self.columnList ~= c then
Flick@237 755 local list = { }
Flick@237 756 for i = 1, c do
Flick@237 757 table.insert(list,i)
Flick@237 758 end
Flick@237 759 self.columnList = list
Flick@237 760 end
Flick@237 761 return self.columnList
Flick@237 762 end
Flick@237 763
Flick@237 764 function ActionHandler:GetSelectedColumn()
Flick@237 765 local r, c = self.bar:GetButtonGrid()
Flick@237 766 local col = self.selectedColumn or 1
Flick@237 767 if col > c then
Flick@237 768 col = 1
Flick@237 769 end
Flick@237 770 self.selectedColumn = col
Flick@237 771 return col
Flick@237 772 end
Flick@237 773
Flick@237 774 function ActionHandler:SetSelectedColumn(info, value)
Flick@237 775 self.selectedColumn = value
Flick@237 776 end
Flick@237 777
Flick@237 778 function ActionHandler:IsPageSelectHidden()
Flick@237 779 return self.editMethod ~= 1 or (self.config.nPages or 1) < 2
Flick@237 780 end
Flick@237 781
Flick@237 782 function ActionHandler:GetPageList()
Flick@237 783 local n = self.config.nPages or 1
Flick@237 784 if self.pageList == nil or #self.pageList ~= n then
Flick@237 785 local p = { }
Flick@237 786 for i = 1, n do
Flick@237 787 table.insert(p,i)
Flick@237 788 end
Flick@237 789 self.pageList = p
Flick@237 790 end
Flick@237 791 return self.pageList
Flick@237 792 end
Flick@237 793
Flick@237 794 function ActionHandler:GetSelectedPage()
Flick@237 795 local p = self.selectedPage or 1
Flick@237 796 if p > (self.config.nPages or 1) then
Flick@237 797 p = 1
Flick@237 798 end
Flick@237 799 self.selectedPage = p
Flick@237 800 return p
Flick@237 801 end
Flick@237 802
Flick@237 803 function ActionHandler:SetSelectedPage(info, value)
Flick@237 804 self.selectedPage = value
Flick@237 805 end
Flick@237 806
Flick@237 807 function ActionHandler:GetActionID()
Flick@237 808 local row = self.selectedRow or 1
Flick@237 809 local col = self.selectedColumn or 1
Flick@237 810 local r, c = self.bar:GetButtonGrid()
Flick@237 811 local n = (row-1) * c + col
Flick@237 812 local btn = self.bar:GetButton(n)
Flick@237 813 if btn then
Flick@237 814 return tostring(btn:GetActionID(self.selectedPage or 1))
Flick@237 815 end
Flick@237 816 end
Flick@237 817
Flick@237 818 function ActionHandler:SetActionID(info, value)
Flick@237 819 local row = self.selectedRow or 1
Flick@237 820 local col = self.selectedColumn or 1
Flick@237 821 local r, c = self.bar:GetButtonGrid()
Flick@237 822 local n = (row-1) * c + col
Flick@237 823 local btn = self.bar:GetButton(n)
Flick@237 824 if btn then
Flick@237 825 btn:SetActionID(tonumber(value), self.selectedPage or 1)
Flick@237 826 end
Flick@237 827 end
Flick@237 828
Flick@237 829 function ActionHandler:ValidateActionID(info, value)
Flick@237 830 value = tonumber(value)
Flick@237 831 if value == nil or value < 1 or value > 120 then
Flick@237 832 return L["Specify ID 1-120"]
Flick@237 833 end
Flick@237 834 return true
Flick@237 835 end
Flick@237 836
Flick@237 837 function ActionHandler:IsMultiIDHidden()
Flick@237 838 return self.editMethod ~= 2
Flick@237 839 end
Flick@237 840
Flick@237 841 function ActionHandler:GetMultiID()
Flick@237 842 local p = { }
Flick@237 843 for i = 1, self.config.nPages or 1 do
Flick@237 844 local b = { }
Flick@237 845 for _, btn in self.bar:IterateButtons() do
Flick@237 846 table.insert(b, btn:GetActionID(i))
Flick@237 847 end
Flick@237 848 table.insert(p, table.concat(b,","))
Flick@237 849 end
Flick@237 850 return table.concat(p,";\n")
Flick@237 851 end
Flick@237 852
Flick@237 853
Flick@237 854 local function ParseMultiID(nBtns, nPages, s)
Flick@237 855 if s:match("[^%d%s,;]") then
Flick@237 856 return nil
Flick@237 857 end
Flick@237 858 local p = { }
Flick@237 859 for list in s:gmatch("[^;]+") do
Flick@237 860 local pattern = ("^%s?$"):format(("%s*(%d+)%s*,"):rep(nBtns))
Flick@237 861 local ids = { list:match(pattern) }
Flick@237 862 if #ids ~= nBtns then
Flick@237 863 return nil
Flick@237 864 end
Flick@237 865 table.insert(p,ids)
Flick@237 866 end
Flick@237 867 if #p ~= nPages then
Flick@237 868 return nil
Flick@237 869 end
Flick@237 870 return p
Flick@237 871 end
Flick@237 872
Flick@237 873 function ActionHandler:SetMultiID(info, value)
Flick@237 874 local p = ParseMultiID(self.bar:GetNumButtons(), self.config.nPages or 1, value)
Flick@237 875 for page, b in ipairs(p) do
Flick@237 876 for button, id in ipairs(b) do
Flick@237 877 self.bar:GetButton(button):SetActionID(id, page)
Flick@237 878 end
Flick@237 879 end
Flick@237 880 end
Flick@237 881
Flick@237 882 function ActionHandler:ValidateMultiID(info, value)
Flick@237 883 local bad = L["Invalid action ID list string"]
Flick@237 884 if value == nil or ParseMultiID(self.bar:GetNumButtons(), self.config.nPages or 1, value) == nil then
Flick@237 885 return bad
Flick@237 886 end
Flick@237 887 return true
Flick@237 888 end
Flick@237 889 end
Flick@237 890
Flick@237 891
Flick@237 892 ----------------------------------
Flick@237 893 ---- PetAction button handler ----
Flick@237 894 ----------------------------------
Flick@237 895
Flick@237 896 do
Flick@237 897 local PetHandler = {
Flick@237 898 buttonClass = ReAction.Button.PetAction,
Flick@237 899 }
Flick@237 900
Flick@237 901 Editor.buttonHandlers[PetHandler.buttonClass:GetButtonTypeID()] = PetHandler
Flick@237 902
Flick@237 903 local meta = { __index = PetHandler }
Flick@237 904
Flick@237 905 function PetHandler:New(bar)
Flick@237 906 return setmetatable(
Flick@237 907 {
Flick@237 908 bar = bar,
Flick@237 909 config = bar.config
Flick@237 910 }, meta)
Flick@237 911 end
Flick@237 912
Flick@237 913 function PetHandler:GetLockButtons()
Flick@237 914 return self.config.lockButtons
Flick@237 915 end
Flick@237 916
Flick@237 917 function PetHandler:SetLockButtons(info, value)
Flick@237 918 self.config.lockButtons = value
Flick@237 919 self.buttonClass:UpdateButtonLock(self.bar)
Flick@237 920 end
Flick@237 921
Flick@237 922 function PetHandler:GetLockButtonsCombat()
Flick@237 923 return self.config.lockButtonsCombat
Flick@237 924 end
Flick@237 925
Flick@237 926 function PetHandler:SetLockButtonsCombat(info, value)
Flick@237 927 self.config.lockButtonsCombat = value
Flick@237 928 self.buttonClass:UpdateButtonLock(self.bar)
Flick@237 929 end
Flick@237 930
Flick@237 931 function PetHandler:LockButtonsCombatDisabled()
Flick@237 932 return not self.config.lockButtons
Flick@237 933 end
Flick@237 934
Flick@237 935 function PetHandler:GetOptions()
Flick@237 936 return {
Flick@237 937 type = "group",
Flick@237 938 name = L["Pet Buttons"],
Flick@237 939 handler = self,
Flick@237 940 order = 2,
Flick@237 941 args = {
Flick@237 942 lockButtons = {
Flick@237 943 name = L["Lock Buttons"],
Flick@237 944 desc = L["Prevents picking up/dragging actions (use SHIFT to override this behavior)"],
Flick@237 945 order = 2,
Flick@237 946 type = "toggle",
Flick@237 947 get = "GetLockButtons",
Flick@237 948 set = "SetLockButtons",
Flick@237 949 },
Flick@237 950 lockOnlyCombat = {
Flick@237 951 name = L["Only in Combat"],
Flick@237 952 desc = L["Only lock the buttons when in combat"],
Flick@237 953 order = 3,
Flick@237 954 type = "toggle",
Flick@237 955 disabled = "LockButtonsCombatDisabled",
Flick@237 956 get = "GetLockButtonsCombat",
Flick@237 957 set = "SetLockButtonsCombat",
Flick@237 958 },
Flick@237 959 }
Flick@237 960 }
Flick@237 961 end
Flick@237 962 end
Flick@237 963
Flick@237 964
Flick@237 965 -------------------------------------
Flick@237 966 ---- Vehicle Exit button handler ----
Flick@237 967 -------------------------------------
Flick@237 968
Flick@237 969 do
Flick@237 970 local VExitHandler = {
Flick@237 971 buttonClass = ReAction.Button.VehicleExit,
Flick@237 972 }
Flick@237 973
Flick@237 974 Editor.buttonHandlers[VExitHandler.buttonClass:GetButtonTypeID()] = VExitHandler
Flick@237 975
Flick@237 976 local meta = { __index = VExitHandler }
Flick@237 977
Flick@237 978 function VExitHandler:New(bar)
Flick@237 979 return setmetatable(
Flick@237 980 {
Flick@237 981 bar = bar,
Flick@237 982 }, meta)
Flick@237 983 end
Flick@237 984
Flick@237 985 function VExitHandler:GetConfig()
Flick@237 986 return self.bar:GetConfig()
Flick@237 987 end
Flick@237 988
Flick@237 989 function VExitHandler:GetPassengerOnly()
Flick@237 990 return not self:GetConfig().withControls
Flick@237 991 end
Flick@237 992
Flick@237 993 function VExitHandler:SetPassengerOnly(info, value)
Flick@237 994 self:GetConfig().withControls = not value
Flick@237 995 self.buttonClass:UpdateRegistration(self.bar)
Flick@237 996 end
Flick@237 997
Flick@237 998
Flick@237 999 function VExitHandler:GetOptions()
Flick@237 1000 return {
Flick@237 1001 type = "group",
Flick@237 1002 name = L["Exit Vehicle"],
Flick@237 1003 handler = self,
Flick@237 1004 args = {
Flick@237 1005 passengerOnly = {
Flick@237 1006 name = L["Show only when passenger"],
Flick@237 1007 desc = L["Only show the button when riding as a passenger in a vehicle (no vehicle controls)"],
Flick@237 1008 order = 2,
Flick@237 1009 width = "double",
Flick@237 1010 type = "toggle",
Flick@237 1011 get = "GetPassengerOnly",
Flick@237 1012 set = "SetPassengerOnly",
Flick@237 1013 },
Flick@237 1014 }
Flick@237 1015 }
Flick@237 1016 end
Flick@237 1017 end
Flick@237 1018
flickerstreak@185 1019
Flick@244 1020 ------------------------------
Flick@244 1021 --- Dynamic State options ----
Flick@244 1022 ------------------------------
Flick@244 1023 do
Flick@244 1024 local ApplyStates = ReAction.Bar.ApplyStates
Flick@244 1025 local CleanupStates = ReAction.Bar.CleanupStates
Flick@244 1026 local SetProperty = ReAction.Bar.SetStateProperty
Flick@244 1027 local GetProperty = ReAction.Bar.GetStateProperty
Flick@244 1028
Flick@244 1029 -- pre-sorted by the order they should appear in
Flick@244 1030 local rules = {
Flick@244 1031 -- rule fields
Flick@244 1032 { "stance", { {battle = L["Battle Stance"]}, {defensive = L["Defensive Stance"]}, {berserker = L["Berserker Stance"]} } },
Flick@244 1033 { "form", { {caster = L["Caster Form"]}, {bear = L["Bear Form"]}, {cat = L["Cat Form"]}, {tree = L["Tree of Life"]}, {moonkin = L["Moonkin Form"]} } },
Flick@244 1034 { "stealth", { {stealth = L["Stealth"]}, {nostealth = L["No Stealth"]}, {shadowdance = L["Shadow Dance"]} } },
Flick@244 1035 { "shadow", { {shadowform = L["Shadowform"]}, {noshadowform = L["No Shadowform"]} } },
Flick@244 1036 { "demon", { {demon = L["Demon Form"]}, {nodemon = L["No Demon Form"]} } },
Flick@244 1037 { "pet", { {pet = L["With Pet"]}, {nopet = L["Without Pet"]} } },
Flick@244 1038 { "target", { {harm = L["Hostile Target"]}, {help = L["Friendly Target"]}, {notarget = L["No Target"]} } },
Flick@244 1039 { "focus", { {focusharm = L["Hostile Focus"]}, {focushelp = L["Friendly Focus"]}, {nofocus = L["No Focus"]} } },
Flick@295 1040 { "vehicle", { {vehicle = L["In a Vehicle"]} } },
Flick@300 1041 { "possess", { {possess = L["Ability Override"]} } },
Flick@301 1042 { "extrabar",{ {extrabar = L["Has Special Action"]} } },
Flick@244 1043 { "group", { {raid = L["Raid"]}, {party = L["Party"]}, {solo = L["Solo"]} } },
Flick@244 1044 { "combat", { {combat = L["In Combat"]}, {nocombat = L["Out of Combat"]} } },
Flick@244 1045 }
Flick@244 1046
Flick@244 1047 local ruleSelect = { }
Flick@244 1048 local ruleMap = { }
Flick@244 1049 local optionMap = setmetatable({},{__mode="k"})
Flick@244 1050
Flick@244 1051
Flick@244 1052 -- unpack rules table into ruleSelect and ruleMap
Flick@244 1053 for _, c in ipairs(rules) do
Flick@244 1054 local rule, fields = unpack(c)
Flick@244 1055 for _, field in ipairs(fields) do
Flick@244 1056 local key, label = next(field)
Flick@244 1057 table.insert(ruleSelect, label)
Flick@244 1058 table.insert(ruleMap, key)
Flick@244 1059 end
Flick@244 1060 end
Flick@244 1061
Flick@244 1062 local stateOptions = {
Flick@244 1063 ordering = {
Flick@244 1064 name = L["Info"],
Flick@244 1065 order = 1,
Flick@244 1066 type = "group",
Flick@244 1067 args = {
Flick@244 1068 rename = {
Flick@244 1069 name = L["Name"],
Flick@244 1070 order = 1,
Flick@244 1071 type = "input",
Flick@244 1072 get = "GetName",
Flick@244 1073 set = "SetStateName",
Flick@244 1074 pattern = "^%w*$",
Flick@244 1075 usage = L["State names must be alphanumeric without spaces"],
Flick@244 1076 },
Flick@269 1077 delete = {
Flick@269 1078 name = L["Delete this State"],
Flick@269 1079 order = 2,
Flick@269 1080 type = "execute",
Flick@269 1081 func = "DeleteState",
Flick@269 1082 confirm = true,
Flick@269 1083 },
Flick@244 1084 ordering = {
Flick@244 1085 name = L["Evaluation Order"],
Flick@256 1086 desc = L["State transitions are evaluated in the order listed: Move a state up or down to change the order"],
Flick@269 1087 order = 3,
Flick@244 1088 type = "group",
Flick@244 1089 inline = true,
Flick@244 1090 args = {
Flick@244 1091 up = {
Flick@244 1092 name = L["Up"],
Flick@244 1093 order = 1,
Flick@244 1094 type = "execute",
Flick@244 1095 width = "half",
Flick@244 1096 func = "MoveStateUp",
Flick@244 1097 },
Flick@244 1098 down = {
Flick@244 1099 name = L["Down"],
Flick@244 1100 order = 2,
Flick@244 1101 type = "execute",
Flick@244 1102 width = "half",
Flick@244 1103 func = "MoveStateDown",
Flick@244 1104 }
Flick@244 1105 }
Flick@244 1106 }
Flick@244 1107 }
Flick@244 1108 },
Flick@244 1109 properties = {
Flick@244 1110 name = L["Properties"],
Flick@244 1111 order = 2,
Flick@244 1112 type = "group",
Flick@244 1113 args = {
Flick@244 1114 desc = {
Flick@244 1115 name = L["Set the properties for the bar when in this state"],
Flick@244 1116 order = 1,
Flick@244 1117 type = "description"
Flick@244 1118 },
Flick@244 1119 page = {
Flick@244 1120 name = L["Show Page #"],
Flick@244 1121 order = 11,
Flick@244 1122 type = "select",
Flick@244 1123 width = "half",
Flick@244 1124 disabled = "IsPageDisabled",
Flick@244 1125 hidden = "IsPageHidden",
Flick@244 1126 values = "GetPageValues",
Flick@244 1127 set = "SetProp",
Flick@244 1128 get = "GetPage",
Flick@244 1129 },
Flick@244 1130 hide = {
Flick@244 1131 name = L["Hide Bar"],
Flick@244 1132 order = 90,
Flick@269 1133 width = "full",
Flick@244 1134 type = "toggle",
Flick@244 1135 set = "SetProp",
Flick@244 1136 get = "GetProp",
Flick@244 1137 },
Flick@244 1138 --[[ BROKEN
Flick@244 1139 keybindState = {
Flick@244 1140 name = L["Override Keybinds"],
Flick@244 1141 desc = L["Set this state to maintain its own set of keybinds which override the defaults when active"],
Flick@244 1142 order = 91,
Flick@244 1143 type = "toggle",
Flick@244 1144 set = "SetProp",
Flick@244 1145 get = "GetProp",
Flick@244 1146 }, ]]
Flick@269 1147
Flick@269 1148 anchorEnable = {
Flick@269 1149 name = L["Reposition"],
Flick@269 1150 order = 111,
Flick@269 1151 type = "toggle",
Flick@269 1152 set = "SetProp",
Flick@269 1153 get = "GetProp",
Flick@269 1154 },
Flick@269 1155 anchorGroup = {
Flick@244 1156 name = L["Position"],
Flick@269 1157 order = 112,
Flick@244 1158 type = "group",
Flick@244 1159 inline = true,
Flick@269 1160 disabled = "GetAnchorDisabled",
Flick@244 1161 args = {
Flick@244 1162 anchorFrame = {
Flick@244 1163 name = L["Anchor Frame"],
Flick@269 1164 order = 1,
Flick@244 1165 type = "select",
Flick@244 1166 values = "GetAnchorFrames",
Flick@244 1167 set = "SetAnchorFrame",
Flick@244 1168 get = "GetAnchorFrame",
Flick@244 1169 },
Flick@244 1170 anchorPoint = {
Flick@244 1171 name = L["Point"],
Flick@269 1172 order = 2,
Flick@269 1173 type = "select",
Flick@269 1174 values = pointTable,
Flick@269 1175 set = "SetAnchorPointProp",
Flick@269 1176 get = "GetAnchorPointProp",
Flick@269 1177 },
Flick@269 1178 anchorRelPoint = {
Flick@269 1179 name = L["Relative Point"],
Flick@244 1180 order = 3,
Flick@244 1181 type = "select",
Flick@244 1182 values = pointTable,
Flick@244 1183 set = "SetAnchorPointProp",
Flick@244 1184 get = "GetAnchorPointProp",
Flick@244 1185 },
Flick@244 1186 anchorX = {
Flick@244 1187 name = L["X Offset"],
Flick@269 1188 order = 4,
Flick@269 1189 type = "range",
Flick@269 1190 min = -100,
Flick@269 1191 max = 100,
Flick@269 1192 step = 1,
Flick@269 1193 set = "SetProp",
Flick@269 1194 get = "GetProp",
Flick@269 1195 },
Flick@269 1196 anchorY = {
Flick@269 1197 name = L["Y Offset"],
Flick@244 1198 order = 5,
Flick@244 1199 type = "range",
Flick@244 1200 min = -100,
Flick@244 1201 max = 100,
Flick@244 1202 step = 1,
Flick@244 1203 set = "SetProp",
Flick@244 1204 get = "GetProp",
Flick@244 1205 },
Flick@244 1206 },
Flick@244 1207 },
Flick@269 1208
Flick@269 1209 enableScale = {
Flick@269 1210 name = L["Set New Scale"],
Flick@269 1211 order = 121,
Flick@269 1212 type = "toggle",
Flick@269 1213 set = "SetProp",
Flick@269 1214 get = "GetProp",
Flick@269 1215 },
Flick@269 1216 scaleGroup = {
Flick@244 1217 name = L["Scale"],
Flick@269 1218 order = 122,
Flick@244 1219 type = "group",
Flick@244 1220 inline = true,
Flick@269 1221 disabled = "GetScaleDisabled",
Flick@244 1222 args = {
Flick@244 1223 scale = {
Flick@244 1224 name = L["Scale"],
Flick@269 1225 order = 1,
Flick@244 1226 type = "range",
Flick@244 1227 min = 0.25,
Flick@244 1228 max = 2.5,
Flick@244 1229 step = 0.05,
Flick@244 1230 isPercent = true,
Flick@244 1231 set = "SetProp",
Flick@244 1232 get = "GetScale",
Flick@244 1233 },
Flick@244 1234 },
Flick@244 1235 },
Flick@269 1236
Flick@269 1237 enableAlpha = {
Flick@269 1238 name = L["Set Transparency"],
Flick@269 1239 order = 131,
Flick@269 1240 type = "toggle",
Flick@269 1241 set = "SetProp",
Flick@269 1242 get = "GetProp",
Flick@269 1243 },
Flick@269 1244 alphaGroup = {
Flick@244 1245 name = L["Transparency"],
Flick@269 1246 order = 132,
Flick@244 1247 type = "group",
Flick@244 1248 inline = true,
Flick@269 1249 disabled = "GetAlphaDisabled",
Flick@244 1250 args = {
Flick@244 1251 alpha = {
Flick@244 1252 name = L["Transparency"],
Flick@269 1253 order = 1,
Flick@244 1254 type = "range",
Flick@244 1255 min = 0,
Flick@244 1256 max = 1,
Flick@244 1257 step = 0.01,
Flick@244 1258 bigStep = 0.05,
Flick@244 1259 isPercent = true,
Flick@244 1260 set = "SetProp",
Flick@244 1261 get = "GetAlpha",
Flick@244 1262 },
Flick@244 1263 },
Flick@244 1264 },
Flick@244 1265 },
Flick@244 1266 plugins = { }
Flick@244 1267 },
Flick@244 1268 rules = {
Flick@244 1269 name = L["Rule"],
Flick@244 1270 order = 3,
Flick@244 1271 type = "group",
Flick@244 1272 args = {
Flick@244 1273 mode = {
Flick@244 1274 name = L["Select this state"],
Flick@244 1275 order = 2,
Flick@244 1276 type = "select",
Flick@269 1277 style = "dropdown",
Flick@244 1278 values = {
Flick@244 1279 default = L["by default"],
Flick@244 1280 any = L["when ANY of these"],
Flick@244 1281 all = L["when ALL of these"],
Flick@244 1282 custom = L["via custom rule"],
Flick@244 1283 keybind = L["via keybinding"],
Flick@244 1284 },
Flick@244 1285 set = "SetType",
Flick@244 1286 get = "GetType",
Flick@244 1287 },
Flick@244 1288 clear = {
Flick@244 1289 name = L["Clear All"],
Flick@244 1290 order = 3,
Flick@244 1291 type = "execute",
Flick@244 1292 hidden = "GetClearAllDisabled",
Flick@244 1293 disabled = "GetClearAllDisabled",
Flick@244 1294 func = "ClearAllConditions",
Flick@244 1295 },
Flick@244 1296 inputs = {
Flick@244 1297 name = L["Conditions"],
Flick@244 1298 order = 4,
Flick@244 1299 type = "multiselect",
Flick@244 1300 hidden = "GetConditionsDisabled",
Flick@244 1301 disabled = "GetConditionsDisabled",
Flick@244 1302 values = ruleSelect,
Flick@244 1303 set = "SetCondition",
Flick@244 1304 get = "GetCondition",
Flick@244 1305 },
Flick@244 1306 custom = {
Flick@244 1307 name = L["Custom Rule"],
Flick@244 1308 order = 5,
Flick@244 1309 type = "input",
Flick@244 1310 multiline = true,
Flick@244 1311 hidden = "GetCustomDisabled",
Flick@244 1312 disabled = "GetCustomDisabled",
Flick@244 1313 desc = L["Syntax like macro rules: see preset rules for examples"],
Flick@244 1314 set = "SetCustomRule",
Flick@244 1315 get = "GetCustomRule",
Flick@244 1316 validate = "ValidateCustomRule",
Flick@244 1317 },
Flick@244 1318 keybind = {
Flick@244 1319 name = L["Keybinding"],
Flick@244 1320 order = 6,
Flick@244 1321 inline = true,
Flick@244 1322 hidden = "GetKeybindDisabled",
Flick@244 1323 disabled = "GetKeybindDisabled",
Flick@244 1324 type = "group",
Flick@244 1325 args = {
Flick@244 1326 desc = {
Flick@244 1327 name = L["Invoking a state keybind toggles an override of all other transition rules."],
Flick@244 1328 order = 1,
Flick@244 1329 type = "description",
Flick@244 1330 },
Flick@244 1331 keybind = {
Flick@244 1332 name = L["State Hotkey"],
Flick@244 1333 desc = L["Define an override toggle keybind"],
Flick@244 1334 order = 2,
Flick@244 1335 type = "keybinding",
Flick@244 1336 set = "SetKeybind",
Flick@244 1337 get = "GetKeybind",
Flick@244 1338 },
Flick@244 1339 },
Flick@244 1340 },
Flick@244 1341 },
Flick@244 1342 },
Flick@244 1343 }
Flick@244 1344
Flick@244 1345 local StateHandler = { }
Flick@244 1346 local meta = { __index = StateHandler }
Flick@244 1347
Flick@244 1348 function StateHandler:New( bar, opts )
Flick@244 1349 local self = setmetatable(
Flick@244 1350 {
Flick@244 1351 bar = bar
Flick@244 1352 },
Flick@244 1353 meta )
Flick@244 1354
Flick@244 1355 function self:GetName()
Flick@244 1356 return opts.name
Flick@244 1357 end
Flick@244 1358
Flick@244 1359 function self:SetName(name)
Flick@244 1360 opts.name = name
Flick@244 1361 end
Flick@244 1362
Flick@244 1363 function self:GetOrder()
Flick@244 1364 return opts.order
Flick@244 1365 end
Flick@244 1366
Flick@244 1367 -- get reference to states table: even if the bar
Flick@244 1368 -- name changes the states table ref won't
Flick@244 1369 self.states = tbuild(bar:GetConfig(), "states")
Flick@244 1370 self.state = tbuild(self.states, opts.name)
Flick@244 1371
Flick@244 1372 opts.order = self:GetRuleField("order")
Flick@244 1373 if opts.order == nil then
Flick@244 1374 -- add after the highest
Flick@244 1375 opts.order = 100
Flick@244 1376 for _, state in pairs(self.states) do
Flick@244 1377 local x = tonumber(tfetch(state, "rule", "order"))
Flick@244 1378 if x and x >= opts.order then
Flick@244 1379 opts.order = x + 1
Flick@244 1380 end
Flick@244 1381 end
Flick@244 1382 self:SetRuleField("order",opts.order)
Flick@244 1383 end
Flick@244 1384
Flick@244 1385 return self
Flick@244 1386 end
Flick@244 1387
Flick@244 1388 -- helper methods
Flick@244 1389
Flick@244 1390 function StateHandler:SetRuleField( key, value, ... )
Flick@244 1391 tbuild(self.state, "rule", ...)[key] = value
Flick@244 1392 end
Flick@244 1393
Flick@244 1394 function StateHandler:GetRuleField( ... )
Flick@244 1395 return tfetch(self.state, "rule", ...)
Flick@244 1396 end
Flick@244 1397
Flick@244 1398 function StateHandler:FixAll( setkey )
Flick@244 1399 -- if multiple selections in the same group are chosen when 'all' is selected,
Flick@244 1400 -- keep only one of them. If changing the mode, the first in the fields list will
Flick@244 1401 -- be chosen arbitrarily. Otherwise, if selecting a new checkbox from the field-set,
Flick@244 1402 -- it will be retained.
Flick@244 1403 local notified = false
Flick@244 1404 if self:GetRuleField("type") == "all" then
Flick@244 1405 for _, c in ipairs(rules) do
Flick@244 1406 local rule, fields = unpack(c)
Flick@244 1407 local once = false
Flick@244 1408 if setkey then
Flick@244 1409 for idx, field in ipairs(fields) do
Flick@244 1410 if next(field) == setkey then
Flick@244 1411 once = true
Flick@244 1412 end
Flick@244 1413 end
Flick@244 1414 end
Flick@244 1415 for idx, field in ipairs(fields) do
Flick@244 1416 local key = next(field)
Flick@244 1417 if self:GetRuleField("values",key) then
Flick@244 1418 if once and key ~= setkey then
Flick@244 1419 self:SetRuleField(key,false,"values")
Flick@244 1420 if not setkey and not notified then
Flick@244 1421 ReAction:UserError(L["Warning: one or more incompatible rules were turned off"])
Flick@244 1422 notified = true
Flick@244 1423 end
Flick@244 1424 end
Flick@244 1425 once = true
Flick@244 1426 end
Flick@244 1427 end
Flick@244 1428 end
Flick@244 1429 end
Flick@244 1430 end
Flick@244 1431
Flick@244 1432 function StateHandler:GetNeighbors()
Flick@244 1433 local before, after
Flick@244 1434 for k, v in pairs(self.states) do
Flick@244 1435 local o = tonumber(tfetch(v, "rule", "order"))
Flick@244 1436 if o and k ~= self:GetName() then
Flick@244 1437 local obefore = tfetch(self.states,before,"rule","order")
Flick@244 1438 local oafter = tfetch(self.states,after,"rule","order")
Flick@244 1439 if o < self:GetOrder() and (not obefore or obefore < o) then
Flick@244 1440 before = k
Flick@244 1441 end
Flick@244 1442 if o > self:GetOrder() and (not oafter or oafter > o) then
Flick@244 1443 after = k
Flick@244 1444 end
Flick@244 1445 end
Flick@244 1446 end
Flick@244 1447 return before, after
Flick@244 1448 end
Flick@244 1449
Flick@244 1450 function StateHandler:SwapOrder( a, b )
Flick@244 1451 -- do options table
Flick@244 1452 local args = optionMap[self.bar].args
Flick@244 1453 args[a].order, args[b].order = args[b].order, args[a].order
Flick@244 1454 -- do profile
Flick@244 1455 a = tbuild(self.states, a, "rule")
Flick@244 1456 b = tbuild(self.states, b, "rule")
Flick@244 1457 a.order, b.order = b.order, a.order
Flick@244 1458 end
Flick@244 1459
Flick@244 1460 -- handler methods
Flick@244 1461
Flick@244 1462 function StateHandler:GetProp( info )
Flick@244 1463 -- gets property of the same name as the options arg
Flick@244 1464 return GetProperty(self.bar, self:GetName(), info[#info])
Flick@244 1465 end
Flick@244 1466
Flick@244 1467 function StateHandler:SetProp( info, value )
Flick@244 1468 -- sets property of the same name as the options arg
Flick@244 1469 SetProperty(self.bar, self:GetName(), info[#info], value)
Flick@244 1470 end
Flick@244 1471
Flick@244 1472 function StateHandler:DeleteState()
Flick@244 1473 if self.states[self:GetName()] then
Flick@244 1474 self.states[self:GetName()] = nil
Flick@244 1475 ApplyStates(self.bar)
Flick@244 1476 end
Flick@244 1477 optionMap[self.bar].args[self:GetName()] = nil
Flick@244 1478 end
Flick@244 1479
Flick@244 1480 function StateHandler:SetStateName(info, value)
Flick@244 1481 -- check for existing state name
Flick@244 1482 if self.states[value] then
Flick@244 1483 ReAction:UserError(format(L["State named '%s' already exists"],value))
Flick@244 1484 return
Flick@244 1485 end
Flick@244 1486 local args = optionMap[self.bar].args
Flick@244 1487 local name = self:GetName()
Flick@244 1488 self.states[value], args[value], self.states[name], args[name] = self.states[name], args[name], nil, nil
Flick@244 1489 self:SetName(value)
Flick@244 1490 ApplyStates(self.bar)
Flick@244 1491 ReAction:ShowEditor(self.bar, moduleID, value)
Flick@244 1492 end
Flick@244 1493
Flick@244 1494 function StateHandler:MoveStateUp()
Flick@244 1495 local before, after = self:GetNeighbors()
Flick@244 1496 if before then
Flick@244 1497 self:SwapOrder(before, self:GetName())
Flick@244 1498 ApplyStates(self.bar)
Flick@244 1499 end
Flick@244 1500 end
Flick@244 1501
Flick@244 1502 function StateHandler:MoveStateDown()
Flick@244 1503 local before, after = self:GetNeighbors()
Flick@244 1504 if after then
Flick@244 1505 self:SwapOrder(self:GetName(), after)
Flick@244 1506 ApplyStates(self.bar)
Flick@244 1507 end
Flick@244 1508 end
Flick@244 1509
Flick@244 1510 function StateHandler:GetAnchorDisabled()
Flick@244 1511 return not GetProperty(self.bar, self:GetName(), "anchorEnable")
Flick@244 1512 end
Flick@244 1513
Flick@244 1514 function StateHandler:IsPageDisabled()
Flick@244 1515 local n = self.bar:GetConfig().nPages or 1
Flick@244 1516 return not (n > 1)
Flick@244 1517 end
Flick@244 1518
Flick@244 1519 function StateHandler:IsPageHidden()
Flick@244 1520 return not self.bar:GetConfig().nPages
Flick@244 1521 end
Flick@244 1522
Flick@244 1523 function StateHandler:GetPageValues()
Flick@244 1524 if not self._pagevalues then
Flick@244 1525 self._pagevalues = { }
Flick@244 1526 end
Flick@244 1527 local n = self.bar:GetConfig().nPages
Flick@244 1528 -- cache the results
Flick@244 1529 if self._npages ~= n then
Flick@244 1530 self._npages = n
Flick@244 1531 wipe(self._pagevalues)
Flick@244 1532 for i = 1, n do
Flick@244 1533 self._pagevalues["page"..i] = i
Flick@244 1534 end
Flick@244 1535 end
Flick@244 1536 return self._pagevalues
Flick@244 1537 end
Flick@244 1538
Flick@244 1539 function StateHandler:GetPage(info)
Flick@244 1540 return self:GetProp(info) or 1
Flick@244 1541 end
Flick@244 1542
Flick@244 1543 function StateHandler:GetAnchorFrames(info)
Flick@244 1544 self._anchorframes = self._anchorframes or { }
Flick@244 1545 table.wipe(self._anchorframes)
Flick@244 1546
Flick@244 1547 table.insert(self._anchorframes, "UIParent")
Flick@244 1548 for name, bar in ReAction:IterateBars() do
Flick@244 1549 table.insert(self._anchorframes, bar:GetFrame():GetName())
Flick@244 1550 end
Flick@244 1551 return self._anchorframes
Flick@244 1552 end
Flick@244 1553
Flick@244 1554 function StateHandler:GetAnchorFrame(info)
Flick@244 1555 local value = self:GetProp(info)
Flick@244 1556 for k,v in pairs(self._anchorframes) do
Flick@244 1557 if v == value then
Flick@244 1558 return k
Flick@244 1559 end
Flick@244 1560 end
Flick@244 1561 end
Flick@244 1562
Flick@244 1563 function StateHandler:SetAnchorFrame(info, value)
Flick@244 1564 local f = _G[self._anchorframes[value]]
Flick@244 1565 if f then
Flick@244 1566 self.bar:SetFrameRef("anchor-"..self:GetName(), f)
Flick@244 1567 self:SetProp(info, f:GetName())
Flick@244 1568 end
Flick@244 1569 end
Flick@244 1570
Flick@244 1571 function StateHandler:SetAnchorPointProp(info, value)
Flick@244 1572 self:SetProp(info, value ~= "NONE" and value or nil)
Flick@244 1573 end
Flick@244 1574
Flick@244 1575 function StateHandler:GetAnchorPointProp(info)
Flick@244 1576 return self:GetProp(info) or "NONE"
Flick@244 1577 end
Flick@244 1578
Flick@244 1579 function StateHandler:GetScale(info)
Flick@244 1580 return self:GetProp(info) or 1.0
Flick@244 1581 end
Flick@244 1582
Flick@244 1583 function StateHandler:GetScaleDisabled()
Flick@244 1584 return not GetProperty(self.bar, self:GetName(), "enableScale")
Flick@244 1585 end
Flick@244 1586
Flick@244 1587 function StateHandler:GetAlpha(info)
Flick@244 1588 return self:GetProp(info) or 1.0
Flick@244 1589 end
Flick@244 1590
Flick@244 1591 function StateHandler:GetAlphaDisabled()
Flick@244 1592 return not GetProperty(self.bar, self:GetName(), "enableAlpha")
Flick@244 1593 end
Flick@244 1594
Flick@244 1595 function StateHandler:SetType(info, value)
Flick@244 1596 self:SetRuleField("type", value)
Flick@244 1597 self:FixAll()
Flick@244 1598 ApplyStates(self.bar)
Flick@244 1599 end
Flick@244 1600
Flick@244 1601 function StateHandler:GetType()
Flick@244 1602 return self:GetRuleField("type")
Flick@244 1603 end
Flick@244 1604
Flick@244 1605 function StateHandler:GetClearAllDisabled()
Flick@244 1606 local t = self:GetRuleField("type")
Flick@244 1607 return not( t == "any" or t == "all" or t == "custom")
Flick@244 1608 end
Flick@244 1609
Flick@244 1610 function StateHandler:ClearAllConditions()
Flick@244 1611 local t = self:GetRuleField("type")
Flick@244 1612 if t == "custom" then
Flick@244 1613 self:SetRuleField("custom","")
Flick@244 1614 elseif t == "any" or t == "all" then
Flick@244 1615 self:SetRuleField("values", {})
Flick@244 1616 end
Flick@244 1617 ApplyStates(self.bar)
Flick@244 1618 end
Flick@244 1619
Flick@244 1620 function StateHandler:GetConditionsDisabled()
Flick@244 1621 local t = self:GetRuleField("type")
Flick@244 1622 return not( t == "any" or t == "all")
Flick@244 1623 end
Flick@244 1624
Flick@244 1625 function StateHandler:SetCondition(info, key, value)
Flick@244 1626 self:SetRuleField(ruleMap[key], value or nil, "values")
Flick@244 1627 if value then
Flick@244 1628 self:FixAll(ruleMap[key])
Flick@244 1629 end
Flick@244 1630 ApplyStates(self.bar)
Flick@244 1631 end
Flick@244 1632
Flick@244 1633 function StateHandler:GetCondition(info, key)
Flick@244 1634 return self:GetRuleField("values", ruleMap[key]) or false
Flick@244 1635 end
Flick@244 1636
Flick@244 1637 function StateHandler:GetCustomDisabled()
Flick@244 1638 return self:GetRuleField("type") ~= "custom"
Flick@244 1639 end
Flick@244 1640
Flick@244 1641 function StateHandler:SetCustomRule(info, value)
Flick@244 1642 self:SetRuleField("custom",value)
Flick@244 1643 ApplyStates(self.bar)
Flick@244 1644 end
Flick@244 1645
Flick@244 1646 function StateHandler:GetCustomRule()
Flick@244 1647 return self:GetRuleField("custom") or ""
Flick@244 1648 end
Flick@244 1649
Flick@244 1650 function StateHandler:ValidateCustomRule(info, value)
Flick@244 1651 local s = value:gsub("%s","") -- remove all spaces
Flick@244 1652 -- unfortunately %b and captures don't support the '+' notation, or this would be considerably simpler
Flick@244 1653 repeat
Flick@244 1654 if s == "" then
Flick@244 1655 return true
Flick@244 1656 end
Flick@244 1657 local c, r = s:match("(%b[])(.*)")
Flick@244 1658 if c == nil and s and #s > 0 then
Flick@244 1659 return format(L["Invalid custom rule '%s': each clause must appear within [brackets]"],value or "")
Flick@244 1660 end
Flick@244 1661 s = r
Flick@244 1662 until c == nil
Flick@244 1663 return true
Flick@244 1664 end
Flick@244 1665
Flick@244 1666 function StateHandler:GetKeybindDisabled()
Flick@244 1667 return self:GetRuleField("type") ~= "keybind"
Flick@244 1668 end
Flick@244 1669
Flick@244 1670 function StateHandler:GetKeybind()
Flick@244 1671 return self:GetRuleField("keybind")
Flick@244 1672 end
Flick@244 1673
Flick@244 1674 function StateHandler:SetKeybind(info, value)
Flick@244 1675 if value and #value == 0 then
Flick@244 1676 value = nil
Flick@244 1677 end
Flick@244 1678 self:SetRuleField("keybind",value)
Flick@244 1679 ApplyStates(self.bar)
Flick@244 1680 end
Flick@244 1681
Flick@244 1682 local function CreateStateOptions(bar, name)
Flick@244 1683 local opts = {
Flick@244 1684 type = "group",
Flick@244 1685 name = name,
Flick@244 1686 childGroups = "tab",
Flick@244 1687 args = stateOptions
Flick@244 1688 }
Flick@244 1689
Flick@244 1690 opts.handler = StateHandler:New(bar,opts)
Flick@244 1691
Flick@244 1692 return opts
Flick@244 1693 end
Flick@244 1694
Flick@244 1695 function Editor:CreateStateOptions(bar)
Flick@244 1696 local private = { }
Flick@244 1697 local states = tbuild(bar:GetConfig(), "states")
Flick@244 1698 local options = {
Flick@244 1699 name = L["Dynamic State"],
Flick@244 1700 type = "group",
Flick@244 1701 order = -1,
Flick@244 1702 childGroups = "tree",
Flick@244 1703 disabled = InCombatLockdown,
Flick@244 1704 args = {
Flick@244 1705 __desc__ = {
Flick@244 1706 name = L["States are evaluated in the order they are listed"],
Flick@244 1707 order = 1,
Flick@244 1708 type = "description",
Flick@244 1709 },
Flick@244 1710 __new__ = {
Flick@244 1711 name = L["New State..."],
Flick@244 1712 order = 2,
Flick@244 1713 type = "group",
Flick@244 1714 args = {
Flick@244 1715 name = {
Flick@244 1716 name = L["State Name"],
Flick@244 1717 desc = L["Set a name for the new state"],
Flick@244 1718 order = 1,
Flick@244 1719 type = "input",
Flick@244 1720 get = function() return private.newstatename or "" end,
Flick@244 1721 set = function(info,value) private.newstatename = value end,
Flick@244 1722 pattern = "^%w*$",
Flick@244 1723 usage = L["State names must be alphanumeric without spaces"],
Flick@244 1724 },
Flick@244 1725 create = {
Flick@244 1726 name = L["Create State"],
Flick@244 1727 order = 2,
Flick@244 1728 type = "execute",
Flick@244 1729 func = function ()
Flick@244 1730 local name = private.newstatename
Flick@244 1731 if states[name] then
Flick@244 1732 ReAction:UserError(format(L["State named '%s' already exists"],name))
Flick@244 1733 else
Flick@244 1734 -- TODO: select default state options and pass as final argument
Flick@244 1735 states[name] = { }
Flick@244 1736 optionMap[bar].args[name] = CreateStateOptions(bar,name)
Flick@269 1737 ReAction:ShowEditor(bar, "stateOpts", name)
Flick@244 1738 private.newstatename = ""
Flick@244 1739 end
Flick@244 1740 end,
Flick@244 1741 disabled = function()
Flick@244 1742 local name = private.newstatename or ""
Flick@244 1743 return #name == 0 or name:find("%W")
Flick@244 1744 end,
Flick@244 1745 }
Flick@244 1746 }
Flick@244 1747 }
Flick@244 1748 }
Flick@244 1749 }
Flick@244 1750 for name, config in pairs(states) do
Flick@244 1751 options.args[name] = CreateStateOptions(bar,name)
Flick@244 1752 end
Flick@244 1753 optionMap[bar] = options
Flick@244 1754 return options
Flick@244 1755 end
Flick@244 1756 end
Flick@244 1757
flickerstreak@185 1758
flickerstreak@185 1759 ---- Export to ReAction ----
flickerstreak@185 1760 function ReAction:ShowEditor(bar, ...)
flickerstreak@185 1761 if InCombatLockdown() then
flickerstreak@185 1762 self:UserError(L["ReAction config mode disabled during combat."])
flickerstreak@185 1763 else
flickerstreak@185 1764 self.editor = self.editor or Editor:New()
flickerstreak@185 1765 self.editor:Open(bar, ...)
flickerstreak@185 1766 self:SetConfigMode(true)
flickerstreak@185 1767 end
flickerstreak@185 1768 end
flickerstreak@185 1769
flickerstreak@185 1770 function ReAction:CloseEditor()
flickerstreak@185 1771 if self.editor then
flickerstreak@185 1772 self.editor:Close()
flickerstreak@185 1773 end
flickerstreak@185 1774 end
flickerstreak@185 1775
flickerstreak@185 1776 function ReAction:RefreshEditor()
flickerstreak@185 1777 if self.editor then
flickerstreak@185 1778 self.editor:RefreshBarOptions()
flickerstreak@185 1779 end
flickerstreak@185 1780 end
flickerstreak@185 1781