comparison Fog.lua @ 1:766d8a40a1d6

first commit?
author Nenue
date Tue, 15 Dec 2015 08:07:21 -0500
parents
children 62f9b057c91b
comparison
equal deleted inserted replaced
0:ebbcc148a407 1:766d8a40a1d6
1 -- User: Krakyn
2 -- Created: 12/4/2015 11:13 PM
3 --[[
4 -- Core tools, mostly frame handling business. It's an interface script after all.
5 -- Types:
6 -- StatusFrame
7 -- Primary container for status data, carries primary value information by default
8 -- FIELDS
9 -- value = exact primary value represented by frame
10 -- min = exact minimum for primary value
11 -- max = exact maximum for primary value
12 -- percent = value / max
13 -- alpha = base frame alpha level, set when a fade animation has completed
14 -- fadeTo = when set, the frame will begin fading to this level
15 -- fadeDuration = set with fadeTo when the transition needs to be time-adjusted for unpredictable alpha states
16 -- fadeTime = set with fadeTo when the transition has an explicit desired timing
17 -- throttle_rate = animation frame delay
18 --
19 -- METHODS
20 -- Update() = Runs the frame's Update script, and calls UpdateText()
21 -- UpdateText() = Iterates over frame children and calls Update() if it is a StatusText frame
22 --
23 -- StatusText
24 -- Sub-container for individual text elements, carries string output values, controlled by from Update(). By default
25 -- these are derived from the parent's primary value data, but is mostly overridden in module code.
26 -- FIELDS
27 -- text = WoW FontString object housing text data
28 -- format = a format string for expressing complex data (timer bars, etc.)
29 -- METHODS
30 -- SetText() = shortcut for text:SetText(...)
31 -- SetJustifyH() = shortcut for text:SetJustifyH(...)
32 -- Implements:
33 -- frame = CreateBar(name, config root)
34 -- Creates and displays a generic bar frame with progress textures and default updater, based on the variables from
35 -- the smart config table. Seeded with methods Update() and UpdateText().
36 -- Update() will refresh the entire frame and tail call UpdateText()
37 -- UpdateText() will iterate over the contents of frame:GetChildren() and call Update()
38 -- NEVER CREATE A CHILD FRAME WITHOUT Update() DEFINED
39 -- NEVER INVOKE METHODS FROM A GetParent() RETURN
40 --
41 -- Bar_SetUpdateHandler(frame, function)
42 -- Takes the desired OnUpdate script and wraps it inside frame throttling logic, then does SetScript
43 --
44 -- frame = AddLabel(frame, config root, name)
45 -- Constructs a text display and adds it to the frame's list of internal text objects. Contains method Update(), which
46 -- refreshed text.
47 --
48 -- HANDLERS
49 -- Bar_Update([value, min/duration, max/end])
50 -- Default handler for any non-timed bar (where isTimer = false in config vars. Invoked by frame:Update()
51 ]]
52 local T = LibStub("AceAddon-3.0"):GetAddon("Turok")
53 local LSM = LibStub("LibSharedMedia-3.0")
54 local TL = 'Fog'
55 local print = function(...)
56 _G.print(TL, ...)
57 end
58 --setprinthandler(function (...) T:debug('Fog', nil, ...) end)
59 local time = _G.ct
60 local FADE_OUT_TIME = 1 -- duration per 1-0 alpha transition
61 local FADE_IN_TIME = 0.4 -- duration per 0-1 alpha transition
62
63 local inset_factor = {
64 ['TOPLEFT'] = {-1, 1},
65 ['TOP'] = {0, 1},
66 ['TOPRIGHT'] = {1, 1},
67 ['RIGHT'] = {1, 0},
68 ['BOTTOMRIGHT'] = {1, -1},
69 ['BOTTOM'] = {0, -1},
70 ['BOTTOMLEFT'] = {-1,-1},
71 ['LEFT'] = {-1, 0}
72 }
73
74 T.anchor_inverse = { ['LEFT'] = 'RIGHT', ['RIGHT'] = 'LEFT', ['UP'] = 'DOWN', ['DOWN'] = 'UP' } -- directional inverse
75 T.direction_coord = { ['LEFT'] = {1, 0}, ['RIGHT'] = {-1,0}, ['UP'] = {0, -1}, ['DOWN'] = {0, 1 } } -- directional derivatives
76 T.anchor_direction = { ['LEFT'] = 'RIGHT', ['RIGHT'] = 'LEFT', ['UP'] = 'BOTTOM', ['DOWN'] = 'TOP'} -- directional anchors
77
78 function T:CreateBar(name, config)
79 local parent = type(config.parent) == 'string' and _G[config.parent] or parent
80 if not parent then
81 parent = CreateFrame('Frame', config.parent, UIParent)
82 print('creating dry frame |cFFDDDDDD' .. config.parent .. '|r for |cFFFFFF00' .. name .. '|r')
83 end
84
85 local f
86 if _G[name] and _G[name].GetFrameType and _G[name].GetFrameType() == 'Frame' then
87 f = _G[name]
88 print('found existing table |cFFFFFF00' .. name .. '|r')
89 else
90 print('creating statusbar '.. name, config.anchor, parent:GetName(), config.anchorTo, config.posX, config.posY)
91 end
92
93
94 f = CreateFrame('Frame', name, UIParent)
95 f.db = config
96
97 -- state vars
98 f.combat = InCombatLockdown()
99 f.min = 0
100 f.max = 1
101 f.value = 0
102 f.percent = 0
103 f.alpha = f.combat and config.alpha or config.alpha_ooc
104 f:SetAlpha(f.combat and config.alpha or config.alpha_ooc)
105 f:SetPoint(config.anchor, config.parent, config.anchorTo, config.posX, config.posY)
106 f:SetSize(config.width, config.height)
107 f:SetFrameStrata(config.strata)
108 self:CreateStatusTextures(f, config)
109
110 f.throttle_rate = 0.0166666666 -- ~60fps
111 f.throttle_point = time
112
113 -- default handler
114 f.Update = T.Bar_Update
115 f.UpdateText = T.Bar_UpdateText
116 T:Bar_SetUpdateHandler(f, T.Bar_Update)
117
118 return f
119 end
120
121 function T:CreateStatusTextures(region, c)
122 c = c and c or region.db
123 print('STATUSTEX_make', region:GetName(), c.background_texture, c.background_color, c.foreground_texture, c.foreground_color)
124 region.background = region:CreateTexture('background', 'BACKGROUND')
125 region.background:SetAllPoints(region)
126 if c.background_texture then
127 region.background:SetTexture(LSM:Fetch('statusbar', c.background_texture))
128 region.background:SetVertexColor(unpack(c.background_color))
129 else
130 region.background:SetTexture(unpack(c.background_color))
131 end
132 region.background:SetBlendMode(c.background_blend)
133
134 region.foreground = region:CreateTexture('foreground', 'ARTWORK')
135 region.foreground:SetPoint('TOPLEFT', region, 'TOPLEFT', 0-c.foreground_inset, c.foreground_inset)
136 region.foreground:SetPoint('BOTTOMRIGHT', region, 'BOTTOMRIGHT', c.foreground_inset, 0-c.foreground_inset)
137 if c.foreground_texture then
138 region.foreground:SetTexture(LSM:Fetch('statusbar', c.foreground_texture))
139 region.foreground:SetVertexColor(unpack(c.foreground_color))
140 else
141 region.foreground:SetTexture(unpack(c.foreground_color))
142 end
143 region.foreground:SetBlendMode(c.foreground_blend)
144 end
145
146 function T:CreateStatusIcon(region, c)
147 local file = type(c) == 'string' and c or region.icon
148 if type(c) ~= 'table' then
149 c = region.db
150 end
151 print('STATUSICON', region:GetName(), file, c.icon_show)
152
153 end
154
155 -- Sets the OnUpdate handler within a timing scheme
156 function T:Bar_SetUpdateHandler(bar, func)
157 bar:SetScript('OnUpdate', function(bar)
158 if GetTime() < bar.throttle_point then
159 return
160 end
161
162 bar.throttle_point = bar.throttle_point + bar.throttle_rate
163 if type(func) == 'string' then
164 if type(bar[func]) ~= 'function' then
165 error('TurokBar:SetUpdateScript(); string "' ..func.. '" is not a valid method name')
166 return
167 end
168 elseif type(func) ~= 'function' then
169 error('TurokBar:SetUpdateScript(function or string); got '.. type(func) .. 'instead')
170 return
171 end
172
173 func(bar)
174 end)
175 end
176
177 -- Default update loop
178 function T:Bar_Update (value, min, max)
179
180 if value ~= nil then -- could be 0
181 self.value = value
182 end
183 if (min ~= nil and max ~= nil) then
184 if self.isTimer then
185 self.duration = min
186 self.endTime = max
187 else
188 self.min = min
189 self.max = max
190 self.duration = max
191 end
192 end
193
194 if self.combat ~= InCombatLockdown() then
195 self.combat = InCombatLockdown()
196 if self.combat then
197 self.fadeTo = self.db.alpha
198 self.fadeDuration = FADE_IN_TIME
199 else
200 self.fadeTo = self.db.alpha_ooc
201 self.fadeDuration = FADE_OUT_TIME
202 end
203 end
204
205 -- we need the time for something
206 if self.isTimer or self.fadeTo ~= nil then
207 local time = GetTime()
208
209 -- start doing fade animation things
210 if self.fadeTo ~= nil then
211
212 if not self.fadeFrom then
213 self.fadeFrom = self:GetAlpha()
214 end
215
216 -- fadeDuration missing, fill it in
217 if not self.fadeDuration then
218 self.fadeDuration = self.fadeFrom > self.fadeTo and FADE_OUT_TIME or FADE_IN_TIME
219 end
220
221 -- fadeTime missing,
222 if not self.fadeTime then
223 local fadeRatio = 1
224 if self.fadeFrom ~= self.alpha then
225 fadeRatio = (self.fadeTo - self.fadeFrom) / (self.fadeTo - self.alpha) -- target delta
226 end
227 --print(fadeRatio, self.fadeDuration)
228 self.fadeTime = time + fadeRatio * self.fadeDuration -- fixed rate of change
229 end
230
231 -- are we done?
232 if time >= self.fadeTime then
233 self:SetAlpha(self.fadeTo)
234 self.alpha = self.fadeTo
235 self.fadeTo = nil
236 self.fadeFrom = nil
237 self.fadeDuration = nil
238 self.fadeTime = nil
239 else --nope
240 local remaining = (self.fadeTime - time) / self.fadeDuration
241 local fadeTotal = (self.fadeTo - self.fadeFrom)
242 --print(self.fadeTo - (fadeTotal * remaining), fadeTotal * remaining)
243 self:SetAlpha(self.fadeTo - (fadeTotal * remaining))
244 end
245 end
246
247 -- termination check
248 if self.isTimer then
249 if time >= self.endTime and self.fadeTo == nil then
250 self:Hide()
251 return
252 else
253 self.percent = (self.endTime - time) / self.duration
254 end
255 end
256
257 else
258 self.percent = (self.value - self.min) / (self.max - self.min)
259 end
260
261 self:UpdateText()
262 self.foreground:SetPoint('BOTTOMRIGHT', self, 'BOTTOMLEFT', self.db.width * self.percent + self.db.foreground_inset, 0-self.db.foreground_inset)
263 end
264
265 function T:Bar_UpdateText()
266 local c = {self:GetChildren()}
267 for _, rl in ipairs(c) do
268 if rl.text then
269 rl.format = self.db.label_string
270 rl:Update()
271 end
272 end
273 end
274
275 -- addon:AddLabel
276 -- Constructs a text display and adds it to that region
277 --
278 function T:AddLabel (region, config, labelname)
279 assert(region:IsObjectType('Frame'), "T:CreateLabel(table, table [, string])")
280 labelname = (labelname or string.format('%x', GetTime() % 1000000))
281 print('assigning frame for text object |cFFFF9922'..labelname..'|r to '..region:GetName())
282
283 local lf = CreateFrame('Frame', region:GetName()..'_'..labelname, region)
284 local ft = lf:CreateFontString(labelname, 'OVERLAY')
285 local lx, ly, lp = 0,0, config.label_point
286 if config.label_inset ~= 0 and lp ~= 'CENTER' then
287 lx = config.label_inset * inset_factor[lp][1]
288 ly = config.label_inset * inset_factor[lp][2]
289 end
290
291 lf:SetPoint(lp, region, lp, lx, ly)
292 lf:SetSize(region:GetWidth(), region:GetHeight())
293 lf:SetFrameStrata(config.label_strata)
294
295 ft:SetFont(LSM:Fetch('font', config.label_font), config.label_size, config.label_outline)
296 ft:SetAllPoints(lf)
297 ft:SetJustifyH(config.label_justifyH or (config.label_point:find('LEFT') and 'LEFT' or (config.label_point:find('RIGHT') and 'RIGHT' or 'CENTER')))
298 ft:SetJustifyV(config.label_justifyV or (config.label_point:find('TOP') and 'TOP' or (config.label_point:find('BOTTOM') and 'BOTTOM' or 'MIDDLE')))
299 ft:SetTextColor(1, 1, 1)
300 ft:SetText('SET ME!')
301
302 lf.Update = region.isTimer and T.Label_UpdateFormat or T.Label_Update
303 lf.SetJustifyH = function(self, justify) ft:SetJustifyH(justify) end
304 lf.SetText = function(self, text) ft:SetText(text) end
305
306 lf.text = ft
307 region[labelname] = lf
308 return lf
309 end
310
311 -- one of two possible assignments for label:Update()
312 function T:Label_UpdateFormat()
313 local region = self:GetParent()
314 if self.format then
315 self.value = string.gsub(self.format, '%%p', string.format('%.1f', region.value))
316 self.value = string.gsub(self.value, '%%d', region.duration)
317 if region.name then
318 self.value = string.gsub(self.value, '%%n', region.name)
319 end
320 end
321 self.text:SetText(self.value)
322 end
323 function T:Label_Update()
324 self.text:SetText(self:GetParent().value)
325 end
326