Mercurial > wow > turok
view Fog.lua @ 5:8a9a6637f082
focusbar data collection tracking
db info declarations to main chunk
author | Nenue |
---|---|
date | Tue, 15 Dec 2015 10:10:22 -0500 |
parents | 62f9b057c91b |
children |
line wrap: on
line source
-- User: Krakyn -- Created: 12/4/2015 11:13 PM --[[ -- Core tools, mostly frame handling business. It's an interface script after all. -- Types: -- StatusFrame -- Primary container for status data, carries primary value information by default -- FIELDS -- value = exact primary value represented by frame -- min = exact minimum for primary value -- max = exact maximum for primary value -- percent = value / max -- alpha = base frame alpha level, set when a fade animation has completed -- fadeTo = when set, the frame will begin fading to this level -- fadeDuration = set with fadeTo when the transition needs to be time-adjusted for unpredictable alpha states -- fadeTime = set with fadeTo when the transition has an explicit desired timing -- throttle_rate = animation frame delay -- -- METHODS -- Update() = Runs the frame's Update script, and calls UpdateText() -- UpdateText() = Iterates over frame children and calls Update() if it is a StatusText frame -- -- StatusText -- Sub-container for individual text elements, carries string output values, controlled by from Update(). By default -- these are derived from the parent's primary value data, but is mostly overridden in module code. -- FIELDS -- text = WoW FontString object housing text data -- format = a format string for expressing complex data (timer bars, etc.) -- METHODS -- SetText() = shortcut for text:SetText(...) -- SetJustifyH() = shortcut for text:SetJustifyH(...) -- Implements: -- frame = CreateBar(name, config root) -- Creates and displays a generic bar frame with progress textures and default updater, based on the variables from -- the smart config table. Seeded with methods Update() and UpdateText(). -- Update() will refresh the entire frame and tail call UpdateText() -- UpdateText() will iterate over the contents of frame:GetChildren() and call Update() -- NEVER CREATE A CHILD FRAME WITHOUT Update() DEFINED -- NEVER INVOKE METHODS FROM A GetParent() RETURN -- -- Bar_SetUpdateHandler(frame, function) -- Takes the desired OnUpdate script and wraps it inside frame throttling logic, then does SetScript -- -- frame = AddLabel(frame, config root, name) -- Constructs a text display and adds it to the frame's list of internal text objects. Contains method Update(), which -- refreshed text. -- -- HANDLERS -- Bar_Update([value, min/duration, max/end]) -- Default handler for any non-timed bar (where isTimer = false in config vars. Invoked by frame:Update() ]] local T = LibStub("AceAddon-3.0"):GetAddon("Turok") local LSM = LibStub("LibSharedMedia-3.0") local TL = 'Fog' local print = function(...) _G.print(TL, ...) end --setprinthandler(function (...) T:debug('Fog', nil, ...) end) local FADE_OUT_TIME = 1 -- duration per 1-0 alpha transition local FADE_IN_TIME = 0.4 -- duration per 0-1 alpha transition local inset_factor = { ['TOPLEFT'] = {-1, 1}, ['TOP'] = {0, 1}, ['TOPRIGHT'] = {1, 1}, ['RIGHT'] = {1, 0}, ['BOTTOMRIGHT'] = {1, -1}, ['BOTTOM'] = {0, -1}, ['BOTTOMLEFT'] = {-1,-1}, ['LEFT'] = {-1, 0} } T.anchor_inverse = { ['LEFT'] = 'RIGHT', ['RIGHT'] = 'LEFT', ['UP'] = 'DOWN', ['DOWN'] = 'UP' } -- directional inverse T.direction_coord = { ['LEFT'] = {1, 0}, ['RIGHT'] = {-1,0}, ['UP'] = {0, -1}, ['DOWN'] = {0, 1 } } -- directional derivatives T.anchor_direction = { ['LEFT'] = 'RIGHT', ['RIGHT'] = 'LEFT', ['UP'] = 'BOTTOM', ['DOWN'] = 'TOP'} -- directional anchors function T:CreateBar(name, config) local parent = type(config.parent) == 'string' and _G[config.parent] or parent if not parent then parent = CreateFrame('Frame', config.parent, UIParent) print('creating dry frame |cFFDDDDDD' .. config.parent .. '|r for |cFFFFFF00' .. name .. '|r') end local f if _G[name] and _G[name].GetFrameType and _G[name].GetFrameType() == 'Frame' then f = _G[name] print('found existing table |cFFFFFF00' .. name .. '|r') else print('creating statusbar '.. name, config.anchor, parent:GetName(), config.anchorTo, config.posX, config.posY) end f = CreateFrame('Frame', name, UIParent) f.db = config -- state vars f.combat = InCombatLockdown() f.min = 0 f.max = 1 f.value = 0 f.percent = 0 f.alpha = f.combat and config.alpha or config.alpha_ooc f:SetAlpha(f.combat and config.alpha or config.alpha_ooc) f:SetPoint(config.anchor, config.parent, config.anchorTo, config.posX, config.posY) f:SetSize(config.width, config.height) f:SetFrameStrata(config.strata) self:CreateStatusTextures(f, config) f.throttle_rate = 0.0166666666 -- ~60fps f.throttle_point = GetTime() -- default handler f.Update = T.Bar_Update f.UpdateText = T.Bar_UpdateText T:Bar_SetUpdateHandler(f, T.Bar_Update) return f end function T:CreateStatusTextures(region, c) c = c and c or region.db print('STATUSTEX_make', region:GetName(), c.background_texture, c.background_color, c.foreground_texture, c.foreground_color) region.background = region:CreateTexture('background', 'BACKGROUND') region.background:SetAllPoints(region) if c.background_texture then region.background:SetTexture(LSM:Fetch('statusbar', c.background_texture)) region.background:SetVertexColor(unpack(c.background_color)) else region.background:SetTexture(unpack(c.background_color)) end region.background:SetBlendMode(c.background_blend) region.foreground = region:CreateTexture('foreground', 'ARTWORK') region.foreground:SetPoint('TOPLEFT', region, 'TOPLEFT', 0-c.foreground_inset, c.foreground_inset) region.foreground:SetPoint('BOTTOMRIGHT', region, 'BOTTOMRIGHT', c.foreground_inset, 0-c.foreground_inset) if c.foreground_texture then region.foreground:SetTexture(LSM:Fetch('statusbar', c.foreground_texture)) region.foreground:SetVertexColor(unpack(c.foreground_color)) else region.foreground:SetTexture(unpack(c.foreground_color)) end region.foreground:SetBlendMode(c.foreground_blend) end function T:CreateStatusIcon(region, c) local file = type(c) == 'string' and c or region.icon if type(c) ~= 'table' then c = region.db end print('STATUSICON', region:GetName(), file, c.icon_show) end -- Sets the OnUpdate handler within a timing scheme function T:Bar_SetUpdateHandler(bar, func) bar:SetScript('OnUpdate', function(bar) if GetTime() < bar.throttle_point then return end bar.throttle_point = bar.throttle_point + bar.throttle_rate if type(func) == 'string' then if type(bar[func]) ~= 'function' then error('TurokBar:SetUpdateScript(); string "' ..func.. '" is not a valid method name') return end elseif type(func) ~= 'function' then error('TurokBar:SetUpdateScript(function or string); got '.. type(func) .. 'instead') return end func(bar) end) end -- Default update loop function T:Bar_Update (value, min, max) if value ~= nil then -- could be 0 self.value = value end if (min ~= nil and max ~= nil) then if self.isTimer then self.duration = min self.endTime = max else self.min = min self.max = max self.duration = max end end if self.combat ~= InCombatLockdown() then self.combat = InCombatLockdown() if self.combat then self.fadeTo = self.db.alpha self.fadeDuration = FADE_IN_TIME else self.fadeTo = self.db.alpha_ooc self.fadeDuration = FADE_OUT_TIME end end -- we need the time for something if self.isTimer or self.fadeTo ~= nil then local time = GetTime() -- start doing fade animation things if self.fadeTo ~= nil then if not self.fadeFrom then self.fadeFrom = self:GetAlpha() end -- fadeDuration missing, fill it in if not self.fadeDuration then self.fadeDuration = self.fadeFrom > self.fadeTo and FADE_OUT_TIME or FADE_IN_TIME end -- fadeTime missing, if not self.fadeTime then local fadeRatio = 1 if self.fadeFrom ~= self.alpha then fadeRatio = (self.fadeTo - self.fadeFrom) / (self.fadeTo - self.alpha) -- target delta end --print(fadeRatio, self.fadeDuration) self.fadeTime = time + fadeRatio * self.fadeDuration -- fixed rate of change end -- are we done? if time >= self.fadeTime then self:SetAlpha(self.fadeTo) self.alpha = self.fadeTo self.fadeTo = nil self.fadeFrom = nil self.fadeDuration = nil self.fadeTime = nil else --nope local remaining = (self.fadeTime - time) / self.fadeDuration local fadeTotal = (self.fadeTo - self.fadeFrom) --print(self.fadeTo - (fadeTotal * remaining), fadeTotal * remaining) self:SetAlpha(self.fadeTo - (fadeTotal * remaining)) end end -- termination check if self.isTimer then if time >= self.endTime and self.fadeTo == nil then self:Hide() return else self.percent = (self.endTime - time) / self.duration end end else self.percent = (self.value - self.min) / (self.max - self.min) end self:UpdateText() self.foreground:SetPoint('BOTTOMRIGHT', self, 'BOTTOMLEFT', self.db.width * self.percent + self.db.foreground_inset, 0-self.db.foreground_inset) end function T:Bar_UpdateText() local c = {self:GetChildren()} for _, rl in ipairs(c) do if rl.text then rl.format = self.db.label_string rl:Update() end end end -- addon:AddLabel -- Constructs a text display and adds it to that region -- function T:AddLabel (region, config, labelname) assert(region:IsObjectType('Frame'), "T:CreateLabel(table, table [, string])") labelname = (labelname or string.format('%x', GetTime() % 1000000)) print('assigning frame for text object |cFFFF9922'..labelname..'|r to '..region:GetName()) local lf = CreateFrame('Frame', region:GetName()..'_'..labelname, region) local ft = lf:CreateFontString(labelname, 'OVERLAY') local lx, ly, lp = 0,0, config.label_point if config.label_inset ~= 0 and lp ~= 'CENTER' then lx = config.label_inset * inset_factor[lp][1] ly = config.label_inset * inset_factor[lp][2] end lf:SetPoint(lp, region, lp, lx, ly) lf:SetSize(region:GetWidth(), region:GetHeight()) lf:SetFrameStrata(config.label_strata) ft:SetFont(LSM:Fetch('font', config.label_font), config.label_size, config.label_outline) ft:SetAllPoints(lf) ft:SetJustifyH(config.label_justifyH or (config.label_point:find('LEFT') and 'LEFT' or (config.label_point:find('RIGHT') and 'RIGHT' or 'CENTER'))) ft:SetJustifyV(config.label_justifyV or (config.label_point:find('TOP') and 'TOP' or (config.label_point:find('BOTTOM') and 'BOTTOM' or 'MIDDLE'))) ft:SetTextColor(1, 1, 1) ft:SetText('SET ME!') lf.Update = region.isTimer and T.Label_UpdateFormat or T.Label_Update lf.SetJustifyH = function(self, justify) ft:SetJustifyH(justify) end lf.SetText = function(self, text) ft:SetText(text) end lf.text = ft region[labelname] = lf return lf end -- one of two possible assignments for label:Update() function T:Label_UpdateFormat() local region = self:GetParent() if self.format then self.value = string.gsub(self.format, '%%p', string.format('%.1f', region.value)) self.value = string.gsub(self.value, '%%d', region.duration) if region.name then self.value = string.gsub(self.value, '%%n', region.name) end end self.text:SetText(self.value) end function T:Label_Update() self.text:SetText(self:GetParent().value) end