flickerstreak@201
|
1 local addonName, addonTable = ...
|
flickerstreak@185
|
2 local ReAction = LibStub("AceAddon-3.0"):NewAddon( "ReAction",
|
flickerstreak@33
|
3 "AceEvent-3.0"
|
flickerstreak@30
|
4 )
|
flickerstreak@201
|
5 ReAction.version = GetAddOnMetadata(addonName,"Version")
|
flickerstreak@175
|
6 addonTable.ReAction = ReAction
|
flickerstreak@27
|
7
|
flickerstreak@33
|
8 ------ LIBRARIES ------
|
flickerstreak@63
|
9 local callbacks = LibStub("CallbackHandler-1.0"):New(ReAction)
|
flickerstreak@184
|
10 local LKB = LibStub("LibKeyBound-1.0")
|
flickerstreak@33
|
11 local L = LibStub("AceLocale-3.0"):GetLocale("ReAction")
|
flickerstreak@33
|
12 ReAction.L = L
|
flickerstreak@184
|
13 ReAction.LKB = LKB
|
flickerstreak@182
|
14 ReAction.callbacks = callbacks
|
flickerstreak@33
|
15
|
flickerstreak@28
|
16 ------ PRIVATE ------
|
flickerstreak@116
|
17 local private = { }
|
flickerstreak@63
|
18 local bars = {}
|
flickerstreak@63
|
19 local defaultBarConfig = {}
|
flickerstreak@63
|
20
|
flickerstreak@116
|
21
|
flickerstreak@185
|
22 local SelectBar, DestroyBar, InitializeBars, TearDownBars, DeepCopy
|
flickerstreak@28
|
23 do
|
flickerstreak@28
|
24 local pcall = pcall
|
flickerstreak@28
|
25 local geterrorhandler = geterrorhandler
|
flickerstreak@63
|
26 local self = ReAction
|
flickerstreak@63
|
27 local inited = false
|
flickerstreak@28
|
28
|
flickerstreak@63
|
29 function SelectBar(x)
|
flickerstreak@28
|
30 local bar, name
|
flickerstreak@28
|
31 if type(x) == "string" then
|
flickerstreak@28
|
32 name = x
|
flickerstreak@63
|
33 bar = self:GetBar(name)
|
flickerstreak@50
|
34 else
|
flickerstreak@63
|
35 for k,v in pairs(bars) do
|
flickerstreak@50
|
36 if v == x then
|
flickerstreak@28
|
37 name = k
|
flickerstreak@50
|
38 bar = x
|
flickerstreak@28
|
39 end
|
flickerstreak@28
|
40 end
|
flickerstreak@28
|
41 end
|
flickerstreak@28
|
42 return bar, name
|
flickerstreak@28
|
43 end
|
flickerstreak@28
|
44
|
flickerstreak@63
|
45 function DestroyBar(x)
|
flickerstreak@28
|
46 local bar, name = SelectBar(x)
|
flickerstreak@63
|
47 if bar and name then
|
flickerstreak@63
|
48 bars[name] = nil
|
flickerstreak@63
|
49 callbacks:Fire("OnDestroyBar", bar, name)
|
flickerstreak@28
|
50 bar:Destroy()
|
flickerstreak@28
|
51 end
|
flickerstreak@28
|
52 end
|
flickerstreak@28
|
53
|
flickerstreak@63
|
54 function InitializeBars()
|
flickerstreak@63
|
55 if not inited then
|
flickerstreak@63
|
56 for name, config in pairs(self.db.profile.bars) do
|
flickerstreak@28
|
57 if config then
|
flickerstreak@63
|
58 self:CreateBar(name, config)
|
flickerstreak@28
|
59 end
|
flickerstreak@28
|
60 end
|
flickerstreak@101
|
61 -- re-anchor and refresh in case anchor order does not match init order
|
flickerstreak@63
|
62 for name, bar in pairs(bars) do
|
flickerstreak@63
|
63 bar:ApplyAnchor()
|
flickerstreak@101
|
64 callbacks:Fire("OnRefreshBar", bar, name)
|
flickerstreak@63
|
65 end
|
flickerstreak@63
|
66 inited = true
|
flickerstreak@28
|
67 end
|
flickerstreak@28
|
68 end
|
flickerstreak@28
|
69
|
flickerstreak@63
|
70 function TearDownBars()
|
flickerstreak@63
|
71 for name, bar in pairs(bars) do
|
flickerstreak@28
|
72 if bar then
|
flickerstreak@63
|
73 bars[name] = DestroyBar(bar)
|
flickerstreak@28
|
74 end
|
flickerstreak@28
|
75 end
|
flickerstreak@63
|
76 inited = false
|
flickerstreak@28
|
77 end
|
flickerstreak@28
|
78
|
flickerstreak@63
|
79 function DeepCopy(x)
|
flickerstreak@28
|
80 if type(x) ~= "table" then
|
flickerstreak@28
|
81 return x
|
flickerstreak@28
|
82 end
|
flickerstreak@28
|
83 local r = {}
|
flickerstreak@28
|
84 for k,v in pairs(x) do
|
flickerstreak@28
|
85 r[k] = DeepCopy(v)
|
flickerstreak@28
|
86 end
|
flickerstreak@28
|
87 return r
|
flickerstreak@28
|
88 end
|
flickerstreak@28
|
89
|
flickerstreak@28
|
90 end
|
flickerstreak@28
|
91
|
flickerstreak@28
|
92
|
flickerstreak@28
|
93 ------ HANDLERS ------
|
flickerstreak@28
|
94 function ReAction:OnInitialize()
|
flickerstreak@28
|
95 self.db = LibStub("AceDB-3.0"):New("ReAction_DB",
|
flickerstreak@28
|
96 {
|
flickerstreak@28
|
97 profile = {
|
flickerstreak@28
|
98 bars = { },
|
flickerstreak@184
|
99 defaultBar = { },
|
flickerstreak@28
|
100 }
|
flickerstreak@111
|
101 },
|
flickerstreak@182
|
102 true -- use global 'Default' (locale-specific)
|
flickerstreak@28
|
103 )
|
flickerstreak@184
|
104 LKB.RegisterCallback(self,"LIBKEYBOUND_ENABLED")
|
flickerstreak@184
|
105 LKB.RegisterCallback(self,"LIBKEYBOUND_DISABLED")
|
flickerstreak@88
|
106
|
flickerstreak@182
|
107 self:RegisterEvent("PLAYER_REGEN_DISABLED")
|
flickerstreak@63
|
108
|
flickerstreak@182
|
109 self:InitializeOptions()
|
flickerstreak@28
|
110 end
|
flickerstreak@28
|
111
|
flickerstreak@28
|
112 function ReAction:OnEnable()
|
flickerstreak@28
|
113 InitializeBars()
|
flickerstreak@28
|
114 end
|
flickerstreak@28
|
115
|
flickerstreak@28
|
116 function ReAction:OnDisable()
|
flickerstreak@28
|
117 TearDownBars()
|
flickerstreak@28
|
118 end
|
flickerstreak@28
|
119
|
flickerstreak@33
|
120 function ReAction:PLAYER_REGEN_DISABLED()
|
flickerstreak@63
|
121 if private.configMode == true then
|
flickerstreak@63
|
122 self:UserError(L["ReAction config mode disabled during combat."])
|
flickerstreak@33
|
123 self:SetConfigMode(false)
|
flickerstreak@88
|
124 self:SetKeybindMode(false)
|
flickerstreak@185
|
125 self:CloseEditor()
|
flickerstreak@33
|
126 end
|
flickerstreak@33
|
127 end
|
flickerstreak@33
|
128
|
flickerstreak@88
|
129 function ReAction:LIBKEYBOUND_ENABLED( evt )
|
flickerstreak@88
|
130 self:SetKeybindMode(true)
|
flickerstreak@88
|
131 end
|
flickerstreak@88
|
132
|
flickerstreak@88
|
133 function ReAction:LIBKEYBOUND_DISABLED( evt )
|
flickerstreak@88
|
134 return self:SetKeybindMode(false)
|
flickerstreak@88
|
135 end
|
flickerstreak@88
|
136
|
flickerstreak@33
|
137
|
flickerstreak@28
|
138
|
flickerstreak@28
|
139 ------ API ------
|
flickerstreak@77
|
140
|
flickerstreak@61
|
141 function ReAction:UserError(msg)
|
flickerstreak@61
|
142 -- any user errors should be flashed to the UIErrorsFrame
|
flickerstreak@61
|
143 UIErrorsFrame:AddMessage(msg)
|
flickerstreak@61
|
144 end
|
flickerstreak@61
|
145
|
flickerstreak@184
|
146 function ReAction:RebuildAll()
|
flickerstreak@184
|
147 TearDownBars()
|
flickerstreak@184
|
148 InitializeBars()
|
flickerstreak@184
|
149 end
|
flickerstreak@184
|
150
|
flickerstreak@184
|
151
|
flickerstreak@63
|
152 -- usage:
|
flickerstreak@91
|
153 -- (1) ReAction:CreateBar(name, [cfgTable])
|
flickerstreak@63
|
154 -- (2) ReAction:CreateBar(name, "barType", [nRows], [nCols], [btnSize], [btnSpacing])
|
flickerstreak@91
|
155 function ReAction:CreateBar(name, config, ...)
|
flickerstreak@91
|
156 local profile = self.db.profile
|
flickerstreak@91
|
157
|
flickerstreak@127
|
158 if name then
|
flickerstreak@127
|
159 if bars[name] then
|
flickerstreak@127
|
160 self:UserError(format(L["ReAction: name '%s' already in use"],name))
|
flickerstreak@127
|
161 return nil
|
flickerstreak@127
|
162 end
|
flickerstreak@127
|
163 else
|
flickerstreak@91
|
164 local prefix = L["Bar "]
|
flickerstreak@91
|
165 local i = 1
|
flickerstreak@91
|
166 repeat
|
flickerstreak@91
|
167 name = prefix..i
|
flickerstreak@91
|
168 i = i + 1
|
flickerstreak@91
|
169 until bars[name] == nil
|
flickerstreak@91
|
170 end
|
flickerstreak@91
|
171
|
flickerstreak@91
|
172 if type(config) == "string" then
|
flickerstreak@91
|
173 config = defaultBarConfig[config]
|
flickerstreak@48
|
174 if not config then
|
flickerstreak@91
|
175 error(("ReAction:CreateBar() - unknown bar type '%s'"):format(tostring(select(1,...))))
|
flickerstreak@48
|
176 end
|
flickerstreak@48
|
177 config = DeepCopy(config)
|
flickerstreak@91
|
178 config.btnRows = select(1,...) or config.btnRows or 1
|
flickerstreak@91
|
179 config.btnColumns = select(2,...) or config.btnColumns or 12
|
flickerstreak@91
|
180 config.btnWidth = select(3,...) or config.btnWidth or 36
|
flickerstreak@91
|
181 config.btnHeight = select(3,...) or config.btnHeight or 36
|
flickerstreak@91
|
182 config.spacing = select(4,...) or config.spacing or 3
|
flickerstreak@48
|
183 config.width = config.width or config.btnColumns*(config.btnWidth + config.spacing) + 1
|
flickerstreak@48
|
184 config.height = config.height or config.btnRows*(config.btnHeight + config.spacing) + 1
|
flickerstreak@81
|
185 config.anchor = config.anchor or "UIParent"
|
flickerstreak@81
|
186 config.point = config.point or "BOTTOM"
|
flickerstreak@81
|
187 config.relpoint = config.relpoint or "BOTTOM"
|
flickerstreak@48
|
188 config.y = config.y or 200
|
flickerstreak@48
|
189 config.x = config.x or 0
|
flickerstreak@48
|
190 end
|
flickerstreak@91
|
191 config = config or profile.bars[name] or DeepCopy(profile.defaultBar)
|
flickerstreak@91
|
192
|
flickerstreak@91
|
193 profile.bars[name] = config
|
flickerstreak@91
|
194 local bar = self.Bar:New( name, config ) -- ReAction.Bar defined in Bar.lua
|
flickerstreak@63
|
195 bars[name] = bar
|
flickerstreak@63
|
196 callbacks:Fire("OnCreateBar", bar, name)
|
flickerstreak@63
|
197 if private.configMode then
|
flickerstreak@33
|
198 bar:ShowControls(true)
|
flickerstreak@33
|
199 end
|
flickerstreak@33
|
200
|
flickerstreak@28
|
201 return bar
|
flickerstreak@28
|
202 end
|
flickerstreak@28
|
203
|
flickerstreak@28
|
204 function ReAction:EraseBar(x)
|
flickerstreak@28
|
205 local bar, name = SelectBar(x)
|
flickerstreak@63
|
206 if bar and name then
|
flickerstreak@63
|
207 callbacks:Fire("OnEraseBar", bar, name)
|
flickerstreak@28
|
208 DestroyBar(bar)
|
flickerstreak@28
|
209 self.db.profile.bars[name] = nil
|
flickerstreak@28
|
210 end
|
flickerstreak@28
|
211 end
|
flickerstreak@28
|
212
|
flickerstreak@28
|
213 function ReAction:GetBar(name)
|
flickerstreak@63
|
214 return bars[name]
|
flickerstreak@63
|
215 end
|
flickerstreak@63
|
216
|
flickerstreak@90
|
217 -- returns pairs of name, bar
|
flickerstreak@63
|
218 function ReAction:IterateBars()
|
flickerstreak@63
|
219 return pairs(bars)
|
flickerstreak@28
|
220 end
|
flickerstreak@28
|
221
|
flickerstreak@28
|
222 function ReAction:RenameBar(x, newname)
|
flickerstreak@28
|
223 local bar, name = SelectBar(x)
|
flickerstreak@63
|
224 if type(newname) ~= "string" then
|
flickerstreak@63
|
225 error("ReAction:RenameBar() - second argument must be a string")
|
flickerstreak@63
|
226 end
|
flickerstreak@63
|
227 if bar and name and #newname > 0 then
|
flickerstreak@127
|
228 if newname == name then
|
flickerstreak@127
|
229 return
|
flickerstreak@127
|
230 end
|
flickerstreak@63
|
231 if bars[newname] then
|
flickerstreak@127
|
232 self:UserError(format(L["ReAction: name '%s' already in use"],newname))
|
flickerstreak@47
|
233 else
|
flickerstreak@63
|
234 bars[newname], bars[name] = bars[name], nil
|
flickerstreak@47
|
235 bar:SetName(newname or "")
|
flickerstreak@47
|
236 local cfg = self.db.profile.bars
|
flickerstreak@47
|
237 cfg[newname], cfg[name] = cfg[name], nil
|
flickerstreak@63
|
238 callbacks:Fire("OnRenameBar", bar, name, newname)
|
flickerstreak@28
|
239 end
|
flickerstreak@28
|
240 end
|
flickerstreak@28
|
241 end
|
flickerstreak@28
|
242
|
flickerstreak@63
|
243 function ReAction:RefreshBar(x)
|
flickerstreak@63
|
244 local bar, name = SelectBar(x)
|
flickerstreak@63
|
245 if bar and name then
|
flickerstreak@63
|
246 callbacks:Fire("OnRefreshBar", bar, name)
|
flickerstreak@63
|
247 end
|
flickerstreak@63
|
248 end
|
flickerstreak@63
|
249
|
flickerstreak@53
|
250 function ReAction:RegisterBarType( name, config, isDefaultChoice )
|
flickerstreak@63
|
251 defaultBarConfig[name] = config
|
flickerstreak@48
|
252 if isDefaultChoice then
|
flickerstreak@81
|
253 private.defaultBarConfigChoice = name
|
flickerstreak@48
|
254 end
|
flickerstreak@185
|
255 self:RefreshEditor()
|
flickerstreak@48
|
256 end
|
flickerstreak@48
|
257
|
flickerstreak@53
|
258 function ReAction:UnregisterBarType( name )
|
flickerstreak@63
|
259 defaultBarConfig[name] = nil
|
flickerstreak@63
|
260 if private.defaultBarConfigChoice == name then
|
flickerstreak@63
|
261 private.defaultBarConfigChoice = nil
|
flickerstreak@48
|
262 end
|
flickerstreak@185
|
263 self:RefreshEditor()
|
flickerstreak@48
|
264 end
|
flickerstreak@48
|
265
|
flickerstreak@63
|
266 function ReAction:IterateBarTypes()
|
flickerstreak@63
|
267 return pairs(defaultBarConfig)
|
flickerstreak@63
|
268 end
|
flickerstreak@63
|
269
|
flickerstreak@63
|
270 function ReAction:GetBarTypeConfig(name)
|
flickerstreak@63
|
271 if name then
|
flickerstreak@63
|
272 return defaultBarConfig[name]
|
flickerstreak@63
|
273 end
|
flickerstreak@63
|
274 end
|
flickerstreak@63
|
275
|
flickerstreak@63
|
276 function ReAction:GetBarTypeOptions( fill )
|
flickerstreak@63
|
277 fill = fill or { }
|
flickerstreak@63
|
278 for k in self:IterateBarTypes() do
|
flickerstreak@63
|
279 fill[k] = k
|
flickerstreak@63
|
280 end
|
flickerstreak@63
|
281 return fill
|
flickerstreak@63
|
282 end
|
flickerstreak@63
|
283
|
flickerstreak@63
|
284 function ReAction:GetDefaultBarType()
|
flickerstreak@63
|
285 return private.defaultBarConfigChoice
|
flickerstreak@63
|
286 end
|
flickerstreak@63
|
287
|
flickerstreak@33
|
288 function ReAction:SetConfigMode( mode )
|
flickerstreak@77
|
289 if mode ~= private.configMode then
|
flickerstreak@77
|
290 private.configMode = mode
|
flickerstreak@77
|
291 callbacks:Fire("OnConfigModeChanged", mode)
|
flickerstreak@77
|
292 end
|
flickerstreak@63
|
293 end
|
flickerstreak@63
|
294
|
flickerstreak@63
|
295 function ReAction:GetConfigMode()
|
flickerstreak@63
|
296 return private.configMode
|
flickerstreak@33
|
297 end
|
flickerstreak@38
|
298
|
flickerstreak@88
|
299 function ReAction:SetKeybindMode( mode )
|
flickerstreak@88
|
300 if mode ~= private.kbMode then
|
flickerstreak@88
|
301 if mode then
|
flickerstreak@184
|
302 LKB:Activate()
|
flickerstreak@88
|
303 else
|
flickerstreak@184
|
304 LKB:Deactivate()
|
flickerstreak@88
|
305 end
|
flickerstreak@184
|
306 private.kbMode = LKB:IsShown() or false
|
flickerstreak@88
|
307 end
|
flickerstreak@88
|
308 end
|
flickerstreak@88
|
309
|
flickerstreak@88
|
310 function ReAction:GetKeybindMode( mode )
|
flickerstreak@88
|
311 return private.kbMode
|
flickerstreak@88
|
312 end
|