vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
--[[
        button.lua
                Scripts for Bongos Action Buttons, which add more features to blizzard action buttons
                
        Changes over the normal action buttons:
                Colored red when out of range
                Selfcast can be enabled
                Altcast can be enabled
                Hotkeys are shortened
                Added the abiliy to skip pages when paging.
                GetPagedID is flexible
--]]

--local constants
local MAX_BUTTONS = 120; --the current maximum amount of action buttons

local function ReuseAndRename(oldName, newName, newParent)
        local button = getglobal(oldName);
        button:SetParent(newParent);
        button:SetAlpha(newParent:GetAlpha());
        button:SetFrameLevel(0);        
        setglobal(newName, button);
        
        return button;
end 

BActionButton = {
        --[[ Constructor Functions ]]--
        
        --Create an Action Button with the given ID and parent
        Create = function(id, parent)
                local name = "BActionButton" .. id;
                local button;
                if BongosSets.dontReuse then
                        button = CreateFrame("CheckButton", name, parent, "ActionButtonTemplate");
                else
                        if id <= 12 then
                                button = ReuseAndRename("ActionButton" .. id, name, parent)
                        elseif id <= 24 then
                                button = ReuseAndRename("MultiBarBottomLeftButton" .. id-12, name, parent)
                        elseif id <= 36 then
                                button = ReuseAndRename("MultiBarBottomRightButton" .. id-24, name, parent)
                        elseif id <= 48 then
                                button = ReuseAndRename("MultiBarRightButton" .. id-36, name, parent)
                        elseif id <= 60 then
                                button = ReuseAndRename("MultiBarLeftButton" .. id-48, name, parent)
                        else
                                button = CreateFrame("CheckButton", name, parent, "ActionButtonTemplate");
                        end
                end
                button:SetID(id)

                getglobal(button:GetName() .. "Icon"):SetTexCoord(0.06,0.94,0.06,0.94);
                
                getglobal(button:GetName() .. "Border"):SetVertexColor(0, 1, 0, 0.6);
                
                if not BActionSets_HotkeysShown() then
                        getglobal(button:GetName() .. "HotKey"):Hide();
                end
                
                if not BActionSets_MacrosShown() then
                        getglobal(button:GetName() .. "Name"):Hide();
                end
                
                BActionButton.UpdateHotkey(button);
                BActionButton.SetScripts(button);
                
                return button;
        end,
                
        --Called after the button is created, sets all scripts and listeners
        SetScripts = function(button)
                button.flashing = 0;
                button.flashtime = 0;
                
                button:RegisterForDrag("LeftButton", "RightButton");
                button:RegisterForClicks("LeftButtonUp", "RightButtonUp");
                
                button:SetScript("OnUpdate", BActionButton.OnUpdate);
                button:SetScript("OnClick", BActionButton.OnClick);
                button:SetScript("OnDragStart", BActionButton.OnDragStart);
                button:SetScript("OnReceiveDrag", BActionButton.OnReceiveDrag);
                button:SetScript("OnEnter", BActionButton.OnEnter);
                button:SetScript("OnLeave", BActionButton.OnLeave);
        end,
        
        --[[ OnX Functions ]]--
        
        OnClick = function()
                local pagedID = BActionButton.GetPagedID(this:GetID());
                
                if BActionSets_IsQuickMoveKeyDown() or bg_showGrid then
                        PickupAction(pagedID);
                else
                        if MacroFrame_SaveMacro then
                                MacroFrame_SaveMacro();
                        end
                        
                        local selfCast;
                        if arg1 == "RightButton" then
                                selfCast = 1;
                        end
                        UseAction(pagedID, 0, selfCast);
                end
                BActionButton.UpdateState(this);
        end,
        
        OnDragStart = function()
                if not BActionSets_ButtonsLocked() or BActionSets_IsQuickMoveKeyDown() or bg_showGrid then
                        PickupAction(BActionButton.GetPagedID(this:GetID()));
                        BActionButton.UpdateState(this);
                end
        end,
        
        OnReceiveDrag = function()
                PlaceAction(BActionButton.GetPagedID(this:GetID()));
                BActionButton.UpdateState(this);
        end,
        
        OnEnter = function()
                BActionButton.UpdateTooltip(this);
        end,

        OnLeave = function()
                this.updateTooltip = nil;
                GameTooltip:Hide();
        end,
        
        --OnUpdate
        OnUpdate = function()   
                --update flashing
                if this.flashing == 1 then
                        this.flashtime = this.flashtime - arg1;
                        if this.flashtime <= 0 then
                                local overtime = -this.flashtime;
                                if overtime >= ATTACK_BUTTON_FLASH_TIME then
                                        overtime = 0;
                                end
                                this.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime;

                                local flashTexture = getglobal(this:GetName().."Flash");
                                if flashTexture:IsShown() then
                                        flashTexture:Hide();
                                else
                                        flashTexture:Show();
                                end
                        end
                end
                
                -- Handle range indicator
                if this.rangeTimer then
                        if this.rangeTimer < 0 then
                                local pagedID = BActionButton.GetPagedID(this:GetID());
                                local hotkey = getglobal(this:GetName().."HotKey");
                                
                                if IsActionInRange(pagedID) == 0 then
                                        hotkey:SetVertexColor(1, 0.1, 0.1);
                                        if BActionSets_ColorOutOfRange() and IsUsableAction(pagedID) then
                                                local rangeColor = BActionSets_GetRangeColor();
                                                getglobal(this:GetName() .. "Icon"):SetVertexColor(rangeColor.r, rangeColor.g, rangeColor.b);
                                        end
                                else
                                        hotkey:SetVertexColor(0.6, 0.6, 0.6);
                                        if IsUsableAction(pagedID) then
                                                getglobal(this:GetName() .. "Icon"):SetVertexColor(1, 1, 1);
                                        end
                                end
                                this.rangeTimer = TOOLTIP_UPDATE_TIME;
                        else
                                this.rangeTimer = this.rangeTimer - arg1;
                        end
                end

                --Tooltip stuff, probably for the cooldown timer
                if this.updateTooltip then
                        this.updateTooltip = this.updateTooltip - arg1;
                        if this.updateTooltip <= 0 then
                                if GameTooltip:IsOwned(this) then
                                        BActionButton.UpdateTooltip(this);
                                else
                                        this.updateTooltip = nil;
                                end
                        end
                end
        end,
        
        --[[ Update Functions ]]--
        
        --Updates the icon, count, cooldown, usability color, if the button is flashing, if the button is equipped,  and macro text.
        Update = function(button)
                local pagedID = BActionButton.GetPagedID(button:GetID());
                local buttonName = button:GetName();
                
                --if the button's not empty, then show the icon, else show an empty button
                local texture = GetActionTexture(pagedID);
                local icon = getglobal(buttonName.."Icon");
                local buttonCooldown = getglobal(buttonName.."Cooldown");
                
                if texture then
                        icon:SetTexture(texture);
                        icon:Show();
                        button.rangeTimer = TOOLTIP_UPDATE_TIME;
                        button:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2");
                        getglobal(buttonName.."NormalTexture"):SetVertexColor(1, 1, 1, 1);
                else
                        icon:Hide();
                        buttonCooldown:Hide();
                        button.rangeTimer = nil;
                        getglobal(buttonName.."HotKey"):SetVertexColor(0.6, 0.6, 0.6);
                        button:SetNormalTexture("Interface\\Buttons\\UI-Quickslot");
                        getglobal(buttonName.."NormalTexture"):SetVertexColor(1, 1, 1, 0.4);
                end
                
                --update count
                if IsConsumableAction(pagedID) then
                        getglobal(buttonName.."Count"):SetText(GetActionCount(pagedID));
                else
                        getglobal(buttonName.."Count"):SetText("");
                end
                
                --update cooldown/usability if there's an action
                if HasAction(pagedID) then
                        button:Show();
                        BActionButton.UpdateUsable(button);
                        BActionButton.UpdateCooldown(button);
                elseif not (bg_showGrid or BActionSets_ShowGrid()) then
                        button:Hide();
                else
                        button:Show();
                        buttonCooldown:Hide();
                end
                
                --Update if the button is flashing or not
                BActionButton.UpdateFlash(button);
                
                -- Add a green border if the button is an equipped ite
                local border = getglobal(buttonName.."Border");
                if IsEquippedAction(pagedID) then
                        border:Show();
                else
                        border:Hide();
                end
                
                if GameTooltip:IsOwned(button) then
                        BActionButton.UpdateTooltip(button);
                else
                        button.updateTooltip = nil;
                end
        
                -- Update Macro Text
                getglobal(buttonName.."Name"):SetText(GetActionText(pagedID));
        end,
        
        --colors the action button if out of mana, out of range, etc
        UpdateUsable = function(button)
                local pagedID = BActionButton.GetPagedID(button:GetID());
                local icon = getglobal(button:GetName().."Icon");
                
                local isUsable, notEnoughMana = IsUsableAction(pagedID);
                if isUsable then
                        if BActionSets_ColorOutOfRange() and IsActionInRange(pagedID) == 0 then
                                local rangeColor = BActionSets_GetRangeColor();
                                icon:SetVertexColor(rangeColor.r, rangeColor.g, rangeColor.b);
                        else
                                icon:SetVertexColor(1,1,1);
                        end
                elseif notEnoughMana then
                        --Make the icon blue if out of mana
                        icon:SetVertexColor(0.5, 0.5, 1);
                else
                        --Skill unusable
                        icon:SetVertexColor(0.3, 0.3, 0.3);
                end
        end,
        
        --Update the cooldown timer
        UpdateCooldown = function(button)
                local start, duration, enable = GetActionCooldown(BActionButton.GetPagedID(button:GetID()));
                CooldownFrame_SetTimer(getglobal(button:GetName().."Cooldown"), start, duration, enable);
        end,
        
        --Update if a button is checked or not
        UpdateState = function(button)
                local pagedID = BActionButton.GetPagedID(button:GetID());
                button:SetChecked(IsCurrentAction(pagedID) or IsAutoRepeatAction(pagedID));
        end,
        
        --Update a a flashing button
        UpdateFlash = function(button)
                local pagedID = BActionButton.GetPagedID(button:GetID());
                if (IsCurrentAction(pagedID) and IsAttackAction(pagedID)) or IsAutoRepeatAction(pagedID) then
                        button.flashing = 1;
                        button.flashtime = 0;
                else
                        button.flashing = nil;
                        getglobal(button:GetName().."Flash"):Hide();
                end
                BActionButton.UpdateState(button);
        end,
        
        UpdateTooltip = function(button)
                if BActionSets_TooltipsShown() then
                        if GetCVar("UberTooltips") == "1" then
                                GameTooltip_SetDefaultAnchor(GameTooltip, button);
                        else
                                GameTooltip:SetOwner(button, "ANCHOR_RIGHT");
                        end

                        if GameTooltip:SetAction(BActionButton.GetPagedID(button:GetID())) then
                                button.updateTooltip = TOOLTIP_UPDATE_TIME;
                        else
                                button.updateTooltip = nil;
                        end
                end
        end,
        
        UpdateHotkey = BBasicActionButton.UpdateHotkey,
        
        --next two are basically wrapper functions for use with ForAllButtons
        UpdateUsableAndCooldown = function(button)
                BActionButton.UpdateUsable(button);
                BActionButton.UpdateCooldown(button);
        end,
        
        UpdateAll = function(button)
                BActionButton.Update(button);
                BActionButton.UpdateState(button);
        end,
        
        --hides a button, if its currently not attached to any actionbar
        ShowIfUsed = function(button)
                if button:GetParent() then
                        BActionButton.UpdateAll(button);
                        if not button:GetParent():IsShown() then
                                button:Hide();
                        end
                else
                        button:Hide();
                end
        end,
        
        --[[ Toggles ]]--
        
        --Show Empty Buttons
        ShowGrid = function(button)
                button:Show();
        end,
        
        --Hide Empty Buttons
        HideGrid = function(button)
                if not HasAction(BActionButton.GetPagedID(button:GetID())) then
                        button:Hide();
                end
        end,
        
        ShowMacroText = function(button, enable)
                if enable then
                        getglobal(button:GetName().."Name"):Show();
                else
                        getglobal(button:GetName().."Name"):Hide();
                end
        end,
        
        --[[ Action ID Functions ]]--
        
        --returns the barID of the button's parent
        GetParent = function(buttonID)
                local button = getglobal("BActionButton" .. buttonID);
                if button and button:GetParent() then
                        return button:GetParent().id;
                end
                
                local numActionBars = BActionBar.GetNumber();
                local maxButtonsPerBar = math.floor(MAX_BUTTONS / numActionBars);
                for i = 1, numActionBars do
                        if buttonID <= maxButtonsPerBar * i then
                                return i;
                        end
                end
                
                return nil;
        end,

        --Paging, this extends it to page 10 and allows page skipping
        GetPagedID = function(buttonID, barID)
                if not barID then
                        barID = BActionButton.GetParent(buttonID);
                        if not barID then
                                return buttonID;
                        end
                end
                
                --normal paging
                local pageOffset = BActionBar.GetPage(barID);
                if pageOffset ~= 0 then
                        local pagedID = mod(buttonID + pageOffset * BActionBar.GetSize(barID), MAX_BUTTONS);    
                        if pagedID == 0 then
                                return MAX_BUTTONS;
                        end
                        return pagedID;
                end
                
                --stance paging - (bear form, fury stance, etc)
                local stanceOffset = BActionBar.GetStance(barID);
                if stanceOffset ~= 0 then
                        local pagedID =  mod(buttonID + stanceOffset * BActionBar.GetSize(barID), MAX_BUTTONS);
                        if pagedID == 0 then
                                return MAX_BUTTONS;
                        end                     
                        return pagedID;
                end
                
                --Contextual paging - targeting a friendly unit or something
                local contextOffset = BActionBar.GetContext(barID)
                if contextOffset ~= 0 then
                        local pagedID =  mod(buttonID + contextOffset * BActionBar.GetSize(barID), MAX_BUTTONS);
                        if pagedID == 0 then
                                return MAX_BUTTONS;
                        end                     
                        return pagedID;
                end
                
                return buttonID;
        end,
}

--[[ Function Hooks and Overrides ]]--

local oUseAction = UseAction;
UseAction = function(id, s, onSelf)
        if BActionSets_IsSelfCastHotkeyDown() then
                oUseAction(id, s, 1);
                if SpellIsTargeting() then
                        SpellTargetUnit("player");
                end
        else
                oUseAction(id, s, onSelf);
                if SpellIsTargeting() and onSelf then
                        SpellTargetUnit("player");
                end
        end
end

--Release button, do action
ActionButtonUp = function(id, onSelf)
        local button = getglobal("BActionButton".. id);
        
        -- Used to save a macro
        if MacroFrame_SaveMacro then
                MacroFrame_SaveMacro();
        end
                
        local pagedID = BActionButton.GetPagedID(id);
        
        if button and button:GetButtonState() == "PUSHED" then
                button:SetButtonState("NORMAL");
                button:SetChecked(IsCurrentAction(pagedID));
        end
        UseAction(pagedID, 0, onSelf);
end

--Press button
ActionButtonDown = function(id)
        local button = getglobal("BActionButton".. id);
        
        if button and button:GetButtonState() == "NORMAL" then
                button:SetButtonState("PUSHED");
        end
end

Generated by GNU Enscript 1.6.5.90.