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 },