Mercurial > wow > turok
diff Fog.lua @ 1:766d8a40a1d6
first commit?
author | Nenue |
---|---|
date | Tue, 15 Dec 2015 08:07:21 -0500 |
parents | |
children | 62f9b057c91b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fog.lua Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,326 @@ +-- 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 time = _G.ct +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 = time + + -- 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 +