vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
local EMPTY_TABLE = {};
local TIMEX_BAR = "TimexBar";
local DEFAULT_SCALE = 0.8;
local DEFAULT_RES = 0.1;

local strformat = string.format;

local function ARG_ID(t) return t.timexBar.id; end;
local function ARG_ELAPSED(t) return t.timexBar.elapsed; end;
local function ARG_REMAINING(t) return t.timexBar.v; end;

local timexDebug = nil;

--<< ================================================= >>--
-- Section I: Initialize the AddOn Object.               --
--<< ================================================= >>--

TimexBar = AceModule:new({
--      name          = TimexLocals.TimexBar_Title,
--      author        = "Rowne/facboy",
--      aceCompatible = "100",

        ARG_ID = ARG_ID,
        ARG_ELAPSED = ARG_ELAPSED,
        ARG_REMAINING = ARG_REMAINING,
})

function TimexBar:Enable()
        self.barDB  = {};
        self.barMap = setmetatable({}, Timex.weakV_mt);
        table.setn(self.barDB, 20);
        for id = 1,20,1 do getglobal(TIMEX_BAR..id):SetScale(DEFAULT_SCALE); end
        --for id = 1,20,1 do getglobal(TIMEX_BAR..id):SetFrameStrata("TOOLTIP"); end
end

--<< ================================================= >>--
-- Section II: Private utility functions.                --
--<< ================================================= >>--

--------------------
-- argument stuff
--------------------
local args_switch = {};
args_switch[ARG_ID] = ARG_ID;
args_switch[ARG_ELAPSED] = ARG_ELAPSED;
args_switch[ARG_REMAINING] = ARG_REMAINING;

local function buildArgs(args, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
        local sub = args.sub;
        local f = args_switch[a20]; args[20], sub[20] = not f and a20 or nil, f;
        f = args_switch[a19]; args[19], sub[19] = not f and a19 or nil, f;
        f = args_switch[a18]; args[18], sub[18] = not f and a18 or nil, f;
        f = args_switch[a17]; args[17], sub[17] = not f and a17 or nil, f;
        f = args_switch[a16]; args[16], sub[16] = not f and a16 or nil, f;
        f = args_switch[a15]; args[15], sub[15] = not f and a15 or nil, f;
        f = args_switch[a14]; args[14], sub[14] = not f and a14 or nil, f;
        f = args_switch[a13]; args[13], sub[13] = not f and a13 or nil, f;
        f = args_switch[a12]; args[12], sub[12] = not f and a12 or nil, f;
        f = args_switch[a11]; args[11], sub[11] = not f and a11 or nil, f;
        f = args_switch[a10]; args[10], sub[10] = not f and a10 or nil, f;
        f = args_switch[a9]; args[9], sub[9] = not f and a9 or nil, f;
        f = args_switch[a8]; args[8], sub[8] = not f and a8 or nil, f;
        f = args_switch[a7]; args[7], sub[7] = not f and a7 or nil, f;
        f = args_switch[a6]; args[6], sub[6] = not f and a6 or nil, f;
        f = args_switch[a5]; args[5], sub[5] = not f and a5 or nil, f;
        f = args_switch[a4]; args[4], sub[4] = not f and a4 or nil, f;
        f = args_switch[a3]; args[3], sub[3] = not f and a3 or nil, f;
        f = args_switch[a2]; args[2], sub[2] = not f and a2 or nil, f;
        f = args_switch[a1]; args[1], sub[1] = not f and a1 or nil, f;
end

local args_mt = {
        __index = function(t, k)
                local f = t.sub[k];
                if f then return f(t); end
        end,
}

local function newArgs(timexBar)
        local args = { timexBar = timexBar, sub = {} };
        setmetatable(args, args_mt);
        return args;
end

--<< ================================================= >>--
-- Section III: The Time-Event Handler.                  --
--<< ================================================= >>--

local function timexHandler(self, timexBar, elapsed)
        --self.cmd:msg("timexHandler: timexBar.n = %s", tostring(timexBar.n));
        local v = timexBar.v;
        if v then
                v = v - elapsed;
                if v <= 0 then
                        if timexBar.f then
                                timexBar.elapsed = elapsed;
                                local a = timexBar.a;
                                local status, err = pcall(timexBar.f, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20]);
                                if (not status) then
                                        Timex.cmd:msg("TimexBar function '%s' failed with error: %s", tostring(timexBar.id), tostring(err));
                                end
                        end
                        self:Stop(timexBar.id);
                        return;
                elseif timexBar.uf then
                        timexBar.elapsed = elapsed;
                        local a = timexBar.ua;
                        local status, err = pcall(timexBar.uf, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20]);
                        if (not status) then
                                Timex.cmd:msg("TimexBar update function '%s' failed with error: %s", tostring(timexBar.id), tostring(err));
                        end
                end
                -- Update bar
                local settext = ceil(v);
                settext = settext > 60 and (format("%d", settext / 60)..":"..format("%02d", mod(settext, 60))) or settext;
                timexBar.ttxt:SetText(settext);
                timexBar.sbar:SetValue(v);
                timexBar.v = v;
        end
