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