Mercurial > wow > reaction
changeset 69:a785d6708388
moved State.lua to a top level file
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Tue, 03 Jun 2008 23:05:16 +0000 |
parents | fcb5dad031f9 |
children | 2c12e2b1752e |
files | ReAction.xml State.lua locale/enUS.lua modules/ReAction_State/ReAction_State.lua modules/ReAction_State/ReAction_State.toc modules/ReAction_State/ReAction_State.xml modules/modules.xml |
diffstat | 7 files changed, 992 insertions(+), 996 deletions(-) [+] |
line wrap: on
line diff
--- a/ReAction.xml Tue Jun 03 22:57:34 2008 +0000 +++ b/ReAction.xml Tue Jun 03 23:05:16 2008 +0000 @@ -7,6 +7,7 @@ <Script file="ReAction.lua"/> <Script file="Bar.lua"/> +<Script file="State.lua"/> <Include file="modules\modules.xml"/> <Include file="bindings.lua"/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/State.lua Tue Jun 03 23:05:16 2008 +0000 @@ -0,0 +1,927 @@ +--[[ + ReAction bar state driver interface + +--]] + +-- local imports +local ReAction = ReAction +local L = ReAction.L +local _G = _G +local InCombatLockdown = InCombatLockdown + +-- module declaration +local moduleID = "State" +local module = ReAction:NewModule( moduleID, "AceEvent-3.0" ) + +-- Utility -- + +-- traverse a table tree by key list and fetch the result or first nil +local function tfetch(t, ...) + for i = 1, select('#', ...) do + t = t and t[select(i, ...)] + end + return t +end + +-- traverse a table tree by key list and build tree as necessary +local function tbuild(t, ...) + for i = 1, select('#', ...) do + local key = select(i, ...) + if not t[key] then t[key] = { } end + t = t[key] + end + return t +end + +-- PRIVATE -- + +local InitRules, ApplyStates, SetProperty, GetProperty +do + -- As far as I can tell the macro clauses are NOT locale-specific. + local ruleformats = { + stealth = "stealth", + nostealth = "nostealth", + shadowform = "form:1", + noshadowform = "noform", + pet = "pet", + nopet = "nopet", + harm = "target=target,harm", + help = "target=target,help", + notarget = "target=target,noexists", + focusharm = "target=focus,harm", + focushelp = "target=focus,help", + nofocus = "target=focus,noexists", + raid = "group:raid", + party = "group:party", + solo = "nogroup", + combat = "combat", + nocombat = "nocombat", + } + + -- Have to do these shenanigans instead of hardcoding the stances/forms because + -- the ordering varies if the character is missing a form. For warriors + -- this is rarely a problem (c'mon, who actually skips the level 10 def stance quest?) + -- but for druids it can be. Some people never bother to do the aquatic form quest + -- until well past when they get cat form, and stance 5 can be flight, tree, or moonkin + -- depending on talents. + function InitRules() + local forms = { } + -- sort by icon since it's locale-independent + for i = 1, GetNumShapeshiftForms() do + local icon = GetShapeshiftFormInfo(i) + forms[icon] = i; + end + -- use 9 if not found since 9 is never a valid stance/form + local defensive = forms["Interface\\Icons\\Ability_Warrior_DefensiveStance"] or 9 + local berserker = forms["Interface\\Icons\\Ability_Racial_Avatar"] or 9 + local bear = forms["Interface\\Icons\\Ability_Racial_BearForm"] or 9 -- bear and dire bear share the same icon + local aquatic = forms["Interface\\Icons\\Ability_Druid_AquaticForm"] or 9 + local cat = forms["Interface\\Icons\\Ability_Druid_CatForm"] or 9 + local travel = forms["Interface\\Icons\\Ability_Druid_TravelForm"] or 9 + local treekin = forms["Interface\\Icons\\Ability_Druid_TreeofLife"] or forms["Interface\\Icons\\Spell_Nature_ForceOfNature"] or 9 + local flight = forms["Interface\\Icons\\Ability_Druid_FlightForm"] or 9 -- flight and swift flight share the same icon + + ruleformats.battle = "stance:1" + ruleformats.defensive = ("stance:%d"):format(defensive) + ruleformats.berserker = ("stance:%d"):format(berserker) + ruleformats.caster = ("form:0/%d/%d/%d"):format(aquatic, travel, flight) + ruleformats.bear = ("form:%d"):format(bear) + ruleformats.cat = ("form:%d"):format(cat) + ruleformats.treeOrMoonkin = ("form:%d"):format(treekin) + end + + -- return a new array of keys of table 't', sorted by comparing + -- sub-fields (obtained via tfetch) of the table values + local function fieldsort( t, ... ) + local r = { } + for k in pairs(t) do + table.insert(r,k) + end + local dotdotdot = { ... } + table.sort(r, function(lhs, rhs) + local olhs = tfetch(t[lhs], unpack(dotdotdot)) or 0 + local orhs = tfetch(t[rhs], unpack(dotdotdot)) or 0 + return olhs < orhs + end) + return r + end + + local function BuildRuleString(states) + local s = "" + local default + local sorted = fieldsort(states, "rule", "order") + for idx, name in ipairs(sorted) do + local state = states[name] + local semi = #s > 0 and "; " or "" + local mode = tfetch(state,"rule","type") + if mode == "default" then + default = name + elseif mode == "custom" then + if state.rule.custom then + -- strip out all spaces from the custom rule + s = ("%s%s%s %s"):format(s, semi, state.rule.custom:gsub("%s",""), name) + end + elseif mode == "any" then + if state.rule.values then + local clause = "" + for key, value in pairs(state.rule.values) do + clause = ("%s[%s]"):format(clause,ruleformats[key]) + end + if #clause > 0 then + s = ("%s%s%s %s"):format(s, semi, clause, name) + end + end + elseif mode == "all" then + if state.rule.values then + local clause = "" + for key, value in pairs(state.rule.values) do + clause = ("%s%s%s"):format(clause,#clause > 0 and "," or "", ruleformats[key]) + end + if #clause > 0 then + s = ("%s%s[%s] %s"):format(s, semi, clause, name) + end + end + end + end + if default then + s = ("%s%s%s"):format(s, #s > 0 and "; " or "", default) + end + return s, default + end + + local drivers = setmetatable({},{__mode="k"}) + local propertyFuncs = { } + + function ApplyStates( bar ) + local states = tfetch(module.db.profile.bars, bar:GetName(), "states") + if states then + local frame = bar:GetFrame() + local string, default = BuildRuleString(states) + if string and #string > 0 then + drivers[bar] = true + -- register a map for each "statemap-reaction-XXX" to set 'state' to 'XXX' + -- UNLESS we're in a keybound state AND there's a default state, in which case + -- all keybound states go back to themselves. + local keybindprefix + if default then + local tmp = { } + for state, config in pairs(states) do + if tfetch(config, "rule", "type") == "keybind" then + bar:SetStateKeybind(tfetch(config,"rule","keybind"), state, tfetch(config,"rule","keybindreturn") or default or 0) + table.insert(tmp, ("%s:%s"):format(state,state)) + end + end + if #tmp > 0 then + table.insert(tmp,"") -- to get a final ';' + end + keybindprefix = table.concat(tmp,";") + end + for state in pairs(states) do + frame:SetAttribute(("statemap-reaction-%s"):format(state), ("%s%s"):format(keybindprefix or "",state)) + end + -- register a handler to set the value of attribute "state-reaction" + -- in response to events as per the rule string + RegisterStateDriver(frame, "reaction", string) + SecureStateHeader_Refresh(frame) + elseif drivers[bar] then + UnregisterStateDriver(frame, "reaction") + drivers[bar] = nil + end + for k, f in pairs(propertyFuncs) do + f(bar, states) + end + end + end + + function GetProperty( bar, state, propname ) + return tfetch(module.db.profile.bars, bar:GetName(), "states", state, propname) + end + + function SetProperty( bar, state, propname, value ) + local states = tbuild(module.db.profile.bars, bar:GetName(), "states") + tbuild(states, state)[propname] = value + local f = propertyFuncs[propname] + if f then + f(bar, states) + end + end + + -- state property functions + function propertyFuncs.hide( bar, states ) + local tmp = { } + for state, config in pairs(states) do + if config.hide then + table.insert(tmp, state) + end + end + local s = table.concat(tmp,",") + bar:SetHideStates(s) + end + + function propertyFuncs.page( bar, states ) + local map = { } + for state, config in pairs(states) do + map[state] = config.page + end + bar:SetStatePageMap(state, map) + end + + function propertyFuncs.keybindstate( bar, states ) + local map = { } + for state, config in pairs(states) do + if config.keybindstate then + table.insert(map,state) + end + end + bar:SetStateKeybindOverrideMap(map) + end + + function propertyFuncs.enableanchor( bar, states ) + + end + + function propertyFuncs.anchorPoint( bar, states ) + + end + + function propertyFuncs.anchorRelPoint( bar, states ) + + end + + function propertyFuncs.anchorX( bar, states ) + + end + + function propertyFuncs.anchorY( bar, states ) + + end + + function propertyFuncs.enablescale( bar, states ) + + end + + function propertyFuncs.scale( bar, states ) + + end + +end + + + +-- module event handlers -- + +function module:OnInitialize() + self.db = ReAction.db:RegisterNamespace( moduleID, + { + profile = { + bars = { }, + } + } + ) + + InitRules() + self:RegisterEvent("PLAYER_AURAS_CHANGED") + + ReAction:RegisterBarOptionGenerator(self, "GetBarOptions") + + ReAction.RegisterCallback(self, "OnCreateBar","OnRefreshBar") + ReAction.RegisterCallback(self, "OnRefreshBar") + ReAction.RegisterCallback(self, "OnEraseBar") + ReAction.RegisterCallback(self, "OnRenameBar") + ReAction.RegisterCallback(self, "OnConfigModeChanged") +end + +function module:PLAYER_AURAS_CHANGED() + self:UnregisterEvent("PLAYER_AURAS_CHANGED") + -- on login the number of stances is 0 until this event fires during the init sequence. + -- however if you reload just the UI the number of stances is correct immediately + -- and this event won't fire until you gain/lose buffs/debuffs, at which point you might + -- be in combat. + if not InCombatLockdown() then + InitRules() + for name, bar in ReAction:IterateBars() do + self:OnRefreshBar(nil,bar,name) + end + end +end + +function module:OnRefreshBar(event, bar, name) + local c = self.db.profile.bars[name] + if c then + ApplyStates(bar) + end +end + +function module:OnEraseBar(event, bar, name) + self.db.profile.bars[name] = nil +end + +function module:OnRenameBar(event, bar, oldname, newname) + local b = self.db.profile.bars + bars[newname], bars[oldname] = bars[oldname], nil +end + +function module:OnConfigModeChanged(event, mode) + -- TODO: unregister all state drivers (temporarily) and hidestates +end + + + +-- Options -- + +local CreateBarOptions +do + local function ClassCheck(...) + for i = 1, select('#',...) do + local _, c = UnitClass("player") + if c == select(i,...) then + return false + end + end + return true + end + + -- pre-sorted by the order they should appear in + local rules = { + -- rule hidden fields + { "stance", ClassCheck("WARRIOR"), { {battle = L["Battle Stance"]}, {defensive = L["Defensive Stance"]}, {berserker = L["Berserker Stance"]} } }, + { "form", ClassCheck("DRUID"), { {caster = L["Caster Form"]}, {bear = L["Bear Form"]}, {cat = L["Cat Form"]}, {treeOrMoonkin = L["Tree/Moonkin"]} } }, + { "stealth", ClassCheck("ROGUE","DRUID"), { {stealth = L["Stealth"]}, {nostealth = L["No Stealth"]} } }, + { "shadow", ClassCheck("PRIEST"), { {shadowform = L["Shadowform"]}, {noshadowform = L["No Shadowform"]} } }, + { "pet", ClassCheck("HUNTER","WARLOCK"), { {pet = L["With Pet"]}, {nopet = L["Without Pet"]} } }, + { "target", false, { {harm = L["Hostile Target"]}, {help = L["Friendly Target"]}, {notarget = L["No Target"]} } }, + { "focus", false, { {focusharm = L["Hostile Focus"]}, {focushelp = L["Friendly Focus"]}, {nofocus = L["No Focus"]} } }, + { "group", false, { {raid = L["Raid"]}, {party = L["Party"]}, {solo = L["Solo"]} } }, + { "combat", false, { {combat = L["In Combat"]}, {nocombat = L["Out of Combat"]} } }, + } + + local ruleSelect = { } + local ruleMap = { } + local optionMap = setmetatable({},{__mode="k"}) + + local pointTable = { + NONE = " ", + CENTER = L["Center"], + LEFT = L["Left"], + RIGHT = L["Right"], + TOP = L["Top"], + BOTTOM = L["Bottom"], + TOPLEFT = L["Top Left"], + TOPRIGHT = L["Top Right"], + BOTTOMLEFT = L["Bottom Left"], + BOTTOMRIGHT = L["Bottom Right"], + } + + -- unpack rules table into ruleSelect and ruleMap + for _, c in ipairs(rules) do + local rule, hidden, fields = unpack(c) + if not hidden then + for _, field in ipairs(fields) do + local key, label = next(field) + table.insert(ruleSelect, label) + table.insert(ruleMap, key) + end + end + end + + local function CreateStateOptions(bar, name) + local opts = { + type = "group", + name = name, + childGroups = "tab", + } + + local states = tbuild(module.db.profile.bars, bar:GetName(), "states") + + local function update() + ApplyStates(bar) + end + + local function setrule( key, value, ... ) + tbuild(states, opts.name, "rule", ...)[key] = value + end + + local function getrule( ... ) + return tfetch(states, opts.name, "rule", ...) + end + + local function setprop(info, value) + SetProperty(bar, opts.name, info[#info], value) + end + + local function getprop(info) + return GetProperty(bar, opts.name, info[#info]) + end + + local function fixall(setkey) + -- if multiple selections in the same group are chosen when 'all' is selected, + -- keep only one of them. If changing the mode, the first in the fields list will + -- be chosen arbitrarily. Otherwise, if selecting a new checkbox from the field-set, + -- it will be retained. + local notified = false + for _, c in ipairs(rules) do + local rule, hidden, fields = unpack(c) + local found = false + for key in ipairs(fields) do + if getrule("values",key) then + if (found or setkey) and key ~= setkey then + setrule(key,false,"values") + if not setkey and not notified then + ReAction:UserError(L["Warning: one or more incompatible rules were turned off"]) + notified = true + end + end + found = true + end + end + end + end + + local function getNeighbors() + local before, after + for k, v in pairs(states) do + local o = tonumber(tfetch(v, "rule", "order")) + if o and k ~= opts.name then + local obefore = tfetch(states,before,"rule","order") + local oafter = tfetch(states,after,"rule","order") + if o < opts.order and (not obefore or obefore < o) then + before = k + end + if o > opts.order and (not oafter or oafter > o) then + after = k + end + end + end + return before, after + end + + local function swapOrder( a, b ) + -- do options table + local args = optionMap[bar].args + args[a].order, args[b].order = args[b].order, args[a].order + -- do profile + a = tbuild(states, a, "rule") + b = tbuild(states, b, "rule") + a.order, b.order = b.order, a.order + end + + local function anchordisable() + return not GetProperty(bar, opts.name, "enableanchor") + end + + tbuild(states, name) + + opts.order = getrule("order") + if opts.order == nil then + -- add after the highest + opts.order = 100 + for _, state in pairs(states) do + local x = tonumber(tfetch(state, "rule", "order")) + if x and x >= opts.order then + opts.order = x + 1 + end + end + setrule("order",opts.order) + end + + opts.args = { + ordering = { + name = L["Info"], + order = 1, + type = "group", + args = { + delete = { + name = L["Delete this State"], + order = -1, + type = "execute", + func = function(info) + if states[opts.name] then + states[opts.name] = nil + ApplyStates(bar) + end + optionMap[bar].args[opts.name] = nil + end, + }, + rename = { + name = L["Name"], + order = 1, + type = "input", + get = function() return opts.name end, + set = function(info, value) + -- check for existing state name + if states[value] then + L["State named '%s' already exists"]:format(value) + end + local args = optionMap[bar].args + states[value], args[value], states[opts.name], args[opts.name] = states[opts.name], args[opts.name], nil, nil + opts.name = value + update() + end, + pattern = "^%w*$", + usage = L["State names must be alphanumeric without spaces"], + }, + ordering = { + name = L["Evaluation Order"], + desc = L["State transitions are evaluated in the order listed:\nMove a state up or down to change the order"], + order = 2, + type = "group", + inline = true, + args = { + up = { + name = L["Up"], + order = 1, + type = "execute", + width = "half", + func = function() + local before, after = getNeighbors() + if before then + swapOrder(before, opts.name) + update() + end + end, + }, + down = { + name = L["Down"], + order = 2, + type = "execute", + width = "half", + func = function() + local before, after = getNeighbors() + if after then + swapOrder(opts.name, after) + update() + end + end, + } + } + } + } + }, + properties = { + name = L["Properties"], + order = 2, + type = "group", + args = { + desc = { + name = L["Set the properties for the bar when in this state"], + order = 1, + type = "description" + }, + hide = { + name = L["Hide Bar"], + order = 2, + type = "toggle", + set = setprop, + get = getprop, + }, + page = { + name = L["Show Page #"], + order = 3, + type = "select", + disabled = function() + return bar:GetNumPages() < 2 + end, + hidden = function() + return bar:GetNumPages() < 2 + end, + values = function() + local pages = { none = " " } + for i = 1, bar:GetNumPages() do + pages[i] = i + end + return pages + end, + set = function(info, value) + if value == "none" then + setprop(info, nil) + else + setprop(info, value) + end + end, + get = function(info) + return getprop(info) or "none" + end, + }, + keybindstate = { + name = L["Override Keybinds"], + desc = L["Set this state to maintain its own set of keybinds which override the defaults when active"], + order = 4, + type = "toggle", + set = setprop, + get = getprop, + }, + position = { + name = L["Position"], + order = 5, + type = "group", + inline = true, + args = { + enableanchor = { + name = L["Set New Position"], + order = 1, + type = "toggle", + set = setprop, + get = getprop, + }, + anchorPoint = { + name = L["Point"], + order = 2, + type = "select", + values = pointTable, + set = function(info, value) setprop(info, value ~= "NONE" and value or nil) end, + get = function(info) return getprop(info) or "NONE" end, + disabled = anchordisable, + hidden = anchordisable, + }, + anchorRelPoint = { + name = L["Relative Point"], + order = 3, + type = "select", + values = pointTable, + set = function(info, value) setprop(info, value ~= "NONE" and value or nil) end, + get = function(info) return getprop(info) or "NONE" end, + disabled = anchordisable, + hidden = anchordisable, + }, + anchorX = { + name = L["X Offset"], + order = 4, + type = "range", + min = -100, + max = 100, + step = 1, + set = setprop, + get = getprop, + disabled = anchordisable, + hidden = anchordisable, + }, + anchorY = { + name = L["Y Offset"], + order = 5, + type = "range", + min = -100, + max = 100, + step = 1, + set = setprop, + get = getprop, + disabled = anchordisable, + hidden = anchordisable, + }, + }, + }, + scale = { + name = L["Scale"], + order = 6, + type = "group", + inline = true, + args = { + enablescale = { + name = L["Set New Scale"], + order = 1, + type = "toggle", + set = setprop, + get = getprop, + }, + scale = { + name = L["Scale"], + order = 2, + type = "range", + min = 0.1, + max = 2.5, + step = 0.05, + isPercent = true, + set = setprop, + get = function(info) return getprop(info) or 1 end, + disabled = function() return not GetProperty(bar, opts.name, "enablescale") end, + hidden = function() return not GetProperty(bar, opts.name, "enablescale") end, + }, + }, + }, + }, + }, + rules = { + name = L["Selection Rule"], + order = 3, + type = "group", + args = { + mode = { + name = L["Select this state"], + order = 2, + type = "select", + style = "radio", + values = { + default = L["by default"], + any = L["when ANY of these"], + all = L["when ALL of these"], + custom = L["via custom rule"], + keybind = L["via keybinding"], + }, + set = function( info, value ) + setrule("type", value) + fixall() + update() + end, + get = function( info ) + return getrule("type") + end, + }, + clear = { + name = L["Clear All"], + order = 3, + type = "execute", + hidden = function() + local t = getrule("type") + return t ~= "any" and t ~= "all" + end, + disabled = function() + local t = getrule("type") + return t ~= "any" and t ~= "all" + end, + func = function() + local type = getrule("type") + if type == "custom" then + setrule("custom","") + elseif type == "any" or type == "all" then + setrule("values", {}) + end + update() + end, + }, + inputs = { + name = L["Conditions"], + order = 4, + type = "multiselect", + hidden = function() + local t = getrule("type") + return t ~= "any" and t ~= "all" + end, + disabled = function() + local t = getrule("type") + return t ~= "any" and t ~= "all" + end, + values = ruleSelect, + set = function(info, key, value ) + setrule(ruleMap[key], value or nil, "values") + if value then + fixall(ruleMap[key]) + end + update() + end, + get = function(info, key) + return getrule("values", ruleMap[key]) or false + end, + }, + custom = { + name = L["Custom Rule"], + order = 5, + type = "input", + multiline = true, + hidden = function() + return getrule("type") ~= "custom" + end, + disabled = function() + return getrule("type") ~= "custom" + end, + desc = L["Syntax like macro rules: see preset rules for examples"], + set = function(info, value) + setrule("custom",value) + update() + end, + get = function(info) + return getrule("custom") or "" + end, + validate = function (info, rule) + local s = rule:gsub("%s","") -- remove all spaces + -- unfortunately %b and captures don't support the '+' notation, or this would be considerably simpler + repeat + if s == "" then + return true + end + local c, r = s:match("(%b[])(.*)") + if c == nil and s and #s > 0 then + return L["Invalid custom rule '%s': each clause must appear within [brackets]"]:format(rule) + end + s = r + until c == nil + return true + end, + }, + keybind = { + name = L["Keybinding"], + order = 6, + inline = true, + hidden = function() return getrule("type") ~= "keybind" end, + disabled = function() return getrule("type") ~= "keybind" end, + type = "group", + args = { + desc = { + 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."], + order = 1, + type = "description", + }, + keybind = { + name = L["State Hotkey"], + desc = L["Define an override toggle keybind"], + order = 2, + type = "keybinding", + set = function(info, value) + setrule("keybind",value) + update() + end, + get = function() return getrule("keybind") end, + }, + default = { + name = L["Toggle Off State"], + desc = L["Select a state to return to when the keybind override is toggled off"], + order = 3, + type = "select", + values = function() + local t = { } + for k in pairs(states) do + if k ~= opts.name then + t[k] = k + end + end + return t + end, + set = function(info, value) + setrule("keybindreturn",value) + update() + end, + get = function() return getrule("keybindreturn") end, + }, + }, + }, + }, + }, + } + return opts + end + + + CreateBarOptions = function(bar) + local private = { } + local options = { + type = "group", + name = L["Dynamic State"], + childGroups = "tree", + disabled = InCombatLockdown, + args = { + __desc__ = { + name = L["States are evaluated in the order they are listed"], + order = 1, + type = "description", + }, + __new__ = { + name = L["New State..."], + order = 2, + type = "group", + args = { + name = { + name = L["State Name"], + desc = L["Set a name for the new state"], + order = 1, + type = "input", + get = function() return private.newstatename or "" end, + set = function(info,value) private.newstatename = value end, + pattern = "^%w*$", + usage = L["State names must be alphanumeric without spaces"], + }, + create = { + name = L["Create State"], + order = 2, + type = "execute", + func = function () + local name = private.newstatename + if states[name] then + ReAction:UserError(L["State named '%s' already exists"]:format(name)) + else + -- TODO: select default state options and pass as final argument + states[name] = { } + optionMap[bar].args[name] = CreateStateOptions(bar,name) + private.newstatename = "" + end + end, + disabled = function() + local name = private.newstatename or "" + return #name == 0 or name:find("%W") + end, + } + } + } + } + } + local states = tfetch(module.db.profile.bars, bar:GetName(), "states") + if states then + for name, config in pairs(states) do + options.args[name] = CreateStateOptions(bar,name) + end + end + optionMap[bar] = options + return options + end +end + +function module:GetBarOptions(bar) + return CreateBarOptions(bar) +end
--- a/locale/enUS.lua Tue Jun 03 22:57:34 2008 +0000 +++ b/locale/enUS.lua Tue Jun 03 23:05:16 2008 +0000 @@ -38,69 +38,7 @@ "Remove the bar from the current profile", "Are you sure you want to remove this bar?", --- modules/ReAction_HideBlizzard -"Hide Blizzard Action Bars", -"Hide the default main bar and extra action bars", - --- modules/ReAction_Action -"Action Bar", -"Action Bars", -"Hide Empty Buttons", -"Action Buttons", - --- modules/ReAction_PetAction -"Pet Action Bar", -"Pet Buttons", - --- modules/ReAction_PossessBar -"Possess Bar", -"Hide Empty Possess Bar Buttons", -"Possess Buttons", - --- modules/ReAction_ConfigUI -"Center", -"Left", -"Right", -"Top", -"Bottom", -"Top Left", -"Top Right", -"Bottom Left", -"Bottom Right", -"Edit Bars...", -"Show the ReAction Bar Editor dialogue", -"Close on Launch", -"Close the Interface Options window when launching the ReAction Bar Editor", -"Bar Editor", -"Global Config", -"Opens ReAction global configuration settings panel", -"Close the Bar Editor when opening the ReAction global Interface Options", -"New Bar...", -"Choose a name, type, and initial grid for your new action bar:", -"Bar Name", -"Enter a name for your new action bar", -"Button Type", -"Create Bar", -"General", -"Rename Bar", -"Delete Bar", -"Anchor", -"Frame", -"The frame that the bar is anchored to", -"Point", -"Anchor point on the bar frame", -"Relative Point", -"Anchor point on the target frame", -"X offset", -"Y offset", -"Button Grid", -"Rows", -"Columns", -"Size", -"Spacing", -"Use the mouse to arrange and resize the bars on screen. Tooltips on bars indicate additional functionality.", - --- modules/ReAction_State +-- State.lua "State named '%s' already exists", "Battle Stance", "Defensive Stance", @@ -176,6 +114,69 @@ "State named '%s' already exists", +-- modules/ReAction_HideBlizzard +"Hide Blizzard Action Bars", +"Hide the default main bar and extra action bars", + +-- modules/ReAction_Action +"Action Bar", +"Action Bars", +"Hide Empty Buttons", +"Action Buttons", + +-- modules/ReAction_PetAction +"Pet Action Bar", +"Pet Buttons", + +-- modules/ReAction_PossessBar +"Possess Bar", +"Hide Empty Possess Bar Buttons", +"Possess Buttons", + +-- modules/ReAction_ConfigUI +"Center", +"Left", +"Right", +"Top", +"Bottom", +"Top Left", +"Top Right", +"Bottom Left", +"Bottom Right", +"Edit Bars...", +"Show the ReAction Bar Editor dialogue", +"Close on Launch", +"Close the Interface Options window when launching the ReAction Bar Editor", +"Bar Editor", +"Global Config", +"Opens ReAction global configuration settings panel", +"Close the Bar Editor when opening the ReAction global Interface Options", +"New Bar...", +"Choose a name, type, and initial grid for your new action bar:", +"Bar Name", +"Enter a name for your new action bar", +"Button Type", +"Create Bar", +"General", +"Rename Bar", +"Delete Bar", +"Anchor", +"Frame", +"The frame that the bar is anchored to", +"Point", +"Anchor point on the bar frame", +"Relative Point", +"Anchor point on the target frame", +"X offset", +"Y offset", +"Button Grid", +"Rows", +"Columns", +"Size", +"Spacing", +"Use the mouse to arrange and resize the bars on screen. Tooltips on bars indicate additional functionality.", + + }) do L[string] = true end
--- a/modules/ReAction_State/ReAction_State.lua Tue Jun 03 22:57:34 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,927 +0,0 @@ ---[[ - ReAction bar state driver interface - ---]] - --- local imports -local ReAction = ReAction -local L = ReAction.L -local _G = _G -local InCombatLockdown = InCombatLockdown - --- module declaration -local moduleID = "State" -local module = ReAction:NewModule( moduleID, "AceEvent-3.0" ) - --- Utility -- - --- traverse a table tree by key list and fetch the result or first nil -local function tfetch(t, ...) - for i = 1, select('#', ...) do - t = t and t[select(i, ...)] - end - return t -end - --- traverse a table tree by key list and build tree as necessary -local function tbuild(t, ...) - for i = 1, select('#', ...) do - local key = select(i, ...) - if not t[key] then t[key] = { } end - t = t[key] - end - return t -end - --- PRIVATE -- - -local InitRules, ApplyStates, SetProperty, GetProperty -do - -- As far as I can tell the macro clauses are NOT locale-specific. - local ruleformats = { - stealth = "stealth", - nostealth = "nostealth", - shadowform = "form:1", - noshadowform = "noform", - pet = "pet", - nopet = "nopet", - harm = "target=target,harm", - help = "target=target,help", - notarget = "target=target,noexists", - focusharm = "target=focus,harm", - focushelp = "target=focus,help", - nofocus = "target=focus,noexists", - raid = "group:raid", - party = "group:party", - solo = "nogroup", - combat = "combat", - nocombat = "nocombat", - } - - -- Have to do these shenanigans instead of hardcoding the stances/forms because - -- the ordering varies if the character is missing a form. For warriors - -- this is rarely a problem (c'mon, who actually skips the level 10 def stance quest?) - -- but for druids it can be. Some people never bother to do the aquatic form quest - -- until well past when they get cat form, and stance 5 can be flight, tree, or moonkin - -- depending on talents. - function InitRules() - local forms = { } - -- sort by icon since it's locale-independent - for i = 1, GetNumShapeshiftForms() do - local icon = GetShapeshiftFormInfo(i) - forms[icon] = i; - end - -- use 9 if not found since 9 is never a valid stance/form - local defensive = forms["Interface\\Icons\\Ability_Warrior_DefensiveStance"] or 9 - local berserker = forms["Interface\\Icons\\Ability_Racial_Avatar"] or 9 - local bear = forms["Interface\\Icons\\Ability_Racial_BearForm"] or 9 -- bear and dire bear share the same icon - local aquatic = forms["Interface\\Icons\\Ability_Druid_AquaticForm"] or 9 - local cat = forms["Interface\\Icons\\Ability_Druid_CatForm"] or 9 - local travel = forms["Interface\\Icons\\Ability_Druid_TravelForm"] or 9 - local treekin = forms["Interface\\Icons\\Ability_Druid_TreeofLife"] or forms["Interface\\Icons\\Spell_Nature_ForceOfNature"] or 9 - local flight = forms["Interface\\Icons\\Ability_Druid_FlightForm"] or 9 -- flight and swift flight share the same icon - - ruleformats.battle = "stance:1" - ruleformats.defensive = ("stance:%d"):format(defensive) - ruleformats.berserker = ("stance:%d"):format(berserker) - ruleformats.caster = ("form:0/%d/%d/%d"):format(aquatic, travel, flight) - ruleformats.bear = ("form:%d"):format(bear) - ruleformats.cat = ("form:%d"):format(cat) - ruleformats.treeOrMoonkin = ("form:%d"):format(treekin) - end - - -- return a new array of keys of table 't', sorted by comparing - -- sub-fields (obtained via tfetch) of the table values - local function fieldsort( t, ... ) - local r = { } - for k in pairs(t) do - table.insert(r,k) - end - local dotdotdot = { ... } - table.sort(r, function(lhs, rhs) - local olhs = tfetch(t[lhs], unpack(dotdotdot)) or 0 - local orhs = tfetch(t[rhs], unpack(dotdotdot)) or 0 - return olhs < orhs - end) - return r - end - - local function BuildRuleString(states) - local s = "" - local default - local sorted = fieldsort(states, "rule", "order") - for idx, name in ipairs(sorted) do - local state = states[name] - local semi = #s > 0 and "; " or "" - local mode = tfetch(state,"rule","type") - if mode == "default" then - default = name - elseif mode == "custom" then - if state.rule.custom then - -- strip out all spaces from the custom rule - s = ("%s%s%s %s"):format(s, semi, state.rule.custom:gsub("%s",""), name) - end - elseif mode == "any" then - if state.rule.values then - local clause = "" - for key, value in pairs(state.rule.values) do - clause = ("%s[%s]"):format(clause,ruleformats[key]) - end - if #clause > 0 then - s = ("%s%s%s %s"):format(s, semi, clause, name) - end - end - elseif mode == "all" then - if state.rule.values then - local clause = "" - for key, value in pairs(state.rule.values) do - clause = ("%s%s%s"):format(clause,#clause > 0 and "," or "", ruleformats[key]) - end - if #clause > 0 then - s = ("%s%s[%s] %s"):format(s, semi, clause, name) - end - end - end - end - if default then - s = ("%s%s%s"):format(s, #s > 0 and "; " or "", default) - end - return s, default - end - - local drivers = setmetatable({},{__mode="k"}) - local propertyFuncs = { } - - function ApplyStates( bar ) - local states = tfetch(module.db.profile.bars, bar:GetName(), "states") - if states then - local frame = bar:GetFrame() - local string, default = BuildRuleString(states) - if string and #string > 0 then - drivers[bar] = true - -- register a map for each "statemap-reaction-XXX" to set 'state' to 'XXX' - -- UNLESS we're in a keybound state AND there's a default state, in which case - -- all keybound states go back to themselves. - local keybindprefix - if default then - local tmp = { } - for state, config in pairs(states) do - if tfetch(config, "rule", "type") == "keybind" then - bar:SetStateKeybind(tfetch(config,"rule","keybind"), state, tfetch(config,"rule","keybindreturn") or default or 0) - table.insert(tmp, ("%s:%s"):format(state,state)) - end - end - if #tmp > 0 then - table.insert(tmp,"") -- to get a final ';' - end - keybindprefix = table.concat(tmp,";") - end - for state in pairs(states) do - frame:SetAttribute(("statemap-reaction-%s"):format(state), ("%s%s"):format(keybindprefix or "",state)) - end - -- register a handler to set the value of attribute "state-reaction" - -- in response to events as per the rule string - RegisterStateDriver(frame, "reaction", string) - SecureStateHeader_Refresh(frame) - elseif drivers[bar] then - UnregisterStateDriver(frame, "reaction") - drivers[bar] = nil - end - for k, f in pairs(propertyFuncs) do - f(bar, states) - end - end - end - - function GetProperty( bar, state, propname ) - return tfetch(module.db.profile.bars, bar:GetName(), "states", state, propname) - end - - function SetProperty( bar, state, propname, value ) - local states = tbuild(module.db.profile.bars, bar:GetName(), "states") - tbuild(states, state)[propname] = value - local f = propertyFuncs[propname] - if f then - f(bar, states) - end - end - - -- state property functions - function propertyFuncs.hide( bar, states ) - local tmp = { } - for state, config in pairs(states) do - if config.hide then - table.insert(tmp, state) - end - end - local s = table.concat(tmp,",") - bar:SetHideStates(s) - end - - function propertyFuncs.page( bar, states ) - local map = { } - for state, config in pairs(states) do - map[state] = config.page - end - bar:SetStatePageMap(state, map) - end - - function propertyFuncs.keybindstate( bar, states ) - local map = { } - for state, config in pairs(states) do - if config.keybindstate then - table.insert(map,state) - end - end - bar:SetStateKeybindOverrideMap(map) - end - - function propertyFuncs.enableanchor( bar, states ) - - end - - function propertyFuncs.anchorPoint( bar, states ) - - end - - function propertyFuncs.anchorRelPoint( bar, states ) - - end - - function propertyFuncs.anchorX( bar, states ) - - end - - function propertyFuncs.anchorY( bar, states ) - - end - - function propertyFuncs.enablescale( bar, states ) - - end - - function propertyFuncs.scale( bar, states ) - - end - -end - - - --- module event handlers -- - -function module:OnInitialize() - self.db = ReAction.db:RegisterNamespace( moduleID, - { - profile = { - bars = { }, - } - } - ) - - InitRules() - self:RegisterEvent("PLAYER_AURAS_CHANGED") - - ReAction:RegisterBarOptionGenerator(self, "GetBarOptions") - - ReAction.RegisterCallback(self, "OnCreateBar","OnRefreshBar") - ReAction.RegisterCallback(self, "OnRefreshBar") - ReAction.RegisterCallback(self, "OnEraseBar") - ReAction.RegisterCallback(self, "OnRenameBar") - ReAction.RegisterCallback(self, "OnConfigModeChanged") -end - -function module:PLAYER_AURAS_CHANGED() - self:UnregisterEvent("PLAYER_AURAS_CHANGED") - -- on login the number of stances is 0 until this event fires during the init sequence. - -- however if you reload just the UI the number of stances is correct immediately - -- and this event won't fire until you gain/lose buffs/debuffs, at which point you might - -- be in combat. - if not InCombatLockdown() then - InitRules() - for name, bar in ReAction:IterateBars() do - self:OnRefreshBar(nil,bar,name) - end - end -end - -function module:OnRefreshBar(event, bar, name) - local c = self.db.profile.bars[name] - if c then - ApplyStates(bar) - end -end - -function module:OnEraseBar(event, bar, name) - self.db.profile.bars[name] = nil -end - -function module:OnRenameBar(event, bar, oldname, newname) - local b = self.db.profile.bars - bars[newname], bars[oldname] = bars[oldname], nil -end - -function module:OnConfigModeChanged(event, mode) - -- TODO: unregister all state drivers (temporarily) and hidestates -end - - - --- Options -- - -local CreateBarOptions -do - local function ClassCheck(...) - for i = 1, select('#',...) do - local _, c = UnitClass("player") - if c == select(i,...) then - return false - end - end - return true - end - - -- pre-sorted by the order they should appear in - local rules = { - -- rule hidden fields - { "stance", ClassCheck("WARRIOR"), { {battle = L["Battle Stance"]}, {defensive = L["Defensive Stance"]}, {berserker = L["Berserker Stance"]} } }, - { "form", ClassCheck("DRUID"), { {caster = L["Caster Form"]}, {bear = L["Bear Form"]}, {cat = L["Cat Form"]}, {treeOrMoonkin = L["Tree/Moonkin"]} } }, - { "stealth", ClassCheck("ROGUE","DRUID"), { {stealth = L["Stealth"]}, {nostealth = L["No Stealth"]} } }, - { "shadow", ClassCheck("PRIEST"), { {shadowform = L["Shadowform"]}, {noshadowform = L["No Shadowform"]} } }, - { "pet", ClassCheck("HUNTER","WARLOCK"), { {pet = L["With Pet"]}, {nopet = L["Without Pet"]} } }, - { "target", false, { {harm = L["Hostile Target"]}, {help = L["Friendly Target"]}, {notarget = L["No Target"]} } }, - { "focus", false, { {focusharm = L["Hostile Focus"]}, {focushelp = L["Friendly Focus"]}, {nofocus = L["No Focus"]} } }, - { "group", false, { {raid = L["Raid"]}, {party = L["Party"]}, {solo = L["Solo"]} } }, - { "combat", false, { {combat = L["In Combat"]}, {nocombat = L["Out of Combat"]} } }, - } - - local ruleSelect = { } - local ruleMap = { } - local optionMap = setmetatable({},{__mode="k"}) - - local pointTable = { - NONE = " ", - CENTER = L["Center"], - LEFT = L["Left"], - RIGHT = L["Right"], - TOP = L["Top"], - BOTTOM = L["Bottom"], - TOPLEFT = L["Top Left"], - TOPRIGHT = L["Top Right"], - BOTTOMLEFT = L["Bottom Left"], - BOTTOMRIGHT = L["Bottom Right"], - } - - -- unpack rules table into ruleSelect and ruleMap - for _, c in ipairs(rules) do - local rule, hidden, fields = unpack(c) - if not hidden then - for _, field in ipairs(fields) do - local key, label = next(field) - table.insert(ruleSelect, label) - table.insert(ruleMap, key) - end - end - end - - local function CreateStateOptions(bar, name) - local opts = { - type = "group", - name = name, - childGroups = "tab", - } - - local states = tbuild(module.db.profile.bars, bar:GetName(), "states") - - local function update() - ApplyStates(bar) - end - - local function setrule( key, value, ... ) - tbuild(states, opts.name, "rule", ...)[key] = value - end - - local function getrule( ... ) - return tfetch(states, opts.name, "rule", ...) - end - - local function setprop(info, value) - SetProperty(bar, opts.name, info[#info], value) - end - - local function getprop(info) - return GetProperty(bar, opts.name, info[#info]) - end - - local function fixall(setkey) - -- if multiple selections in the same group are chosen when 'all' is selected, - -- keep only one of them. If changing the mode, the first in the fields list will - -- be chosen arbitrarily. Otherwise, if selecting a new checkbox from the field-set, - -- it will be retained. - local notified = false - for _, c in ipairs(rules) do - local rule, hidden, fields = unpack(c) - local found = false - for key in ipairs(fields) do - if getrule("values",key) then - if (found or setkey) and key ~= setkey then - setrule(key,false,"values") - if not setkey and not notified then - ReAction:UserError(L["Warning: one or more incompatible rules were turned off"]) - notified = true - end - end - found = true - end - end - end - end - - local function getNeighbors() - local before, after - for k, v in pairs(states) do - local o = tonumber(tfetch(v, "rule", "order")) - if o and k ~= opts.name then - local obefore = tfetch(states,before,"rule","order") - local oafter = tfetch(states,after,"rule","order") - if o < opts.order and (not obefore or obefore < o) then - before = k - end - if o > opts.order and (not oafter or oafter > o) then - after = k - end - end - end - return before, after - end - - local function swapOrder( a, b ) - -- do options table - local args = optionMap[bar].args - args[a].order, args[b].order = args[b].order, args[a].order - -- do profile - a = tbuild(states, a, "rule") - b = tbuild(states, b, "rule") - a.order, b.order = b.order, a.order - end - - local function anchordisable() - return not GetProperty(bar, opts.name, "enableanchor") - end - - tbuild(states, name) - - opts.order = getrule("order") - if opts.order == nil then - -- add after the highest - opts.order = 100 - for _, state in pairs(states) do - local x = tonumber(tfetch(state, "rule", "order")) - if x and x >= opts.order then - opts.order = x + 1 - end - end - setrule("order",opts.order) - end - - opts.args = { - ordering = { - name = L["Info"], - order = 1, - type = "group", - args = { - delete = { - name = L["Delete this State"], - order = -1, - type = "execute", - func = function(info) - if states[opts.name] then - states[opts.name] = nil - ApplyStates(bar) - end - optionMap[bar].args[opts.name] = nil - end, - }, - rename = { - name = L["Name"], - order = 1, - type = "input", - get = function() return opts.name end, - set = function(info, value) - -- check for existing state name - if states[value] then - L["State named '%s' already exists"]:format(value) - end - local args = optionMap[bar].args - states[value], args[value], states[opts.name], args[opts.name] = states[opts.name], args[opts.name], nil, nil - opts.name = value - update() - end, - pattern = "^%w*$", - usage = L["State names must be alphanumeric without spaces"], - }, - ordering = { - name = L["Evaluation Order"], - desc = L["State transitions are evaluated in the order listed:\nMove a state up or down to change the order"], - order = 2, - type = "group", - inline = true, - args = { - up = { - name = L["Up"], - order = 1, - type = "execute", - width = "half", - func = function() - local before, after = getNeighbors() - if before then - swapOrder(before, opts.name) - update() - end - end, - }, - down = { - name = L["Down"], - order = 2, - type = "execute", - width = "half", - func = function() - local before, after = getNeighbors() - if after then - swapOrder(opts.name, after) - update() - end - end, - } - } - } - } - }, - properties = { - name = L["Properties"], - order = 2, - type = "group", - args = { - desc = { - name = L["Set the properties for the bar when in this state"], - order = 1, - type = "description" - }, - hide = { - name = L["Hide Bar"], - order = 2, - type = "toggle", - set = setprop, - get = getprop, - }, - page = { - name = L["Show Page #"], - order = 3, - type = "select", - disabled = function() - return bar:GetNumPages() < 2 - end, - hidden = function() - return bar:GetNumPages() < 2 - end, - values = function() - local pages = { none = " " } - for i = 1, bar:GetNumPages() do - pages[i] = i - end - return pages - end, - set = function(info, value) - if value == "none" then - setprop(info, nil) - else - setprop(info, value) - end - end, - get = function(info) - return getprop(info) or "none" - end, - }, - keybindstate = { - name = L["Override Keybinds"], - desc = L["Set this state to maintain its own set of keybinds which override the defaults when active"], - order = 4, - type = "toggle", - set = setprop, - get = getprop, - }, - position = { - name = L["Position"], - order = 5, - type = "group", - inline = true, - args = { - enableanchor = { - name = L["Set New Position"], - order = 1, - type = "toggle", - set = setprop, - get = getprop, - }, - anchorPoint = { - name = L["Point"], - order = 2, - type = "select", - values = pointTable, - set = function(info, value) setprop(info, value ~= "NONE" and value or nil) end, - get = function(info) return getprop(info) or "NONE" end, - disabled = anchordisable, - hidden = anchordisable, - }, - anchorRelPoint = { - name = L["Relative Point"], - order = 3, - type = "select", - values = pointTable, - set = function(info, value) setprop(info, value ~= "NONE" and value or nil) end, - get = function(info) return getprop(info) or "NONE" end, - disabled = anchordisable, - hidden = anchordisable, - }, - anchorX = { - name = L["X Offset"], - order = 4, - type = "range", - min = -100, - max = 100, - step = 1, - set = setprop, - get = getprop, - disabled = anchordisable, - hidden = anchordisable, - }, - anchorY = { - name = L["Y Offset"], - order = 5, - type = "range", - min = -100, - max = 100, - step = 1, - set = setprop, - get = getprop, - disabled = anchordisable, - hidden = anchordisable, - }, - }, - }, - scale = { - name = L["Scale"], - order = 6, - type = "group", - inline = true, - args = { - enablescale = { - name = L["Set New Scale"], - order = 1, - type = "toggle", - set = setprop, - get = getprop, - }, - scale = { - name = L["Scale"], - order = 2, - type = "range", - min = 0.1, - max = 2.5, - step = 0.05, - isPercent = true, - set = setprop, - get = function(info) return getprop(info) or 1 end, - disabled = function() return not GetProperty(bar, opts.name, "enablescale") end, - hidden = function() return not GetProperty(bar, opts.name, "enablescale") end, - }, - }, - }, - }, - }, - rules = { - name = L["Selection Rule"], - order = 3, - type = "group", - args = { - mode = { - name = L["Select this state"], - order = 2, - type = "select", - style = "radio", - values = { - default = L["by default"], - any = L["when ANY of these"], - all = L["when ALL of these"], - custom = L["via custom rule"], - keybind = L["via keybinding"], - }, - set = function( info, value ) - setrule("type", value) - fixall() - update() - end, - get = function( info ) - return getrule("type") - end, - }, - clear = { - name = L["Clear All"], - order = 3, - type = "execute", - hidden = function() - local t = getrule("type") - return t ~= "any" and t ~= "all" - end, - disabled = function() - local t = getrule("type") - return t ~= "any" and t ~= "all" - end, - func = function() - local type = getrule("type") - if type == "custom" then - setrule("custom","") - elseif type == "any" or type == "all" then - setrule("values", {}) - end - update() - end, - }, - inputs = { - name = L["Conditions"], - order = 4, - type = "multiselect", - hidden = function() - local t = getrule("type") - return t ~= "any" and t ~= "all" - end, - disabled = function() - local t = getrule("type") - return t ~= "any" and t ~= "all" - end, - values = ruleSelect, - set = function(info, key, value ) - setrule(ruleMap[key], value or nil, "values") - if value then - fixall(ruleMap[key]) - end - update() - end, - get = function(info, key) - return getrule("values", ruleMap[key]) or false - end, - }, - custom = { - name = L["Custom Rule"], - order = 5, - type = "input", - multiline = true, - hidden = function() - return getrule("type") ~= "custom" - end, - disabled = function() - return getrule("type") ~= "custom" - end, - desc = L["Syntax like macro rules: see preset rules for examples"], - set = function(info, value) - setrule("custom",value) - update() - end, - get = function(info) - return getrule("custom") or "" - end, - validate = function (info, rule) - local s = rule:gsub("%s","") -- remove all spaces - -- unfortunately %b and captures don't support the '+' notation, or this would be considerably simpler - repeat - if s == "" then - return true - end - local c, r = s:match("(%b[])(.*)") - if c == nil and s and #s > 0 then - return L["Invalid custom rule '%s': each clause must appear within [brackets]"]:format(rule) - end - s = r - until c == nil - return true - end, - }, - keybind = { - name = L["Keybinding"], - order = 6, - inline = true, - hidden = function() return getrule("type") ~= "keybind" end, - disabled = function() return getrule("type") ~= "keybind" end, - type = "group", - args = { - desc = { - 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."], - order = 1, - type = "description", - }, - keybind = { - name = L["State Hotkey"], - desc = L["Define an override toggle keybind"], - order = 2, - type = "keybinding", - set = function(info, value) - setrule("keybind",value) - update() - end, - get = function() return getrule("keybind") end, - }, - default = { - name = L["Toggle Off State"], - desc = L["Select a state to return to when the keybind override is toggled off"], - order = 3, - type = "select", - values = function() - local t = { } - for k in pairs(states) do - if k ~= opts.name then - t[k] = k - end - end - return t - end, - set = function(info, value) - setrule("keybindreturn",value) - update() - end, - get = function() return getrule("keybindreturn") end, - }, - }, - }, - }, - }, - } - return opts - end - - - CreateBarOptions = function(bar) - local private = { } - local options = { - type = "group", - name = L["Dynamic State"], - childGroups = "tree", - disabled = InCombatLockdown, - args = { - __desc__ = { - name = L["States are evaluated in the order they are listed"], - order = 1, - type = "description", - }, - __new__ = { - name = L["New State..."], - order = 2, - type = "group", - args = { - name = { - name = L["State Name"], - desc = L["Set a name for the new state"], - order = 1, - type = "input", - get = function() return private.newstatename or "" end, - set = function(info,value) private.newstatename = value end, - pattern = "^%w*$", - usage = L["State names must be alphanumeric without spaces"], - }, - create = { - name = L["Create State"], - order = 2, - type = "execute", - func = function () - local name = private.newstatename - if states[name] then - ReAction:UserError(L["State named '%s' already exists"]:format(name)) - else - -- TODO: select default state options and pass as final argument - states[name] = { } - optionMap[bar].args[name] = CreateStateOptions(bar,name) - private.newstatename = "" - end - end, - disabled = function() - local name = private.newstatename or "" - return #name == 0 or name:find("%W") - end, - } - } - } - } - } - local states = tfetch(module.db.profile.bars, bar:GetName(), "states") - if states then - for name, config in pairs(states) do - options.args[name] = CreateStateOptions(bar,name) - end - end - optionMap[bar] = options - return options - end -end - -function module:GetBarOptions(bar) - return CreateBarOptions(bar) -end
--- a/modules/ReAction_State/ReAction_State.toc Tue Jun 03 22:57:34 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -## Interface: 20300 -## Title: ReAction: State -## Notes: Dynamic bar states for ReAction -## DefaultState: enabled -## LoadOnDemand: 1 -## Author: Flick -## Version: 1.0 -## X-Category: Action Bars -## Dependencies: ReAction - -ReAction_State.xml
--- a/modules/ReAction_State/ReAction_State.xml Tue Jun 03 22:57:34 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -<Ui xmlns="http://www.blizzard.com/wow/ui/" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd"> - -<Script file="ReAction_State.lua"/> - -</Ui> \ No newline at end of file
--- a/modules/modules.xml Tue Jun 03 22:57:34 2008 +0000 +++ b/modules/modules.xml Tue Jun 03 23:05:16 2008 +0000 @@ -6,8 +6,6 @@ <Include file="ReAction_ConfigUI\ReAction_ConfigUI.xml"/> <Include file="ReAction_HideBlizzard\ReAction_HideBlizzard.xml"/> -<!-- general utility modules --> -<Include file="ReAction_State\ReAction_State.xml"/> <!-- button modules --> <Include file="ReAction_Action\ReAction_Action.xml"/>