end

--<< ================================================= >>--
-- Section IV: The TimexBarClass 'inner' class           --
--<< ================================================= >>--

-- class definition
local TimexBarClass = {
        bR = 0.1, bB = 0.2, bG = 0.8, bA = 1.0,
        tR = 1.0, tB = 1.0, tG = 1.0, tA = 1.0,
        aP = "CENTER", aF = "UIParent", aRP = "CENTER", xO = 0, yO = 0,
};
local TimexBarClass_mt = { __index = TimexBarClass };

do
        local bar = getglobal(TIMEX_BAR.."1");
        TimexBarClass.s, TimexBarClass.bW, TimexBarClass.bH = DEFAULT_SCALE, bar:GetWidth(), bar:GetHeight();
        local ttxt = getglobal(TIMEX_BAR.."1TimerText");
        TimexBarClass.tW = ttxt:GetWidth();
end

-- private constructor
local function newTimexBar(timexBar, b)
        local n = TIMEX_BAR..b;
        local newInst = {
                n = n,
                bar  = getglobal(n),
                sbar = getglobal(n.."StatusBar"),
                txt  = getglobal(n.."Text"),
                ttxt = getglobal(n.."TimerText"),
                btn = getglobal(n.."Button"),
                btnTex = getglobal(n.."ButtonTexture")
        };
        setmetatable(newInst, TimexBarClass_mt);
        return newInst;
end

-- private reset function (only resets the 'functional' attributes, not the formatting ones)
local function resetTimexBar(timexBar)
        -- reset all values to nil
        timexBar.id, timexBar.f, timexBar.uf, timexBar.elapsed, timexBar.v, timexBar.res = nil, nil, nil, nil, nil, nil;
        -- clear arg tables
        local args = timexBar.a;
        if args then
                args[1], args[2], args[3], args[4], args[5] = nil, nil, nil, nil, nil;
                args[6], args[7], args[8], args[9], args[10] = nil, nil, nil, nil, nil;
                args[11], args[12], args[13], args[14], args[15] = nil, nil, nil, nil, nil;
                args[16], args[17], args[18], args[19], args[20] = nil, nil, nil, nil, nil;
        end
        args = timexBar.ua;
        if args then
                args[1], args[2], args[3], args[4], args[5] = nil, nil, nil, nil, nil;
                args[6], args[7], args[8], args[9], args[10] = nil, nil, nil, nil, nil;
                args[11], args[12], args[13], args[14], args[15] = nil, nil, nil, nil, nil;
                args[16], args[17], args[18], args[19], args[20] = nil, nil, nil, nil, nil;
        end
        if timexBar.cf then
                timexBar.cf = nil;
                args = timexBar.ca;
                if args then
                        args[1], args[2], args[3], args[4], args[5] = nil, nil, nil, nil, nil;
                        args[6], args[7], args[8], args[9], args[10] = nil, nil, nil, nil, nil;
                        args[11], args[12], args[13], args[14], args[15] = nil, nil, nil, nil, nil;
                        args[16], args[17], args[18], args[19], args[20] = nil, nil, nil, nil, nil;
                end
        end     
