Mercurial > wow > reaction
comparison ReAction_Bar.lua @ 25:bf997ea151ca
yet another attempt to add missing files
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Fri, 07 Mar 2008 22:19:03 +0000 |
parents | |
children | f1e838841ce1 |
comparison
equal
deleted
inserted
replaced
24:9e1984088124 | 25:bf997ea151ca |
---|---|
1 --[[ | |
2 ReAction bar module. | |
3 | |
4 This is the heart of ReAction, the bar management module. Many of its | |
5 functions turn around and iterate all modules registered to the ReAction | |
6 parent core. | |
7 | |
8 Also defined in this file is the Bar class implementation, which can be | |
9 used by other modules to manipulate the action bars. Many of the module | |
10 iterated calls pass a bar or list of bars as an argument. | |
11 | |
12 Module methods called by the Bar module: | |
13 module:ApplyToBar(bar) | |
14 module:RemoveFromBar(bar) | |
15 module:RefreshBar(bar) | |
16 module:ApplyConfigMode(mode,listOfBars) | |
17 module:GetBarNameModifier(bar) | |
18 module:EraseBarConfig(barName) | |
19 | |
20 | |
21 useful Bar object API (partial list): | |
22 f = bar:GetFrame() -- f is derived from SecureStateDriver | |
23 bar:RefreshLayout() | |
24 w,h = bar:GetSize() | |
25 r,c,s = bar:GetButtonGrid() -- #rows, #columns, inter-button spacing | |
26 name = bar:GetName() | |
27 bar:PlaceButton(frame, idx, baseSizeX, baseSizeY) -- idx is 1-based | |
28 | |
29 --]] | |
30 | |
31 -- local imports | |
32 local ReAction = ReAction | |
33 local L = ReAction.L | |
34 local _G = _G | |
35 local AceOO = AceLibrary("AceOO-2.0") | |
36 local CreateFrame = CreateFrame | |
37 local geterrorhandler = geterrorhandler | |
38 local pcall = pcall | |
39 local print = ReAction.print | |
40 | |
41 -- update ReAction revision if this file is newer | |
42 local revision = tonumber(("$Revision: 1 $"):match("%d+")) | |
43 if revision > ReAction.revision then | |
44 Reaction.revision = revision | |
45 end | |
46 | |
47 local moduleID = "Bar" | |
48 | |
49 -- | |
50 -- Bar module declaration | |
51 -- | |
52 local module = ReAction:NewModule( moduleID ) | |
53 | |
54 -- | |
55 -- Bar class declaration | |
56 -- | |
57 local BarClass = AceOO.Class() | |
58 local Bar = BarClass.prototype | |
59 module.BarClass = BarClass | |
60 | |
61 | |
62 -- | |
63 -- Bar module implementation | |
64 -- | |
65 function module:OnInitialize() | |
66 self.db = ReAction:AcquireDBNamespace(moduleID) | |
67 ReAction:RegisterDefaults(moduleID,"profile", | |
68 { | |
69 bars = { }, | |
70 defaultBar = { } | |
71 } | |
72 ) | |
73 self.bars = {} | |
74 end | |
75 | |
76 function module:OnEnable() | |
77 self:InitializeBars() | |
78 end | |
79 | |
80 function module:OnDisable() | |
81 self:TearDownBars() | |
82 end | |
83 | |
84 function module:OnProfileEnable() | |
85 self:InitializeBars() | |
86 end | |
87 | |
88 function module:OnProfileDisable() | |
89 self:TearDownBars() | |
90 end | |
91 | |
92 function module:InitializeBars() | |
93 if not(self.inited) then | |
94 for name, config in pairs(self.db.profile.bars) do | |
95 if config then | |
96 self:CreateBar(name, config) | |
97 end | |
98 end | |
99 self:CallMethodOnAllBars("ApplyAnchor") -- re-anchor in the case of oddball ordering | |
100 self.inited = true | |
101 end | |
102 end | |
103 | |
104 function module:TearDownBars() | |
105 for name, bar in pairs(self.bars) do | |
106 if bar then | |
107 self.bars[name] = self:DeleteBar(bar) | |
108 end | |
109 end | |
110 self.inited = false | |
111 end | |
112 | |
113 -- Gets config from existing DB name or default if not supplied | |
114 -- Saves to DB if name not known | |
115 function module:CreateBar(name, config) | |
116 local profile = self.db.profile | |
117 if not name then | |
118 i = 1 | |
119 repeat | |
120 name = L["Bar "]..i | |
121 i = i + 1 | |
122 until self.bars[name] == nil | |
123 end | |
124 config = config or profile.bars[name] or deepCopy(profile.defaultBar) | |
125 if not profile.bars[name] then | |
126 profile.bars[name] = config | |
127 end | |
128 local bar = self.BarClass:new( name, config ) | |
129 ReAction:CallMethodOnAllModules("ApplyToBar", bar) | |
130 self.bars[name] = bar | |
131 return bar | |
132 end | |
133 | |
134 | |
135 local SelectBar | |
136 do | |
137 SelectBar = function(x) | |
138 local bar, name | |
139 if type(x) == "string" then | |
140 name = x | |
141 bar = module:GetBar(name) | |
142 elseif AceOO.inherits(x,BarClass) then | |
143 bar = x | |
144 for k,v in pairs(module.bars) do | |
145 if v == bar then | |
146 name = k | |
147 end | |
148 end | |
149 else | |
150 error("bad argument to SelectBar") | |
151 end | |
152 return bar, name | |
153 end | |
154 end | |
155 | |
156 -- Takes either a bar name string or a bar object. | |
157 -- Does NOT destroy the DB entry, this function is only used for | |
158 -- enable/disable and profile switching. To remove a bar permanently, | |
159 -- use EraseBar() instead. | |
160 function module:DeleteBar(x) | |
161 local bar, name = SelectBar(x) | |
162 if name and bar then | |
163 self.bars[name] = nil | |
164 ReAction:CallMethodOnAllModules("RemoveFromBar", bar) | |
165 bar:Destroy() | |
166 end | |
167 end | |
168 | |
169 function module:EraseBar(x) | |
170 local bar, name = SelectBar(x) | |
171 if name and bar then | |
172 self:DeleteBar(bar) | |
173 self.db.profile.bars[name] = nil | |
174 ReAction:CallMethodOnAllModules("EraseBarConfig", name) | |
175 end | |
176 end | |
177 | |
178 function module:GetBar(name) | |
179 return self.bars[name] | |
180 end | |
181 | |
182 function module:RenameBar(x, newname) | |
183 local bar, name = SelectBar(x) | |
184 if bar and name and newname then | |
185 if self.bars[newname] then | |
186 error(L["ReAction: name already in use"]) | |
187 end | |
188 self.bars[newname] = self.bars[name] | |
189 self.bars[name] = nil | |
190 bar:SetName(newname) | |
191 local cfg = self.db.profile.bars | |
192 cfg[newname], cfg[name] = cfg[name], nil | |
193 end | |
194 end | |
195 | |
196 function module:CallMethodOnAllBars(method,...) | |
197 local m | |
198 if type(method) == "function" then | |
199 m = method | |
200 elseif type(method) ~= "string" then | |
201 error("Invalid method passed to ReAction_Bar:CallMethodOnAllBars()") | |
202 end | |
203 for _, bar in pairs(self.bars) do | |
204 if bar then | |
205 local m = m or bar[method] | |
206 if m then | |
207 local success,err = pcall(m,bar,...) | |
208 if not success then | |
209 geterrorhandler()(err) | |
210 end | |
211 end | |
212 end | |
213 end | |
214 end | |
215 | |
216 | |
217 | |
218 function module:GetBarMenuOptions(bar) | |
219 if not(bar.modMenuOpts[moduleID]) then | |
220 bar.modMenuOpts[moduleID] = { | |
221 delete = { | |
222 type = "execute", | |
223 name = L["Delete Bar"], | |
224 desc = L["Remove the bar from the current profile"], | |
225 func = function() self:EraseBar(bar) end, | |
226 order = 1 | |
227 }, | |
228 } | |
229 end | |
230 return bar.modMenuOpts[moduleID] | |
231 end | |
232 | |
233 function module:GetBarConfigOptions(bar, cfgModule) | |
234 if not(bar.modConfigOpts[moduleID]) then | |
235 bar.modConfigOpts[moduleID] = { | |
236 delete = { | |
237 type = "execute", | |
238 name = L["Delete Bar"], | |
239 desc = L["Remove the bar from the current profile"], | |
240 func = function() self:EraseBar(bar); cfgModule:RefreshConfig() end | |
241 }, | |
242 rename = { | |
243 type = "text", | |
244 name = L["Rename Bar"], | |
245 desc = L["Set a name for the bar"], | |
246 get = "GetName", | |
247 set = function(name) self:RenameBar(bar,name); cfgModule:RefreshConfig() end | |
248 } | |
249 } | |
250 end | |
251 return bar.modConfigOpts[moduleID] | |
252 end | |
253 | |
254 | |
255 | |
256 -- | |
257 -- Bar class implementation | |
258 -- | |
259 function Bar:init( name, config ) | |
260 BarClass.super.prototype.init(self) | |
261 self.name, self.config = name, config | |
262 | |
263 if type(config) ~= "table" then | |
264 error("ReAction:Bar: config table required") | |
265 end | |
266 | |
267 local f = CreateFrame("Frame",nil,config.parent or UIParent,"SecureStateDriverTemplate") | |
268 f:SetFrameStrata("MEDIUM") | |
269 config.width = config.width or 400 | |
270 config.height = config.height or 80 | |
271 f:SetWidth(config.width) | |
272 f:SetWidth(config.height) | |
273 | |
274 self.frame = f | |
275 self:RefreshLayout() | |
276 self:ApplyAnchor() | |
277 f:Show() | |
278 end | |
279 | |
280 function Bar:Destroy() | |
281 local f = self.frame | |
282 f:UnregisterAllEvents() | |
283 f:Hide() | |
284 f:SetParent(UIParent) | |
285 f:ClearAllPoints() | |
286 self.labelString = nil | |
287 self.controlFrame = nil | |
288 self.frame = nil | |
289 self.config = nil | |
290 end | |
291 | |
292 function Bar:RefreshLayout() | |
293 ReAction:CallMethodOnAllModules("RefreshBar", self) | |
294 end | |
295 | |
296 function Bar:ApplyAnchor() | |
297 local f, config = self.frame, self.config | |
298 f:SetWidth(config.width) | |
299 f:SetHeight(config.height) | |
300 local anchor = config.anchor | |
301 if anchor then | |
302 local anchorTo | |
303 if config.anchorTo then | |
304 anchorTo = module:GetBar(config.anchorTo) or _G[config.anchorTo] | |
305 end | |
306 f:SetPoint(anchor, anchorTo, config.relativePoint, config.x or 0, config.y or 0) | |
307 else | |
308 f:SetPoint("CENTER") | |
309 end | |
310 end | |
311 | |
312 function Bar:GetFrame() | |
313 return self.frame | |
314 end | |
315 | |
316 function Bar:GetSize() | |
317 return self.frame:GetWidth() or 200, self.frame:GetHeight() or 200 | |
318 end | |
319 | |
320 function Bar:SetSize(w,h) | |
321 self.config.width = w | |
322 self.config.height = h | |
323 end | |
324 | |
325 function Bar:GetButtonSize() | |
326 local w = self.config.btnWidth or 32 | |
327 local h = self.config.btnHeight or 32 | |
328 -- TODO: get from modules? | |
329 return w,h | |
330 end | |
331 | |
332 function Bar:SetButtonSize(w,h) | |
333 if w > 0 and h > 0 then | |
334 self.config.btnWidth = w | |
335 self.config.btnHeight = h | |
336 end | |
337 end | |
338 | |
339 function Bar:GetButtonGrid() | |
340 local cfg = self.config | |
341 local r = cfg.btnRows or 1 | |
342 local c = cfg.btnColumns or 1 | |
343 local s = cfg.spacing or 4 | |
344 return r,c,s | |
345 end | |
346 | |
347 function Bar:SetButtonGrid(r,c,s) | |
348 if r > 0 and c > 0 and s > 0 then | |
349 local cfg = self.config | |
350 cfg.btnRows = r | |
351 cfg.btnColumns = c | |
352 cfg.spacing = s | |
353 end | |
354 end | |
355 | |
356 -- This should only be called from module:RenameBar(), otherwise | |
357 -- the bar's internal name and the module's list of bars by name | |
358 -- can get out of sync. | |
359 function Bar:SetName( name ) | |
360 name = name or "" | |
361 self.name = name | |
362 end | |
363 | |
364 function Bar:GetName() | |
365 return self.name | |
366 end | |
367 | |
368 function Bar:PlaceButton(f, idx, baseW, baseH) | |
369 local r, c, s = self:GetButtonGrid() | |
370 local bh, bw = self:GetButtonSize() | |
371 local row, col = floor((idx-1)/c), mod((idx-1),c) -- zero-based | |
372 local x, y = col*bw + (col+0.5)*s, row*bh + (row+0.5)*s | |
373 local scale = bw/baseW | |
374 | |
375 f:ClearAllPoints() | |
376 f:SetPoint("TOPLEFT",x/scale,-y/scale) | |
377 f:SetScale(scale) | |
378 -- f:Show() | |
379 end | |
380 |