Mercurial > wow > reaction
changeset 244:f255cd69e890
fold state options into Editor.lua
author | Flick |
---|---|
date | Sat, 26 Mar 2011 12:26:55 -0700 |
parents | 0ea0cdd7f386 |
children | 65f2805957a0 |
files | Editor.lua classes/State.lua classes/classes.xml |
diffstat | 3 files changed, 751 insertions(+), 823 deletions(-) [+] |
line wrap: on
line diff
--- a/Editor.lua Sat Mar 26 11:31:01 2011 -0700 +++ b/Editor.lua Sat Mar 26 12:26:55 2011 -0700 @@ -3,12 +3,17 @@ local L = ReAction.L local _G = _G local wipe = wipe +local format = string.format +local InCombatLockdown = InCombatLockdown +local tfetch = addonTable.tfetch +local tbuild = addonTable.tbuild local AceConfigReg = LibStub("AceConfigRegistry-3.0") local AceConfigDialog = LibStub("AceConfigDialog-3.0") local pointTable = { + NONE = " ", CENTER = L["Center"], LEFT = L["Left"], RIGHT = L["Right"], @@ -325,29 +330,12 @@ }, }, }, - buttonOpts = self:CreateButtonOptions(bar) - }, - plugins = { } + buttonOpts = self:CreateButtonOptions(bar), + stateOpts = self:CreateStateOptions(bar) + } } end - if ReAction.barOptionGenerators then - for module, func in pairs(ReAction.barOptionGenerators) do - local success, r - if type(func) == "string" then - success, r = pcall(module[func], module, bar) - else - success, r = pcall(func, bar) - end - if success then - if r then - args[key].plugins[module:GetName()] = { [module:GetName()] = r } - end - else - geterrorhandler()(r) - end - end - end end function Editor:CreateButtonOptions(bar) @@ -956,6 +944,749 @@ end +------------------------------ +--- Dynamic State options ---- +------------------------------ +do + local ApplyStates = ReAction.Bar.ApplyStates + local CleanupStates = ReAction.Bar.CleanupStates + local SetProperty = ReAction.Bar.SetStateProperty + local GetProperty = ReAction.Bar.GetStateProperty + + -- pre-sorted by the order they should appear in + local rules = { + -- rule fields + { "stance", { {battle = L["Battle Stance"]}, {defensive = L["Defensive Stance"]}, {berserker = L["Berserker Stance"]} } }, + { "form", { {caster = L["Caster Form"]}, {bear = L["Bear Form"]}, {cat = L["Cat Form"]}, {tree = L["Tree of Life"]}, {moonkin = L["Moonkin Form"]} } }, + { "stealth", { {stealth = L["Stealth"]}, {nostealth = L["No Stealth"]}, {shadowdance = L["Shadow Dance"]} } }, + { "shadow", { {shadowform = L["Shadowform"]}, {noshadowform = L["No Shadowform"]} } }, + { "demon", { {demon = L["Demon Form"]}, {nodemon = L["No Demon Form"]} } }, + { "pet", { {pet = L["With Pet"]}, {nopet = L["Without Pet"]} } }, + { "target", { {harm = L["Hostile Target"]}, {help = L["Friendly Target"]}, {notarget = L["No Target"]} } }, + { "focus", { {focusharm = L["Hostile Focus"]}, {focushelp = L["Friendly Focus"]}, {nofocus = L["No Focus"]} } }, + { "possess", { {possess = L["Mind Control"]} } }, + { "vehicle", { {vehicle = L["In a Vehicle"]} } }, + { "group", { {raid = L["Raid"]}, {party = L["Party"]}, {solo = L["Solo"]} } }, + { "combat", { {combat = L["In Combat"]}, {nocombat = L["Out of Combat"]} } }, + } + + local ruleSelect = { } + local ruleMap = { } + local optionMap = setmetatable({},{__mode="k"}) + + + -- unpack rules table into ruleSelect and ruleMap + for _, c in ipairs(rules) do + local rule, fields = unpack(c) + for _, field in ipairs(fields) do + local key, label = next(field) + table.insert(ruleSelect, label) + table.insert(ruleMap, key) + end + end + + local stateOptions = { + ordering = { + name = L["Info"], + order = 1, + type = "group", + args = { + delete = { + name = L["Delete this State"], + order = -1, + type = "execute", + func = "DeleteState", + }, + rename = { + name = L["Name"], + order = 1, + type = "input", + get = "GetName", + set = "SetStateName", + 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 = "MoveStateUp", + }, + down = { + name = L["Down"], + order = 2, + type = "execute", + width = "half", + func = "MoveStateDown", + } + } + } + } + }, + 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" + }, + page = { + name = L["Show Page #"], + order = 11, + type = "select", + width = "half", + disabled = "IsPageDisabled", + hidden = "IsPageHidden", + values = "GetPageValues", + set = "SetProp", + get = "GetPage", + }, + hide = { + name = L["Hide Bar"], + order = 90, + type = "toggle", + set = "SetProp", + get = "GetProp", + }, + --[[ BROKEN + keybindState = { + name = L["Override Keybinds"], + desc = L["Set this state to maintain its own set of keybinds which override the defaults when active"], + order = 91, + type = "toggle", + set = "SetProp", + get = "GetProp", + }, ]] + position = { + name = L["Position"], + order = 92, + type = "group", + inline = true, + args = { + anchorEnable = { + name = L["Reposition"], + order = 1, + type = "toggle", + set = "SetProp", + get = "GetProp", + }, + anchorFrame = { + name = L["Anchor Frame"], + order = 2, + type = "select", + values = "GetAnchorFrames", + set = "SetAnchorFrame", + get = "GetAnchorFrame", + disabled = "GetAnchorDisabled", + hidden = "GetAnchorDisabled", + }, + anchorPoint = { + name = L["Point"], + order = 3, + type = "select", + values = pointTable, + set = "SetAnchorPointProp", + get = "GetAnchorPointProp", + disabled = "GetAnchorDisabled", + hidden = "GetAnchorDisabled", + }, + anchorRelPoint = { + name = L["Relative Point"], + order = 4, + type = "select", + values = pointTable, + set = "SetAnchorPointProp", + get = "GetAnchorPointProp", + disabled = "GetAnchorDisabled", + hidden = "GetAnchorDisabled", + }, + anchorX = { + name = L["X Offset"], + order = 5, + type = "range", + min = -100, + max = 100, + step = 1, + set = "SetProp", + get = "GetProp", + disabled = "GetAnchorDisabled", + hidden = "GetAnchorDisabled", + }, + anchorY = { + name = L["Y Offset"], + order = 6, + type = "range", + min = -100, + max = 100, + step = 1, + set = "SetProp", + get = "GetProp", + disabled = "GetAnchorDisabled", + hidden = "GetAnchorDisabled", + }, + }, + }, + scale = { + name = L["Scale"], + order = 93, + 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.25, + max = 2.5, + step = 0.05, + isPercent = true, + set = "SetProp", + get = "GetScale", + disabled = "GetScaleDisabled", + hidden = "GetScaleDisabled", + }, + }, + }, + alpha = { + name = L["Transparency"], + order = 94, + type = "group", + inline = true, + args = { + enableAlpha = { + name = L["Set Transparency"], + order = 1, + type = "toggle", + set = "SetProp", + get = "GetProp", + }, + alpha = { + name = L["Transparency"], + order = 2, + type = "range", + min = 0, + max = 1, + step = 0.01, + bigStep = 0.05, + isPercent = true, + set = "SetProp", + get = "GetAlpha", + disabled = "GetAlphaDisabled", + hidden = "GetAlphaDisabled", + }, + }, + }, + }, + plugins = { } + }, + rules = { + name = L["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 = "SetType", + get = "GetType", + }, + clear = { + name = L["Clear All"], + order = 3, + type = "execute", + hidden = "GetClearAllDisabled", + disabled = "GetClearAllDisabled", + func = "ClearAllConditions", + }, + inputs = { + name = L["Conditions"], + order = 4, + type = "multiselect", + hidden = "GetConditionsDisabled", + disabled = "GetConditionsDisabled", + values = ruleSelect, + set = "SetCondition", + get = "GetCondition", + }, + custom = { + name = L["Custom Rule"], + order = 5, + type = "input", + multiline = true, + hidden = "GetCustomDisabled", + disabled = "GetCustomDisabled", + desc = L["Syntax like macro rules: see preset rules for examples"], + set = "SetCustomRule", + get = "GetCustomRule", + validate = "ValidateCustomRule", + }, + keybind = { + name = L["Keybinding"], + order = 6, + inline = true, + hidden = "GetKeybindDisabled", + disabled = "GetKeybindDisabled", + type = "group", + args = { + desc = { + name = L["Invoking a state keybind toggles an override of all other transition rules."], + order = 1, + type = "description", + }, + keybind = { + name = L["State Hotkey"], + desc = L["Define an override toggle keybind"], + order = 2, + type = "keybinding", + set = "SetKeybind", + get = "GetKeybind", + }, + }, + }, + }, + }, + } + + local StateHandler = { } + local meta = { __index = StateHandler } + + function StateHandler:New( bar, opts ) + local self = setmetatable( + { + bar = bar + }, + meta ) + + function self:GetName() + return opts.name + end + + function self:SetName(name) + opts.name = name + end + + function self:GetOrder() + return opts.order + end + + -- get reference to states table: even if the bar + -- name changes the states table ref won't + self.states = tbuild(bar:GetConfig(), "states") + self.state = tbuild(self.states, opts.name) + + opts.order = self:GetRuleField("order") + if opts.order == nil then + -- add after the highest + opts.order = 100 + for _, state in pairs(self.states) do + local x = tonumber(tfetch(state, "rule", "order")) + if x and x >= opts.order then + opts.order = x + 1 + end + end + self:SetRuleField("order",opts.order) + end + + return self + end + + -- helper methods + + function StateHandler:SetRuleField( key, value, ... ) + tbuild(self.state, "rule", ...)[key] = value + end + + function StateHandler:GetRuleField( ... ) + return tfetch(self.state, "rule", ...) + end + + function StateHandler: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 + if self:GetRuleField("type") == "all" then + for _, c in ipairs(rules) do + local rule, fields = unpack(c) + local once = false + if setkey then + for idx, field in ipairs(fields) do + if next(field) == setkey then + once = true + end + end + end + for idx, field in ipairs(fields) do + local key = next(field) + if self:GetRuleField("values",key) then + if once and key ~= setkey then + self:SetRuleField(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 + once = true + end + end + end + end + end + + function StateHandler:GetNeighbors() + local before, after + for k, v in pairs(self.states) do + local o = tonumber(tfetch(v, "rule", "order")) + if o and k ~= self:GetName() then + local obefore = tfetch(self.states,before,"rule","order") + local oafter = tfetch(self.states,after,"rule","order") + if o < self:GetOrder() and (not obefore or obefore < o) then + before = k + end + if o > self:GetOrder() and (not oafter or oafter > o) then + after = k + end + end + end + return before, after + end + + function StateHandler:SwapOrder( a, b ) + -- do options table + local args = optionMap[self.bar].args + args[a].order, args[b].order = args[b].order, args[a].order + -- do profile + a = tbuild(self.states, a, "rule") + b = tbuild(self.states, b, "rule") + a.order, b.order = b.order, a.order + end + + -- handler methods + + function StateHandler:GetProp( info ) + -- gets property of the same name as the options arg + return GetProperty(self.bar, self:GetName(), info[#info]) + end + + function StateHandler:SetProp( info, value ) + -- sets property of the same name as the options arg + SetProperty(self.bar, self:GetName(), info[#info], value) + end + + function StateHandler:DeleteState() + if self.states[self:GetName()] then + self.states[self:GetName()] = nil + ApplyStates(self.bar) + end + optionMap[self.bar].args[self:GetName()] = nil + end + + function StateHandler:SetStateName(info, value) + -- check for existing state name + if self.states[value] then + ReAction:UserError(format(L["State named '%s' already exists"],value)) + return + end + local args = optionMap[self.bar].args + local name = self:GetName() + self.states[value], args[value], self.states[name], args[name] = self.states[name], args[name], nil, nil + self:SetName(value) + ApplyStates(self.bar) + ReAction:ShowEditor(self.bar, moduleID, value) + end + + function StateHandler:MoveStateUp() + local before, after = self:GetNeighbors() + if before then + self:SwapOrder(before, self:GetName()) + ApplyStates(self.bar) + end + end + + function StateHandler:MoveStateDown() + local before, after = self:GetNeighbors() + if after then + self:SwapOrder(self:GetName(), after) + ApplyStates(self.bar) + end + end + + function StateHandler:GetAnchorDisabled() + return not GetProperty(self.bar, self:GetName(), "anchorEnable") + end + + function StateHandler:IsPageDisabled() + local n = self.bar:GetConfig().nPages or 1 + return not (n > 1) + end + + function StateHandler:IsPageHidden() + return not self.bar:GetConfig().nPages + end + + function StateHandler:GetPageValues() + if not self._pagevalues then + self._pagevalues = { } + end + local n = self.bar:GetConfig().nPages + -- cache the results + if self._npages ~= n then + self._npages = n + wipe(self._pagevalues) + for i = 1, n do + self._pagevalues["page"..i] = i + end + end + return self._pagevalues + end + + function StateHandler:GetPage(info) + return self:GetProp(info) or 1 + end + + function StateHandler:GetAnchorFrames(info) + self._anchorframes = self._anchorframes or { } + table.wipe(self._anchorframes) + + table.insert(self._anchorframes, "UIParent") + for name, bar in ReAction:IterateBars() do + table.insert(self._anchorframes, bar:GetFrame():GetName()) + end + return self._anchorframes + end + + function StateHandler:GetAnchorFrame(info) + local value = self:GetProp(info) + for k,v in pairs(self._anchorframes) do + if v == value then + return k + end + end + end + + function StateHandler:SetAnchorFrame(info, value) + local f = _G[self._anchorframes[value]] + if f then + self.bar:SetFrameRef("anchor-"..self:GetName(), f) + self:SetProp(info, f:GetName()) + end + end + + function StateHandler:SetAnchorPointProp(info, value) + self:SetProp(info, value ~= "NONE" and value or nil) + end + + function StateHandler:GetAnchorPointProp(info) + return self:GetProp(info) or "NONE" + end + + function StateHandler:GetScale(info) + return self:GetProp(info) or 1.0 + end + + function StateHandler:GetScaleDisabled() + return not GetProperty(self.bar, self:GetName(), "enableScale") + end + + function StateHandler:GetAlpha(info) + return self:GetProp(info) or 1.0 + end + + function StateHandler:GetAlphaDisabled() + return not GetProperty(self.bar, self:GetName(), "enableAlpha") + end + + function StateHandler:SetType(info, value) + self:SetRuleField("type", value) + self:FixAll() + ApplyStates(self.bar) + end + + function StateHandler:GetType() + return self:GetRuleField("type") + end + + function StateHandler:GetClearAllDisabled() + local t = self:GetRuleField("type") + return not( t == "any" or t == "all" or t == "custom") + end + + function StateHandler:ClearAllConditions() + local t = self:GetRuleField("type") + if t == "custom" then + self:SetRuleField("custom","") + elseif t == "any" or t == "all" then + self:SetRuleField("values", {}) + end + ApplyStates(self.bar) + end + + function StateHandler:GetConditionsDisabled() + local t = self:GetRuleField("type") + return not( t == "any" or t == "all") + end + + function StateHandler:SetCondition(info, key, value) + self:SetRuleField(ruleMap[key], value or nil, "values") + if value then + self:FixAll(ruleMap[key]) + end + ApplyStates(self.bar) + end + + function StateHandler:GetCondition(info, key) + return self:GetRuleField("values", ruleMap[key]) or false + end + + function StateHandler:GetCustomDisabled() + return self:GetRuleField("type") ~= "custom" + end + + function StateHandler:SetCustomRule(info, value) + self:SetRuleField("custom",value) + ApplyStates(self.bar) + end + + function StateHandler:GetCustomRule() + return self:GetRuleField("custom") or "" + end + + function StateHandler:ValidateCustomRule(info, value) + local s = value: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 format(L["Invalid custom rule '%s': each clause must appear within [brackets]"],value or "") + end + s = r + until c == nil + return true + end + + function StateHandler:GetKeybindDisabled() + return self:GetRuleField("type") ~= "keybind" + end + + function StateHandler:GetKeybind() + return self:GetRuleField("keybind") + end + + function StateHandler:SetKeybind(info, value) + if value and #value == 0 then + value = nil + end + self:SetRuleField("keybind",value) + ApplyStates(self.bar) + end + + local function CreateStateOptions(bar, name) + local opts = { + type = "group", + name = name, + childGroups = "tab", + args = stateOptions + } + + opts.handler = StateHandler:New(bar,opts) + + return opts + end + + function Editor:CreateStateOptions(bar) + local private = { } + local states = tbuild(bar:GetConfig(), "states") + local options = { + name = L["Dynamic State"], + type = "group", + order = -1, + 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(format(L["State named '%s' already exists"],name)) + else + -- TODO: select default state options and pass as final argument + states[name] = { } + optionMap[bar].args[name] = CreateStateOptions(bar,name) + ReAction:ShowEditor(bar, moduleID, name) + private.newstatename = "" + end + end, + disabled = function() + local name = private.newstatename or "" + return #name == 0 or name:find("%W") + end, + } + } + } + } + } + for name, config in pairs(states) do + options.args[name] = CreateStateOptions(bar,name) + end + optionMap[bar] = options + return options + end +end + ---- Export to ReAction ---- function ReAction:ShowEditor(bar, ...) @@ -980,22 +1711,3 @@ end end -function ReAction:RegisterBarOptionGenerator( module, func ) - if not module or type(module) ~= "table" then -- doesn't need to be a proper module, strictly - error("ReAction:RegisterBarOptionGenerator() : Invalid module") - end - if type(func) == "string" then - if not module[func] then - error(("ReAction:RegisterBarOptionGenerator() : Invalid method '%s'"):format(func)) - end - elseif func and type(func) ~= "function" then - error("ReAction:RegisterBarOptionGenerator() : Invalid function") - end - self.barOptionGenerators = self.barOptionGenerators or { } - self.barOptionGenerators[module] = func - - if self.editor then - self.editor:RefreshBarOptions() - end -end -
--- a/classes/State.lua Sat Mar 26 11:31:01 2011 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,788 +0,0 @@ ---[[ - ReAction bar state driver interface - ---]] - --- local imports -local addonName, addonTable = ... -local ReAction = addonTable.ReAction -local L = ReAction.L -local _G = _G -local format = string.format -local InCombatLockdown = InCombatLockdown -local RegisterStateDriver = RegisterStateDriver -local tfetch = addonTable.tfetch -local tbuild = addonTable.tbuild -local ApplyStates = ReAction.Bar.ApplyStates -local CleanupStates = ReAction.Bar.CleanupStates -local SetProperty = ReAction.Bar.SetStateProperty -local GetProperty = ReAction.Bar.GetStateProperty - --- module declaration -local moduleID = "State" -local module = ReAction:NewModule( moduleID, "AceEvent-3.0" ) - - --- module event handlers -- - -function module:OnInitialize() - ReAction:RegisterBarOptionGenerator(self, "GetBarOptions") -end - - - - --- Options -- - -do - -- pre-sorted by the order they should appear in - local rules = { - -- rule fields - { "stance", { {battle = L["Battle Stance"]}, {defensive = L["Defensive Stance"]}, {berserker = L["Berserker Stance"]} } }, - { "form", { {caster = L["Caster Form"]}, {bear = L["Bear Form"]}, {cat = L["Cat Form"]}, {tree = L["Tree of Life"]}, {moonkin = L["Moonkin Form"]} } }, - { "stealth", { {stealth = L["Stealth"]}, {nostealth = L["No Stealth"]}, {shadowdance = L["Shadow Dance"]} } }, - { "shadow", { {shadowform = L["Shadowform"]}, {noshadowform = L["No Shadowform"]} } }, - { "demon", { {demon = L["Demon Form"]}, {nodemon = L["No Demon Form"]} } }, - { "pet", { {pet = L["With Pet"]}, {nopet = L["Without Pet"]} } }, - { "target", { {harm = L["Hostile Target"]}, {help = L["Friendly Target"]}, {notarget = L["No Target"]} } }, - { "focus", { {focusharm = L["Hostile Focus"]}, {focushelp = L["Friendly Focus"]}, {nofocus = L["No Focus"]} } }, - { "possess", { {possess = L["Mind Control"]} } }, - { "vehicle", { {vehicle = L["In a Vehicle"]} } }, - { "group", { {raid = L["Raid"]}, {party = L["Party"]}, {solo = L["Solo"]} } }, - { "combat", { {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, fields = unpack(c) - for _, field in ipairs(fields) do - local key, label = next(field) - table.insert(ruleSelect, label) - table.insert(ruleMap, key) - end - end - - local stateOptions = { - ordering = { - name = L["Info"], - order = 1, - type = "group", - args = { - delete = { - name = L["Delete this State"], - order = -1, - type = "execute", - func = "DeleteState", - }, - rename = { - name = L["Name"], - order = 1, - type = "input", - get = "GetName", - set = "SetStateName", - 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 = "MoveStateUp", - }, - down = { - name = L["Down"], - order = 2, - type = "execute", - width = "half", - func = "MoveStateDown", - } - } - } - } - }, - 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" - }, - page = { - name = L["Show Page #"], - order = 11, - type = "select", - width = "half", - disabled = "IsPageDisabled", - hidden = "IsPageHidden", - values = "GetPageValues", - set = "SetProp", - get = "GetPage", - }, - hide = { - name = L["Hide Bar"], - order = 90, - type = "toggle", - set = "SetProp", - get = "GetProp", - }, - --[[ BROKEN - keybindState = { - name = L["Override Keybinds"], - desc = L["Set this state to maintain its own set of keybinds which override the defaults when active"], - order = 91, - type = "toggle", - set = "SetProp", - get = "GetProp", - }, ]] - position = { - name = L["Position"], - order = 92, - type = "group", - inline = true, - args = { - anchorEnable = { - name = L["Reposition"], - order = 1, - type = "toggle", - set = "SetProp", - get = "GetProp", - }, - anchorFrame = { - name = L["Anchor Frame"], - order = 2, - type = "select", - values = "GetAnchorFrames", - set = "SetAnchorFrame", - get = "GetAnchorFrame", - disabled = "GetAnchorDisabled", - hidden = "GetAnchorDisabled", - }, - anchorPoint = { - name = L["Point"], - order = 3, - type = "select", - values = pointTable, - set = "SetAnchorPointProp", - get = "GetAnchorPointProp", - disabled = "GetAnchorDisabled", - hidden = "GetAnchorDisabled", - }, - anchorRelPoint = { - name = L["Relative Point"], - order = 4, - type = "select", - values = pointTable, - set = "SetAnchorPointProp", - get = "GetAnchorPointProp", - disabled = "GetAnchorDisabled", - hidden = "GetAnchorDisabled", - }, - anchorX = { - name = L["X Offset"], - order = 5, - type = "range", - min = -100, - max = 100, - step = 1, - set = "SetProp", - get = "GetProp", - disabled = "GetAnchorDisabled", - hidden = "GetAnchorDisabled", - }, - anchorY = { - name = L["Y Offset"], - order = 6, - type = "range", - min = -100, - max = 100, - step = 1, - set = "SetProp", - get = "GetProp", - disabled = "GetAnchorDisabled", - hidden = "GetAnchorDisabled", - }, - }, - }, - scale = { - name = L["Scale"], - order = 93, - 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.25, - max = 2.5, - step = 0.05, - isPercent = true, - set = "SetProp", - get = "GetScale", - disabled = "GetScaleDisabled", - hidden = "GetScaleDisabled", - }, - }, - }, - alpha = { - name = L["Transparency"], - order = 94, - type = "group", - inline = true, - args = { - enableAlpha = { - name = L["Set Transparency"], - order = 1, - type = "toggle", - set = "SetProp", - get = "GetProp", - }, - alpha = { - name = L["Transparency"], - order = 2, - type = "range", - min = 0, - max = 1, - step = 0.01, - bigStep = 0.05, - isPercent = true, - set = "SetProp", - get = "GetAlpha", - disabled = "GetAlphaDisabled", - hidden = "GetAlphaDisabled", - }, - }, - }, - }, - plugins = { } - }, - rules = { - name = L["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 = "SetType", - get = "GetType", - }, - clear = { - name = L["Clear All"], - order = 3, - type = "execute", - hidden = "GetClearAllDisabled", - disabled = "GetClearAllDisabled", - func = "ClearAllConditions", - }, - inputs = { - name = L["Conditions"], - order = 4, - type = "multiselect", - hidden = "GetConditionsDisabled", - disabled = "GetConditionsDisabled", - values = ruleSelect, - set = "SetCondition", - get = "GetCondition", - }, - custom = { - name = L["Custom Rule"], - order = 5, - type = "input", - multiline = true, - hidden = "GetCustomDisabled", - disabled = "GetCustomDisabled", - desc = L["Syntax like macro rules: see preset rules for examples"], - set = "SetCustomRule", - get = "GetCustomRule", - validate = "ValidateCustomRule", - }, - keybind = { - name = L["Keybinding"], - order = 6, - inline = true, - hidden = "GetKeybindDisabled", - disabled = "GetKeybindDisabled", - type = "group", - args = { - desc = { - name = L["Invoking a state keybind toggles an override of all other transition rules."], - order = 1, - type = "description", - }, - keybind = { - name = L["State Hotkey"], - desc = L["Define an override toggle keybind"], - order = 2, - type = "keybinding", - set = "SetKeybind", - get = "GetKeybind", - }, - }, - }, - }, - }, - } - - local StateHandler = { } - local meta = { __index = StateHandler } - - function StateHandler:New( bar, opts ) - local self = setmetatable( - { - bar = bar - }, - meta ) - - function self:GetName() - return opts.name - end - - function self:SetName(name) - opts.name = name - end - - function self:GetOrder() - return opts.order - end - - -- get reference to states table: even if the bar - -- name changes the states table ref won't - self.states = tbuild(bar:GetConfig(), "states") - self.state = tbuild(self.states, opts.name) - - opts.order = self:GetRuleField("order") - if opts.order == nil then - -- add after the highest - opts.order = 100 - for _, state in pairs(self.states) do - local x = tonumber(tfetch(state, "rule", "order")) - if x and x >= opts.order then - opts.order = x + 1 - end - end - self:SetRuleField("order",opts.order) - end - - return self - end - - -- helper methods - - function StateHandler:SetRuleField( key, value, ... ) - tbuild(self.state, "rule", ...)[key] = value - end - - function StateHandler:GetRuleField( ... ) - return tfetch(self.state, "rule", ...) - end - - function StateHandler: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 - if self:GetRuleField("type") == "all" then - for _, c in ipairs(rules) do - local rule, fields = unpack(c) - local once = false - if setkey then - for idx, field in ipairs(fields) do - if next(field) == setkey then - once = true - end - end - end - for idx, field in ipairs(fields) do - local key = next(field) - if self:GetRuleField("values",key) then - if once and key ~= setkey then - self:SetRuleField(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 - once = true - end - end - end - end - end - - function StateHandler:GetNeighbors() - local before, after - for k, v in pairs(self.states) do - local o = tonumber(tfetch(v, "rule", "order")) - if o and k ~= self:GetName() then - local obefore = tfetch(self.states,before,"rule","order") - local oafter = tfetch(self.states,after,"rule","order") - if o < self:GetOrder() and (not obefore or obefore < o) then - before = k - end - if o > self:GetOrder() and (not oafter or oafter > o) then - after = k - end - end - end - return before, after - end - - function StateHandler:SwapOrder( a, b ) - -- do options table - local args = optionMap[self.bar].args - args[a].order, args[b].order = args[b].order, args[a].order - -- do profile - a = tbuild(self.states, a, "rule") - b = tbuild(self.states, b, "rule") - a.order, b.order = b.order, a.order - end - - -- handler methods - - function StateHandler:GetProp( info ) - -- gets property of the same name as the options arg - return GetProperty(self.bar, self:GetName(), info[#info]) - end - - function StateHandler:SetProp( info, value ) - -- sets property of the same name as the options arg - SetProperty(self.bar, self:GetName(), info[#info], value) - end - - function StateHandler:DeleteState() - if self.states[self:GetName()] then - self.states[self:GetName()] = nil - ApplyStates(self.bar) - end - optionMap[self.bar].args[self:GetName()] = nil - end - - function StateHandler:SetStateName(info, value) - -- check for existing state name - if self.states[value] then - ReAction:UserError(format(L["State named '%s' already exists"],value)) - return - end - local args = optionMap[self.bar].args - local name = self:GetName() - self.states[value], args[value], self.states[name], args[name] = self.states[name], args[name], nil, nil - self:SetName(value) - ApplyStates(self.bar) - ReAction:ShowEditor(self.bar, moduleID, value) - end - - function StateHandler:MoveStateUp() - local before, after = self:GetNeighbors() - if before then - self:SwapOrder(before, self:GetName()) - ApplyStates(self.bar) - end - end - - function StateHandler:MoveStateDown() - local before, after = self:GetNeighbors() - if after then - self:SwapOrder(self:GetName(), after) - ApplyStates(self.bar) - end - end - - function StateHandler:GetAnchorDisabled() - return not GetProperty(self.bar, self:GetName(), "anchorEnable") - end - - function StateHandler:IsPageDisabled() - local n = self.bar:GetConfig().nPages or 1 - return not (n > 1) - end - - function StateHandler:IsPageHidden() - return not self.bar:GetConfig().nPages - end - - function StateHandler:GetPageValues() - if not self._pagevalues then - self._pagevalues = { } - end - local n = self.bar:GetConfig().nPages - -- cache the results - if self._npages ~= n then - self._npages = n - wipe(self._pagevalues) - for i = 1, n do - self._pagevalues["page"..i] = i - end - end - return self._pagevalues - end - - function StateHandler:GetPage(info) - return self:GetProp(info) or 1 - end - - function StateHandler:GetAnchorFrames(info) - self._anchorframes = self._anchorframes or { } - table.wipe(self._anchorframes) - - table.insert(self._anchorframes, "UIParent") - for name, bar in ReAction:IterateBars() do - table.insert(self._anchorframes, bar:GetFrame():GetName()) - end - return self._anchorframes - end - - function StateHandler:GetAnchorFrame(info) - local value = self:GetProp(info) - for k,v in pairs(self._anchorframes) do - if v == value then - return k - end - end - end - - function StateHandler:SetAnchorFrame(info, value) - local f = _G[self._anchorframes[value]] - if f then - self.bar:SetFrameRef("anchor-"..self:GetName(), f) - self:SetProp(info, f:GetName()) - end - end - - function StateHandler:SetAnchorPointProp(info, value) - self:SetProp(info, value ~= "NONE" and value or nil) - end - - function StateHandler:GetAnchorPointProp(info) - return self:GetProp(info) or "NONE" - end - - function StateHandler:GetScale(info) - return self:GetProp(info) or 1.0 - end - - function StateHandler:GetScaleDisabled() - return not GetProperty(self.bar, self:GetName(), "enableScale") - end - - function StateHandler:GetAlpha(info) - return self:GetProp(info) or 1.0 - end - - function StateHandler:GetAlphaDisabled() - return not GetProperty(self.bar, self:GetName(), "enableAlpha") - end - - function StateHandler:SetType(info, value) - self:SetRuleField("type", value) - self:FixAll() - ApplyStates(self.bar) - end - - function StateHandler:GetType() - return self:GetRuleField("type") - end - - function StateHandler:GetClearAllDisabled() - local t = self:GetRuleField("type") - return not( t == "any" or t == "all" or t == "custom") - end - - function StateHandler:ClearAllConditions() - local t = self:GetRuleField("type") - if t == "custom" then - self:SetRuleField("custom","") - elseif t == "any" or t == "all" then - self:SetRuleField("values", {}) - end - ApplyStates(self.bar) - end - - function StateHandler:GetConditionsDisabled() - local t = self:GetRuleField("type") - return not( t == "any" or t == "all") - end - - function StateHandler:SetCondition(info, key, value) - self:SetRuleField(ruleMap[key], value or nil, "values") - if value then - self:FixAll(ruleMap[key]) - end - ApplyStates(self.bar) - end - - function StateHandler:GetCondition(info, key) - return self:GetRuleField("values", ruleMap[key]) or false - end - - function StateHandler:GetCustomDisabled() - return self:GetRuleField("type") ~= "custom" - end - - function StateHandler:SetCustomRule(info, value) - self:SetRuleField("custom",value) - ApplyStates(self.bar) - end - - function StateHandler:GetCustomRule() - return self:GetRuleField("custom") or "" - end - - function StateHandler:ValidateCustomRule(info, value) - local s = value: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 format(L["Invalid custom rule '%s': each clause must appear within [brackets]"],value or "") - end - s = r - until c == nil - return true - end - - function StateHandler:GetKeybindDisabled() - return self:GetRuleField("type") ~= "keybind" - end - - function StateHandler:GetKeybind() - return self:GetRuleField("keybind") - end - - function StateHandler:SetKeybind(info, value) - if value and #value == 0 then - value = nil - end - self:SetRuleField("keybind",value) - ApplyStates(self.bar) - end - - local function CreateStateOptions(bar, name) - local opts = { - type = "group", - name = name, - childGroups = "tab", - args = stateOptions - } - - opts.handler = StateHandler:New(bar,opts) - - return opts - end - - function module:GetBarOptions(bar) - local private = { } - local states = tbuild(bar:GetConfig(), "states") - local options = { - name = L["Dynamic State"], - type = "group", - order = -1, - 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(format(L["State named '%s' already exists"],name)) - else - -- TODO: select default state options and pass as final argument - states[name] = { } - optionMap[bar].args[name] = CreateStateOptions(bar,name) - ReAction:ShowEditor(bar, moduleID, name) - private.newstatename = "" - end - end, - disabled = function() - local name = private.newstatename or "" - return #name == 0 or name:find("%W") - end, - } - } - } - } - } - for name, config in pairs(states) do - options.args[name] = CreateStateOptions(bar,name) - end - optionMap[bar] = options - return options - end -end - - --- Export methods to Bar class -- - -ReAction.Bar.GetStateProperty = GetProperty -ReAction.Bar.SetStateProperty = SetProperty
--- a/classes/classes.xml Sat Mar 26 11:31:01 2011 -0700 +++ b/classes/classes.xml Sat Mar 26 12:26:55 2011 -0700 @@ -11,6 +11,5 @@ <Script file="BagButton.lua"/> <Script file="VehicleExitButton.lua"/> <Script file="MultiCastButton.lua"/> -<Script file="State.lua"/> </Ui> \ No newline at end of file