end

-- private formatting function
local function resetTimexBarFormat(timexBar)
        local bar, txt, ttxt  = timexBar.bar, timexBar.txt, timexBar.ttxt;
        
        if not timexBar.sColor and timexBar.rColor then
                timexBar.bR, timexBar.bB, timexBar.bG, timexBar.bA = nil, nil, nil, nil;
                timexBar.sbar:SetStatusBarColor(timexBar.bR, timexBar.bB, timexBar.bG, timexBar.bA);
                timexBar.rColor = nil;
        end
        
        if not timexBar.sTextColor and timexBar.rTextColor then
                timexBar.tR, timexBar.tB, timexBar.tG, timexBar.tA = nil, nil, nil, nil;
                txt:SetTextColor(timexBar.tR, timexBar.tB, timexBar.tG, timexBar.tA);
                ttxt:SetTextColor(timexBar.tR, timexBar.tB, timexBar.tG, timexBar.tA);
                timexBar.rTextColor = nil;
        end
        
        if not timexBar.sPoint and timexBar.rPoint then
                timexBar.aP, timexBar.aF, timexBar.aRP, timexBar.xO, timexBar.yO = nil, nil, nil, nil, nil;
                bar:ClearAllPoints();
                bar:SetPoint(timexBar.aP, timexBar.aF, timexBar.aRP, timexBar.xO, timexBar.yO);
                timexBar.rPoint = nil;
        end
                
        if not timexBar.sWidth and timexBar.rWidth then
                timexBar.bW = nil;
                bar:SetWidth(timexBar.bW);
                timexBar.rWidth = nil;
        end

        if not timexBar.sHeight and timexBar.rHeight then
                timexBar.bH = nil;
                bar:SetHeight(timexBar.bH);
                timexBar.rHeight = nil;
        end
        
        if not timexBar.sScale and timexBar.rScale then
                timexBar.s = nil;
                bar:SetScale(timexBar.s);
                timexBar.rScale = nil;
        end
        
        if not timexBar.sTimeWidth and timexBar.rTimeWidth then
                timexBar.tW = nil;
                ttxt:SetWidth(timexBar.tW);
                txt:SetPoint("TOPLEFT", bar, "LEFT", timexBar.tW, 13);
                timexBar.rTimeWidth = nil;
        end

        if not timexBar.sText and timexBar.rText then
                timexBar.text = nil;
                if timexBar.text then 
                        timexBar.txt:SetText("| "..timexBar.text);
                else
                        timexBar.txt:SetText("");
                end
                timexBar.rText = nil;
        end

        if not timexBar.sTexture and timexBar.rTexture then
                timexBar.tex = nil;
                if timexBar.tex then
                        timexBar.btnTex:SetTexture(timexBar.tex);
                        timexBar.btn:Show();
                else
                        timexBar.btn:Hide();
                end
                timexBar.rTexture = nil;
        end
end

local function clearSetFlags(timexBar)
        timexBar.sColor, timexBar.sTextColor, timexBar.sPoint, timexBar.sWidth = nil, nil, nil, nil;
        timexBar.sHeight, timexBar.sScale, timexBar.sTimeWidth, timexBar.sText, timexBar.sTexture = nil, nil, nil, nil, nil;
end

--<< ================================================= >>--
-- Section V: The Start and Stop Bar Functions.          --
--<< ================================================= >>--

-- Assigns a bar to id
function TimexBar:Get(id)
        if id and id ~= "" then
                local timexBar = self.barMap[id];
                -- if not found
                if not timexBar then
                        -- find first available
                        local b = 1;
                        timexBar = self.barDB[b];
                        while (timexBar) do
                                if (not timexBar.v) then
                                        break;
                                end
                                b = b + 1;
                                timexBar = self.barDB[b];
                        end
                        if timexBar then
                                clearSetFlags(timexBar);
                        elseif (b <= 20) then
                                timexBar = newTimexBar(self, b);
                                self.barDB[b] = timexBar;
                        else
                                error("No more bars available!");
                        end
                        -- assign id
                        timexBar.id, self.barMap[id] = id, timexBar;
                end
                return timexBar.n;
        end
