Mercurial > wow > reaction
comparison libs/AceConsole-2.0/AceConsole-2.0.lua @ 1:c11ca1d8ed91
Version 0.1
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Tue, 20 Mar 2007 21:03:57 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:4e2ce2894c21 | 1:c11ca1d8ed91 |
---|---|
1 --[[ | |
2 Name: AceConsole-2.0 | |
3 Revision: $Rev: 19865 $ | |
4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team) | |
5 Inspired By: Ace 1.x by Turan (turan@gryphon.com) | |
6 Website: http://www.wowace.com/ | |
7 Documentation: http://www.wowace.com/index.php/AceConsole-2.0 | |
8 SVN: http://svn.wowace.com/root/trunk/Ace2/AceConsole-2.0 | |
9 Description: Mixin to allow for input/output capabilities. This uses the | |
10 AceOptions data table format to determine input. | |
11 http://wiki.wowace.com/index.php/AceOptions_data_table | |
12 Dependencies: AceLibrary, AceOO-2.0 | |
13 ]] | |
14 | |
15 local MAJOR_VERSION = "AceConsole-2.0" | |
16 local MINOR_VERSION = "$Revision: 19865 $" | |
17 | |
18 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end | |
19 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end | |
20 | |
21 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0.") end | |
22 | |
23 local MAP_ONOFF, USAGE, IS_CURRENTLY_SET_TO, IS_NOW_SET_TO, IS_NOT_A_VALID_OPTION_FOR, IS_NOT_A_VALID_VALUE_FOR, NO_OPTIONS_AVAILABLE, OPTION_HANDLER_NOT_FOUND, OPTION_HANDLER_NOT_VALID, OPTION_IS_DISABLED, KEYBINDING_USAGE | |
24 if GetLocale() == "deDE" then | |
25 MAP_ONOFF = { [false] = "|cffff0000Aus|r", [true] = "|cff00ff00An|r" } | |
26 USAGE = "Benutzung" | |
27 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r steht momentan auf |cffffff7f[|r%s|cffffff7f]|r" | |
28 IS_NOW_SET_TO = "|cffffff7f%s|r ist nun auf |cffffff7f[|r%s|cffffff7f]|r gesetzt" | |
29 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] ist keine g\195\188ltige Option f\195\188r |cffffff7f%s|r" | |
30 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] ist kein g\195\188ltiger Wert f\195\188r |cffffff7f%s|r" | |
31 NO_OPTIONS_AVAILABLE = "Keine Optionen verfügbar" | |
32 OPTION_HANDLER_NOT_FOUND = "Optionen handler |cffffff7f%q|r nicht gefunden." | |
33 OPTION_HANDLER_NOT_VALID = "Optionen handler nicht g\195\188ltig." | |
34 OPTION_IS_DISABLED = "Option |cffffff7f%s|r deaktiviert." | |
35 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix | |
36 elseif GetLocale() == "frFR" then | |
37 MAP_ONOFF = { [false] = "|cffff0000Inactif|r", [true] = "|cff00ff00Actif|r" } | |
38 USAGE = "Utilisation" | |
39 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r est actuellement positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r" | |
40 IS_NOW_SET_TO = "|cffffff7f%s|r est maintenant positionn\195\169 sur |cffffff7f[|r%s|cffffff7f]|r" | |
41 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] n'est pas une option valide pour |cffffff7f%s|r" | |
42 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] n'est pas une valeur valide pour |cffffff7f%s|r" | |
43 NO_OPTIONS_AVAILABLE = "Pas d'options disponibles" | |
44 OPTION_HANDLER_NOT_FOUND = "Le gestionnaire d'option |cffffff7f%q|r n'a pas \195\169t\195\169 trouv\195\169." | |
45 OPTION_HANDLER_NOT_VALID = "Le gestionnaire d'option n'est pas valide." | |
46 OPTION_IS_DISABLED = "L'option |cffffff7f%s|r est d\195\169sactiv\195\169e." | |
47 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix | |
48 elseif GetLocale() == "koKR" then | |
49 MAP_ONOFF = { [false] = "|cffff0000끔|r", [true] = "|cff00ff00켬|r" } | |
50 USAGE = "사용법" | |
51 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r|1은;는; 현재 상태는 |cffffff7f[|r%s|cffffff7f]|r|1으로;로; 설정되어 있습니다" | |
52 IS_NOW_SET_TO = "|cffffff7f%s|r|1을;를; |cffffff7f[|r%s|cffffff7f]|r 상태로 변경합니다" | |
53 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r]|1은;는; |cffffff7f%s|r에서 사용불가능한 설정입니다" | |
54 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r]|1은;는; |cffffff7f%s|r에서 사용불가능한 설정값입니다" | |
55 NO_OPTIONS_AVAILABLE = "가능한 설정이 없습니다" | |
56 OPTION_HANDLER_NOT_FOUND = "설정 조정값인 |cffffff7f%q|r|1을;를; 찾지 못했습니다." | |
57 OPTION_HANDLER_NOT_VALID = "설정 조정값이 올바르지 않습니다." | |
58 OPTION_IS_DISABLED = "|cffffff7f%s|r 설정은 사용할 수 없습니다." | |
59 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix | |
60 elseif GetLocale() == "zhCN" then | |
61 MAP_ONOFF = { [false] = "|cffff0000\229\133\179\233\151\173|r", [true] = "|cff00ff00\229\188\128\229\144\175|r" } | |
62 USAGE = "\231\148\168\230\179\149" | |
63 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r \229\189\147\229\137\141\232\162\171\232\174\190\231\189\174 |cffffff7f[|r%s|cffffff7f]|r" | |
64 IS_NOW_SET_TO = "|cffffff7f%s|r \231\142\176\229\156\168\232\162\171\232\174\190\231\189\174\228\184\186 |cffffff7f[|r%s|cffffff7f]|r" | |
65 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] \228\184\141\230\152\175\228\184\128\228\184\170\230\156\137\230\149\136\231\154\132\233\128\137\233\161\185 \228\184\186 |cffffff7f%s|r" | |
66 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] \228\184\141\230\152\175\228\184\128\228\184\170\230\156\137\230\149\136\229\128\188 \228\184\186 |cffffff7f%s|r" | |
67 NO_OPTIONS_AVAILABLE = "\230\178\161\230\156\137\233\128\137\233\161\185\229\143\175\231\148\168" | |
68 OPTION_HANDLER_NOT_FOUND = "\233\128\137\233\161\185\229\164\132\231\144\134\231\168\139\229\186\143 |cffffff7f%q|r \230\178\161\230\159\165\230\137\190." | |
69 OPTION_HANDLER_NOT_VALID = "\233\128\137\233\161\185\229\164\132\231\144\134\231\168\139\229\186\143 \230\151\160\230\149\136." | |
70 OPTION_IS_DISABLED = "\233\128\137\233\161\185 |cffffff7f%s|r \228\184\141\229\174\140\230\149\180." | |
71 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix | |
72 elseif GetLocale() == "zhTW" then | |
73 MAP_ONOFF = { [false] = "|cffff0000關閉|r", [true] = "|cff00ff00開啟|r" } | |
74 USAGE = "用法" | |
75 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r 目前的設定為 |cffffff7f[|r%s|cffffff7f]|r" | |
76 IS_NOW_SET_TO = "|cffffff7f%s|r 現在被設定為 |cffffff7f[|r%s|cffffff7f]|r" | |
77 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] 是一個不符合規定的選項,對 |cffffff7f%s|r" | |
78 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] 是一個不符合規定的數值,對 |cffffff7f%s|r" | |
79 NO_OPTIONS_AVAILABLE = "沒有可用的選項處理器。" | |
80 OPTION_HANDLER_NOT_FOUND = "找不到 |cffffff7f%q|r 選項處理器。" | |
81 OPTION_HANDLER_NOT_VALID = "選項處理器不符合規定。" | |
82 OPTION_IS_DISABLED = "|cffffff7f%s|r 已被停用。" | |
83 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" -- fix | |
84 else -- enUS | |
85 MAP_ONOFF = { [false] = "|cffff0000Off|r", [true] = "|cff00ff00On|r" } | |
86 USAGE = "Usage" | |
87 IS_CURRENTLY_SET_TO = "|cffffff7f%s|r is currently set to |cffffff7f[|r%s|cffffff7f]|r" | |
88 IS_NOW_SET_TO = "|cffffff7f%s|r is now set to |cffffff7f[|r%s|cffffff7f]|r" | |
89 IS_NOT_A_VALID_OPTION_FOR = "[|cffffff7f%s|r] is not a valid option for |cffffff7f%s|r" | |
90 IS_NOT_A_VALID_VALUE_FOR = "[|cffffff7f%s|r] is not a valid value for |cffffff7f%s|r" | |
91 NO_OPTIONS_AVAILABLE = "No options available" | |
92 OPTION_HANDLER_NOT_FOUND = "Option handler |cffffff7f%q|r not found." | |
93 OPTION_HANDLER_NOT_VALID = "Option handler not valid." | |
94 OPTION_IS_DISABLED = "Option |cffffff7f%s|r is disabled." | |
95 KEYBINDING_USAGE = "<ALT-CTRL-SHIFT-KEY>" | |
96 end | |
97 | |
98 local NONE = NONE or "None" | |
99 | |
100 local AceOO = AceLibrary("AceOO-2.0") | |
101 local AceEvent | |
102 | |
103 local AceConsole = AceOO.Mixin { "Print", "PrintComma", "CustomPrint", "RegisterChatCommand" } | |
104 local Dewdrop | |
105 | |
106 local _G = getfenv(0) | |
107 | |
108 local function print(text, name, r, g, b, frame, delay) | |
109 if not text or text:len() == 0 then | |
110 text = " " | |
111 end | |
112 if not name or name == AceConsole then | |
113 (frame or DEFAULT_CHAT_FRAME):AddMessage(text, r, g, b, nil, delay or 5) | |
114 else | |
115 (frame or DEFAULT_CHAT_FRAME):AddMessage("|cffffff78" .. tostring(name) .. ":|r " .. text, r, g, b, nil, delay or 5) | |
116 end | |
117 end | |
118 | |
119 local real_tostring = tostring | |
120 | |
121 local function tostring(t) | |
122 if type(t) == "table" then | |
123 if type(rawget(t, 0)) == "userdata" and type(t.GetObjectType) == "function" then | |
124 return string.format("<%s:%s>", t:GetObjectType(), t:GetName() or "(anon)") | |
125 end | |
126 end | |
127 return real_tostring(t) | |
128 end | |
129 | |
130 local function _tostring(...) | |
131 if select('#', ...) < 1 then | |
132 return | |
133 end | |
134 return tostring((...)), _tostring(select(2, ...)) | |
135 end | |
136 function AceConsole:CustomPrint(r, g, b, frame, delay, connector, a1, ...) | |
137 if tostring(a1):find("%%") and select('#', ...) >= 1 then | |
138 local success, text = pcall(string.format, _tostring(a1, ...)) | |
139 if success then | |
140 print(text, self, r, g, b, frame or self.printFrame, delay) | |
141 return | |
142 end | |
143 end | |
144 print((connector or " "):join(_tostring(a1, ...)), self, r, g, b, frame or self.printFrame, delay) | |
145 end | |
146 | |
147 function AceConsole:Print(...) | |
148 return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, " ", ...) | |
149 end | |
150 | |
151 function AceConsole:PrintComma(...) | |
152 return AceConsole.CustomPrint(self, nil, nil, nil, nil, nil, ", ", ...) | |
153 end | |
154 | |
155 local work | |
156 local argwork | |
157 | |
158 local function findTableLevel(self, options, chat, text, index, passTable) | |
159 if not index then | |
160 index = 1 | |
161 if work then | |
162 for k,v in pairs(work) do | |
163 work[k] = nil | |
164 end | |
165 for k,v in pairs(argwork) do | |
166 argwork[k] = nil | |
167 end | |
168 else | |
169 work = {} | |
170 argwork = {} | |
171 end | |
172 local len = text:len() | |
173 local count | |
174 repeat | |
175 text, count = text:gsub("(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[[^%]]-) (.-%]|h|r)", "%1\001%2") | |
176 until count == 0 | |
177 text = text:gsub("(%]|h|r)(|cff%x%x%x%x%x%x|Hitem:%d-:%d-:%d-:%d-|h%[)", "%1 %2") | |
178 for token in text:gmatch("([^%s]+)") do | |
179 local token = token | |
180 local num = tonumber(token) | |
181 if num then | |
182 token = num | |
183 else | |
184 token = token:gsub("\001", " ") | |
185 end | |
186 table.insert(work, token) | |
187 end | |
188 end | |
189 | |
190 local path = chat | |
191 for i = 1, index - 1 do | |
192 path = path .. " " .. tostring(work[i]) | |
193 end | |
194 | |
195 if type(options.args) == "table" then | |
196 local disabled, hidden = options.disabled, options.cmdHidden or options.hidden | |
197 if hidden then | |
198 if type(hidden) == "function" then | |
199 hidden = hidden() | |
200 elseif type(hidden) == "string" then | |
201 local handler = options.handler or self | |
202 local f = hidden | |
203 local neg = f:match("^~(.-)$") | |
204 if neg then | |
205 f = neg | |
206 end | |
207 if type(handler[f]) ~= "function" then | |
208 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
209 end | |
210 hidden = handler[f](handler) | |
211 if neg then | |
212 hidden = not hidden | |
213 end | |
214 end | |
215 end | |
216 if hidden then | |
217 disabled = true | |
218 elseif disabled then | |
219 if type(disabled) == "function" then | |
220 disabled = disabled() | |
221 elseif type(disabled) == "string" then | |
222 local handler = options.handler or self | |
223 local f = disabled | |
224 local neg = f:match("^~(.-)$") | |
225 if neg then | |
226 f = neg | |
227 end | |
228 if type(handler[f]) ~= "function" then | |
229 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
230 end | |
231 disabled = handler[f](handler) | |
232 if neg then | |
233 disabled = not disabled | |
234 end | |
235 end | |
236 end | |
237 if not disabled then | |
238 local next = work[index] and work[index]:lower() | |
239 if next then | |
240 for k,v in pairs(options.args) do | |
241 local good = false | |
242 if k:lower() == next then | |
243 good = true | |
244 elseif type(v.aliases) == "table" then | |
245 for _,alias in ipairs(v.aliases) do | |
246 if alias:lower() == next then | |
247 good = true | |
248 break | |
249 end | |
250 end | |
251 elseif type(v.aliases) == "string" and v.aliases:lower() == next then | |
252 good = true | |
253 end | |
254 if good then | |
255 return findTableLevel(options.handler or self, v, chat, text, index + 1, options.pass and options or nil) | |
256 end | |
257 end | |
258 end | |
259 end | |
260 end | |
261 for i = index, #work do | |
262 table.insert(argwork, work[i]) | |
263 end | |
264 return options, path, argwork, options.handler or self, passTable, passTable and work[index - 1] | |
265 end | |
266 | |
267 local function validateOptionsMethods(self, options, position) | |
268 if type(options) ~= "table" then | |
269 return "Options must be a table.", position | |
270 end | |
271 self = options.handler or self | |
272 if options.type == "execute" then | |
273 if options.func and type(options.func) ~= "string" and type(options.func) ~= "function" then | |
274 return "func must be a string or function", position | |
275 end | |
276 if options.func and type(options.func) == "string" and type(self[options.func]) ~= "function" then | |
277 return string.format("%q is not a proper function", options.func), position | |
278 end | |
279 else | |
280 if options.get then | |
281 if type(options.get) ~= "string" and type(options.get) ~= "function" then | |
282 return "get must be a string or function", position | |
283 end | |
284 if type(options.get) == "string" then | |
285 local f = options.get | |
286 if options.type == "toggle" then | |
287 f = f:match("^~(.-)$") or f | |
288 end | |
289 if type(self[f]) ~= "function" then | |
290 return string.format("%q is not a proper function", f), position | |
291 end | |
292 end | |
293 end | |
294 if options.set then | |
295 if type(options.set) ~= "string" and type(options.set) ~= "function" then | |
296 return "set must be a string or function", position | |
297 end | |
298 if type(options.set) == "string" and type(self[options.set]) ~= "function" then | |
299 return string.format("%q is not a proper function", options.set), position | |
300 end | |
301 end | |
302 if options.validate and type(options.validate) ~= "table" and options.validate ~= "keybinding" then | |
303 if type(options.validate) ~= "string" and type(options.validate) ~= "function" then | |
304 return "validate must be a string or function", position | |
305 end | |
306 if type(options.validate) == "string" and type(self[options.validate]) ~= "function" then | |
307 return string.format("%q is not a proper function", options.validate), position | |
308 end | |
309 end | |
310 end | |
311 if options.disabled and type(options.disabled) == "string" then | |
312 local f = options.disabled | |
313 f = f:match("^~(.-)$") or f | |
314 if type(self[f]) ~= "function" then | |
315 return string.format("%q is not a proper function", f), position | |
316 end | |
317 end | |
318 if options.cmdHidden and type(options.cmdHidden) == "string" then | |
319 local f = options.cmdHidden | |
320 f = f:match("^~(.-)$") or f | |
321 if type(self[f]) ~= "function" then | |
322 return string.format("%q is not a proper function", f), position | |
323 end | |
324 end | |
325 if options.guiHidden and type(options.guiHidden) == "string" then | |
326 local f = options.guiHidden | |
327 f = f:match("^~(.-)$") or f | |
328 if type(self[f]) ~= "function" then | |
329 return string.format("%q is not a proper function", f), position | |
330 end | |
331 end | |
332 if options.hidden and type(options.hidden) == "string" then | |
333 local f = options.hidden | |
334 f = f:match("^~(.-)$") or f | |
335 if type(self[f]) ~= "function" then | |
336 return string.format("%q is not a proper function", f), position | |
337 end | |
338 end | |
339 if options.type == "group" and type(options.args) == "table" then | |
340 for k,v in pairs(options.args) do | |
341 if type(v) == "table" then | |
342 local newposition | |
343 if position then | |
344 newposition = position .. ".args." .. k | |
345 else | |
346 newposition = "args." .. k | |
347 end | |
348 local err, pos = validateOptionsMethods(self, v, newposition) | |
349 if err then | |
350 return err, pos | |
351 end | |
352 end | |
353 end | |
354 end | |
355 end | |
356 | |
357 local function validateOptions(options, position, baseOptions, fromPass) | |
358 if not baseOptions then | |
359 baseOptions = options | |
360 end | |
361 if type(options) ~= "table" then | |
362 return "Options must be a table.", position | |
363 end | |
364 local kind = options.type | |
365 if type(kind) ~= "string" then | |
366 return '"type" must be a string.', position | |
367 elseif kind ~= "group" and kind ~= "range" and kind ~= "text" and kind ~= "execute" and kind ~= "toggle" and kind ~= "color" and kind ~= "header" then | |
368 return '"type" must either be "range", "text", "group", "toggle", "execute", "color", or "header".', position | |
369 end | |
370 if options.aliases then | |
371 if type(options.aliases) ~= "table" and type(options.aliases) ~= "string" then | |
372 return '"alias" must be a table or string', position | |
373 end | |
374 end | |
375 if not fromPass then | |
376 if kind == "execute" then | |
377 if type(options.func) ~= "string" and type(options.func) ~= "function" then | |
378 return '"func" must be a string or function', position | |
379 end | |
380 elseif kind == "range" or kind == "text" or kind == "toggle" then | |
381 if type(options.set) ~= "string" and type(options.set) ~= "function" then | |
382 return '"set" must be a string or function', position | |
383 end | |
384 if kind == "text" and options.get == false then | |
385 elseif type(options.get) ~= "string" and type(options.get) ~= "function" then | |
386 return '"get" must be a string or function', position | |
387 end | |
388 elseif kind == "group" and options.pass then | |
389 if options.pass ~= true then | |
390 return '"pass" must be either nil, true, or false', position | |
391 end | |
392 if not options.func then | |
393 if type(options.set) ~= "string" and type(options.set) ~= "function" then | |
394 return '"set" must be a string or function', position | |
395 end | |
396 if type(options.get) ~= "string" and type(options.get) ~= "function" then | |
397 return '"get" must be a string or function', position | |
398 end | |
399 elseif type(options.func) ~= "string" and type(options.func) ~= "function" then | |
400 return '"func" must be a string or function', position | |
401 end | |
402 end | |
403 else | |
404 if kind == "group" then | |
405 return 'cannot have "type" = "group" as a subgroup of a passing group', position | |
406 end | |
407 end | |
408 if options ~= baseOptions then | |
409 if kind == "header" then | |
410 elseif type(options.desc) ~= "string" then | |
411 return '"desc" must be a string', position | |
412 elseif options.desc:len() == 0 then | |
413 return '"desc" cannot be a 0-length string', position | |
414 end | |
415 end | |
416 | |
417 if options ~= baseOptions or kind == "range" or kind == "text" or kind == "toggle" or kind == "color" then | |
418 if options.type == "header" and not options.cmdName and not options.name then | |
419 elseif options.cmdName then | |
420 if type(options.cmdName) ~= "string" then | |
421 return '"cmdName" must be a string or nil', position | |
422 elseif options.cmdName:len() == 0 then | |
423 return '"cmdName" cannot be a 0-length string', position | |
424 end | |
425 if type(options.guiName) ~= "string" then | |
426 if not options.guiNameIsMap then | |
427 return '"guiName" must be a string or nil', position | |
428 end | |
429 elseif options.guiName:len() == 0 then | |
430 return '"guiName" cannot be a 0-length string', position | |
431 end | |
432 else | |
433 if type(options.name) ~= "string" then | |
434 return '"name" must be a string', position | |
435 elseif options.name:len() == 0 then | |
436 return '"name" cannot be a 0-length string', position | |
437 end | |
438 end | |
439 end | |
440 if options.guiNameIsMap then | |
441 if type(options.guiNameIsMap) ~= "boolean" then | |
442 return '"guiNameIsMap" must be a boolean or nil', position | |
443 elseif options.type ~= "toggle" then | |
444 return 'if "guiNameIsMap" is true, then "type" must be set to \'toggle\'', position | |
445 elseif type(options.map) ~= "table" then | |
446 return '"map" must be a table', position | |
447 end | |
448 end | |
449 if options.message and type(options.message) ~= "string" then | |
450 return '"message" must be a string or nil', position | |
451 end | |
452 if options.error and type(options.error) ~= "string" then | |
453 return '"error" must be a string or nil', position | |
454 end | |
455 if options.current and type(options.current) ~= "string" then | |
456 return '"current" must be a string or nil', position | |
457 end | |
458 if options.order then | |
459 if type(options.order) ~= "number" or (-1 < options.order and options.order < 0.999) then | |
460 return '"order" must be a non-zero number or nil', position | |
461 end | |
462 end | |
463 if options.disabled then | |
464 if type(options.disabled) ~= "function" and type(options.disabled) ~= "string" and options.disabled ~= true then | |
465 return '"disabled" must be a function, string, or boolean', position | |
466 end | |
467 end | |
468 if options.cmdHidden then | |
469 if type(options.cmdHidden) ~= "function" and type(options.cmdHidden) ~= "string" and options.cmdHidden ~= true then | |
470 return '"cmdHidden" must be a function, string, or boolean', position | |
471 end | |
472 end | |
473 if options.guiHidden then | |
474 if type(options.guiHidden) ~= "function" and type(options.guiHidden) ~= "string" and options.guiHidden ~= true then | |
475 return '"guiHidden" must be a function, string, or boolean', position | |
476 end | |
477 end | |
478 if options.hidden then | |
479 if type(options.hidden) ~= "function" and type(options.hidden) ~= "string" and options.hidden ~= true then | |
480 return '"hidden" must be a function, string, or boolean', position | |
481 end | |
482 end | |
483 if kind == "text" then | |
484 if type(options.validate) == "table" then | |
485 local t = options.validate | |
486 local iTable = nil | |
487 for k,v in pairs(t) do | |
488 if type(k) == "number" then | |
489 if iTable == nil then | |
490 iTable = true | |
491 elseif not iTable then | |
492 return '"validate" must either have all keys be indexed numbers or strings', position | |
493 elseif k < 1 or k > #t then | |
494 return '"validate" numeric keys must be indexed properly. >= 1 and <= #validate', position | |
495 end | |
496 else | |
497 if iTable == nil then | |
498 iTable = false | |
499 elseif iTable then | |
500 return '"validate" must either have all keys be indexed numbers or strings', position | |
501 end | |
502 end | |
503 if type(v) ~= "string" then | |
504 return '"validate" values must all be strings', position | |
505 end | |
506 end | |
507 elseif options.validate == "keybinding" then | |
508 | |
509 else | |
510 if type(options.usage) ~= "string" then | |
511 return '"usage" must be a string', position | |
512 elseif options.validate and type(options.validate) ~= "string" and type(options.validate) ~= "function" then | |
513 return '"validate" must be a string, function, or table', position | |
514 end | |
515 end | |
516 elseif kind == "range" then | |
517 if options.min or options.max then | |
518 if type(options.min) ~= "number" then | |
519 return '"min" must be a number', position | |
520 elseif type(options.max) ~= "number" then | |
521 return '"max" must be a number', position | |
522 elseif options.min >= options.max then | |
523 return '"min" must be less than "max"', position | |
524 end | |
525 end | |
526 if options.step then | |
527 if type(options.step) ~= "number" then | |
528 return '"step" must be a number', position | |
529 elseif options.step < 0 then | |
530 return '"step" must be nonnegative', position | |
531 end | |
532 end | |
533 if options.isPercent and options.isPercent ~= true then | |
534 return '"isPercent" must either be nil, true, or false', position | |
535 end | |
536 elseif kind == "toggle" then | |
537 if options.map then | |
538 if type(options.map) ~= "table" then | |
539 return '"map" must be a table', position | |
540 elseif type(options.map[true]) ~= "string" then | |
541 return '"map[true]" must be a string', position | |
542 elseif type(options.map[false]) ~= "string" then | |
543 return '"map[false]" must be a string', position | |
544 end | |
545 end | |
546 elseif kind == "color" then | |
547 if options.hasAlpha and options.hasAlpha ~= true then | |
548 return '"hasAlpha" must be nil, true, or false', position | |
549 end | |
550 elseif kind == "group" then | |
551 if options.pass and options.pass ~= true then | |
552 return '"pass" must be nil, true, or false', position | |
553 end | |
554 if type(options.args) ~= "table" then | |
555 return '"args" must be a table', position | |
556 end | |
557 for k,v in pairs(options.args) do | |
558 if type(k) ~= "string" then | |
559 return '"args" keys must be strings', position | |
560 elseif k:find("%s") then | |
561 return string.format('"args" keys must not include spaces. %q is not appropriate.', k), position | |
562 elseif k:len() == 0 then | |
563 return '"args" keys must not be 0-length strings.', position | |
564 end | |
565 if type(v) ~= "table" then | |
566 return '"args" values must be tables', position and position .. "." .. k or k | |
567 end | |
568 local newposition | |
569 if position then | |
570 newposition = position .. ".args." .. k | |
571 else | |
572 newposition = "args." .. k | |
573 end | |
574 local err, pos = validateOptions(v, newposition, baseOptions, options.pass) | |
575 if err then | |
576 return err, pos | |
577 end | |
578 end | |
579 end | |
580 end | |
581 | |
582 local colorTable | |
583 local colorFunc | |
584 local colorCancelFunc | |
585 | |
586 local function keybindingValidateFunc(text) | |
587 if text == nil or text == "NONE" then | |
588 return nil | |
589 end | |
590 text = text:upper() | |
591 local shift, ctrl, alt | |
592 local modifier | |
593 while true do | |
594 if text == "-" then | |
595 break | |
596 end | |
597 modifier, text = strsplit('-', text, 2) | |
598 if text then | |
599 if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then | |
600 return false | |
601 end | |
602 if modifier == "SHIFT" then | |
603 if shift then | |
604 return false | |
605 end | |
606 shift = true | |
607 end | |
608 if modifier == "CTRL" then | |
609 if ctrl then | |
610 return false | |
611 end | |
612 ctrl = true | |
613 end | |
614 if modifier == "ALT" then | |
615 if alt then | |
616 return false | |
617 end | |
618 alt = true | |
619 end | |
620 else | |
621 text = modifier | |
622 break | |
623 end | |
624 end | |
625 if not text:find("^F%d+$") and text:len() ~= 1 and (text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] then | |
626 return false | |
627 end | |
628 local s = text | |
629 if shift then | |
630 s = "SHIFT-" .. s | |
631 end | |
632 if ctrl then | |
633 s = "CTRL-" .. s | |
634 end | |
635 if alt then | |
636 s = "ALT-" .. s | |
637 end | |
638 return s | |
639 end | |
640 AceConsole.keybindingValidateFunc = keybindingValidateFunc | |
641 | |
642 local order | |
643 | |
644 local mysort_args | |
645 local mysort | |
646 | |
647 local function printUsage(self, handler, realOptions, options, path, args, quiet, filter) | |
648 if filter then | |
649 filter = "^" .. filter:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1") | |
650 end | |
651 local hidden, disabled = options.cmdHidden or options.hidden, options.disabled | |
652 if hidden then | |
653 if type(hidden) == "function" then | |
654 hidden = hidden() | |
655 elseif type(hidden) == "string" then | |
656 local f = hidden | |
657 local neg = f:match("^~(.-)$") | |
658 if neg then | |
659 f = neg | |
660 end | |
661 if type(handler[f]) ~= "function" then | |
662 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
663 end | |
664 hidden = handler[f](handler) | |
665 if neg then | |
666 hidden = not hidden | |
667 end | |
668 end | |
669 end | |
670 if hidden then | |
671 disabled = true | |
672 elseif disabled then | |
673 if type(disabled) == "function" then | |
674 disabled = disabled() | |
675 elseif type(disabled) == "string" then | |
676 local f = disabled | |
677 local neg = f:match("^~(.-)$") | |
678 if neg then | |
679 f = neg | |
680 end | |
681 if type(handler[f]) ~= "function" then | |
682 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
683 end | |
684 disabled = handler[f](handler) | |
685 if neg then | |
686 disabled = not disabled | |
687 end | |
688 end | |
689 end | |
690 local kind = (options.type or "group"):lower() | |
691 if disabled then | |
692 print(string.format(OPTION_IS_DISABLED, path), realOptions.cmdName or realOptions.name or self) | |
693 elseif kind == "text" then | |
694 local var | |
695 if passTable then | |
696 if not passTable.get then | |
697 elseif type(passTable.get) == "function" then | |
698 var = passTable.get(passValue) | |
699 else | |
700 local handler = passTable.handler or handler | |
701 if type(handler[passTable.get]) ~= "function" then | |
702 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get)) | |
703 end | |
704 var = handler[passTable.get](handler, passValue) | |
705 end | |
706 else | |
707 if not options.get then | |
708 elseif type(options.get) == "function" then | |
709 var = options.get() | |
710 else | |
711 local handler = options.handler or handler | |
712 if type(handler[options.get]) ~= "function" then | |
713 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get)) | |
714 end | |
715 var = handler[options.get](handler) | |
716 end | |
717 end | |
718 | |
719 local usage | |
720 if type(options.validate) == "table" then | |
721 if filter then | |
722 if not order then | |
723 order = {} | |
724 end | |
725 for k,v in pairs(options.validate) do | |
726 if v:find(filter) then | |
727 table.insert(order, v) | |
728 end | |
729 end | |
730 usage = "{" .. table.concat(order, " || ") .. "}" | |
731 for k in pairs(order) do | |
732 order[k] = nil | |
733 end | |
734 else | |
735 if not order then | |
736 order = {} | |
737 end | |
738 for k,v in pairs(options.validate) do | |
739 table.insert(order, v) | |
740 end | |
741 usage = "{" .. table.concat(order, " || ") .. "}" | |
742 for k in pairs(order) do | |
743 order[k] = nil | |
744 end | |
745 end | |
746 var = options.validate[var] or var | |
747 elseif options.validate == "keybinding" then | |
748 usage = KEYBINDING_USAGE | |
749 else | |
750 usage = options.usage or "<value>" | |
751 end | |
752 if not quiet then | |
753 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage), realOptions.cmdName or realOptions.name or self) | |
754 end | |
755 if (passTable and passTable.get) or options.get then | |
756 print(string.format(options.current or IS_CURRENTLY_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE))) | |
757 end | |
758 elseif kind == "range" then | |
759 local var | |
760 if passTable then | |
761 if type(passTable.get) == "function" then | |
762 var = passTable.get(passValue) | |
763 else | |
764 local handler = passTable.handler or handler | |
765 if type(handler[passTable.get]) ~= "function" then | |
766 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get)) | |
767 end | |
768 var = handler[passTable.get](handler, passValue) | |
769 end | |
770 else | |
771 if type(options.get) == "function" then | |
772 var = options.get() | |
773 else | |
774 local handler = options.handler or handler | |
775 if type(handler[options.get]) ~= "function" then | |
776 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get)) | |
777 end | |
778 var = handler[options.get](handler) | |
779 end | |
780 end | |
781 | |
782 local usage | |
783 local min = options.min or 0 | |
784 local max = options.max or 1 | |
785 if options.isPercent then | |
786 min, max = min * 100, max * 100 | |
787 var = tostring(var * 100) .. "%" | |
788 end | |
789 local bit = "-" | |
790 if min < 0 or max < 0 then | |
791 bit = " - " | |
792 end | |
793 usage = string.format("(%s%s%s)", min, bit, max) | |
794 if not quiet then | |
795 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage), realOptions.cmdName or realOptions.name or self) | |
796 end | |
797 print(string.format(options.current or IS_CURRENTLY_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE))) | |
798 elseif kind == "group" then | |
799 local usage | |
800 if next(options.args) then | |
801 if not order then | |
802 order = {} | |
803 end | |
804 for k,v in pairs(options.args) do | |
805 if v.type ~= "header" then | |
806 local hidden = v.cmdHidden or v.hidden | |
807 if hidden then | |
808 if type(hidden) == "function" then | |
809 hidden = hidden() | |
810 elseif type(hidden) == "string" then | |
811 local f = hidden | |
812 local neg = f:match("^~(.-)$") | |
813 if neg then | |
814 f = neg | |
815 end | |
816 if type(handler[f]) ~= "function" then | |
817 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
818 end | |
819 hidden = handler[f](handler) | |
820 if neg then | |
821 hidden = not hidden | |
822 end | |
823 end | |
824 end | |
825 if not hidden then | |
826 if filter then | |
827 if k:find(filter) then | |
828 table.insert(order, k) | |
829 elseif type(v.aliases) == "table" then | |
830 for _,bit in ipairs(v.aliases) do | |
831 if bit:find(filter) then | |
832 table.insert(order, k) | |
833 break | |
834 end | |
835 end | |
836 elseif type(v.aliases) == "string" then | |
837 if v.aliases:find(filter) then | |
838 table.insert(order, k) | |
839 end | |
840 end | |
841 else | |
842 table.insert(order, k) | |
843 end | |
844 end | |
845 end | |
846 end | |
847 if not mysort then | |
848 mysort = function(a, b) | |
849 local alpha, bravo = mysort_args[a], mysort_args[b] | |
850 local alpha_order = alpha and alpha.order or 100 | |
851 local bravo_order = bravo and bravo.order or 100 | |
852 if alpha_order == bravo_order then | |
853 return tostring(a) < tostring(b) | |
854 else | |
855 if alpha_order < 0 then | |
856 if bravo_order > 0 then | |
857 return false | |
858 end | |
859 else | |
860 if bravo_order < 0 then | |
861 return true | |
862 end | |
863 end | |
864 if alpha_order > 0 and bravo_order > 0 then | |
865 return tostring(a) < tostring(b) | |
866 end | |
867 return alpha_order < bravo_order | |
868 end | |
869 end | |
870 end | |
871 mysort_args = options.args | |
872 table.sort(order, mysort) | |
873 mysort_args = nil | |
874 if not quiet then | |
875 if options == realOptions then | |
876 if options.desc then | |
877 print(tostring(options.desc), realOptions.cmdName or realOptions.name or self) | |
878 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}")) | |
879 elseif self.description or self.notes then | |
880 print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self) | |
881 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}")) | |
882 else | |
883 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self) | |
884 end | |
885 else | |
886 if options.desc then | |
887 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self) | |
888 print(tostring(options.desc)) | |
889 else | |
890 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, "{" .. table.concat(order, " || ") .. "}"), realOptions.cmdName or realOptions.name or self) | |
891 end | |
892 end | |
893 end | |
894 for _,k in ipairs(order) do | |
895 local v = options.args[k] | |
896 if v then | |
897 local disabled = v.disabled | |
898 if disabled then | |
899 if type(disabled) == "function" then | |
900 disabled = disabled() | |
901 elseif type(disabled) == "string" then | |
902 local f = disabled | |
903 local neg = f:match("^~(.-)$") | |
904 if neg then | |
905 f = neg | |
906 end | |
907 if type(handler[f]) ~= "function" then | |
908 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
909 end | |
910 disabled = handler[f](handler) | |
911 if neg then | |
912 disabled = not disabled | |
913 end | |
914 end | |
915 end | |
916 if type(v.aliases) == "table" then | |
917 k = k .. " || " .. table.concat(v.aliases, " || ") | |
918 elseif type(v.aliases) == "string" then | |
919 k = k .. " || " .. v.aliases | |
920 end | |
921 if v.get then | |
922 local a1,a2,a3,a4 | |
923 if type(v.get) == "function" then | |
924 if options.pass then | |
925 a1,a2,a3,a4 = v.get(k) | |
926 else | |
927 a1,a2,a3,a4 = v.get() | |
928 end | |
929 else | |
930 local handler = v.handler or handler | |
931 local f = v.get | |
932 local neg | |
933 if v.type == "toggle" then | |
934 neg = f:match("^~(.-)$") | |
935 if neg then | |
936 f = neg | |
937 end | |
938 end | |
939 if type(handler[f]) ~= "function" then | |
940 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
941 end | |
942 if options.pass then | |
943 a1,a2,a3,a4 = handler[f](handler, k) | |
944 else | |
945 a1,a2,a3,a4 = handler[f](handler) | |
946 end | |
947 if neg then | |
948 a1 = not a1 | |
949 end | |
950 end | |
951 if v.type == "color" then | |
952 if v.hasAlpha then | |
953 if not a1 or not a2 or not a3 or not a4 then | |
954 s = NONE | |
955 else | |
956 s = string.format("|c%02x%02x%02x%02x%02x%02x%02x%02x|r", a4*255, a1*255, a2*255, a3*255, a4*255, a1*255, a2*255, a3*255) | |
957 end | |
958 else | |
959 if not a1 or not a2 or not a3 then | |
960 s = NONE | |
961 else | |
962 s = string.format("|cff%02x%02x%02x%02x%02x%02x|r", a1*255, a2*255, a3*255, a1*255, a2*255, a3*255) | |
963 end | |
964 end | |
965 elseif v.type == "toggle" then | |
966 if v.map then | |
967 s = tostring(v.map[a1 and true or false] or NONE) | |
968 else | |
969 s = tostring(MAP_ONOFF[a1 and true or false] or NONE) | |
970 end | |
971 elseif v.type == "range" then | |
972 if v.isPercent then | |
973 s = tostring(a1 * 100) .. "%" | |
974 else | |
975 s = tostring(a1) | |
976 end | |
977 elseif v.type == "text" and type(v.validate) == "table" then | |
978 s = tostring(v.validate[a1] or a1 or NONE) | |
979 else | |
980 s = tostring(a1 or NONE) | |
981 end | |
982 if disabled then | |
983 local s = s:gsub("|cff%x%x%x%x%x%x(.-)|r", "%1") | |
984 local desc = (v.desc or NONE):gsub("|cff%x%x%x%x%x%x(.-)|r", "%1") | |
985 print(string.format("|cffcfcfcf - %s: [%s] %s|r", k, s, desc)) | |
986 else | |
987 print(string.format(" - |cffffff7f%s: [|r%s|cffffff7f]|r %s", k, s, v.desc or NONE)) | |
988 end | |
989 else | |
990 if disabled then | |
991 local desc = (v.desc or NONE):gsub("|cff%x%x%x%x%x%x(.-)|r", "%1") | |
992 print(string.format("|cffcfcfcf - %s: %s", k, desc)) | |
993 else | |
994 print(string.format(" - |cffffff7f%s:|r %s", k, v.desc or NONE)) | |
995 end | |
996 end | |
997 end | |
998 end | |
999 for k in pairs(order) do | |
1000 order[k] = nil | |
1001 end | |
1002 else | |
1003 if options.desc then | |
1004 desc = options.desc | |
1005 print(string.format("|cffffff7f%s:|r %s", USAGE, path), realOptions.cmdName or realOptions.name or self) | |
1006 print(tostring(options.desc)) | |
1007 elseif options == realOptions and (self.description or self.notes) then | |
1008 print(tostring(self.description or self.notes), realOptions.cmdName or realOptions.name or self) | |
1009 print(string.format("|cffffff7f%s:|r %s", USAGE, path)) | |
1010 else | |
1011 print(string.format("|cffffff7f%s:|r %s", USAGE, path), realOptions.cmdName or realOptions.name or self) | |
1012 end | |
1013 print(NO_OPTIONS_AVAILABLE) | |
1014 end | |
1015 end | |
1016 end | |
1017 | |
1018 local function handlerFunc(self, chat, msg, options) | |
1019 if not msg then | |
1020 msg = "" | |
1021 else | |
1022 msg = msg:gsub("^%s*(.-)%s*$", "%1") | |
1023 msg = msg:gsub("%s+", " ") | |
1024 end | |
1025 | |
1026 local realOptions = options | |
1027 local options, path, args, handler, passTable, passValue = findTableLevel(self, options, chat, msg) | |
1028 | |
1029 local hidden, disabled = options.cmdHidden or options.hidden, options.disabled | |
1030 if hidden then | |
1031 if type(hidden) == "function" then | |
1032 hidden = hidden() | |
1033 elseif type(hidden) == "string" then | |
1034 local f = hidden | |
1035 local neg = f:match("^~(.-)$") | |
1036 if neg then | |
1037 f = neg | |
1038 end | |
1039 if type(handler[f]) ~= "function" then | |
1040 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
1041 end | |
1042 hidden = handler[f](handler) | |
1043 if neg then | |
1044 hidden = not hidden | |
1045 end | |
1046 end | |
1047 end | |
1048 if hidden then | |
1049 disabled = true | |
1050 elseif disabled then | |
1051 if type(disabled) == "function" then | |
1052 disabled = disabled() | |
1053 elseif type(disabled) == "string" then | |
1054 local f = disabled | |
1055 local neg = f:match("^~(.-)$") | |
1056 if neg then | |
1057 f = neg | |
1058 end | |
1059 if type(handler[f]) ~= "function" then | |
1060 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
1061 end | |
1062 disabled = handler[f](handler) | |
1063 if neg then | |
1064 disabled = not disabled | |
1065 end | |
1066 end | |
1067 end | |
1068 local _G_this = this | |
1069 local kind = (options.type or "group"):lower() | |
1070 if disabled then | |
1071 print(string.format(OPTION_IS_DISABLED, path), realOptions.cmdName or realOptions.name or self) | |
1072 elseif kind == "text" then | |
1073 if #args > 0 then | |
1074 if (type(options.validate) == "table" and #args > 1) or (type(options.validate) ~= "table" and not options.input) then | |
1075 local arg = table.concat(args, " ") | |
1076 for k,v in pairs(args) do | |
1077 args[k] = nil | |
1078 end | |
1079 args[1] = arg | |
1080 end | |
1081 if options.validate then | |
1082 local good | |
1083 if type(options.validate) == "function" then | |
1084 good = options.validate(unpack(args)) | |
1085 elseif type(options.validate) == "table" then | |
1086 local arg = args[1] | |
1087 arg = tostring(arg):lower() | |
1088 for k,v in pairs(options.validate) do | |
1089 if v:lower() == arg then | |
1090 args[1] = type(k) == "string" and k or v | |
1091 good = true | |
1092 break | |
1093 end | |
1094 end | |
1095 if not good and type((next(options.validate))) == "string" then | |
1096 for k,v in pairs(options.validate) do | |
1097 if type(k) == "string" and k:lower() == arg then | |
1098 args[1] = k | |
1099 good = true | |
1100 break | |
1101 end | |
1102 end | |
1103 end | |
1104 elseif options.validate == "keybinding" then | |
1105 good = keybindingValidateFunc(unpack(args)) | |
1106 if good ~= false then | |
1107 args[1] = good | |
1108 end | |
1109 else | |
1110 if type(handler[options.validate]) ~= "function" then | |
1111 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.validate)) | |
1112 end | |
1113 good = handler[options.validate](handler, unpack(args)) | |
1114 end | |
1115 if not good then | |
1116 local usage | |
1117 if type(options.validate) == "table" then | |
1118 if not order then | |
1119 order = {} | |
1120 end | |
1121 for k,v in pairs(options.validate) do | |
1122 table.insert(order, v) | |
1123 end | |
1124 usage = "{" .. table.concat(order, " || ") .. "}" | |
1125 for k in pairs(order) do | |
1126 order[k] = nil | |
1127 end | |
1128 elseif options.validate == "keybinding" then | |
1129 usage = KEYBINDING_USAGE | |
1130 else | |
1131 usage = options.usage or "<value>" | |
1132 end | |
1133 print(string.format(options.error or IS_NOT_A_VALID_OPTION_FOR, tostring(table.concat(args, " ")), path), realOptions.cmdName or realOptions.name or self) | |
1134 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage)) | |
1135 return | |
1136 end | |
1137 end | |
1138 | |
1139 local var | |
1140 if passTable then | |
1141 if not passTable.get then | |
1142 elseif type(passTable.get) == "function" then | |
1143 var = passTable.get(passValue) | |
1144 else | |
1145 if type(handler[passTable.get]) ~= "function" then | |
1146 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get)) | |
1147 end | |
1148 var = handler[passTable.get](handler, passValue) | |
1149 end | |
1150 else | |
1151 if not options.get then | |
1152 elseif type(options.get) == "function" then | |
1153 var = options.get() | |
1154 else | |
1155 if type(handler[options.get]) ~= "function" then | |
1156 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get)) | |
1157 end | |
1158 var = handler[options.get](handler) | |
1159 end | |
1160 end | |
1161 | |
1162 if var ~= args[1] then | |
1163 if passTable then | |
1164 if type(passTable.set) == "function" then | |
1165 passTable.set(passValue, unpack(args)) | |
1166 else | |
1167 if type(handler[passTable.set]) ~= "function" then | |
1168 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.set)) | |
1169 end | |
1170 handler[passTable.set](handler, passTable.set, unpack(args)) | |
1171 end | |
1172 else | |
1173 if type(options.set) == "function" then | |
1174 options.set(unpack(args)) | |
1175 else | |
1176 if type(handler[options.set]) ~= "function" then | |
1177 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.set)) | |
1178 end | |
1179 handler[options.set](handler, unpack(args)) | |
1180 end | |
1181 end | |
1182 end | |
1183 end | |
1184 | |
1185 if #args > 0 then | |
1186 local var | |
1187 if passTable then | |
1188 if not passTable.get then | |
1189 elseif type(passTable.get) == "function" then | |
1190 var = passTable.get(passValue) | |
1191 else | |
1192 if type(handler[passTable.get]) ~= "function" then | |
1193 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get)) | |
1194 end | |
1195 var = handler[passTable.get](handler, passValue) | |
1196 end | |
1197 else | |
1198 if not options.get then | |
1199 elseif type(options.get) == "function" then | |
1200 var = options.get() | |
1201 else | |
1202 if type(handler[options.get]) ~= "function" then | |
1203 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get)) | |
1204 end | |
1205 var = handler[options.get](handler) | |
1206 end | |
1207 end | |
1208 if type(options.validate) == "table" then | |
1209 var = options.validate[var] or var | |
1210 end | |
1211 if (passTable and passTable.get) or options.get then | |
1212 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)), realOptions.cmdName or realOptions.name or self) | |
1213 end | |
1214 if var == args[1] then | |
1215 return | |
1216 end | |
1217 else | |
1218 printUsage(self, handler, realOptions, options, path, args) | |
1219 return | |
1220 end | |
1221 elseif kind == "execute" then | |
1222 if passTable then | |
1223 if type(passFunc) == "function" then | |
1224 set(passValue) | |
1225 else | |
1226 if type(handler[passFunc]) ~= "function" then | |
1227 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passFunc)) | |
1228 end | |
1229 handler[passFunc](handler, passValue) | |
1230 end | |
1231 else | |
1232 local ret, msg | |
1233 if type(options.func) == "function" then | |
1234 options.func() | |
1235 else | |
1236 local handler = options.handler or self | |
1237 if type(handler[options.func]) ~= "function" then | |
1238 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.func)) | |
1239 end | |
1240 handler[options.func](handler) | |
1241 end | |
1242 end | |
1243 elseif kind == "toggle" then | |
1244 local var | |
1245 if passTable then | |
1246 if type(passTable.get) == "function" then | |
1247 var = passTable.get(passValue) | |
1248 else | |
1249 local f = passTable.get | |
1250 local neg = f:match("^~(.-)$") | |
1251 if neg then | |
1252 f = neg | |
1253 end | |
1254 if type(handler[f]) ~= "function" then | |
1255 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
1256 end | |
1257 var = handler[f](handler, passValue) | |
1258 if neg then | |
1259 var = not var | |
1260 end | |
1261 end | |
1262 if type(passTable.set) == "function" then | |
1263 passTable.set(passValue, not var) | |
1264 else | |
1265 if type(handler[passTable.set]) ~= "function" then | |
1266 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.set)) | |
1267 end | |
1268 handler[passTable.set](handler, passValue, not var) | |
1269 end | |
1270 if type(passTable.get) == "function" then | |
1271 var = passTable.get(passValue) | |
1272 else | |
1273 local f = passTable.get | |
1274 local neg = f:match("^~(.-)$") | |
1275 if neg then | |
1276 f = neg | |
1277 end | |
1278 var = handler[f](handler, passValue) | |
1279 if neg then | |
1280 var = not var | |
1281 end | |
1282 end | |
1283 else | |
1284 local handler = options.handler or self | |
1285 if type(options.get) == "function" then | |
1286 var = options.get() | |
1287 else | |
1288 local f = options.get | |
1289 local neg = f:match("^~(.-)$") | |
1290 if neg then | |
1291 f = neg | |
1292 end | |
1293 if type(handler[f]) ~= "function" then | |
1294 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, f)) | |
1295 end | |
1296 var = handler[f](handler) | |
1297 if neg then | |
1298 var = not var | |
1299 end | |
1300 end | |
1301 if type(options.set) == "function" then | |
1302 options.set(not var) | |
1303 else | |
1304 if type(handler[options.set]) ~= "function" then | |
1305 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.set)) | |
1306 end | |
1307 handler[options.set](handler, not var) | |
1308 end | |
1309 if type(options.get) == "function" then | |
1310 var = options.get() | |
1311 else | |
1312 local f = options.get | |
1313 local neg = f:match("^~(.-)$") | |
1314 if neg then | |
1315 f = neg | |
1316 end | |
1317 var = handler[f](handler) | |
1318 if neg then | |
1319 var = not var | |
1320 end | |
1321 end | |
1322 end | |
1323 | |
1324 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), (options.map or MAP_ONOFF)[var and true or false] or NONE), realOptions.cmdName or realOptions.name or self) | |
1325 elseif kind == "range" then | |
1326 local arg | |
1327 if #args <= 1 then | |
1328 arg = args[1] | |
1329 else | |
1330 arg = table.concat(args, " ") | |
1331 end | |
1332 | |
1333 if arg then | |
1334 local min = options.min or 0 | |
1335 local max = options.max or 1 | |
1336 local good = false | |
1337 if type(arg) == "number" then | |
1338 if options.isPercent then | |
1339 arg = arg / 100 | |
1340 end | |
1341 | |
1342 if arg >= min and arg <= max then | |
1343 good = true | |
1344 end | |
1345 | |
1346 if good and type(options.step) == "number" and options.step > 0 then | |
1347 local step = options.step | |
1348 arg = math.floor((arg - min) / step + 0.5) * step + min | |
1349 if arg > max then | |
1350 arg = max | |
1351 elseif arg < min then | |
1352 arg = min | |
1353 end | |
1354 end | |
1355 end | |
1356 if not good then | |
1357 local usage | |
1358 local min = options.min or 0 | |
1359 local max = options.max or 1 | |
1360 if options.isPercent then | |
1361 min, max = min * 100, max * 100 | |
1362 end | |
1363 local bit = "-" | |
1364 if min < 0 or max < 0 then | |
1365 bit = " - " | |
1366 end | |
1367 usage = string.format("(%s%s%s)", min, bit, max) | |
1368 print(string.format(options.error or IS_NOT_A_VALID_VALUE_FOR, tostring(arg), path), realOptions.cmdName or realOptions.name or self) | |
1369 print(string.format("|cffffff7f%s:|r %s %s", USAGE, path, usage)) | |
1370 return | |
1371 end | |
1372 | |
1373 local var | |
1374 if passTable then | |
1375 if type(passTable.get) == "function" then | |
1376 var = passTable.get(passValue) | |
1377 else | |
1378 if type(handler[passTable.get]) ~= "function" then | |
1379 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get)) | |
1380 end | |
1381 var = handler[passTable.get](handler, passValue) | |
1382 end | |
1383 else | |
1384 if type(options.get) == "function" then | |
1385 var = options.get() | |
1386 else | |
1387 local handler = options.handler or self | |
1388 if type(handler[options.get]) ~= "function" then | |
1389 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get)) | |
1390 end | |
1391 var = handler[options.get](handler) | |
1392 end | |
1393 end | |
1394 | |
1395 if var ~= arg then | |
1396 if passTable then | |
1397 if type(passTable.set) == "function" then | |
1398 passTable.set(passValue, arg) | |
1399 else | |
1400 if type(handler[passTable.set]) ~= "function" then | |
1401 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.set)) | |
1402 end | |
1403 handler[passTable.set](handler, passValue, arg) | |
1404 end | |
1405 else | |
1406 if type(options.set) == "function" then | |
1407 options.set(arg) | |
1408 else | |
1409 local handler = options.handler or self | |
1410 if type(handler[options.set]) ~= "function" then | |
1411 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.set)) | |
1412 end | |
1413 handler[options.set](handler, arg) | |
1414 end | |
1415 end | |
1416 end | |
1417 end | |
1418 | |
1419 if arg then | |
1420 local var | |
1421 if passTable then | |
1422 if type(passTable.get) == "function" then | |
1423 var = passTable.get(passValue) | |
1424 else | |
1425 if type(handler[passTable.get]) ~= "function" then | |
1426 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get)) | |
1427 end | |
1428 var = handler[passTable.get](handler, passValue) | |
1429 end | |
1430 else | |
1431 if type(options.get) == "function" then | |
1432 var = options.get() | |
1433 else | |
1434 local handler = options.handler or self | |
1435 if type(handler[options.get]) ~= "function" then | |
1436 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get)) | |
1437 end | |
1438 var = handler[options.get](handler) | |
1439 end | |
1440 end | |
1441 | |
1442 if var and options.isPercent then | |
1443 var = tostring(var * 100) .. "%" | |
1444 end | |
1445 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), tostring(var or NONE)), realOptions.cmdName or realOptions.name or self) | |
1446 if var == arg then | |
1447 return | |
1448 end | |
1449 else | |
1450 printUsage(self, handler, realOptions, options, path, args) | |
1451 return | |
1452 end | |
1453 elseif kind == "color" then | |
1454 if #args > 0 then | |
1455 local r,g,b,a | |
1456 if #args == 1 then | |
1457 local arg = tostring(args[1]) | |
1458 if options.hasAlpha then | |
1459 if arg:len() == 8 and arg:find("^%x*$") then | |
1460 r,g,b,a = tonumber(arg:sub(1, 2), 16) / 255, tonumber(arg:sub(3, 4), 16) / 255, tonumber(arg:sub(5, 6), 16) / 255, tonumber(arg:sub(7, 8), 16) / 255 | |
1461 end | |
1462 else | |
1463 if arg:len() == 6 and arg:find("^%x*$") then | |
1464 r,g,b = tonumber(arg:sub(1, 2), 16) / 255, tonumber(arg:sub(3, 4), 16) / 255, tonumber(arg:sub(5, 6), 16) / 255 | |
1465 end | |
1466 end | |
1467 elseif #args == 4 and options.hasAlpha then | |
1468 local a1,a2,a3,a4 = args[1], args[2], args[3], args[4] | |
1469 if type(a1) == "number" and type(a2) == "number" and type(a3) == "number" and type(a4) == "number" and a1 <= 1 and a2 <= 1 and a3 <= 1 and a4 <= 1 then | |
1470 r,g,b,a = a1,a2,a3,a4 | |
1471 elseif (type(a1) == "number" or a1:len() == 2) and a1:find("^%x*$") and (type(a2) == "number" or a2:len() == 2) and a2:find("^%x*$") and (type(a3) == "number" or a3:len() == 2) and a3:find("^%x*$") and (type(a4) == "number" or a4:len() == 2) and a4:find("^%x*$") then | |
1472 r,g,b,a = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255, tonumber(a4, 16) / 255 | |
1473 end | |
1474 elseif #args == 3 and not options.hasAlpha then | |
1475 local a1,a2,a3 = args[1], args[2], args[3] | |
1476 if type(a1) == "number" and type(a2) == "number" and type(a3) == "number" and a1 <= 1 and a2 <= 1 and a3 <= 1 then | |
1477 r,g,b = a1,a2,a3 | |
1478 elseif (type(a1) == "number" or a1:len() == 2) and a1:find("^%x*$") and (type(a2) == "number" or a2:len() == 2) and a2:find("^%x*$") and (type(a3) == "number" or a3:len() == 2) and a3:find("^%x*$") then | |
1479 r,g,b = tonumber(a1, 16) / 255, tonumber(a2, 16) / 255, tonumber(a3, 16) / 255 | |
1480 end | |
1481 end | |
1482 if not r then | |
1483 print(string.format(options.error or IS_NOT_A_VALID_OPTION_FOR, table.concat(args, ' '), path), realOptions.cmdName or realOptions.name or self) | |
1484 print(string.format("|cffffff7f%s:|r %s {0-1} {0-1} {0-1}%s", USAGE, path, options.hasAlpha and " {0-1}" or "")) | |
1485 return | |
1486 end | |
1487 if passTable then | |
1488 if type(passTable.set) == "function" then | |
1489 passTable.set(passValue, r,g,b,a) | |
1490 else | |
1491 if type(handler[passTable.set]) ~= "function" then | |
1492 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.set)) | |
1493 end | |
1494 handler[passTable.set](handler, passValue, r,g,b,a) | |
1495 end | |
1496 else | |
1497 if type(options.set) == "function" then | |
1498 options.set(r,g,b,a) | |
1499 else | |
1500 if type(handler[options.set]) ~= "function" then | |
1501 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.set)) | |
1502 end | |
1503 handler[options.set](handler, r,g,b,a) | |
1504 end | |
1505 end | |
1506 | |
1507 local r,g,b,a | |
1508 if passTable then | |
1509 if type(passTable.get) == "function" then | |
1510 r,g,b,a = passTable.get(passValue) | |
1511 else | |
1512 if type(handler[passTable.get]) ~= "function" then | |
1513 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get)) | |
1514 end | |
1515 r,g,b,a = handler[passTable.get](handler, passValue) | |
1516 end | |
1517 else | |
1518 if type(options.get) == "function" then | |
1519 r,g,b,a = options.get() | |
1520 else | |
1521 if type(handler[options.get]) ~= "function" then | |
1522 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get)) | |
1523 end | |
1524 r,g,b,a = handler[options.get](handler) | |
1525 end | |
1526 end | |
1527 | |
1528 local s | |
1529 if type(r) == "number" and type(g) == "number" and type(b) == "number" then | |
1530 if options.hasAlpha and type(a) == "number" then | |
1531 s = string.format("|c%02x%02x%02x%02x%02x%02x%02x%02x|r", a*255, r*255, g*255, b*255, r*255, g*255, b*255, a*255) | |
1532 else | |
1533 s = string.format("|cff%02x%02x%02x%02x%02x%02x|r", r*255, g*255, b*255, r*255, g*255, b*255) | |
1534 end | |
1535 else | |
1536 s = NONE | |
1537 end | |
1538 print(string.format(options.message or IS_NOW_SET_TO, tostring(options.cmdName or options.name), s), realOptions.cmdName or realOptions.name or self) | |
1539 else | |
1540 local r,g,b,a | |
1541 if passTable then | |
1542 if type(passTable.get) == "function" then | |
1543 r,g,b,a = passTable.get(passValue) | |
1544 else | |
1545 if type(handler[passTable.get]) ~= "function" then | |
1546 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, passTable.get)) | |
1547 end | |
1548 r,g,b,a = handler[passTable.get](handler, passValue) | |
1549 end | |
1550 else | |
1551 if type(options.get) == "function" then | |
1552 r,g,b,a = options.get() | |
1553 else | |
1554 if type(handler[options.get]) ~= "function" then | |
1555 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, options.get)) | |
1556 end | |
1557 r,g,b,a = handler[options.get](handler) | |
1558 end | |
1559 end | |
1560 | |
1561 if not colorTable then | |
1562 colorTable = {} | |
1563 local t = colorTable | |
1564 | |
1565 if ColorPickerOkayButton then | |
1566 local ColorPickerOkayButton_OnClick = ColorPickerOkayButton:GetScript("OnClick") | |
1567 ColorPickerOkayButton:SetScript("OnClick", function() | |
1568 if ColorPickerOkayButton_OnClick then | |
1569 ColorPickerOkayButton_OnClick() | |
1570 end | |
1571 if t.active then | |
1572 ColorPickerFrame.cancelFunc = nil | |
1573 ColorPickerFrame.func = nil | |
1574 ColorPickerFrame.opacityFunc = nil | |
1575 local r,g,b,a | |
1576 if t.passValue then | |
1577 if type(t.get) == "function" then | |
1578 r,g,b,a = t.get(t.passValue) | |
1579 else | |
1580 if type(t.handler[t.get]) ~= "function" then | |
1581 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.get)) | |
1582 end | |
1583 r,g,b,a = t.handler[t.get](t.handler, t.passValue) | |
1584 end | |
1585 else | |
1586 if type(t.get) == "function" then | |
1587 r,g,b,a = t.get() | |
1588 else | |
1589 if type(t.handler[t.get]) ~= "function" then | |
1590 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.get)) | |
1591 end | |
1592 r,g,b,a = t.handler[t.get](t.handler) | |
1593 end | |
1594 end | |
1595 if r ~= t.r or g ~= t.g or b ~= t.b or (t.hasAlpha and a ~= t.a) then | |
1596 local s | |
1597 if type(r) == "number" and type(g) == "number" and type(b) == "number" then | |
1598 if t.hasAlpha and type(a) == "number" then | |
1599 s = string.format("|c%02x%02x%02x%02x%02x%02x%02x%02x|r", a*255, r*255, g*255, b*255, r*255, g*255, b*255, a*255) | |
1600 else | |
1601 s = string.format("|cff%02x%02x%02x%02x%02x%02x|r", r*255, g*255, b*255, r*255, g*255, b*255) | |
1602 end | |
1603 else | |
1604 s = NONE | |
1605 end | |
1606 print(string.format(t.message, tostring(t.name), s), t.realOptions.cmdName or t.realOptions.name or self) | |
1607 end | |
1608 for k,v in pairs(t) do | |
1609 t[k] = nil | |
1610 end | |
1611 end | |
1612 end) | |
1613 end | |
1614 else | |
1615 for k,v in pairs(colorTable) do | |
1616 colorTable[k] = nil | |
1617 end | |
1618 end | |
1619 | |
1620 if type(r) ~= "number" or type(g) ~= "number" or type(b) ~= "number" then | |
1621 r,g,b = 1, 1, 1 | |
1622 end | |
1623 if type(a) ~= "number" then | |
1624 a = 1 | |
1625 end | |
1626 local t = colorTable | |
1627 t.r = r | |
1628 t.g = g | |
1629 t.b = b | |
1630 if hasAlpha then | |
1631 t.a = a | |
1632 end | |
1633 t.realOptions = realOptions | |
1634 t.hasAlpha = options.hasAlpha | |
1635 t.handler = handler | |
1636 t.set = passTable and passTable.set or options.set | |
1637 t.get = passTable and passTable.get or options.get | |
1638 t.name = options.cmdName or options.name | |
1639 t.message = options.message or IS_NOW_SET_TO | |
1640 t.passValue = passValue | |
1641 t.active = true | |
1642 | |
1643 if not colorFunc then | |
1644 colorFunc = function() | |
1645 local r,g,b = ColorPickerFrame:GetColorRGB() | |
1646 if t.hasAlpha then | |
1647 local a = 1 - OpacitySliderFrame:GetValue() | |
1648 if type(t.set) == "function" then | |
1649 if t.passValue then | |
1650 t.set(t.passValue, r,g,b,a) | |
1651 else | |
1652 t.set(r,g,b,a) | |
1653 end | |
1654 else | |
1655 if type(t.handler[t.set]) ~= "function" then | |
1656 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.set)) | |
1657 end | |
1658 if t.passValue then | |
1659 t.handler[t.set](t.handler, t.passValue, r,g,b,a) | |
1660 else | |
1661 t.handler[t.set](t.handler, r,g,b,a) | |
1662 end | |
1663 end | |
1664 else | |
1665 if type(t.set) == "function" then | |
1666 if t.passValue then | |
1667 t.set(t.passValue, r,g,b) | |
1668 else | |
1669 t.set(r,g,b) | |
1670 end | |
1671 else | |
1672 if type(t.handler[t.set]) ~= "function" then | |
1673 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.set)) | |
1674 end | |
1675 if t.passValue then | |
1676 t.handler[t.set](t.handler, t.passValue, r,g,b) | |
1677 else | |
1678 t.handler[t.set](t.handler, r,g,b) | |
1679 end | |
1680 end | |
1681 end | |
1682 end | |
1683 end | |
1684 | |
1685 ColorPickerFrame.func = colorFunc | |
1686 ColorPickerFrame.hasOpacity = options.hasAlpha | |
1687 if options.hasAlpha then | |
1688 ColorPickerFrame.opacityFunc = ColorPickerFrame.func | |
1689 ColorPickerFrame.opacity = 1 - a | |
1690 end | |
1691 ColorPickerFrame:SetColorRGB(r,g,b) | |
1692 | |
1693 if not colorCancelFunc then | |
1694 colorCancelFunc = function() | |
1695 if t.hasAlpha then | |
1696 if type(t.set) == "function" then | |
1697 if t.passValue then | |
1698 t.set(t.passValue, t.r,t.g,t.b,t.a) | |
1699 else | |
1700 t.set(t.r,t.g,t.b,t.a) | |
1701 end | |
1702 else | |
1703 if type(t.handler[t.get]) ~= "function" then | |
1704 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.get)) | |
1705 end | |
1706 if t.passValue then | |
1707 t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b,t.a) | |
1708 else | |
1709 t.handler[t.set](t.handler, t.r,t.g,t.b,t.a) | |
1710 end | |
1711 end | |
1712 else | |
1713 if type(t.set) == "function" then | |
1714 if t.passValue then | |
1715 t.set(t.passValue, t.r,t.g,t.b) | |
1716 else | |
1717 t.set(t.r,t.g,t.b) | |
1718 end | |
1719 else | |
1720 if type(t.handler[t.set]) ~= "function" then | |
1721 AceConsole:error("%s: %s", handler, string.format(OPTION_HANDLER_NOT_FOUND, t.set)) | |
1722 end | |
1723 if t.passValue then | |
1724 t.handler[t.set](t.handler, t.passValue, t.r,t.g,t.b) | |
1725 else | |
1726 t.handler[t.set](t.handler, t.r,t.g,t.b) | |
1727 end | |
1728 end | |
1729 end | |
1730 for k,v in pairs(t) do | |
1731 t[k] = nil | |
1732 end | |
1733 ColorPickerFrame.cancelFunc = nil | |
1734 ColorPickerFrame.func = nil | |
1735 ColorPickerFrame.opacityFunc = nil | |
1736 end | |
1737 end | |
1738 | |
1739 ColorPickerFrame.cancelFunc = colorCancelFunc | |
1740 | |
1741 ShowUIPanel(ColorPickerFrame) | |
1742 end | |
1743 return | |
1744 elseif kind == "group" then | |
1745 if #args == 0 then | |
1746 printUsage(self, handler, realOptions, options, path, args) | |
1747 else | |
1748 -- invalid argument | |
1749 print(string.format(options.error or IS_NOT_A_VALID_OPTION_FOR, args[1], path), realOptions.cmdName or realOptions.name or self) | |
1750 end | |
1751 return | |
1752 end | |
1753 this = _G_this | |
1754 if Dewdrop then | |
1755 Dewdrop:Refresh(1) | |
1756 Dewdrop:Refresh(2) | |
1757 Dewdrop:Refresh(3) | |
1758 Dewdrop:Refresh(4) | |
1759 Dewdrop:Refresh(5) | |
1760 end | |
1761 end | |
1762 | |
1763 local external | |
1764 function AceConsole:RegisterChatCommand(slashCommands, options, name) | |
1765 if type(slashCommands) ~= "table" and slashCommands ~= false then | |
1766 AceConsole:error("Bad argument #2 to `RegisterChatCommand' (expected table, got %s)", type(slashCommands)) | |
1767 end | |
1768 if not slashCommands and type(name) ~= "string" then | |
1769 AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string, got %s)", type(name)) | |
1770 end | |
1771 if type(options) ~= "table" and type(options) ~= "function" and options ~= nil then | |
1772 AceConsole:error("Bad argument #3 to `RegisterChatCommand' (expected table, function, or nil, got %s)", type(options)) | |
1773 end | |
1774 if name then | |
1775 if type(name) ~= "string" then | |
1776 AceConsole:error("Bad argument #4 to `RegisterChatCommand' (expected string or nil, got %s)", type(name)) | |
1777 elseif not name:find("^%w+$") or name:upper() ~= name or name:len() == 0 then | |
1778 AceConsole:error("Argument #4 must be an uppercase, letters-only string with at least 1 character") | |
1779 end | |
1780 end | |
1781 if slashCommands then | |
1782 if #slashCommands == 0 then | |
1783 AceConsole:error("Argument #2 to `RegisterChatCommand' must include at least one string") | |
1784 end | |
1785 | |
1786 for k,v in pairs(slashCommands) do | |
1787 if type(k) ~= "number" then | |
1788 AceConsole:error("All keys in argument #2 to `RegisterChatCommand' must be numbers") | |
1789 end | |
1790 if type(v) ~= "string" then | |
1791 AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be strings") | |
1792 elseif not v:find("^/[A-Za-z][A-Za-z0-9_]*$") then | |
1793 AceConsole:error("All values in argument #2 to `RegisterChatCommand' must be in the form of \"/word\"") | |
1794 end | |
1795 end | |
1796 end | |
1797 | |
1798 if not options then | |
1799 options = { | |
1800 type = 'group', | |
1801 args = {}, | |
1802 handler = self | |
1803 } | |
1804 end | |
1805 | |
1806 if type(options) == "table" then | |
1807 local err, position = validateOptions(options) | |
1808 if err then | |
1809 if position then | |
1810 AceConsole:error(position .. ": " .. err) | |
1811 else | |
1812 AceConsole:error(err) | |
1813 end | |
1814 end | |
1815 | |
1816 if not options.handler then | |
1817 options.handler = self | |
1818 end | |
1819 | |
1820 if options.handler == self and options.type:lower() == "group" and self.class then | |
1821 AceConsole:InjectAceOptionsTable(self, options) | |
1822 end | |
1823 end | |
1824 | |
1825 local chat | |
1826 if slashCommands then | |
1827 chat = slashCommands[1] | |
1828 else | |
1829 chat = _G["SLASH_"..name..1] | |
1830 end | |
1831 | |
1832 local handler | |
1833 if type(options) == "function" then | |
1834 handler = options | |
1835 for k,v in pairs(_G) do | |
1836 if handler == v then | |
1837 local k = k | |
1838 handler = function(msg) | |
1839 return _G[k](msg) | |
1840 end | |
1841 end | |
1842 end | |
1843 else | |
1844 function handler(msg) | |
1845 handlerFunc(self, chat, msg, options) | |
1846 end | |
1847 end | |
1848 | |
1849 if not _G.SlashCmdList then | |
1850 _G.SlashCmdList = {} | |
1851 end | |
1852 | |
1853 if not name then | |
1854 local A = ('A'):byte() | |
1855 repeat | |
1856 name = string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) .. string.char(math.random(26) + A - 1) | |
1857 until not _G.SlashCmdList[name] | |
1858 end | |
1859 | |
1860 if slashCommands then | |
1861 if _G.SlashCmdList[name] then | |
1862 local i = 0 | |
1863 while true do | |
1864 i = i + 1 | |
1865 if _G["SLASH_"..name..i] then | |
1866 _G["SLASH_"..name..i] = nil | |
1867 else | |
1868 break | |
1869 end | |
1870 end | |
1871 end | |
1872 | |
1873 local i = 0 | |
1874 for _,command in ipairs(slashCommands) do | |
1875 i = i + 1 | |
1876 _G["SLASH_"..name..i] = command | |
1877 if command:lower() ~= command then | |
1878 i = i + 1 | |
1879 _G["SLASH_"..name..i] = command:lower() | |
1880 end | |
1881 end | |
1882 end | |
1883 _G.SlashCmdList[name] = handler | |
1884 if self ~= AceConsole and self.slashCommand == nil then | |
1885 self.slashCommand = chat | |
1886 end | |
1887 | |
1888 if not AceEvent and AceLibrary:HasInstance("AceEvent-2.0") then | |
1889 external(AceConsole, "AceEvent-2.0", AceLibrary("AceEvent-2.0")) | |
1890 end | |
1891 if AceEvent then | |
1892 if not AceConsole.nextAddon then | |
1893 AceConsole.nextAddon = {} | |
1894 end | |
1895 if type(options) == "table" then | |
1896 AceConsole.nextAddon[self] = options | |
1897 if not self.playerLogin then | |
1898 AceConsole:RegisterEvent("PLAYER_LOGIN", "PLAYER_LOGIN", true) | |
1899 end | |
1900 end | |
1901 end | |
1902 | |
1903 AceConsole.registry[name] = options | |
1904 end | |
1905 | |
1906 function AceConsole:InjectAceOptionsTable(handler, options) | |
1907 self:argCheck(handler, 2, "table") | |
1908 self:argCheck(options, 3, "table") | |
1909 if options.type:lower() ~= "group" then | |
1910 self:error('Cannot inject into options table argument #3 if its type is not "group"') | |
1911 end | |
1912 if options.handler ~= nil and options.handler ~= handler then | |
1913 self:error("Cannot inject into options table argument #3 if it has a different handler than argument #2") | |
1914 end | |
1915 options.handler = handler | |
1916 local class = handler.class | |
1917 if not class then | |
1918 self:error("Cannot retrieve AceOptions tables from a non-object argument #2") | |
1919 end | |
1920 while class and class ~= AceOO.Class do | |
1921 if type(class.GetAceOptionsDataTable) == "function" then | |
1922 local t = class:GetAceOptionsDataTable(handler) | |
1923 for k,v in pairs(t) do | |
1924 if type(options.args) ~= "table" then | |
1925 options.args = {} | |
1926 end | |
1927 if options.args[k] == nil then | |
1928 options.args[k] = v | |
1929 end | |
1930 end | |
1931 end | |
1932 local mixins = class.mixins | |
1933 if mixins then | |
1934 for mixin in pairs(mixins) do | |
1935 if type(mixin.GetAceOptionsDataTable) == "function" then | |
1936 local t = mixin:GetAceOptionsDataTable(handler) | |
1937 for k,v in pairs(t) do | |
1938 if type(options.args) ~= "table" then | |
1939 options.args = {} | |
1940 end | |
1941 if options.args[k] == nil then | |
1942 options.args[k] = v | |
1943 end | |
1944 end | |
1945 end | |
1946 end | |
1947 end | |
1948 class = class.super | |
1949 end | |
1950 return options | |
1951 end | |
1952 | |
1953 function AceConsole:PLAYER_LOGIN() | |
1954 self.playerLogin = true | |
1955 for addon, options in pairs(self.nextAddon) do | |
1956 local err, position = validateOptionsMethods(addon, options) | |
1957 if err then | |
1958 if position then | |
1959 geterrorhandler()(tostring(addon) .. ": AceConsole: " .. position .. ": " .. err) | |
1960 else | |
1961 geterrorhandler()(tostring(addon) .. ": AceConsole: " .. err) | |
1962 end | |
1963 end | |
1964 self.nextAddon[addon] = nil | |
1965 end | |
1966 end | |
1967 | |
1968 function AceConsole:TabCompleteInfo(cmdpath) | |
1969 local cmd = cmdpath:match("(/%S+)") | |
1970 if not cmd then | |
1971 return | |
1972 end | |
1973 local path = cmdpath:sub(cmd:len() + 2) | |
1974 for name in pairs(SlashCmdList) do --global | |
1975 if AceConsole.registry[name] then | |
1976 local i = 0 | |
1977 while true do | |
1978 i = i + 1 | |
1979 local scmd = _G["SLASH_"..name..i] | |
1980 if not scmd then break end | |
1981 if cmd == scmd then | |
1982 return name, cmd, path | |
1983 end | |
1984 end | |
1985 end | |
1986 end | |
1987 end | |
1988 | |
1989 function external(self, major, instance) | |
1990 if major == "AceEvent-2.0" then | |
1991 if not AceEvent then | |
1992 AceEvent = instance | |
1993 | |
1994 AceEvent:embed(self) | |
1995 end | |
1996 elseif major == "AceTab-2.0" then | |
1997 instance:RegisterTabCompletion("AceConsole", "%/.*", function(t, cmdpath, pos) | |
1998 local ac = AceLibrary("AceConsole-2.0") | |
1999 local name, cmd, path = ac:TabCompleteInfo(cmdpath:sub(1, pos)) | |
2000 | |
2001 if not ac.registry[name] then | |
2002 return false | |
2003 else | |
2004 local validArgs = findTableLevel(ac, ac.registry[name], cmd, path or "") | |
2005 if validArgs.args then | |
2006 for arg in pairs(validArgs.args) do | |
2007 table.insert(t, arg) | |
2008 end | |
2009 end | |
2010 end | |
2011 end, function(u, matches, gcs, cmdpath) | |
2012 local ac = AceLibrary("AceConsole-2.0") | |
2013 local name, cmd, path = ac:TabCompleteInfo(cmdpath) | |
2014 if ac.registry[name] then | |
2015 local validArgs, path2, argwork = findTableLevel(ac, ac.registry[name], cmd, path) | |
2016 printUsage(ac, validArgs.handler, ac.registry[name], validArgs, path2, argwork, not gcs or gcs ~= "", gcs) | |
2017 end | |
2018 end) | |
2019 elseif major == "Dewdrop-2.0" then | |
2020 Dewdrop = instance | |
2021 end | |
2022 end | |
2023 | |
2024 local function activate(self, oldLib, oldDeactivate) | |
2025 AceConsole = self | |
2026 | |
2027 if oldLib then | |
2028 self.registry = oldLib.registry | |
2029 self.nextAddon = oldLib.nextAddon | |
2030 end | |
2031 | |
2032 if not self.registry then | |
2033 self.registry = {} | |
2034 else | |
2035 for name,options in pairs(self.registry) do | |
2036 self:RegisterChatCommand(false, options, name) | |
2037 end | |
2038 end | |
2039 | |
2040 self:RegisterChatCommand({ "/reload", "/rl", "/reloadui" }, ReloadUI, "RELOAD") | |
2041 | |
2042 self:RegisterChatCommand({ "/print" }, function(text) | |
2043 local f, err = loadstring("AceLibrary('AceConsole-2.0'):PrintComma(" .. text .. ")") | |
2044 if not f then | |
2045 self:Print("|cffff0000Error:|r", err) | |
2046 else | |
2047 f() | |
2048 end | |
2049 end, "PRINT") | |
2050 | |
2051 self:activate(oldLib, oldDeactivate) | |
2052 | |
2053 if oldDeactivate then | |
2054 oldDeactivate(oldLib) | |
2055 end | |
2056 end | |
2057 | |
2058 AceLibrary:Register(AceConsole, MAJOR_VERSION, MINOR_VERSION, activate, nil, external) |