local GetActionCooldown, GetActionCharges = GetActionCooldown, GetActionCharges;
local IsConsumableAction, IsStackableAction = IsConsumableAction, IsStackableAction;
local IsItemAction, GetActionCount = IsItemAction, GetActionCount;
+local HasAction, IsUsableAction = HasAction, IsUsableAction;
+local IsCurrentAction, IsAutoRepeatAction = IsCurrentAction, IsAutoRepeatAction;
+local RegisterStateDriver = RegisterStateDriver;
local CooldownFrame_Set, CooldownFrame_Clear = CooldownFrame_Set, CooldownFrame_Clear;
+local CTimerAfter = C_Timer.After;
local GameTooltip = nil;
local COOLDOWN_TYPE_LOSS_OF_CONTROL = COOLDOWN_TYPE_LOSS_OF_CONTROL;
local COOLDOWN_TYPE_NORMAL = COOLDOWN_TYPE_NORMAL;
x = 1000,
y = 800,
},
- -- bogus data past this
- --["OmaBT7"] = {
- -- start = 73,
- -- length = 12,
- -- x = 1000,
- -- y = 760,
- --},
- --["OmaBT8"] = {
- -- start = 85,
- -- length = 12,
- -- x = 1000,
- -- y = 760,
- --},
- --["OmaBT9"] = {
- -- start = 97,
- -- length = 12,
- -- x = 1000,
- -- y = 760,
- --},
- --["OmaBT10"] = {
- -- start = 109,
- -- length = 12,
- -- x = 1000,
- -- y = 760,
- --},
+ ["OmaBT7"] = {
+ start = 73,
+ length = 12,
+ x = 1000,
+ y = 760,
+ },
+ ["OmaBT8"] = {
+ start = 85,
+ length = 12,
+ x = 1000,
+ y = 720,
+ },
+ ["OmaBT9"] = {
+ start = 97,
+ length = 12,
+ x = 1000,
+ y = 680,
+ },
+ ["OmaBT10"] = {
+ start = 109,
+ length = 12,
+ x = 1000,
+ y = 640,
+ },
};
local buttons = {};
+local activeButtons = {};
local ActionBars = CreateFrame("Frame", "OmaActionBars", UIParent);
-local inheritedFrames = "SecureActionButtonTemplate,SecureHandlerDragTemplate";
+local inheritedFrames = "SecureActionButtonTemplate,SecureHandlerDragTemplate,SecureHandlerStateTemplate";
local numChargeCDs = 0;
local function createChargeCD(parent)
local function updateCooldown(button, slot)
-- CD update from FrameXML/ActionButton.lua
- -- TODO charges
local locstart, locduration = GetActionLossOfControlCooldown(slot);
local start, duration, enable, modrate = GetActionCooldown(slot);
local charges, maxcharges, chargestart, chargeduration, chargemodrate = GetActionCharges(slot);
end
end
+local function updateUsable(button, slot)
+ local isUsable, noMana = IsUsableAction(slot);
+ if isUsable then
+ button.icon:SetVertexColor(1, 1, 1);
+ elseif noMana then
+ button.icon:SetVertexColor(0, 0.5, 1);
+ else
+ button.icon:SetVertexColor(0.4, 0.4, 0.4);
+ end
+end
+
+local function updateState(button, slot)
+ if IsCurrentAction(slot) or IsAutoRepeatAction(slot) then
+ button:SetChecked(true);
+ else
+ button:SetChecked(false);
+ end
+end
+
local function updateButton(button, slot)
- local texture = GetActionTexture(slot);
- if texture then
- button.hasaction = true;
+ if HasAction(slot) then
+ activeButtons[slot] = button;
button.base:Show();
- button.icon:SetTexture(texture);
- updateCount(button, slot);
+ button.icon:SetTexture(GetActionTexture(slot));
updateCooldown(button, slot);
+ updateUsable(button, slot);
+ updateState(button, slot);
+ updateCount(button, slot);
else
- button.hasaction = nil;
+ activeButtons[slot] = nil;
if not button.grid then button.base:Hide() end
button.icon:SetTexture(nil);
+ button.cd:Hide();
+ button.count:SetText("");
end
end
local function createActionBar(parent, name, config)
local prev;
for slot = config.start, config.start+config.length-1 do
- local secure = CreateFrame("Button", name..slot, parent, inheritedFrames);
+ local secure = CreateFrame("CheckButton", name..slot, parent, inheritedFrames);
secure.slot = slot;
if slot == config.start then
secure:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y);
secure.icon:SetPoint("TOPLEFT", secure.iconbase, "TOPLEFT");
secure.icon:SetPoint("BOTTOMRIGHT", secure.iconbase, "BOTTOMRIGHT");
secure.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
+ secure:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight");
secure.hotkey = secure:CreateFontString(nil, "OVERLAY", "NumberFontNormalGray");
secure.hotkey:SetPoint("TOPRIGHT", secure, "TOPRIGHT", 2, -1);
secure.count = secure:CreateFontString(nil, "OVERLAY", "NumberFontNormal");
secure:SetAttribute("type", "action");
secure:SetAttribute("action", slot);
function secure:ActionChanged()
- return updateButton(self, slot);
+ self.slot = self:GetAttribute("action");
+ return updateButton(self, self.slot);
end
secure:ActionChanged(); -- initial update
-- FrameXML/SecureHandlers.lua has arguments and return value
self:CallMethod("ActionChanged");
end
]=]);
+ if slot < 13 then
+ -- first action bar has possible states based on vehicle/possess etc.
+ secure:SetAttribute("origaction", slot);
+ secure:SetAttribute("_onstate-possess", [=[
+ if newstate == "possess" then
+ local slot;
+ if HasVehicleActionBar() then
+ slot = (GetVehicleBarIndex()-1)*12+self:GetAttribute("origaction");
+ elseif HasOverrideActionBar() then
+ slot = (GetOverrideBarIndex()-1)*12+self:GetAttribute("origaction");
+ elseif HasTempShapeshitftActionBar() then
+ slot = (GetTempShapeshiftBarIndex()-1)*12+self:GetAttribute("origaction");
+ else
+ -- something wrong, just revert to normal
+ print("Possess bar index not found");
+ slot = self:GetAttribute("origaction");
+ end
+ self:SetAttribute("action", slot);
+ else
+ self:SetAttribute("action", self:GetAttribute("origaction"));
+ end
+ self:CallMethod("ActionChanged");
+ ]=]);
+ RegisterStateDriver(secure, "possess", "[overridebar][possessbar][shapeshift] possess; normal");
+ else
+ function secure:ShowButton() if HasAction(slot) then activeButtons[slot] = self end end
+ function secure:HideButton() activeButtons[slot] = nil end
+ -- all other action bar are hidden if with overridebar or vehicleui (not shapeshift, possessbar)
+ -- default Bartender4 options
+ secure:SetAttribute("_onstate-possess", [=[
+ if newstate == "possess" then
+ self:Hide();
+ self:CallMethod("HideButton");
+ else
+ self:Show();
+ self:CallMethod("ShowButton");
+ end
+ ]=]);
+ RegisterStateDriver(secure, "possess", "[overridebar][vehicleui] possess; normal");
+ end
buttons[slot] = secure;
prev = secure;
end
end
end
+local throttleCD = false;
+local function throttleCDDone() throttleCD = false end
+
local events = {
["ACTIONBAR_UPDATE_COOLDOWN"] = function()
- for _, button in pairs(buttons) do
- updateCooldown(button, button.slot);
+ if not throttleCD then -- only update at most once/frame
+ throttleCD = true;
+ for _, button in pairs(activeButtons) do
+ updateCooldown(button, button.slot);
+ end
+ CTimerAfter(0.01, throttleCDDone); -- wait one frame
end
end,
["SPELL_UPDATE_CHARGES"] = function()
- for _, button in pairs(buttons) do
+ for _, button in pairs(activeButtons) do
updateCount(button, button.slot);
end
end,
for _, button in pairs(buttons) do
button.grid = true;
button.iconbase:Show();
- if not button.hasaction then button.base:Show() end
+ if not activeButtons[button.slot] then button.base:Show() end
end
end,
["ACTIONBAR_HIDEGRID"] = function()
for _, button in pairs(buttons) do
button.grid = nil;
button.iconbase:Hide();
- if not button.hasaction then button.base:Hide() end
+ if not activeButtons[button.slot] then button.base:Hide() end
+ end
+ end,
+ ["ACTIONBAR_UPDATE_STATE"] = function()
+ for _, button in pairs(activeButtons) do
+ updateState(button, button.slot);
+ end
+ end,
+ ["ACTIONBAR_UPDATE_USABLE"] = function()
+ for _, button in pairs(activeButtons) do
+ updateUsable(button, button.slot);
end
end,
+ ["UPDATE_OVERRIDE_ACTIONBAR"] = function()
+ if buttons[1] then -- called before PLAYER_LOGIN
+ for _, button in pairs(buttons) do
+ updateButton(button, button.slot);
+ end
+ end
+ end,
+ ["UPDATE_BINDINGS"] = function()
+ end,
["UPDATE_ALL_BUTTONS"] = function()
for _, button in pairs(buttons) do
updateButton(button, button.slot);
end
end,
- ["UPDATE_BINDINGS"] = function()
- end,
["PLAYER_LOGIN"] = function()
GameTooltip = _G["GameTooltip"];
initialize();
};
events["LOSS_OF_CONTROL_ADDED"] = events["ACTIONBAR_UPDATE_COOLDOWN"];
events["LOSS_OF_CONTROL_UPDATE"] = events["ACTIONBAR_UPDATE_COOLDOWN"]; -- TODO might change once tooltips are in
+events["PLAYER_MOUNT_DISPLAY_CHANGED"] = events["ACTIONBAR_UPDATE_USABLE"];
+events["UPDATE_VEHICLE_ACTIONBAR"] = events["UPDATE_ALL_BUTTONS"];
events["SPELL_UPDATE_ICON"] = events["UPDATE_ALL_BUTTONS"];
events["PET_STABLE_UPDATE"] = events["UPDATE_ALL_BUTTONS"];
events["PET_STABLE_SHOW"] = events["UPDATE_ALL_BUTTONS"];
--- TODO overlay glow ? don't exactly know what it does
+events["PLAYER_SPECIALIZATION_CHANGED"] = events["UPDATE_ALL_BUTTONS"];
+events["UNIT_ENTERED_VEHICLE"] = function(unit)
+ if unit == "player" then events["ACTIONBAR_UPDATE_STATE"]() end
+end
+events["UNIT_EXITED_VEHICLE"] = events["UNIT_ENTERED_VEHICLE"];
+-- TODO COMPANION_UPDATE needed?
+-- TODO overlay glow ? don't exactly know what it does, proc highlight?
-- autorepeat, tooltips
ActionBars:RegisterEvent("PLAYER_LOGIN");
ActionBars:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN");
-ActionBars:RegisterEvent("SPELL_UPDATE_CHARGES");
+ActionBars:RegisterEvent("ACTIONBAR_UPDATE_USABLE");
+ActionBars:RegisterEvent("ACTIONBAR_UPDATE_STATE");
ActionBars:RegisterEvent("ACTIONBAR_SLOT_CHANGED");
ActionBars:RegisterEvent("ACTIONBAR_SHOWGRID");
ActionBars:RegisterEvent("ACTIONBAR_HIDEGRID");
+ActionBars:RegisterEvent("SPELL_UPDATE_ICON");
+ActionBars:RegisterEvent("SPELL_UPDATE_CHARGES");
+ActionBars:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR");
+ActionBars:RegisterEvent("UPDATE_OVERRIDE_ACTIONBAR");
+ActionBars:RegisterEvent("PLAYER_MOUNT_DISPLAY_CHANGED");
+ActionBars:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
+ActionBars:RegisterEvent("UNIT_ENTERED_VEHICLE");
+ActionBars:RegisterEvent("UNIT_EXITED_VEHICLE");
+ActionBars:RegisterEvent("PET_STABLE_UPDATE");
+ActionBars:RegisterEvent("PET_STABLE_SHOW");
ActionBars:SetScript("OnEvent", function(self, event, arg1)
events[event](arg1);
end);