end

function TimexBar:Start(id, time, res)
        if (time) then
                local timexBar = self.barMap[id];
                if timexBar then
                        res = res or DEFAULT_RES;
                        timexBar.v = time;
                        timexBar.res = res;
                        
                        -- reset bar format and show
                        resetTimexBarFormat(timexBar);

                        local settext = ceil(timexBar.v);
                        settext = settext > 60 and format("%d:%02d", settext/60, mod(settext, 60)) or settext;
                        timexBar.ttxt:SetText(settext);
                        local sbar = timexBar.sbar;
                        sbar:SetMinMaxValues(0, time);
                        sbar:SetValue(timexBar.v);

                        if timexBar.cf then
                                timexBar.btn:EnableMouse(1);
                                timexBar.btn:SetScript("OnClick", timexBar.onClick);
                        end
                        timexBar.bar:Show();
                        
                        Timex:AddSchedule(timexBar, res, true, nil, timexHandler, self, timexBar, Timex.ARG_ELAPSED);
                        return timexBar.n;
                else
                        error(strformat("TimexBar '%s' not found.", tostring(id)));
                end
        end
end

function TimexBar:Stop(id)
        local timexBar = self.barMap[id];
        if timexBar then
                Timex:DeleteSchedule(timexBar);
                if timexBar.cf then
                        timexBar.btn:EnableMouse(0);
                        timexBar.btn:SetScript("OnClick", nil);
                end
                timexBar.bar:Hide();
                resetTimexBar(timexBar);
                self.barMap[id] = nil;
        end
end

function TimexBar:Pause(id)
        local timexBar = self.barMap[id];
        if timexBar then
                Timex:DeleteSchedule(timexBar);
        end
end
        
function TimexBar:Resume(id)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.res then
                        Timex:AddSchedule(timexBar, timexBar.res, true, nil, timexHandler, self, timexBar, Timex.ARG_ELAPSED);
                else
                        error(strformat("TimexBar '%s' has not been started yet.", tostring(id)));
                end
        end
end

function TimexBar:Check(id, r)
        local timexBar = self.barMap[id];
        if timexBar then
                return (r and timexBar.n) or TRUE;
        end
end

function TimexBar:ChangeDuration(id, t)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.v then
                        timexBar.v    = t;
                end
        end
end

function TimexBar:Debug(debug)
        timexDebug = debug;
end

--<< ================================================= >>--
-- Section VI: The Bar Formatting Functions              --
--<< ================================================= >>--

