Mercurial > wow > reaction
comparison modules/ReAction_State/ReAction_State.lua @ 68:fcb5dad031f9
State transitions now working. Keybind toggle states, stance switching, etc.
Hide bar is the only working state property, but the config is there for page #, re-anchoring, re-scaling, and keybind override.
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Tue, 03 Jun 2008 22:57:34 +0000 |
parents | 84721edaa749 |
children |
comparison
equal
deleted
inserted
replaced
67:84721edaa749 | 68:fcb5dad031f9 |
---|---|
32 end | 32 end |
33 return t | 33 return t |
34 end | 34 end |
35 | 35 |
36 -- PRIVATE -- | 36 -- PRIVATE -- |
37 local InitRules, ApplyStates | 37 |
38 local InitRules, ApplyStates, SetProperty, GetProperty | |
38 do | 39 do |
39 -- As far as I can tell the macro clauses are NOT locale-specific. | 40 -- As far as I can tell the macro clauses are NOT locale-specific. |
40 local ruleformats = { | 41 local ruleformats = { |
41 stealth = "stealth", | 42 stealth = "stealth", |
42 nostealth = "nostealth", | 43 nostealth = "nostealth", |
87 ruleformats.bear = ("form:%d"):format(bear) | 88 ruleformats.bear = ("form:%d"):format(bear) |
88 ruleformats.cat = ("form:%d"):format(cat) | 89 ruleformats.cat = ("form:%d"):format(cat) |
89 ruleformats.treeOrMoonkin = ("form:%d"):format(treekin) | 90 ruleformats.treeOrMoonkin = ("form:%d"):format(treekin) |
90 end | 91 end |
91 | 92 |
93 -- return a new array of keys of table 't', sorted by comparing | |
94 -- sub-fields (obtained via tfetch) of the table values | |
95 local function fieldsort( t, ... ) | |
96 local r = { } | |
97 for k in pairs(t) do | |
98 table.insert(r,k) | |
99 end | |
100 local dotdotdot = { ... } | |
101 table.sort(r, function(lhs, rhs) | |
102 local olhs = tfetch(t[lhs], unpack(dotdotdot)) or 0 | |
103 local orhs = tfetch(t[rhs], unpack(dotdotdot)) or 0 | |
104 return olhs < orhs | |
105 end) | |
106 return r | |
107 end | |
108 | |
92 local function BuildRuleString(states) | 109 local function BuildRuleString(states) |
93 local s = "" | 110 local s = "" |
94 local default | 111 local default |
95 local sorted = { } | 112 local sorted = fieldsort(states, "rule", "order") |
96 for name in pairs(states) do | |
97 table.insert(sorted,name) | |
98 end | |
99 table.sort(sorted, function(lhs, rhs) | |
100 local olhs = tfetch(states[lhs],"rule","order") or 0 | |
101 local orhs = tfetch(states[rhs],"rule","order") or 0 | |
102 return olhs < orhs | |
103 end) | |
104 for idx, name in ipairs(sorted) do | 113 for idx, name in ipairs(sorted) do |
105 local state = states[name] | 114 local state = states[name] |
106 local semi = #s > 0 and "; " or "" | 115 local semi = #s > 0 and "; " or "" |
107 local mode = tfetch(state,"rule","type") | 116 local mode = tfetch(state,"rule","type") |
108 if mode == "default" then | 117 if mode == "default" then |
135 end | 144 end |
136 end | 145 end |
137 if default then | 146 if default then |
138 s = ("%s%s%s"):format(s, #s > 0 and "; " or "", default) | 147 s = ("%s%s%s"):format(s, #s > 0 and "; " or "", default) |
139 end | 148 end |
140 return s | 149 return s, default |
141 end | 150 end |
142 | 151 |
143 local drivers = setmetatable({},{__mode="k"}) | 152 local drivers = setmetatable({},{__mode="k"}) |
153 local propertyFuncs = { } | |
144 | 154 |
145 function ApplyStates( bar ) | 155 function ApplyStates( bar ) |
146 local states = tfetch(module.db.profile.bars, bar:GetName(), "states") | 156 local states = tfetch(module.db.profile.bars, bar:GetName(), "states") |
147 if states then | 157 if states then |
148 local frame = bar:GetFrame() | 158 local frame = bar:GetFrame() |
149 local string = BuildRuleString(states) | 159 local string, default = BuildRuleString(states) |
150 ReAction:Print("'"..string.."'") | |
151 if string and #string > 0 then | 160 if string and #string > 0 then |
161 drivers[bar] = true | |
162 -- register a map for each "statemap-reaction-XXX" to set 'state' to 'XXX' | |
163 -- UNLESS we're in a keybound state AND there's a default state, in which case | |
164 -- all keybound states go back to themselves. | |
165 local keybindprefix | |
166 if default then | |
167 local tmp = { } | |
168 for state, config in pairs(states) do | |
169 if tfetch(config, "rule", "type") == "keybind" then | |
170 bar:SetStateKeybind(tfetch(config,"rule","keybind"), state, tfetch(config,"rule","keybindreturn") or default or 0) | |
171 table.insert(tmp, ("%s:%s"):format(state,state)) | |
172 end | |
173 end | |
174 if #tmp > 0 then | |
175 table.insert(tmp,"") -- to get a final ';' | |
176 end | |
177 keybindprefix = table.concat(tmp,";") | |
178 end | |
179 for state in pairs(states) do | |
180 frame:SetAttribute(("statemap-reaction-%s"):format(state), ("%s%s"):format(keybindprefix or "",state)) | |
181 end | |
152 -- register a handler to set the value of attribute "state-reaction" | 182 -- register a handler to set the value of attribute "state-reaction" |
153 -- in response to events as per the rule string | 183 -- in response to events as per the rule string |
154 RegisterStateDriver(frame, "reaction", string) | 184 RegisterStateDriver(frame, "reaction", string) |
155 drivers[bar] = true | 185 SecureStateHeader_Refresh(frame) |
156 -- register a trivial map for each "statemap-reaction-XXX" to set 'state' to 'XXX' | |
157 for state in pairs(states) do | |
158 frame:SetAttribute(("statemap-reaction-%s"):format(state), state) | |
159 end | |
160 elseif drivers[bar] then | 186 elseif drivers[bar] then |
161 UnregisterStateDriver(frame, "reaction") | 187 UnregisterStateDriver(frame, "reaction") |
162 drivers[bar] = nil | 188 drivers[bar] = nil |
163 end | 189 end |
164 end | 190 for k, f in pairs(propertyFuncs) do |
165 end | 191 f(bar, states) |
166 end | 192 end |
167 | 193 end |
168 | 194 end |
169 -- module event handlers | 195 |
196 function GetProperty( bar, state, propname ) | |
197 return tfetch(module.db.profile.bars, bar:GetName(), "states", state, propname) | |
198 end | |
199 | |
200 function SetProperty( bar, state, propname, value ) | |
201 local states = tbuild(module.db.profile.bars, bar:GetName(), "states") | |
202 tbuild(states, state)[propname] = value | |
203 local f = propertyFuncs[propname] | |
204 if f then | |
205 f(bar, states) | |
206 end | |
207 end | |
208 | |
209 -- state property functions | |
210 function propertyFuncs.hide( bar, states ) | |
211 local tmp = { } | |
212 for state, config in pairs(states) do | |
213 if config.hide then | |
214 table.insert(tmp, state) | |
215 end | |
216 end | |
217 local s = table.concat(tmp,",") | |
218 bar:SetHideStates(s) | |
219 end | |
220 | |
221 function propertyFuncs.page( bar, states ) | |
222 local map = { } | |
223 for state, config in pairs(states) do | |
224 map[state] = config.page | |
225 end | |
226 bar:SetStatePageMap(state, map) | |
227 end | |
228 | |
229 function propertyFuncs.keybindstate( bar, states ) | |
230 local map = { } | |
231 for state, config in pairs(states) do | |
232 if config.keybindstate then | |
233 table.insert(map,state) | |
234 end | |
235 end | |
236 bar:SetStateKeybindOverrideMap(map) | |
237 end | |
238 | |
239 function propertyFuncs.enableanchor( bar, states ) | |
240 | |
241 end | |
242 | |
243 function propertyFuncs.anchorPoint( bar, states ) | |
244 | |
245 end | |
246 | |
247 function propertyFuncs.anchorRelPoint( bar, states ) | |
248 | |
249 end | |
250 | |
251 function propertyFuncs.anchorX( bar, states ) | |
252 | |
253 end | |
254 | |
255 function propertyFuncs.anchorY( bar, states ) | |
256 | |
257 end | |
258 | |
259 function propertyFuncs.enablescale( bar, states ) | |
260 | |
261 end | |
262 | |
263 function propertyFuncs.scale( bar, states ) | |
264 | |
265 end | |
266 | |
267 end | |
268 | |
269 | |
270 | |
271 -- module event handlers -- | |
272 | |
170 function module:OnInitialize() | 273 function module:OnInitialize() |
171 self.db = ReAction.db:RegisterNamespace( moduleID, | 274 self.db = ReAction.db:RegisterNamespace( moduleID, |
172 { | 275 { |
173 profile = { | 276 profile = { |
174 bars = { }, | 277 bars = { }, |
203 end | 306 end |
204 | 307 |
205 function module:OnRefreshBar(event, bar, name) | 308 function module:OnRefreshBar(event, bar, name) |
206 local c = self.db.profile.bars[name] | 309 local c = self.db.profile.bars[name] |
207 if c then | 310 if c then |
208 self:UpdateStates(bar) | 311 ApplyStates(bar) |
209 end | 312 end |
210 end | 313 end |
211 | 314 |
212 function module:OnEraseBar(event, bar, name) | 315 function module:OnEraseBar(event, bar, name) |
213 self.db.profile.bars[name] = nil | 316 self.db.profile.bars[name] = nil |
221 function module:OnConfigModeChanged(event, mode) | 324 function module:OnConfigModeChanged(event, mode) |
222 -- TODO: unregister all state drivers (temporarily) and hidestates | 325 -- TODO: unregister all state drivers (temporarily) and hidestates |
223 end | 326 end |
224 | 327 |
225 | 328 |
226 -- API -- | |
227 | |
228 function module:UpdateStates( bar ) | |
229 ApplyStates(bar) | |
230 end | |
231 | |
232 function module:CreateState( bar, name ) | |
233 local states = tbuild(self.db.profile.bars, bar:GetName(), "states") | |
234 if states[name] then | |
235 ReAction:UserError(L["State named '%s' already exists"]:format(name)) | |
236 else | |
237 states[name] = { } | |
238 end | |
239 end | |
240 | |
241 function module:DeleteState( bar, name ) | |
242 local states = tfetch(self.db.profile.bars, bar:GetName(), "states") | |
243 if states[name] then | |
244 states[name] = nil | |
245 self:UpdateStates(bar) | |
246 end | |
247 end | |
248 | 329 |
249 -- Options -- | 330 -- Options -- |
250 | 331 |
251 local CreateBarOptions | 332 local CreateBarOptions |
252 do | 333 do |
276 | 357 |
277 local ruleSelect = { } | 358 local ruleSelect = { } |
278 local ruleMap = { } | 359 local ruleMap = { } |
279 local optionMap = setmetatable({},{__mode="k"}) | 360 local optionMap = setmetatable({},{__mode="k"}) |
280 | 361 |
362 local pointTable = { | |
363 NONE = " ", | |
364 CENTER = L["Center"], | |
365 LEFT = L["Left"], | |
366 RIGHT = L["Right"], | |
367 TOP = L["Top"], | |
368 BOTTOM = L["Bottom"], | |
369 TOPLEFT = L["Top Left"], | |
370 TOPRIGHT = L["Top Right"], | |
371 BOTTOMLEFT = L["Bottom Left"], | |
372 BOTTOMRIGHT = L["Bottom Right"], | |
373 } | |
374 | |
281 -- unpack rules table into ruleSelect and ruleMap | 375 -- unpack rules table into ruleSelect and ruleMap |
282 for _, c in ipairs(rules) do | 376 for _, c in ipairs(rules) do |
283 local rule, hidden, fields = unpack(c) | 377 local rule, hidden, fields = unpack(c) |
284 if not hidden then | 378 if not hidden then |
285 for _, field in ipairs(fields) do | 379 for _, field in ipairs(fields) do |
297 childGroups = "tab", | 391 childGroups = "tab", |
298 } | 392 } |
299 | 393 |
300 local states = tbuild(module.db.profile.bars, bar:GetName(), "states") | 394 local states = tbuild(module.db.profile.bars, bar:GetName(), "states") |
301 | 395 |
302 local function put( key, value, ... ) | 396 local function update() |
397 ApplyStates(bar) | |
398 end | |
399 | |
400 local function setrule( key, value, ... ) | |
303 tbuild(states, opts.name, "rule", ...)[key] = value | 401 tbuild(states, opts.name, "rule", ...)[key] = value |
304 end | 402 end |
305 | 403 |
306 local function fetch( ... ) | 404 local function getrule( ... ) |
307 return tfetch(states, opts.name, "rule", ...) | 405 return tfetch(states, opts.name, "rule", ...) |
406 end | |
407 | |
408 local function setprop(info, value) | |
409 SetProperty(bar, opts.name, info[#info], value) | |
410 end | |
411 | |
412 local function getprop(info) | |
413 return GetProperty(bar, opts.name, info[#info]) | |
308 end | 414 end |
309 | 415 |
310 local function fixall(setkey) | 416 local function fixall(setkey) |
311 -- if multiple selections in the same group are chosen when 'all' is selected, | 417 -- if multiple selections in the same group are chosen when 'all' is selected, |
312 -- keep only one of them. If changing the mode, the first in the fields list will | 418 -- keep only one of them. If changing the mode, the first in the fields list will |
315 local notified = false | 421 local notified = false |
316 for _, c in ipairs(rules) do | 422 for _, c in ipairs(rules) do |
317 local rule, hidden, fields = unpack(c) | 423 local rule, hidden, fields = unpack(c) |
318 local found = false | 424 local found = false |
319 for key in ipairs(fields) do | 425 for key in ipairs(fields) do |
320 if fetch("values",key) then | 426 if getrule("values",key) then |
321 if (found or setkey) and key ~= setkey then | 427 if (found or setkey) and key ~= setkey then |
322 put(key,false,"values") | 428 setrule(key,false,"values") |
323 if not setkey and not notified then | 429 if not setkey and not notified then |
324 ReAction:UserError(L["Warning: one or more incompatible rules were turned off"]) | 430 ReAction:UserError(L["Warning: one or more incompatible rules were turned off"]) |
325 notified = true | 431 notified = true |
326 end | 432 end |
327 end | 433 end |
357 a = tbuild(states, a, "rule") | 463 a = tbuild(states, a, "rule") |
358 b = tbuild(states, b, "rule") | 464 b = tbuild(states, b, "rule") |
359 a.order, b.order = b.order, a.order | 465 a.order, b.order = b.order, a.order |
360 end | 466 end |
361 | 467 |
362 local function update() | 468 local function anchordisable() |
363 module:UpdateStates(bar) | 469 return not GetProperty(bar, opts.name, "enableanchor") |
364 end | 470 end |
365 | 471 |
366 | 472 tbuild(states, name) |
367 opts.order = fetch("order") | 473 |
474 opts.order = getrule("order") | |
368 if opts.order == nil then | 475 if opts.order == nil then |
369 -- add after the highest | 476 -- add after the highest |
370 opts.order = 100 | 477 opts.order = 100 |
371 for _, state in pairs(states) do | 478 for _, state in pairs(states) do |
372 local x = tonumber(tfetch(state, "rule", "order")) | 479 local x = tonumber(tfetch(state, "rule", "order")) |
373 if x and x >= opts.order then | 480 if x and x >= opts.order then |
374 opts.order = x + 1 | 481 opts.order = x + 1 |
375 end | 482 end |
376 end | 483 end |
377 put("order",opts.order) | 484 setrule("order",opts.order) |
378 end | 485 end |
379 | 486 |
380 opts.args = { | 487 opts.args = { |
381 properties = { | 488 ordering = { |
489 name = L["Info"], | |
490 order = 1, | |
382 type = "group", | 491 type = "group", |
383 name = L["Properties"], | |
384 order = 1, | |
385 args = { | 492 args = { |
386 delete = { | 493 delete = { |
494 name = L["Delete this State"], | |
495 order = -1, | |
387 type = "execute", | 496 type = "execute", |
388 name = L["Delete this State"], | |
389 func = function(info) | 497 func = function(info) |
390 module:DeleteState(bar,opts.name) | 498 if states[opts.name] then |
499 states[opts.name] = nil | |
500 ApplyStates(bar) | |
501 end | |
391 optionMap[bar].args[opts.name] = nil | 502 optionMap[bar].args[opts.name] = nil |
392 end, | 503 end, |
393 order = -1 | |
394 }, | 504 }, |
395 rename = { | 505 rename = { |
396 type = "input", | |
397 name = L["Name"], | 506 name = L["Name"], |
398 order = 1, | 507 order = 1, |
508 type = "input", | |
399 get = function() return opts.name end, | 509 get = function() return opts.name end, |
400 set = function(info, value) | 510 set = function(info, value) |
401 -- check for existing state name | 511 -- check for existing state name |
402 if states[value] then | 512 if states[value] then |
403 L["State named '%s' already exists"]:format(value) | 513 L["State named '%s' already exists"]:format(value) |
409 end, | 519 end, |
410 pattern = "^%w*$", | 520 pattern = "^%w*$", |
411 usage = L["State names must be alphanumeric without spaces"], | 521 usage = L["State names must be alphanumeric without spaces"], |
412 }, | 522 }, |
413 ordering = { | 523 ordering = { |
414 type = "group", | |
415 inline = true, | |
416 name = L["Evaluation Order"], | 524 name = L["Evaluation Order"], |
417 desc = L["State transitions are evaluated in the order listed:\nMove a state up or down to change the order"], | 525 desc = L["State transitions are evaluated in the order listed:\nMove a state up or down to change the order"], |
418 order = 2, | 526 order = 2, |
527 type = "group", | |
528 inline = true, | |
419 args = { | 529 args = { |
420 up = { | 530 up = { |
531 name = L["Up"], | |
532 order = 1, | |
421 type = "execute", | 533 type = "execute", |
422 name = L["Up"], | |
423 width = "half", | 534 width = "half", |
424 order = 1, | |
425 func = function() | 535 func = function() |
426 local before, after = getNeighbors() | 536 local before, after = getNeighbors() |
427 if before then | 537 if before then |
428 swapOrder(before, opts.name) | 538 swapOrder(before, opts.name) |
429 update() | 539 update() |
430 end | 540 end |
431 end, | 541 end, |
432 }, | 542 }, |
433 down = { | 543 down = { |
544 name = L["Down"], | |
545 order = 2, | |
434 type = "execute", | 546 type = "execute", |
435 name = L["Down"], | |
436 width = "half", | 547 width = "half", |
437 order = 2, | |
438 func = function() | 548 func = function() |
439 local before, after = getNeighbors() | 549 local before, after = getNeighbors() |
440 if after then | 550 if after then |
441 ReAction:Print(opts.name, after) | |
442 swapOrder(opts.name, after) | 551 swapOrder(opts.name, after) |
443 update() | 552 update() |
444 end | 553 end |
445 end, | 554 end, |
446 } | 555 } |
447 } | 556 } |
448 }, | 557 } |
449 -- keybinding for show-this-state would go here | |
450 -- show/hide would go here | |
451 -- page # would go here | |
452 -- anchoring would go here | |
453 } | 558 } |
454 }, | 559 }, |
560 properties = { | |
561 name = L["Properties"], | |
562 order = 2, | |
563 type = "group", | |
564 args = { | |
565 desc = { | |
566 name = L["Set the properties for the bar when in this state"], | |
567 order = 1, | |
568 type = "description" | |
569 }, | |
570 hide = { | |
571 name = L["Hide Bar"], | |
572 order = 2, | |
573 type = "toggle", | |
574 set = setprop, | |
575 get = getprop, | |
576 }, | |
577 page = { | |
578 name = L["Show Page #"], | |
579 order = 3, | |
580 type = "select", | |
581 disabled = function() | |
582 return bar:GetNumPages() < 2 | |
583 end, | |
584 hidden = function() | |
585 return bar:GetNumPages() < 2 | |
586 end, | |
587 values = function() | |
588 local pages = { none = " " } | |
589 for i = 1, bar:GetNumPages() do | |
590 pages[i] = i | |
591 end | |
592 return pages | |
593 end, | |
594 set = function(info, value) | |
595 if value == "none" then | |
596 setprop(info, nil) | |
597 else | |
598 setprop(info, value) | |
599 end | |
600 end, | |
601 get = function(info) | |
602 return getprop(info) or "none" | |
603 end, | |
604 }, | |
605 keybindstate = { | |
606 name = L["Override Keybinds"], | |
607 desc = L["Set this state to maintain its own set of keybinds which override the defaults when active"], | |
608 order = 4, | |
609 type = "toggle", | |
610 set = setprop, | |
611 get = getprop, | |
612 }, | |
613 position = { | |
614 name = L["Position"], | |
615 order = 5, | |
616 type = "group", | |
617 inline = true, | |
618 args = { | |
619 enableanchor = { | |
620 name = L["Set New Position"], | |
621 order = 1, | |
622 type = "toggle", | |
623 set = setprop, | |
624 get = getprop, | |
625 }, | |
626 anchorPoint = { | |
627 name = L["Point"], | |
628 order = 2, | |
629 type = "select", | |
630 values = pointTable, | |
631 set = function(info, value) setprop(info, value ~= "NONE" and value or nil) end, | |
632 get = function(info) return getprop(info) or "NONE" end, | |
633 disabled = anchordisable, | |
634 hidden = anchordisable, | |
635 }, | |
636 anchorRelPoint = { | |
637 name = L["Relative Point"], | |
638 order = 3, | |
639 type = "select", | |
640 values = pointTable, | |
641 set = function(info, value) setprop(info, value ~= "NONE" and value or nil) end, | |
642 get = function(info) return getprop(info) or "NONE" end, | |
643 disabled = anchordisable, | |
644 hidden = anchordisable, | |
645 }, | |
646 anchorX = { | |
647 name = L["X Offset"], | |
648 order = 4, | |
649 type = "range", | |
650 min = -100, | |
651 max = 100, | |
652 step = 1, | |
653 set = setprop, | |
654 get = getprop, | |
655 disabled = anchordisable, | |
656 hidden = anchordisable, | |
657 }, | |
658 anchorY = { | |
659 name = L["Y Offset"], | |
660 order = 5, | |
661 type = "range", | |
662 min = -100, | |
663 max = 100, | |
664 step = 1, | |
665 set = setprop, | |
666 get = getprop, | |
667 disabled = anchordisable, | |
668 hidden = anchordisable, | |
669 }, | |
670 }, | |
671 }, | |
672 scale = { | |
673 name = L["Scale"], | |
674 order = 6, | |
675 type = "group", | |
676 inline = true, | |
677 args = { | |
678 enablescale = { | |
679 name = L["Set New Scale"], | |
680 order = 1, | |
681 type = "toggle", | |
682 set = setprop, | |
683 get = getprop, | |
684 }, | |
685 scale = { | |
686 name = L["Scale"], | |
687 order = 2, | |
688 type = "range", | |
689 min = 0.1, | |
690 max = 2.5, | |
691 step = 0.05, | |
692 isPercent = true, | |
693 set = setprop, | |
694 get = function(info) return getprop(info) or 1 end, | |
695 disabled = function() return not GetProperty(bar, opts.name, "enablescale") end, | |
696 hidden = function() return not GetProperty(bar, opts.name, "enablescale") end, | |
697 }, | |
698 }, | |
699 }, | |
700 }, | |
701 }, | |
455 rules = { | 702 rules = { |
703 name = L["Selection Rule"], | |
704 order = 3, | |
456 type = "group", | 705 type = "group", |
457 name = L["Rules"], | |
458 order = 2, | |
459 args = { | 706 args = { |
460 mode = { | 707 mode = { |
708 name = L["Select this state"], | |
709 order = 2, | |
461 type = "select", | 710 type = "select", |
462 style = "radio", | 711 style = "radio", |
463 name = L["Select this state"], | |
464 values = { | 712 values = { |
465 default = L["by default"], | 713 default = L["by default"], |
466 any = L["when ANY of these"], | 714 any = L["when ANY of these"], |
467 all = L["when ALL of these"], | 715 all = L["when ALL of these"], |
468 custom = L["via custom rule"] | 716 custom = L["via custom rule"], |
717 keybind = L["via keybinding"], | |
469 }, | 718 }, |
470 set = function( info, value ) | 719 set = function( info, value ) |
471 put("type", value) | 720 setrule("type", value) |
472 fixall() | 721 fixall() |
473 update() | 722 update() |
474 end, | 723 end, |
475 get = function( info ) | 724 get = function( info ) |
476 return fetch("type") | 725 return getrule("type") |
477 end, | 726 end, |
478 order = 2 | |
479 }, | 727 }, |
480 clear = { | 728 clear = { |
729 name = L["Clear All"], | |
730 order = 3, | |
481 type = "execute", | 731 type = "execute", |
482 name = L["Clear All"], | 732 hidden = function() |
733 local t = getrule("type") | |
734 return t ~= "any" and t ~= "all" | |
735 end, | |
736 disabled = function() | |
737 local t = getrule("type") | |
738 return t ~= "any" and t ~= "all" | |
739 end, | |
483 func = function() | 740 func = function() |
484 local type = fetch("type") | 741 local type = getrule("type") |
485 if type == "custom" then | 742 if type == "custom" then |
486 put("custom","") | 743 setrule("custom","") |
487 elseif type == "any" or type == "all" then | 744 elseif type == "any" or type == "all" then |
488 put("values", {}) | 745 setrule("values", {}) |
489 end | 746 end |
490 update() | 747 update() |
491 end, | 748 end, |
492 order = 3 | |
493 }, | 749 }, |
494 inputs = { | 750 inputs = { |
751 name = L["Conditions"], | |
752 order = 4, | |
495 type = "multiselect", | 753 type = "multiselect", |
496 name = L["Rules"], | |
497 hidden = function() | 754 hidden = function() |
498 return fetch("type") == "custom" | 755 local t = getrule("type") |
756 return t ~= "any" and t ~= "all" | |
499 end, | 757 end, |
500 disabled = function() | 758 disabled = function() |
501 return fetch("type") == "default" | 759 local t = getrule("type") |
760 return t ~= "any" and t ~= "all" | |
502 end, | 761 end, |
503 values = ruleSelect, | 762 values = ruleSelect, |
504 set = function(info, key, value ) | 763 set = function(info, key, value ) |
505 put(ruleMap[key], value or nil, "values") | 764 setrule(ruleMap[key], value or nil, "values") |
506 if value then | 765 if value then |
507 fixall(ruleMap[key]) | 766 fixall(ruleMap[key]) |
508 end | 767 end |
509 update() | 768 update() |
510 end, | 769 end, |
511 get = function(info, key) | 770 get = function(info, key) |
512 return fetch("values", ruleMap[key]) or false | 771 return getrule("values", ruleMap[key]) or false |
513 end, | 772 end, |
514 order = 4 | |
515 }, | 773 }, |
516 custom = { | 774 custom = { |
775 name = L["Custom Rule"], | |
776 order = 5, | |
517 type = "input", | 777 type = "input", |
518 multiline = true, | 778 multiline = true, |
519 hidden = function() | 779 hidden = function() |
520 return fetch("type") ~= "custom" | 780 return getrule("type") ~= "custom" |
521 end, | 781 end, |
522 disabled = function() | 782 disabled = function() |
523 return fetch("type") == "default" | 783 return getrule("type") ~= "custom" |
524 end, | 784 end, |
525 name = L["Custom Rule"], | |
526 desc = L["Syntax like macro rules: see preset rules for examples"], | 785 desc = L["Syntax like macro rules: see preset rules for examples"], |
527 set = function(info, value) | 786 set = function(info, value) |
528 put("custom",value) | 787 setrule("custom",value) |
529 update() | 788 update() |
530 end, | 789 end, |
531 get = function(info) | 790 get = function(info) |
532 return fetch("custom") or "" | 791 return getrule("custom") or "" |
533 end, | 792 end, |
534 validate = function (info, rule) | 793 validate = function (info, rule) |
535 local s = rule:gsub("%s","") -- remove all spaces | 794 local s = rule:gsub("%s","") -- remove all spaces |
536 -- unfortunately %b and captures don't support the '+' notation, or this would be considerably simpler | 795 -- unfortunately %b and captures don't support the '+' notation, or this would be considerably simpler |
537 repeat | 796 repeat |
544 end | 803 end |
545 s = r | 804 s = r |
546 until c == nil | 805 until c == nil |
547 return true | 806 return true |
548 end, | 807 end, |
549 order = 5, | 808 }, |
550 } | 809 keybind = { |
551 } | 810 name = L["Keybinding"], |
552 } | 811 order = 6, |
812 inline = true, | |
813 hidden = function() return getrule("type") ~= "keybind" end, | |
814 disabled = function() return getrule("type") ~= "keybind" end, | |
815 type = "group", | |
816 args = { | |
817 desc = { | |
818 name = L["Invoking a state keybind overrides all other transition rules. Toggle the keybind again to remove the override and return to the specified toggle-off state."], | |
819 order = 1, | |
820 type = "description", | |
821 }, | |
822 keybind = { | |
823 name = L["State Hotkey"], | |
824 desc = L["Define an override toggle keybind"], | |
825 order = 2, | |
826 type = "keybinding", | |
827 set = function(info, value) | |
828 setrule("keybind",value) | |
829 update() | |
830 end, | |
831 get = function() return getrule("keybind") end, | |
832 }, | |
833 default = { | |
834 name = L["Toggle Off State"], | |
835 desc = L["Select a state to return to when the keybind override is toggled off"], | |
836 order = 3, | |
837 type = "select", | |
838 values = function() | |
839 local t = { } | |
840 for k in pairs(states) do | |
841 if k ~= opts.name then | |
842 t[k] = k | |
843 end | |
844 end | |
845 return t | |
846 end, | |
847 set = function(info, value) | |
848 setrule("keybindreturn",value) | |
849 update() | |
850 end, | |
851 get = function() return getrule("keybindreturn") end, | |
852 }, | |
853 }, | |
854 }, | |
855 }, | |
856 }, | |
553 } | 857 } |
554 return opts | 858 return opts |
555 end | 859 end |
556 | 860 |
557 | 861 |
562 name = L["Dynamic State"], | 866 name = L["Dynamic State"], |
563 childGroups = "tree", | 867 childGroups = "tree", |
564 disabled = InCombatLockdown, | 868 disabled = InCombatLockdown, |
565 args = { | 869 args = { |
566 __desc__ = { | 870 __desc__ = { |
871 name = L["States are evaluated in the order they are listed"], | |
872 order = 1, | |
567 type = "description", | 873 type = "description", |
568 name = L["States are evaluated in the order they are listed"], | |
569 order = 1 | |
570 }, | 874 }, |
571 __new__ = { | 875 __new__ = { |
572 type = "group", | |
573 name = L["New State..."], | 876 name = L["New State..."], |
574 order = 2, | 877 order = 2, |
878 type = "group", | |
575 args = { | 879 args = { |
576 name = { | 880 name = { |
577 type = "input", | |
578 name = L["State Name"], | 881 name = L["State Name"], |
579 desc = L["Set a name for the new state"], | 882 desc = L["Set a name for the new state"], |
883 order = 1, | |
884 type = "input", | |
580 get = function() return private.newstatename or "" end, | 885 get = function() return private.newstatename or "" end, |
581 set = function(info,value) private.newstatename = value end, | 886 set = function(info,value) private.newstatename = value end, |
582 pattern = "^%w*$", | 887 pattern = "^%w*$", |
583 usage = L["State names must be alphanumeric without spaces"], | 888 usage = L["State names must be alphanumeric without spaces"], |
584 order = 1 | |
585 }, | 889 }, |
586 create = { | 890 create = { |
891 name = L["Create State"], | |
892 order = 2, | |
587 type = "execute", | 893 type = "execute", |
588 name = L["Create State"], | |
589 func = function () | 894 func = function () |
590 local name = private.newstatename | 895 local name = private.newstatename |
591 module:CreateState(bar,name) -- TODO: select default state options and pass as final argument | 896 if states[name] then |
592 optionMap[bar].args[name] = CreateStateOptions(bar,name) | 897 ReAction:UserError(L["State named '%s' already exists"]:format(name)) |
593 private.newstatename = "" | 898 else |
899 -- TODO: select default state options and pass as final argument | |
900 states[name] = { } | |
901 optionMap[bar].args[name] = CreateStateOptions(bar,name) | |
902 private.newstatename = "" | |
903 end | |
594 end, | 904 end, |
595 disabled = function() | 905 disabled = function() |
596 local name = private.newstatename or "" | 906 local name = private.newstatename or "" |
597 return #name == 0 or name:find("%W") | 907 return #name == 0 or name:find("%W") |
598 end, | 908 end, |
599 order = 2, | |
600 } | 909 } |
601 } | 910 } |
602 } | 911 } |
603 } | 912 } |
604 } | 913 } |