524 lines
14 KiB
Lua
524 lines
14 KiB
Lua
CURRENT_ACTIONBAR_PAGE = 1;
|
|
NUM_ACTIONBAR_PAGES = 6;
|
|
NUM_ACTIONBAR_BUTTONS = 12;
|
|
ATTACK_BUTTON_FLASH_TIME = 0.4;
|
|
|
|
BOTTOMLEFT_ACTIONBAR_PAGE = 6;
|
|
BOTTOMRIGHT_ACTIONBAR_PAGE = 5;
|
|
LEFT_ACTIONBAR_PAGE = 4;
|
|
RIGHT_ACTIONBAR_PAGE = 3;
|
|
RANGE_INDICATOR = "●";
|
|
|
|
-- Table of actionbar pages and whether they're viewable or not
|
|
VIEWABLE_ACTION_BAR_PAGES = {1, 1, 1, 1, 1, 1};
|
|
|
|
function ActionButtonDown(id)
|
|
local button;
|
|
if ( VehicleMenuBar:IsShown() and id <= VEHICLE_MAX_ACTIONBUTTONS ) then
|
|
button = _G["VehicleMenuBarActionButton"..id];
|
|
elseif ( BonusActionBarFrame:IsShown() ) then
|
|
button = _G["BonusActionButton"..id];
|
|
else
|
|
button = _G["ActionButton"..id];
|
|
end
|
|
if ( button:GetButtonState() == "NORMAL" ) then
|
|
button:SetButtonState("PUSHED");
|
|
end
|
|
end
|
|
|
|
function ActionButtonUp(id)
|
|
local button;
|
|
if ( VehicleMenuBar:IsShown() and id <= VEHICLE_MAX_ACTIONBUTTONS ) then
|
|
button = _G["VehicleMenuBarActionButton"..id];
|
|
elseif ( BonusActionBarFrame:IsShown() ) then
|
|
button = _G["BonusActionButton"..id];
|
|
else
|
|
button = _G["ActionButton"..id];
|
|
end
|
|
if ( button:GetButtonState() == "PUSHED" ) then
|
|
button:SetButtonState("NORMAL");
|
|
SecureActionButton_OnClick(button, "LeftButton");
|
|
ActionButton_UpdateState(button);
|
|
end
|
|
end
|
|
|
|
function ActionBar_PageUp()
|
|
local nextPage;
|
|
for i=GetActionBarPage() + 1, NUM_ACTIONBAR_PAGES do
|
|
if ( VIEWABLE_ACTION_BAR_PAGES[i] ) then
|
|
nextPage = i;
|
|
break;
|
|
end
|
|
end
|
|
|
|
if ( not nextPage ) then
|
|
nextPage = 1;
|
|
end
|
|
ChangeActionBarPage(nextPage);
|
|
end
|
|
|
|
function ActionBar_PageDown()
|
|
local prevPage;
|
|
for i=GetActionBarPage() - 1, 1, -1 do
|
|
if ( VIEWABLE_ACTION_BAR_PAGES[i] ) then
|
|
prevPage = i;
|
|
break;
|
|
end
|
|
end
|
|
|
|
if ( not prevPage ) then
|
|
for i=NUM_ACTIONBAR_PAGES, 1, -1 do
|
|
if ( VIEWABLE_ACTION_BAR_PAGES[i] ) then
|
|
prevPage = i;
|
|
break;
|
|
end
|
|
end
|
|
end
|
|
ChangeActionBarPage(prevPage);
|
|
end
|
|
|
|
function ActionButton_OnLoad (self)
|
|
self.flashing = 0;
|
|
self.flashtime = 0;
|
|
self:SetAttribute("showgrid", 0);
|
|
self:SetAttribute("type", "action");
|
|
self:SetAttribute("checkselfcast", true);
|
|
self:SetAttribute("checkfocuscast", true);
|
|
self:SetAttribute("useparent-unit", true);
|
|
self:SetAttribute("useparent-actionpage", true);
|
|
self:RegisterForDrag("LeftButton", "RightButton");
|
|
self:RegisterForClicks("AnyUp");
|
|
self:RegisterEvent("PLAYER_ENTERING_WORLD");
|
|
self:RegisterEvent("ACTIONBAR_SHOWGRID");
|
|
self:RegisterEvent("ACTIONBAR_HIDEGRID");
|
|
self:RegisterEvent("ACTIONBAR_PAGE_CHANGED");
|
|
self:RegisterEvent("ACTIONBAR_SLOT_CHANGED");
|
|
self:RegisterEvent("UPDATE_BINDINGS");
|
|
self:RegisterEvent("UPDATE_SHAPESHIFT_FORM");
|
|
ActionButton_UpdateAction(self);
|
|
ActionButton_UpdateHotkeys(self, self.buttonType);
|
|
end
|
|
|
|
function ActionButton_UpdateHotkeys (self, actionButtonType)
|
|
local id;
|
|
if ( not actionButtonType ) then
|
|
actionButtonType = "ACTIONBUTTON";
|
|
id = self:GetID();
|
|
else
|
|
if ( actionButtonType == "MULTICASTACTIONBUTTON" ) then
|
|
id = self.buttonIndex;
|
|
else
|
|
id = self:GetID();
|
|
end
|
|
end
|
|
|
|
local hotkey = _G[self:GetName().."HotKey"];
|
|
local key = GetBindingKey(actionButtonType..id) or
|
|
GetBindingKey("CLICK "..self:GetName()..":LeftButton");
|
|
|
|
local text = GetBindingText(key, "KEY_", 1);
|
|
if ( text == "" ) then
|
|
hotkey:SetText(RANGE_INDICATOR);
|
|
hotkey:SetPoint("TOPLEFT", self, "TOPLEFT", 1, -2);
|
|
hotkey:Hide();
|
|
else
|
|
hotkey:SetText(text);
|
|
hotkey:SetPoint("TOPLEFT", self, "TOPLEFT", -2, -2);
|
|
hotkey:Show();
|
|
end
|
|
end
|
|
|
|
function ActionButton_CalculateAction (self, button)
|
|
if ( not button ) then
|
|
button = SecureButton_GetEffectiveButton(self);
|
|
end
|
|
if ( self:GetID() > 0 ) then
|
|
local page = SecureButton_GetModifiedAttribute(self, "actionpage", button);
|
|
if ( not page ) then
|
|
page = GetActionBarPage();
|
|
if ( self.isBonus and (page == 1 or self.alwaysBonus) ) then
|
|
local offset = GetBonusBarOffset();
|
|
if ( offset == 0 and BonusActionBarFrame and BonusActionBarFrame.lastBonusBar ) then
|
|
offset = BonusActionBarFrame.lastBonusBar;
|
|
end
|
|
page = NUM_ACTIONBAR_PAGES + offset;
|
|
elseif ( self.buttonType == "MULTICASTACTIONBUTTON" ) then
|
|
page = NUM_ACTIONBAR_PAGES + GetMultiCastBarOffset();
|
|
end
|
|
end
|
|
return (self:GetID() + ((page - 1) * NUM_ACTIONBAR_BUTTONS));
|
|
else
|
|
return SecureButton_GetModifiedAttribute(self, "action", button) or 1;
|
|
end
|
|
end
|
|
|
|
function ActionButton_UpdateAction (self)
|
|
local action = ActionButton_CalculateAction(self);
|
|
if ( action ~= self.action ) then
|
|
self.action = action;
|
|
ActionButton_Update(self);
|
|
end
|
|
end
|
|
|
|
function ActionButton_Update (self)
|
|
local name = self:GetName();
|
|
|
|
local action = self.action;
|
|
local icon = _G[name.."Icon"];
|
|
local buttonCooldown = _G[name.."Cooldown"];
|
|
local texture = GetActionTexture(action);
|
|
|
|
if ( HasAction(action) ) then
|
|
if ( not self.eventsRegistered ) then
|
|
self:RegisterEvent("ACTIONBAR_UPDATE_STATE");
|
|
self:RegisterEvent("ACTIONBAR_UPDATE_USABLE");
|
|
self:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN");
|
|
self:RegisterEvent("UPDATE_INVENTORY_ALERTS");
|
|
self:RegisterEvent("PLAYER_TARGET_CHANGED");
|
|
self:RegisterEvent("TRADE_SKILL_SHOW");
|
|
self:RegisterEvent("TRADE_SKILL_CLOSE");
|
|
self:RegisterEvent("PLAYER_ENTER_COMBAT");
|
|
self:RegisterEvent("PLAYER_LEAVE_COMBAT");
|
|
self:RegisterEvent("START_AUTOREPEAT_SPELL");
|
|
self:RegisterEvent("STOP_AUTOREPEAT_SPELL");
|
|
self:RegisterEvent("UNIT_ENTERED_VEHICLE");
|
|
self:RegisterEvent("UNIT_EXITED_VEHICLE");
|
|
self:RegisterEvent("COMPANION_UPDATE");
|
|
self:RegisterEvent("UNIT_INVENTORY_CHANGED");
|
|
self:RegisterEvent("LEARNED_SPELL_IN_TAB");
|
|
self.eventsRegistered = true;
|
|
end
|
|
|
|
if ( not self:GetAttribute("statehidden") ) then
|
|
self:Show();
|
|
end
|
|
ActionButton_UpdateState(self);
|
|
ActionButton_UpdateUsable(self);
|
|
ActionButton_UpdateCooldown(self);
|
|
ActionButton_UpdateFlash(self);
|
|
else
|
|
if ( self.eventsRegistered ) then
|
|
self:UnregisterEvent("ACTIONBAR_UPDATE_STATE");
|
|
self:UnregisterEvent("ACTIONBAR_UPDATE_USABLE");
|
|
self:UnregisterEvent("ACTIONBAR_UPDATE_COOLDOWN");
|
|
self:UnregisterEvent("UPDATE_INVENTORY_ALERTS");
|
|
self:UnregisterEvent("PLAYER_TARGET_CHANGED");
|
|
self:UnregisterEvent("TRADE_SKILL_SHOW");
|
|
self:UnregisterEvent("TRADE_SKILL_CLOSE");
|
|
self:UnregisterEvent("PLAYER_ENTER_COMBAT");
|
|
self:UnregisterEvent("PLAYER_LEAVE_COMBAT");
|
|
self:UnregisterEvent("START_AUTOREPEAT_SPELL");
|
|
self:UnregisterEvent("STOP_AUTOREPEAT_SPELL");
|
|
self:UnregisterEvent("UNIT_ENTERED_VEHICLE");
|
|
self:UnregisterEvent("UNIT_EXITED_VEHICLE");
|
|
self:UnregisterEvent("COMPANION_UPDATE");
|
|
self:UnregisterEvent("UNIT_INVENTORY_CHANGED");
|
|
self:UnregisterEvent("LEARNED_SPELL_IN_TAB");
|
|
self.eventsRegistered = nil;
|
|
end
|
|
|
|
if ( self:GetAttribute("showgrid") == 0 ) then
|
|
self:Hide();
|
|
else
|
|
buttonCooldown:Hide();
|
|
end
|
|
end
|
|
|
|
-- Add a green border if button is an equipped item
|
|
local border = _G[name.."Border"];
|
|
if ( IsEquippedAction(action) ) then
|
|
border:SetVertexColor(0, 1.0, 0, 0.35);
|
|
border:Show();
|
|
else
|
|
border:Hide();
|
|
end
|
|
|
|
-- Update Action Text
|
|
local actionName = _G[name.."Name"];
|
|
if ( not IsConsumableAction(action) and not IsStackableAction(action) ) then
|
|
actionName:SetText(GetActionText(action));
|
|
else
|
|
actionName:SetText("");
|
|
end
|
|
|
|
-- Update icon and hotkey text
|
|
if ( texture ) then
|
|
icon:SetTexture(texture);
|
|
icon:Show();
|
|
self.rangeTimer = -1;
|
|
self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2");
|
|
else
|
|
icon:Hide();
|
|
buttonCooldown:Hide();
|
|
self.rangeTimer = nil;
|
|
self:SetNormalTexture("Interface\\Buttons\\UI-Quickslot");
|
|
local hotkey = _G[name.."HotKey"];
|
|
if ( hotkey:GetText() == RANGE_INDICATOR ) then
|
|
hotkey:Hide();
|
|
else
|
|
hotkey:SetVertexColor(0.6, 0.6, 0.6);
|
|
end
|
|
end
|
|
ActionButton_UpdateCount(self);
|
|
|
|
-- Update tooltip
|
|
if ( GameTooltip:GetOwner() == self ) then
|
|
ActionButton_SetTooltip(self);
|
|
end
|
|
|
|
self.feedback_action = action;
|
|
end
|
|
|
|
function ActionButton_ShowGrid (button)
|
|
assert(button);
|
|
|
|
if ( issecure() ) then
|
|
button:SetAttribute("showgrid", button:GetAttribute("showgrid") + 1);
|
|
end
|
|
|
|
_G[button:GetName().."NormalTexture"]:SetVertexColor(1.0, 1.0, 1.0, 0.5);
|
|
|
|
if ( button:GetAttribute("showgrid") >= 1 and not button:GetAttribute("statehidden") ) then
|
|
button:Show();
|
|
end
|
|
end
|
|
|
|
function ActionButton_HideGrid (button)
|
|
assert(button);
|
|
|
|
local showgrid = button:GetAttribute("showgrid");
|
|
|
|
if ( issecure() ) then
|
|
if ( showgrid > 0 ) then
|
|
button:SetAttribute("showgrid", showgrid - 1);
|
|
end
|
|
end
|
|
|
|
if ( button:GetAttribute("showgrid") == 0 and not HasAction(button.action) ) then
|
|
button:Hide();
|
|
end
|
|
end
|
|
|
|
function ActionButton_UpdateState (button)
|
|
assert(button);
|
|
|
|
local action = button.action;
|
|
if ( IsCurrentAction(action) or IsAutoRepeatAction(action) ) then
|
|
button:SetChecked(1);
|
|
else
|
|
button:SetChecked(0);
|
|
end
|
|
end
|
|
|
|
function ActionButton_UpdateUsable (self)
|
|
local name = self:GetName();
|
|
local icon = _G[name.."Icon"];
|
|
local normalTexture = _G[name.."NormalTexture"];
|
|
local isUsable, notEnoughMana = IsUsableAction(self.action);
|
|
if ( isUsable ) then
|
|
icon:SetVertexColor(1.0, 1.0, 1.0);
|
|
normalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
elseif ( notEnoughMana ) then
|
|
icon:SetVertexColor(0.5, 0.5, 1.0);
|
|
normalTexture:SetVertexColor(0.5, 0.5, 1.0);
|
|
else
|
|
icon:SetVertexColor(0.4, 0.4, 0.4);
|
|
normalTexture:SetVertexColor(1.0, 1.0, 1.0);
|
|
end
|
|
end
|
|
|
|
function ActionButton_UpdateCount (self)
|
|
local text = _G[self:GetName().."Count"];
|
|
local action = self.action;
|
|
if ( IsConsumableAction(action) or IsStackableAction(action) ) then
|
|
local count = GetActionCount(action);
|
|
if ( count > (self.maxDisplayCount or 9999 ) ) then
|
|
text:SetText("*");
|
|
else
|
|
text:SetText(count);
|
|
end
|
|
else
|
|
text:SetText("");
|
|
end
|
|
end
|
|
|
|
function ActionButton_UpdateCooldown (self)
|
|
local cooldown = _G[self:GetName().."Cooldown"];
|
|
local start, duration, enable = GetActionCooldown(self.action);
|
|
CooldownFrame_SetTimer(cooldown, start, duration, enable);
|
|
end
|
|
|
|
function ActionButton_OnEvent (self, event, ...)
|
|
local arg1 = ...;
|
|
if ((event == "UNIT_INVENTORY_CHANGED" and arg1 == "player") or event == "LEARNED_SPELL_IN_TAB") then
|
|
if ( GameTooltip:GetOwner() == self ) then
|
|
ActionButton_SetTooltip(self);
|
|
end
|
|
end
|
|
if ( event == "ACTIONBAR_SLOT_CHANGED" ) then
|
|
if ( arg1 == 0 or arg1 == tonumber(self.action) ) then
|
|
ActionButton_Update(self);
|
|
end
|
|
return;
|
|
end
|
|
if ( event == "PLAYER_ENTERING_WORLD" or event == "UPDATE_SHAPESHIFT_FORM" ) then
|
|
-- need to listen for UPDATE_SHAPESHIFT_FORM because attack icons change when the shapeshift form changes
|
|
ActionButton_Update(self);
|
|
return;
|
|
end
|
|
if ( event == "ACTIONBAR_PAGE_CHANGED" or event == "UPDATE_BONUS_ACTIONBAR" ) then
|
|
ActionButton_UpdateAction(self);
|
|
return;
|
|
end
|
|
if ( event == "ACTIONBAR_SHOWGRID" ) then
|
|
ActionButton_ShowGrid(self);
|
|
return;
|
|
end
|
|
if ( event == "ACTIONBAR_HIDEGRID" ) then
|
|
ActionButton_HideGrid(self);
|
|
return;
|
|
end
|
|
if ( event == "UPDATE_BINDINGS" ) then
|
|
ActionButton_UpdateHotkeys(self, self.buttonType);
|
|
return;
|
|
end
|
|
|
|
-- All event handlers below this line are only set when the button has an action
|
|
|
|
if ( event == "PLAYER_TARGET_CHANGED" ) then
|
|
self.rangeTimer = -1;
|
|
elseif ( (event == "ACTIONBAR_UPDATE_STATE") or
|
|
((event == "UNIT_ENTERED_VEHICLE" or event == "UNIT_EXITED_VEHICLE") and (arg1 == "player")) or
|
|
((event == "COMPANION_UPDATE") and (arg1 == "MOUNT")) ) then
|
|
ActionButton_UpdateState(self);
|
|
elseif ( event == "ACTIONBAR_UPDATE_USABLE" ) then
|
|
ActionButton_UpdateUsable(self);
|
|
elseif ( event == "ACTIONBAR_UPDATE_COOLDOWN" ) then
|
|
ActionButton_UpdateCooldown(self);
|
|
elseif ( event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_CLOSE" ) then
|
|
ActionButton_UpdateState(self);
|
|
elseif ( event == "PLAYER_ENTER_COMBAT" ) then
|
|
if ( IsAttackAction(self.action) ) then
|
|
ActionButton_StartFlash(self);
|
|
end
|
|
elseif ( event == "PLAYER_LEAVE_COMBAT" ) then
|
|
if ( IsAttackAction(self.action) ) then
|
|
ActionButton_StopFlash(self);
|
|
end
|
|
elseif ( event == "START_AUTOREPEAT_SPELL" ) then
|
|
if ( IsAutoRepeatAction(self.action) ) then
|
|
ActionButton_StartFlash(self);
|
|
end
|
|
elseif ( event == "STOP_AUTOREPEAT_SPELL" ) then
|
|
if ( ActionButton_IsFlashing(self) and not IsAttackAction(self.action) ) then
|
|
ActionButton_StopFlash(self);
|
|
end
|
|
end
|
|
end
|
|
|
|
function ActionButton_SetTooltip (self)
|
|
if ( GetCVar("UberTooltips") == "1" ) then
|
|
GameTooltip_SetDefaultAnchor(GameTooltip, self);
|
|
else
|
|
local parent = self:GetParent();
|
|
if ( parent == MultiBarBottomRight or parent == MultiBarRight or parent == MultiBarLeft ) then
|
|
GameTooltip:SetOwner(self, "ANCHOR_LEFT");
|
|
else
|
|
GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
|
|
end
|
|
end
|
|
if ( GameTooltip:SetAction(self.action) ) then
|
|
self.UpdateTooltip = ActionButton_SetTooltip;
|
|
else
|
|
self.UpdateTooltip = nil;
|
|
end
|
|
end
|
|
|
|
function ActionButton_OnUpdate (self, elapsed)
|
|
if ( ActionButton_IsFlashing(self) ) then
|
|
local flashtime = self.flashtime;
|
|
flashtime = flashtime - elapsed;
|
|
|
|
if ( flashtime <= 0 ) then
|
|
local overtime = -flashtime;
|
|
if ( overtime >= ATTACK_BUTTON_FLASH_TIME ) then
|
|
overtime = 0;
|
|
end
|
|
flashtime = ATTACK_BUTTON_FLASH_TIME - overtime;
|
|
|
|
local flashTexture = _G[self:GetName().."Flash"];
|
|
if ( flashTexture:IsShown() ) then
|
|
flashTexture:Hide();
|
|
else
|
|
flashTexture:Show();
|
|
end
|
|
end
|
|
|
|
self.flashtime = flashtime;
|
|
end
|
|
|
|
-- Handle range indicator
|
|
local rangeTimer = self.rangeTimer;
|
|
if ( rangeTimer ) then
|
|
rangeTimer = rangeTimer - elapsed;
|
|
|
|
if ( rangeTimer <= 0 ) then
|
|
local count = _G[self:GetName().."HotKey"];
|
|
local valid = IsActionInRange(self.action);
|
|
if ( count:GetText() == RANGE_INDICATOR ) then
|
|
if ( valid == 0 ) then
|
|
count:Show();
|
|
count:SetVertexColor(1.0, 0.1, 0.1);
|
|
elseif ( valid == 1 ) then
|
|
count:Show();
|
|
count:SetVertexColor(0.6, 0.6, 0.6);
|
|
else
|
|
count:Hide();
|
|
end
|
|
else
|
|
if ( valid == 0 ) then
|
|
count:SetVertexColor(1.0, 0.1, 0.1);
|
|
else
|
|
count:SetVertexColor(0.6, 0.6, 0.6);
|
|
end
|
|
end
|
|
rangeTimer = TOOLTIP_UPDATE_TIME;
|
|
end
|
|
|
|
self.rangeTimer = rangeTimer;
|
|
end
|
|
end
|
|
|
|
function ActionButton_GetPagedID (self)
|
|
return self.action;
|
|
end
|
|
|
|
function ActionButton_UpdateFlash (self)
|
|
local action = self.action;
|
|
if ( (IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action) ) then
|
|
ActionButton_StartFlash(self);
|
|
else
|
|
ActionButton_StopFlash(self);
|
|
end
|
|
end
|
|
|
|
function ActionButton_StartFlash (self)
|
|
self.flashing = 1;
|
|
self.flashtime = 0;
|
|
ActionButton_UpdateState(self);
|
|
end
|
|
|
|
function ActionButton_StopFlash (self)
|
|
self.flashing = 0;
|
|
_G[self:GetName().."Flash"]:Hide();
|
|
ActionButton_UpdateState (self);
|
|
end
|
|
|
|
function ActionButton_IsFlashing (self)
|
|
if ( self.flashing == 1 ) then
|
|
return 1;
|
|
end
|
|
|
|
return nil;
|
|
end
|