function TimexBar:SetColor(id, red, blue, green, alpha)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.bR ~= red or timexBar.bB ~= blue or timexBar.bG ~= green or timexBar.bA ~= alpha then
                        timexBar.bR, timexBar.bB, timexBar.bG, timexBar.bA = red, blue, green, alpha;
                        timexBar.sbar:SetStatusBarColor(timexBar.bR, timexBar.bB, timexBar.bG, timexBar.bA);
                        timexBar.rColor = true;
                end
                timexBar.sColor = true;
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetTextColor(id, red, blue, green, alpha)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.tR ~= red or timexBar.tB ~= blue or timexBar.tG ~= green or timexBar.tA ~= alpha then
                        timexBar.tR, timexBar.tB, timexBar.tG, timexBar.tA = red, blue, green, alpha;
                        timexBar.txt:SetTextColor(timexBar.tR, timexBar.tB, timexBar.tG, timexBar.tA);
                        timexBar.ttxt:SetTextColor(timexBar.tR, timexBar.tB, timexBar.tG, timexBar.tA);
                        timexBar.rTextColor = true;
                end
                timexBar.sTextColor = true;
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetPoint(id, point, relativeFrame, relativePoint, xOffset, yOffset)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.aP ~= point or timexBar.aF ~= relativeFrame or timexBar.aRP ~= relativePoint or timexBar.xO ~= xOffset or timexBar.yO ~= yOffset then
                        timexBar.aP, timexBar.aF, timexBar.aRP, timexBar.xO, timexBar.yO = point, relativeFrame, relativePoint, xOffset, yOffset;
                        local bar = timexBar.bar;
                        bar:ClearAllPoints();
                        bar:SetPoint(timexBar.aP, timexBar.aF, timexBar.aRP, timexBar.xO, timexBar.yO);
                        timexBar.rPoint = true;
                end
                timexBar.sPoint = true;
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetWidth(id, width)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.bW ~= width then
                        timexBar.bW = width;
                        timexBar.bar:SetWidth(timexBar.bW);
                        timexBar.rWidth = true;
                end
                timexBar.sWidth = true;
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetHeight(id, height)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.bH ~= height then
                        timexBar.bH = height;
                        timexBar.bar:SetHeight(timexBar.bH);
                        timexBar.rHeight = true;
                end
                timexBar.sHeight = true;
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetScale(id, scale)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.s ~= scale then
                        timexBar.s = scale;
                        timexBar.bar:SetScale(timexBar.s);
                        timexBar.rScale = true;
                end
                timexBar.sScale = true;
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetTimeWidth(id, width)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.tW ~= width then
                        timexBar.tW = width;
                        timexBar.ttxt:SetWidth(timexBar.tW);
                        timexBar.txt:SetPoint("TOPLEFT", timexBar.bar, "LEFT", timexBar.tW, 13);
                        timexBar.rTimeWidth = true;
                end
                timexBar.sTimeWidth = true;
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetText(id, text)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.text ~= text then
                        timexBar.text = text;
                        if timexBar.text then 
                                timexBar.txt:SetText("| "..timexBar.text);
                        else
                                timexBar.txt:SetText("");
                        end
                        timexBar.rText = true;
                end
                timexBar.sText = true;
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetTexture(id, texturePath)
        local timexBar = self.barMap[id];
        if timexBar then
                if timexBar.tex ~= texturePath then
                        timexBar.tex = texturePath;
                        if timexBar.tex then
                                timexBar.btnTex:SetTexture(timexBar.tex);
                                timexBar.btn:Show();
                        else
                                timexBar.btn:Hide();
                        end
                        timexBar.rTexture = true;
                end
                timexBar.sTexture = true;
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetFunction(id, f, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
        local timexBar = self.barMap[id];
        if timexBar then
                timexBar.f = f;
                if not timexBar.a then
                        timexBar.a = newArgs(timexBar);
                end
                buildArgs(timexBar.a, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetUpdateFunction(id, f, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
        local timexBar = self.barMap[id];
        if timexBar then
                timexBar.uf = f;
                if not timexBar.ua then
                        timexBar.ua = newArgs(timexBar);
                end
                buildArgs(timexBar.ua, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

function TimexBar:SetClickFunction(id, f, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
        local timexBar = self.barMap[id];
        if timexBar then
                -- create the onClick function for this bar.
                if not timexBar.onClick then
                        timexBar.onClick = function()
                                local a = timexBar.ca;
                                local status, err = pcall(timexBar.cf, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20]);
                                if not status then
                                        Timex.cmd:msg("TimexBar click function '%s' failed with error: %s", tostring(timexBar.id), tostring(err));
                                end
                        end
                end

                timexBar.cf = f;
                if not timexBar.ca then
                        timexBar.ca = newArgs(timexBar);
                end
                buildArgs(timexBar.ca, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
        else
                error(strformat("TimexBar '%s' not found.", tostring(id)));
        end
end

--<< ================================================= >>--
-- Section Omega: Register the AddOn Object.             --
--<< ================================================= >>--

--TimexBar:RegisterForLoad()

Generated by GNU Enscript 1.6.5.90.