Mercurial > wow > reaction
comparison State.lua @ 72:aa88aed52124
Fixed bugs with state keybinds.
Simplified state driver API
| author | Flick <flickerstreak@gmail.com> |
|---|---|
| date | Thu, 05 Jun 2008 18:34:36 +0000 |
| parents | 3d2cef5dc459 |
| children | 06cd74bdc7da |
comparison
equal
deleted
inserted
replaced
| 71:3d2cef5dc459 | 72:aa88aed52124 |
|---|---|
| 104 return olhs < orhs | 104 return olhs < orhs |
| 105 end) | 105 end) |
| 106 return r | 106 return r |
| 107 end | 107 end |
| 108 | 108 |
| 109 local function BuildRuleString(states) | 109 local function BuildRules(states) |
| 110 local s = "" | 110 local rules = { } |
| 111 local keybinds = { } | |
| 111 local default | 112 local default |
| 112 local sorted = fieldsort(states, "rule", "order") | 113 local fmt = "%s %s" |
| 113 for idx, name in ipairs(sorted) do | 114 for idx, state in ipairs(fieldsort(states, "rule", "order")) do |
| 114 local state = states[name] | 115 local c = states[state].rule |
| 115 local semi = #s > 0 and "; " or "" | 116 local type = tfetch(c,"type") |
| 116 local mode = tfetch(state,"rule","type") | 117 if type == "default" then |
| 117 if mode == "default" then | 118 default = default or state |
| 118 default = name | 119 elseif type == "keybind" then |
| 119 elseif mode == "custom" then | 120 keybinds[state] = c.keybind or false |
| 120 if state.rule.custom then | 121 elseif type == "custom" then |
| 122 if c.custom then | |
| 121 -- strip out all spaces from the custom rule | 123 -- strip out all spaces from the custom rule |
| 122 s = ("%s%s%s %s"):format(s, semi, state.rule.custom:gsub("%s",""), name) | 124 table.insert(rules, fmt:format(c.custom:gsub("%s",""), state)) |
| 123 end | 125 end |
| 124 elseif mode == "any" then | 126 elseif type == "any" then |
| 125 if state.rule.values then | 127 if c.values then |
| 126 local clause = "" | 128 local clauses = { } |
| 127 for key, value in pairs(state.rule.values) do | 129 for key, value in pairs(c.values) do |
| 128 clause = ("%s[%s]"):format(clause,ruleformats[key]) | 130 table.insert(clauses, ("[%s]"):format(ruleformats[key])) |
| 129 end | 131 end |
| 130 if #clause > 0 then | 132 if #clauses > 0 then |
| 131 s = ("%s%s%s %s"):format(s, semi, clause, name) | 133 table.insert(rules, fmt:format(table.concat(clauses), state)) |
| 132 end | 134 end |
| 133 end | 135 end |
| 134 elseif mode == "all" then | 136 elseif type == "all" then |
| 135 if state.rule.values then | 137 if c.values then |
| 136 local clause = "" | 138 local clauses = { } |
| 137 for key, value in pairs(state.rule.values) do | 139 for key, value in pairs(c.values) do |
| 138 clause = ("%s%s%s"):format(clause,#clause > 0 and "," or "", ruleformats[key]) | 140 table.insert(clauses, ruleformats[key]) |
| 139 end | 141 end |
| 140 if #clause > 0 then | 142 if #clauses > 0 then |
| 141 s = ("%s%s[%s] %s"):format(s, semi, clause, name) | 143 table.insert(rules, fmt:format(("[%s]"):format(table.concat(clauses, ",")), state)) |
| 142 end | 144 end |
| 143 end | 145 end |
| 144 end | 146 end |
| 145 end | 147 end |
| 146 if default then | 148 if default then |
| 147 s = ("%s%s%s"):format(s, #s > 0 and "; " or "", default) | 149 table.insert(rules, default) |
| 148 end | 150 end |
| 149 return s, default | 151 return rules, keybinds |
| 150 end | 152 end |
| 151 | 153 |
| 152 local drivers = setmetatable({},{__mode="k"}) | |
| 153 local propertyFuncs = { } | 154 local propertyFuncs = { } |
| 154 | 155 |
| 155 function ApplyStates( bar ) | 156 function ApplyStates( bar ) |
| 156 local states = tfetch(module.db.profile.bars, bar:GetName(), "states") | 157 local states = tfetch(module.db.profile.bars, bar:GetName(), "states") |
| 157 if states then | 158 if states then |
| 158 local frame = bar:GetFrame() | 159 local rules, keybinds = BuildRules(states) |
| 159 local string, default = BuildRuleString(states) | 160 bar:SetStateDriver(table.concat(rules,";"), states, keybinds) |
| 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 | |
| 182 -- register a handler to set the value of attribute "state-reaction" | |
| 183 -- in response to events as per the rule string | |
| 184 RegisterStateDriver(frame, "reaction", string) | |
| 185 SecureStateHeader_Refresh(frame) | |
| 186 elseif drivers[bar] then | |
| 187 UnregisterStateDriver(frame, "reaction") | |
| 188 drivers[bar] = nil | |
| 189 end | |
| 190 for k, f in pairs(propertyFuncs) do | 161 for k, f in pairs(propertyFuncs) do |
| 191 f(bar, states) | 162 f(bar, states) |
| 192 end | 163 end |
| 193 end | 164 end |
| 194 end | 165 end |
| 814 hidden = function() return getrule("type") ~= "keybind" end, | 785 hidden = function() return getrule("type") ~= "keybind" end, |
| 815 disabled = function() return getrule("type") ~= "keybind" end, | 786 disabled = function() return getrule("type") ~= "keybind" end, |
| 816 type = "group", | 787 type = "group", |
| 817 args = { | 788 args = { |
| 818 desc = { | 789 desc = { |
| 819 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."], | 790 name = L["Invoking a state keybind toggles an override of all other transition rules."], |
| 820 order = 1, | 791 order = 1, |
| 821 type = "description", | 792 type = "description", |
| 822 }, | 793 }, |
| 823 keybind = { | 794 keybind = { |
| 824 name = L["State Hotkey"], | 795 name = L["State Hotkey"], |
| 831 end | 802 end |
| 832 setrule("keybind",value) | 803 setrule("keybind",value) |
| 833 update() | 804 update() |
| 834 end, | 805 end, |
| 835 get = function() return getrule("keybind") end, | 806 get = function() return getrule("keybind") end, |
| 836 }, | |
| 837 default = { | |
| 838 name = L["Toggle Off State"], | |
| 839 desc = L["Select a state to return to when the keybind override is toggled off"], | |
| 840 order = 3, | |
| 841 type = "select", | |
| 842 values = function() | |
| 843 local t = { } | |
| 844 for k in pairs(states) do | |
| 845 if k ~= opts.name then | |
| 846 t[k] = k | |
| 847 end | |
| 848 end | |
| 849 return t | |
| 850 end, | |
| 851 set = function(info, value) | |
| 852 setrule("keybindreturn",value) | |
| 853 update() | |
| 854 end, | |
| 855 get = function() return getrule("keybindreturn") end, | |
| 856 }, | 807 }, |
| 857 }, | 808 }, |
| 858 }, | 809 }, |
| 859 }, | 810 }, |
| 860 }, | 811 }, |
