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