view SkeletonKey/HotKey.lua @ 13:eeec4a600064

- kb.bindings carries the exact values needed for matching GetActionInfo() outputs
author Nenue
date Thu, 28 Jul 2016 18:20:32 -0400
parents f6d1c192afc6
children 82170735e67c
line wrap: on
line source
-- KrakTool
-- HotKey.lua
-- Created: 7/22/2016 10:28 PM
-- %file-revision%
-- Module for fixing actionbar hotkey text

local kb, print = LibStub("LibKraken").register(KeyBinder, 'HotKey')
local hotkey = {}
local hotkeyText = {}
local blizHotKey = {}
local bindings

-- frames obtained via post-load hooks, created by addons like Dominos or BarTender4
local loadedFrames = {}
-- frames divided by update categories
local categoryFrames = {}
-- frames indexed by action slot ID (just the action bar, for... reasons)
local actionFrames = {}

kb.wrap(hotkey)

--- Used to determine which groups of action buttons need updating
local hotkeyEvents = {
  ["UPDATE_BONUS_ACTIONBAR"] = {"bonus"},
  ["UPDATE_VEHICLE_ACTIONBAR"] = {"vehicle"},
  ["UPDATE_OVERRIDE_ACTIONBAR"] = {"override"},
  ["ACTIONBAR_PAGE_CHANGED"] = {"actionbar"},
  ["PLAYER_ENTERING_WORLD"] = {"world","all"},
  ["PET_UI_UPDATE"] = {"pet"},
}

do
  local tickerQueue = {}
  local ticker
  local instant = false
  hotkey.tick = function()

    if #tickerQueue == 0 then
      instant = true
      return
    else
      instant = false
    end
    local func = tremove(tickerQueue, 1)
    if func then
      --print('#', #tickerQueue)
      func()
    end
  end
  hotkey.wrap = function(f)
    if not ticker then
      --print('create ticker')
      ticker = C_Timer.NewTicker(0, hotkey.tick)
    end
    if instant then
      f()
    else
      tinsert(tickerQueue, f)
    end
  end
end

hotkey.wrapEvent = function(event, ...)
  kb:RegisterEvent(event)
  hotkeyEvents[event] = {...}
  hotkey[event] = hotkey.UpdateFromEvent
end

hotkey.unwrapEvent = function(event)
  if not kb[event] then
    kb:UnregisterEvent(event)
  end
  hotkeyEvents[event] = nil
  hotkey[event] = nil
end

hotkey.ActionButton_Update = function(frame)
  hotkey.wrap(function()
    local actionType, actionID = GetActionInfo(frame.action)
    hotkey.UpdateSkeletonKeyText(frame, actionType, actionID, HasAction(frame.action))
  end)
end


hotkey.RegisterFrame = function(frame)
  --hotkey.wrap(function()
  --print('ActionBarButtonEventsFrame_RegisterFrame(', frame:GetName(), frame.action, frame:IsVisible(), frame:IsShown())
  --end)
  blizHotKey[frame] = frame.HotKey
  loadedFrames[frame] = true
end

hotkey.UpdateFromEvent = function(self, event, ...)
  if hotkeyEvents[event] then
    --print('call batch', event, ...)
    for i, func  in ipairs(hotkeyEvents[event]) do

      if hotkey[func] then
        --print(' ', func)
        hotkey[func](self, event, ...)
      end
    end
  end
  return true
end

hotkey.variables = function()
  bindings = kb.GetBindings()
  for event, manifest in pairs(hotkeyEvents) do
    kb:RegisterEvent(event)
    hotkey[event] = hotkey.UpdateFromEvent
  end
  hotkey.wrapEvent('UNIT_PET', 'pet')
end

hotkey.init = function()
  hooksecurefunc("ActionBarButtonEventsFrame_RegisterFrame", hotkey.RegisterFrame)
end

hotkey.ui = function()
  hotkey.player()
  hotkey.pet()
end

hotkey.world = function()
  hotkeyEvents["UPDATE_BINDINGS"] = {"actionbar"}
  hotkey.UPDATE_BINDINGS = hotkey.UpdateFromEvent
  kb:RegisterEvent("UPDATE_BINDINGS")

  hotkey.player()
  hotkey.pet()

  -- Set this after, since we already full-scanned buttons
  hooksecurefunc("ActionButton_Update", hotkey.ActionButton_Update)
end

-- requires all these arguments since non-actionbar buttons don't have all of said methods
hotkey.UpdateSkeletonKeyText = function(frame, actionType, actionID, hasAction)
  bindings = kb.GetBindings()
  print(frame, actionType, actionID, hasAction)
  if bindings[actionType] then
    --print('|cFFFFFF00'..frame:GetName(), actionType, actionID, hasAction)
    local binds = bindings[actionType][actionID]
    if binds  then
      if hasAction and not frame.HotKey:IsVisible() then
        if not hotkeyText[frame] then
          hotkeyText[frame] = frame:CreateFontString('KeyBinderHotKeyText', 'OVERLAY')
          hotkeyText[frame]:SetFont(frame.HotKey:GetFont())
          hotkeyText[frame]:SetTextColor(frame.HotKey:GetTextColor())
          hotkeyText[frame]:SetPoint('TOPRIGHT', frame.HotKey, 'TOPRIGHT')
        end

        hotkeyText[frame]:SetText(kb.BindingString(unpack(binds)))
        print('|cFF00FFFFUpdate text for', frame:GetName())
        print(unpack(binds))
        return
      end
    end
  end

  if hotkeyText[frame] then
    hotkeyText[frame]:SetText(nil)
    --print('|cFFFF4400cleared text from', frame:GetName())
  end
end

hotkey.actionbar = function()
  if ActionBarButtonEventsFrame.frames then
    for index, frame in ipairs(ActionBarButtonEventsFrame.frames) do
      local actionType, actionID = GetActionInfo(frame.action)
      hotkey.UpdateSkeletonKeyText(frame, actionType, actionID, HasAction(frame.action))
    end
  end
end

hotkey.actionslot = function(self, event, slot)
  --print(event, slot)
  --print(GetActionButtonForID(slot))
  hotkey.UpdateSkeletonKeyText(GetActionButtonForID(slot))
end

hotkey.player = function()
  hotkey.actionbar()
end


hotkey.pet = function(self, event, arg1)
  if event == 'UNIT_PET' and arg1 == 'player' then
    if PetHasActionBar() and UnitIsVisible("pet") then
      hotkey.wrapEvent('PET_UI_CLOSE', 'pet')
      hotkey.wrapEvent('PET_BAR_UPDATE', 'pet')
    else
      hotkey.unwrapEvent('PET_UI_CLOSE')
      hotkey.unwrapEvent('PET_BAR_UPDATE')
      return
    end
  end

  for i=1, NUM_PET_ACTION_SLOTS, 1 do
    local button = _G['PetActionButton'.. i]
    --print(button:GetName())
    for k, v in pairs(button) do
      --print(' ', k, type(v))
    end
  end
end