2e5bc88 - Working override/vehicle/possess bars
authorAleksi Blinnikka <aleksi.blinnikka@gmail.com>
Thu, 8 Feb 2018 01:28:04 +0000
committerAleksi Blinnikka <aleksi.blinnikka@gmail.com>
Thu, 8 Feb 2018 01:28:04 +0000
OmaAB/ActionBars.lua

index e3460ed..95d326e 100644 (file)
@@ -6,7 +6,11 @@ local GetActionLossOfControlCooldown = GetActionLossOfControlCooldown;
 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;
@@ -52,37 +56,37 @@ local settings = {
         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)
@@ -111,7 +115,6 @@ local redoCooldown;
 
 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);
@@ -170,25 +173,47 @@ local function updateCount(button, 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);
@@ -213,6 +238,7 @@ local function createActionBar(parent, name, config)
         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");
@@ -222,7 +248,8 @@ local function createActionBar(parent, name, config)
         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
@@ -266,6 +293,46 @@ local function createActionBar(parent, name, config)
                 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
@@ -281,14 +348,21 @@ local function initialize()
     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,
@@ -299,23 +373,40 @@ local events = {
         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();
@@ -323,18 +414,37 @@ local events = {
 };
 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);