comparison Editor.lua @ 244:f255cd69e890

fold state options into Editor.lua
author Flick
date Sat, 26 Mar 2011 12:26:55 -0700
parents 704f4a05a1d7
children d7a7ef367faf
comparison
equal deleted inserted replaced
243:0ea0cdd7f386 244:f255cd69e890
1 local addonName, addonTable = ... 1 local addonName, addonTable = ...
2 local ReAction = addonTable.ReAction 2 local ReAction = addonTable.ReAction
3 local L = ReAction.L 3 local L = ReAction.L
4 local _G = _G 4 local _G = _G
5 local wipe = wipe 5 local wipe = wipe
6 local format = string.format
7 local InCombatLockdown = InCombatLockdown
8 local tfetch = addonTable.tfetch
9 local tbuild = addonTable.tbuild
6 10
7 local AceConfigReg = LibStub("AceConfigRegistry-3.0") 11 local AceConfigReg = LibStub("AceConfigRegistry-3.0")
8 local AceConfigDialog = LibStub("AceConfigDialog-3.0") 12 local AceConfigDialog = LibStub("AceConfigDialog-3.0")
9 13
10 14
11 local pointTable = { 15 local pointTable = {
16 NONE = " ",
12 CENTER = L["Center"], 17 CENTER = L["Center"],
13 LEFT = L["Left"], 18 LEFT = L["Left"],
14 RIGHT = L["Right"], 19 RIGHT = L["Right"],
15 TOP = L["Top"], 20 TOP = L["Top"],
16 BOTTOM = L["Bottom"], 21 BOTTOM = L["Bottom"],
323 bigStep = 0.05, 328 bigStep = 0.05,
324 order = 4, 329 order = 4,
325 }, 330 },
326 }, 331 },
327 }, 332 },
328 buttonOpts = self:CreateButtonOptions(bar) 333 buttonOpts = self:CreateButtonOptions(bar),
329 }, 334 stateOpts = self:CreateStateOptions(bar)
330 plugins = { } 335 }
331 } 336 }
332 end 337 end
333 338
334 if ReAction.barOptionGenerators then
335 for module, func in pairs(ReAction.barOptionGenerators) do
336 local success, r
337 if type(func) == "string" then
338 success, r = pcall(module[func], module, bar)
339 else
340 success, r = pcall(func, bar)
341 end
342 if success then
343 if r then
344 args[key].plugins[module:GetName()] = { [module:GetName()] = r }
345 end
346 else
347 geterrorhandler()(r)
348 end
349 end
350 end
351 end 339 end
352 340
353 function Editor:CreateButtonOptions(bar) 341 function Editor:CreateButtonOptions(bar)
354 local buttonClass = bar:GetButtonClass() 342 local buttonClass = bar:GetButtonClass()
355 local classID = buttonClass:GetButtonTypeID() 343 local classID = buttonClass:GetButtonTypeID()
954 } 942 }
955 end 943 end
956 end 944 end
957 945
958 946
947 ------------------------------
948 --- Dynamic State options ----
949 ------------------------------
950 do
951 local ApplyStates = ReAction.Bar.ApplyStates
952 local CleanupStates = ReAction.Bar.CleanupStates
953 local SetProperty = ReAction.Bar.SetStateProperty
954 local GetProperty = ReAction.Bar.GetStateProperty
955
956 -- pre-sorted by the order they should appear in
957 local rules = {
958 -- rule fields
959 { "stance", { {battle = L["Battle Stance"]}, {defensive = L["Defensive Stance"]}, {berserker = L["Berserker Stance"]} } },
960 { "form", { {caster = L["Caster Form"]}, {bear = L["Bear Form"]}, {cat = L["Cat Form"]}, {tree = L["Tree of Life"]}, {moonkin = L["Moonkin Form"]} } },
961 { "stealth", { {stealth = L["Stealth"]}, {nostealth = L["No Stealth"]}, {shadowdance = L["Shadow Dance"]} } },
962 { "shadow", { {shadowform = L["Shadowform"]}, {noshadowform = L["No Shadowform"]} } },
963 { "demon", { {demon = L["Demon Form"]}, {nodemon = L["No Demon Form"]} } },
964 { "pet", { {pet = L["With Pet"]}, {nopet = L["Without Pet"]} } },
965 { "target", { {harm = L["Hostile Target"]}, {help = L["Friendly Target"]}, {notarget = L["No Target"]} } },
966 { "focus", { {focusharm = L["Hostile Focus"]}, {focushelp = L["Friendly Focus"]}, {nofocus = L["No Focus"]} } },
967 { "possess", { {possess = L["Mind Control"]} } },
968 { "vehicle", { {vehicle = L["In a Vehicle"]} } },
969 { "group", { {raid = L["Raid"]}, {party = L["Party"]}, {solo = L["Solo"]} } },
970 { "combat", { {combat = L["In Combat"]}, {nocombat = L["Out of Combat"]} } },
971 }
972
973 local ruleSelect = { }
974 local ruleMap = { }
975 local optionMap = setmetatable({},{__mode="k"})
976
977
978 -- unpack rules table into ruleSelect and ruleMap
979 for _, c in ipairs(rules) do
980 local rule, fields = unpack(c)
981 for _, field in ipairs(fields) do
982 local key, label = next(field)
983 table.insert(ruleSelect, label)
984 table.insert(ruleMap, key)
985 end
986 end
987
988 local stateOptions = {
989 ordering = {
990 name = L["Info"],
991 order = 1,
992 type = "group",
993 args = {
994 delete = {
995 name = L["Delete this State"],
996 order = -1,
997 type = "execute",
998 func = "DeleteState",
999 },
1000 rename = {
1001 name = L["Name"],
1002 order = 1,
1003 type = "input",
1004 get = "GetName",
1005 set = "SetStateName",
1006 pattern = "^%w*$",
1007 usage = L["State names must be alphanumeric without spaces"],
1008 },
1009 ordering = {
1010 name = L["Evaluation Order"],
1011 desc = L["State transitions are evaluated in the order listed:\nMove a state up or down to change the order"],
1012 order = 2,
1013 type = "group",
1014 inline = true,
1015 args = {
1016 up = {
1017 name = L["Up"],
1018 order = 1,
1019 type = "execute",
1020 width = "half",
1021 func = "MoveStateUp",
1022 },
1023 down = {
1024 name = L["Down"],
1025 order = 2,
1026 type = "execute",
1027 width = "half",
1028 func = "MoveStateDown",
1029 }
1030 }
1031 }
1032 }
1033 },
1034 properties = {
1035 name = L["Properties"],
1036 order = 2,
1037 type = "group",
1038 args = {
1039 desc = {
1040 name = L["Set the properties for the bar when in this state"],
1041 order = 1,
1042 type = "description"
1043 },
1044 page = {
1045 name = L["Show Page #"],
1046 order = 11,
1047 type = "select",
1048 width = "half",
1049 disabled = "IsPageDisabled",
1050 hidden = "IsPageHidden",
1051 values = "GetPageValues",
1052 set = "SetProp",
1053 get = "GetPage",
1054 },
1055 hide = {
1056 name = L["Hide Bar"],
1057 order = 90,
1058 type = "toggle",
1059 set = "SetProp",
1060 get = "GetProp",
1061 },
1062 --[[ BROKEN
1063 keybindState = {
1064 name = L["Override Keybinds"],
1065 desc = L["Set this state to maintain its own set of keybinds which override the defaults when active"],
1066 order = 91,
1067 type = "toggle",
1068 set = "SetProp",
1069 get = "GetProp",
1070 }, ]]
1071 position = {
1072 name = L["Position"],
1073 order = 92,
1074 type = "group",
1075 inline = true,
1076 args = {
1077 anchorEnable = {
1078 name = L["Reposition"],
1079 order = 1,
1080 type = "toggle",
1081 set = "SetProp",
1082 get = "GetProp",
1083 },
1084 anchorFrame = {
1085 name = L["Anchor Frame"],
1086 order = 2,
1087 type = "select",
1088 values = "GetAnchorFrames",
1089 set = "SetAnchorFrame",
1090 get = "GetAnchorFrame",
1091 disabled = "GetAnchorDisabled",
1092 hidden = "GetAnchorDisabled",
1093 },
1094 anchorPoint = {
1095 name = L["Point"],
1096 order = 3,
1097 type = "select",
1098 values = pointTable,
1099 set = "SetAnchorPointProp",
1100 get = "GetAnchorPointProp",
1101 disabled = "GetAnchorDisabled",
1102 hidden = "GetAnchorDisabled",
1103 },
1104 anchorRelPoint = {
1105 name = L["Relative Point"],
1106 order = 4,
1107 type = "select",
1108 values = pointTable,
1109 set = "SetAnchorPointProp",
1110 get = "GetAnchorPointProp",
1111 disabled = "GetAnchorDisabled",
1112 hidden = "GetAnchorDisabled",
1113 },
1114 anchorX = {
1115 name = L["X Offset"],
1116 order = 5,
1117 type = "range",
1118 min = -100,
1119 max = 100,
1120 step = 1,
1121 set = "SetProp",
1122 get = "GetProp",
1123 disabled = "GetAnchorDisabled",
1124 hidden = "GetAnchorDisabled",
1125 },
1126 anchorY = {
1127 name = L["Y Offset"],
1128 order = 6,
1129 type = "range",
1130 min = -100,
1131 max = 100,
1132 step = 1,
1133 set = "SetProp",
1134 get = "GetProp",
1135 disabled = "GetAnchorDisabled",
1136 hidden = "GetAnchorDisabled",
1137 },
1138 },
1139 },
1140 scale = {
1141 name = L["Scale"],
1142 order = 93,
1143 type = "group",
1144 inline = true,
1145 args = {
1146 enableScale = {
1147 name = L["Set New Scale"],
1148 order = 1,
1149 type = "toggle",
1150 set = "SetProp",
1151 get = "GetProp",
1152 },
1153 scale = {
1154 name = L["Scale"],
1155 order = 2,
1156 type = "range",
1157 min = 0.25,
1158 max = 2.5,
1159 step = 0.05,
1160 isPercent = true,
1161 set = "SetProp",
1162 get = "GetScale",
1163 disabled = "GetScaleDisabled",
1164 hidden = "GetScaleDisabled",
1165 },
1166 },
1167 },
1168 alpha = {
1169 name = L["Transparency"],
1170 order = 94,
1171 type = "group",
1172 inline = true,
1173 args = {
1174 enableAlpha = {
1175 name = L["Set Transparency"],
1176 order = 1,
1177 type = "toggle",
1178 set = "SetProp",
1179 get = "GetProp",
1180 },
1181 alpha = {
1182 name = L["Transparency"],
1183 order = 2,
1184 type = "range",
1185 min = 0,
1186 max = 1,
1187 step = 0.01,
1188 bigStep = 0.05,
1189 isPercent = true,
1190 set = "SetProp",
1191 get = "GetAlpha",
1192 disabled = "GetAlphaDisabled",
1193 hidden = "GetAlphaDisabled",
1194 },
1195 },
1196 },
1197 },
1198 plugins = { }
1199 },
1200 rules = {
1201 name = L["Rule"],
1202 order = 3,
1203 type = "group",
1204 args = {
1205 mode = {
1206 name = L["Select this state"],
1207 order = 2,
1208 type = "select",
1209 style = "radio",
1210 values = {
1211 default = L["by default"],
1212 any = L["when ANY of these"],
1213 all = L["when ALL of these"],
1214 custom = L["via custom rule"],
1215 keybind = L["via keybinding"],
1216 },
1217 set = "SetType",
1218 get = "GetType",
1219 },
1220 clear = {
1221 name = L["Clear All"],
1222 order = 3,
1223 type = "execute",
1224 hidden = "GetClearAllDisabled",
1225 disabled = "GetClearAllDisabled",
1226 func = "ClearAllConditions",
1227 },
1228 inputs = {
1229 name = L["Conditions"],
1230 order = 4,
1231 type = "multiselect",
1232 hidden = "GetConditionsDisabled",
1233 disabled = "GetConditionsDisabled",
1234 values = ruleSelect,
1235 set = "SetCondition",
1236 get = "GetCondition",
1237 },
1238 custom = {
1239 name = L["Custom Rule"],
1240 order = 5,
1241 type = "input",
1242 multiline = true,
1243 hidden = "GetCustomDisabled",
1244 disabled = "GetCustomDisabled",
1245 desc = L["Syntax like macro rules: see preset rules for examples"],
1246 set = "SetCustomRule",
1247 get = "GetCustomRule",
1248 validate = "ValidateCustomRule",
1249 },
1250 keybind = {
1251 name = L["Keybinding"],
1252 order = 6,
1253 inline = true,
1254 hidden = "GetKeybindDisabled",
1255 disabled = "GetKeybindDisabled",
1256 type = "group",
1257 args = {
1258 desc = {
1259 name = L["Invoking a state keybind toggles an override of all other transition rules."],
1260 order = 1,
1261 type = "description",
1262 },
1263 keybind = {
1264 name = L["State Hotkey"],
1265 desc = L["Define an override toggle keybind"],
1266 order = 2,
1267 type = "keybinding",
1268 set = "SetKeybind",
1269 get = "GetKeybind",
1270 },
1271 },
1272 },
1273 },
1274 },
1275 }
1276
1277 local StateHandler = { }
1278 local meta = { __index = StateHandler }
1279
1280 function StateHandler:New( bar, opts )
1281 local self = setmetatable(
1282 {
1283 bar = bar
1284 },
1285 meta )
1286
1287 function self:GetName()
1288 return opts.name
1289 end
1290
1291 function self:SetName(name)
1292 opts.name = name
1293 end
1294
1295 function self:GetOrder()
1296 return opts.order
1297 end
1298
1299 -- get reference to states table: even if the bar
1300 -- name changes the states table ref won't
1301 self.states = tbuild(bar:GetConfig(), "states")
1302 self.state = tbuild(self.states, opts.name)
1303
1304 opts.order = self:GetRuleField("order")
1305 if opts.order == nil then
1306 -- add after the highest
1307 opts.order = 100
1308 for _, state in pairs(self.states) do
1309 local x = tonumber(tfetch(state, "rule", "order"))
1310 if x and x >= opts.order then
1311 opts.order = x + 1
1312 end
1313 end
1314 self:SetRuleField("order",opts.order)
1315 end
1316
1317 return self
1318 end
1319
1320 -- helper methods
1321
1322 function StateHandler:SetRuleField( key, value, ... )
1323 tbuild(self.state, "rule", ...)[key] = value
1324 end
1325
1326 function StateHandler:GetRuleField( ... )
1327 return tfetch(self.state, "rule", ...)
1328 end
1329
1330 function StateHandler:FixAll( setkey )
1331 -- if multiple selections in the same group are chosen when 'all' is selected,
1332 -- keep only one of them. If changing the mode, the first in the fields list will
1333 -- be chosen arbitrarily. Otherwise, if selecting a new checkbox from the field-set,
1334 -- it will be retained.
1335 local notified = false
1336 if self:GetRuleField("type") == "all" then
1337 for _, c in ipairs(rules) do
1338 local rule, fields = unpack(c)
1339 local once = false
1340 if setkey then
1341 for idx, field in ipairs(fields) do
1342 if next(field) == setkey then
1343 once = true
1344 end
1345 end
1346 end
1347 for idx, field in ipairs(fields) do
1348 local key = next(field)
1349 if self:GetRuleField("values",key) then
1350 if once and key ~= setkey then
1351 self:SetRuleField(key,false,"values")
1352 if not setkey and not notified then
1353 ReAction:UserError(L["Warning: one or more incompatible rules were turned off"])
1354 notified = true
1355 end
1356 end
1357 once = true
1358 end
1359 end
1360 end
1361 end
1362 end
1363
1364 function StateHandler:GetNeighbors()
1365 local before, after
1366 for k, v in pairs(self.states) do
1367 local o = tonumber(tfetch(v, "rule", "order"))
1368 if o and k ~= self:GetName() then
1369 local obefore = tfetch(self.states,before,"rule","order")
1370 local oafter = tfetch(self.states,after,"rule","order")
1371 if o < self:GetOrder() and (not obefore or obefore < o) then
1372 before = k
1373 end
1374 if o > self:GetOrder() and (not oafter or oafter > o) then
1375 after = k
1376 end
1377 end
1378 end
1379 return before, after
1380 end
1381
1382 function StateHandler:SwapOrder( a, b )
1383 -- do options table
1384 local args = optionMap[self.bar].args
1385 args[a].order, args[b].order = args[b].order, args[a].order
1386 -- do profile
1387 a = tbuild(self.states, a, "rule")
1388 b = tbuild(self.states, b, "rule")
1389 a.order, b.order = b.order, a.order
1390 end
1391
1392 -- handler methods
1393
1394 function StateHandler:GetProp( info )
1395 -- gets property of the same name as the options arg
1396 return GetProperty(self.bar, self:GetName(), info[#info])
1397 end
1398
1399 function StateHandler:SetProp( info, value )
1400 -- sets property of the same name as the options arg
1401 SetProperty(self.bar, self:GetName(), info[#info], value)
1402 end
1403
1404 function StateHandler:DeleteState()
1405 if self.states[self:GetName()] then
1406 self.states[self:GetName()] = nil
1407 ApplyStates(self.bar)
1408 end
1409 optionMap[self.bar].args[self:GetName()] = nil
1410 end
1411
1412 function StateHandler:SetStateName(info, value)
1413 -- check for existing state name
1414 if self.states[value] then
1415 ReAction:UserError(format(L["State named '%s' already exists"],value))
1416 return
1417 end
1418 local args = optionMap[self.bar].args
1419 local name = self:GetName()
1420 self.states[value], args[value], self.states[name], args[name] = self.states[name], args[name], nil, nil
1421 self:SetName(value)
1422 ApplyStates(self.bar)
1423 ReAction:ShowEditor(self.bar, moduleID, value)
1424 end
1425
1426 function StateHandler:MoveStateUp()
1427 local before, after = self:GetNeighbors()
1428 if before then
1429 self:SwapOrder(before, self:GetName())
1430 ApplyStates(self.bar)
1431 end
1432 end
1433
1434 function StateHandler:MoveStateDown()
1435 local before, after = self:GetNeighbors()
1436 if after then
1437 self:SwapOrder(self:GetName(), after)
1438 ApplyStates(self.bar)
1439 end
1440 end
1441
1442 function StateHandler:GetAnchorDisabled()
1443 return not GetProperty(self.bar, self:GetName(), "anchorEnable")
1444 end
1445
1446 function StateHandler:IsPageDisabled()
1447 local n = self.bar:GetConfig().nPages or 1
1448 return not (n > 1)
1449 end
1450
1451 function StateHandler:IsPageHidden()
1452 return not self.bar:GetConfig().nPages
1453 end
1454
1455 function StateHandler:GetPageValues()
1456 if not self._pagevalues then
1457 self._pagevalues = { }
1458 end
1459 local n = self.bar:GetConfig().nPages
1460 -- cache the results
1461 if self._npages ~= n then
1462 self._npages = n
1463 wipe(self._pagevalues)
1464 for i = 1, n do
1465 self._pagevalues["page"..i] = i
1466 end
1467 end
1468 return self._pagevalues
1469 end
1470
1471 function StateHandler:GetPage(info)
1472 return self:GetProp(info) or 1
1473 end
1474
1475 function StateHandler:GetAnchorFrames(info)
1476 self._anchorframes = self._anchorframes or { }
1477 table.wipe(self._anchorframes)
1478
1479 table.insert(self._anchorframes, "UIParent")
1480 for name, bar in ReAction:IterateBars() do
1481 table.insert(self._anchorframes, bar:GetFrame():GetName())
1482 end
1483 return self._anchorframes
1484 end
1485
1486 function StateHandler:GetAnchorFrame(info)
1487 local value = self:GetProp(info)
1488 for k,v in pairs(self._anchorframes) do
1489 if v == value then
1490 return k
1491 end
1492 end
1493 end
1494
1495 function StateHandler:SetAnchorFrame(info, value)
1496 local f = _G[self._anchorframes[value]]
1497 if f then
1498 self.bar:SetFrameRef("anchor-"..self:GetName(), f)
1499 self:SetProp(info, f:GetName())
1500 end
1501 end
1502
1503 function StateHandler:SetAnchorPointProp(info, value)
1504 self:SetProp(info, value ~= "NONE" and value or nil)
1505 end
1506
1507 function StateHandler:GetAnchorPointProp(info)
1508 return self:GetProp(info) or "NONE"
1509 end
1510
1511 function StateHandler:GetScale(info)
1512 return self:GetProp(info) or 1.0
1513 end
1514
1515 function StateHandler:GetScaleDisabled()
1516 return not GetProperty(self.bar, self:GetName(), "enableScale")
1517 end
1518
1519 function StateHandler:GetAlpha(info)
1520 return self:GetProp(info) or 1.0
1521 end
1522
1523 function StateHandler:GetAlphaDisabled()
1524 return not GetProperty(self.bar, self:GetName(), "enableAlpha")
1525 end
1526
1527 function StateHandler:SetType(info, value)
1528 self:SetRuleField("type", value)
1529 self:FixAll()
1530 ApplyStates(self.bar)
1531 end
1532
1533 function StateHandler:GetType()
1534 return self:GetRuleField("type")
1535 end
1536
1537 function StateHandler:GetClearAllDisabled()
1538 local t = self:GetRuleField("type")
1539 return not( t == "any" or t == "all" or t == "custom")
1540 end
1541
1542 function StateHandler:ClearAllConditions()
1543 local t = self:GetRuleField("type")
1544 if t == "custom" then
1545 self:SetRuleField("custom","")
1546 elseif t == "any" or t == "all" then
1547 self:SetRuleField("values", {})
1548 end
1549 ApplyStates(self.bar)
1550 end
1551
1552 function StateHandler:GetConditionsDisabled()
1553 local t = self:GetRuleField("type")
1554 return not( t == "any" or t == "all")
1555 end
1556
1557 function StateHandler:SetCondition(info, key, value)
1558 self:SetRuleField(ruleMap[key], value or nil, "values")
1559 if value then
1560 self:FixAll(ruleMap[key])
1561 end
1562 ApplyStates(self.bar)
1563 end
1564
1565 function StateHandler:GetCondition(info, key)
1566 return self:GetRuleField("values", ruleMap[key]) or false
1567 end
1568
1569 function StateHandler:GetCustomDisabled()
1570 return self:GetRuleField("type") ~= "custom"
1571 end
1572
1573 function StateHandler:SetCustomRule(info, value)
1574 self:SetRuleField("custom",value)
1575 ApplyStates(self.bar)
1576 end
1577
1578 function StateHandler:GetCustomRule()
1579 return self:GetRuleField("custom") or ""
1580 end
1581
1582 function StateHandler:ValidateCustomRule(info, value)
1583 local s = value:gsub("%s","") -- remove all spaces
1584 -- unfortunately %b and captures don't support the '+' notation, or this would be considerably simpler
1585 repeat
1586 if s == "" then
1587 return true
1588 end
1589 local c, r = s:match("(%b[])(.*)")
1590 if c == nil and s and #s > 0 then
1591 return format(L["Invalid custom rule '%s': each clause must appear within [brackets]"],value or "")
1592 end
1593 s = r
1594 until c == nil
1595 return true
1596 end
1597
1598 function StateHandler:GetKeybindDisabled()
1599 return self:GetRuleField("type") ~= "keybind"
1600 end
1601
1602 function StateHandler:GetKeybind()
1603 return self:GetRuleField("keybind")
1604 end
1605
1606 function StateHandler:SetKeybind(info, value)
1607 if value and #value == 0 then
1608 value = nil
1609 end
1610 self:SetRuleField("keybind",value)
1611 ApplyStates(self.bar)
1612 end
1613
1614 local function CreateStateOptions(bar, name)
1615 local opts = {
1616 type = "group",
1617 name = name,
1618 childGroups = "tab",
1619 args = stateOptions
1620 }
1621
1622 opts.handler = StateHandler:New(bar,opts)
1623
1624 return opts
1625 end
1626
1627 function Editor:CreateStateOptions(bar)
1628 local private = { }
1629 local states = tbuild(bar:GetConfig(), "states")
1630 local options = {
1631 name = L["Dynamic State"],
1632 type = "group",
1633 order = -1,
1634 childGroups = "tree",
1635 disabled = InCombatLockdown,
1636 args = {
1637 __desc__ = {
1638 name = L["States are evaluated in the order they are listed"],
1639 order = 1,
1640 type = "description",
1641 },
1642 __new__ = {
1643 name = L["New State..."],
1644 order = 2,
1645 type = "group",
1646 args = {
1647 name = {
1648 name = L["State Name"],
1649 desc = L["Set a name for the new state"],
1650 order = 1,
1651 type = "input",
1652 get = function() return private.newstatename or "" end,
1653 set = function(info,value) private.newstatename = value end,
1654 pattern = "^%w*$",
1655 usage = L["State names must be alphanumeric without spaces"],
1656 },
1657 create = {
1658 name = L["Create State"],
1659 order = 2,
1660 type = "execute",
1661 func = function ()
1662 local name = private.newstatename
1663 if states[name] then
1664 ReAction:UserError(format(L["State named '%s' already exists"],name))
1665 else
1666 -- TODO: select default state options and pass as final argument
1667 states[name] = { }
1668 optionMap[bar].args[name] = CreateStateOptions(bar,name)
1669 ReAction:ShowEditor(bar, moduleID, name)
1670 private.newstatename = ""
1671 end
1672 end,
1673 disabled = function()
1674 local name = private.newstatename or ""
1675 return #name == 0 or name:find("%W")
1676 end,
1677 }
1678 }
1679 }
1680 }
1681 }
1682 for name, config in pairs(states) do
1683 options.args[name] = CreateStateOptions(bar,name)
1684 end
1685 optionMap[bar] = options
1686 return options
1687 end
1688 end
1689
959 1690
960 ---- Export to ReAction ---- 1691 ---- Export to ReAction ----
961 function ReAction:ShowEditor(bar, ...) 1692 function ReAction:ShowEditor(bar, ...)
962 if InCombatLockdown() then 1693 if InCombatLockdown() then
963 self:UserError(L["ReAction config mode disabled during combat."]) 1694 self:UserError(L["ReAction config mode disabled during combat."])
978 if self.editor then 1709 if self.editor then
979 self.editor:RefreshBarOptions() 1710 self.editor:RefreshBarOptions()
980 end 1711 end
981 end 1712 end
982 1713
983 function ReAction:RegisterBarOptionGenerator( module, func )
984 if not module or type(module) ~= "table" then -- doesn't need to be a proper module, strictly
985 error("ReAction:RegisterBarOptionGenerator() : Invalid module")
986 end
987 if type(func) == "string" then
988 if not module[func] then
989 error(("ReAction:RegisterBarOptionGenerator() : Invalid method '%s'"):format(func))
990 end
991 elseif func and type(func) ~= "function" then
992 error("ReAction:RegisterBarOptionGenerator() : Invalid function")
993 end
994 self.barOptionGenerators = self.barOptionGenerators or { }
995 self.barOptionGenerators[module] = func
996
997 if self.editor then
998 self.editor:RefreshBarOptions()
999 end
1000 end
1001