diff modules/ReAction_Action/ReAction_Action.lua @ 88:fc83b3f5b322

Added keybindings using LibKeyBound-1.0, with modifications for Override bindings instead of standard bindings.
author Flick <flickerstreak@gmail.com>
date Sun, 31 Aug 2008 06:02:18 +0000
parents 3499ac7c3a9b
children 7cabc8ac6c16
line wrap: on
line diff
--- a/modules/ReAction_Action/ReAction_Action.lua	Sat Jun 28 00:54:21 2008 +0000
+++ b/modules/ReAction_Action/ReAction_Action.lua	Sun Aug 31 06:02:18 2008 +0000
@@ -15,9 +15,13 @@
 local L = ReAction.L
 local _G = _G
 local CreateFrame = CreateFrame
+local format = string.format
 
 ReAction:UpdateRevision("$Revision$")
 
+-- libraries
+local KB = LibStub("LibKeyBound-1.0")
+
 -- module declaration
 local moduleID = "Action"
 local module = ReAction:NewModule( moduleID )
@@ -61,6 +65,9 @@
   ReAction.RegisterCallback(self, "OnRenameBar")
   ReAction.RegisterCallback(self, "OnConfigModeChanged")
 
+  KB.RegisterCallback(self, "LIBKEYBOUND_ENABLED")
+  KB.RegisterCallback(self, "LIBKEYBOUND_DISABLED")
+  KB.RegisterCallback(self, "LIBKEYBOUND_MODE_COLOR_CHANGED","LIBKEYBOUND_ENABLED")
 end
 
 function module:OnEnable()
@@ -155,6 +162,25 @@
   end
 end
 
+function module:LIBKEYBOUND_ENABLED(evt)
+  -- set the border for all buttons to the keybind-enable color
+  local r,g,b,a = KB:GetColorKeyBoundMode()
+  for _, bar in pairs(self.buttons) do
+    for _, b in pairs(bar) do
+    	b.border:SetVertexColor(r,g,b,a)
+      b.border:Show()
+    end
+  end
+end
+
+function module:LIBKEYBOUND_DISABLED(evt)
+  for _, bar in pairs(self.buttons) do
+    for _, b in pairs(bar) do
+      b.border:Hide()
+    end
+  end
+end
+
 
 ---- Options ----
 do
@@ -652,9 +678,127 @@
   end
 end
 
+------ Button class ------
+
 local frameRecycler = { }
+local trash = CreateFrame("Frame")
+local OnUpdate, KBAttach, GetActionName, GetHotkey, SetKey, FreeKey, ClearBindings, GetBindings
+do
+  local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME
+  local IsActionInRange = IsActionInRange
 
------- Button class ------
+  local buttonLookup = setmetatable({},{__mode="kv"})
+
+  function OnUpdate(frame, elapsed)
+    -- note: This function taints frame.flashtime and frame.rangeTimer. Both of these
+    --       are only read by ActionButton_OnUpdate (which this function replaces). In
+    --       all other places they're just written, so it doesn't taint any secure code.
+    if frame.flashing == 1 then
+      frame.flashtime = frame.flashtime - elapsed
+      if frame.flashtime <= 0 then
+        local overtime = -frame.flashtime
+        if overtime >= ATTACK_BUTTON_FLASH_TIME then
+          overtime = 0
+        end
+        frame.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime
+
+        local flashTexture = frame.flash
+        if flashTexture:IsShown() then
+          flashTexture:Hide()
+        else
+          flashTexture:Show()
+        end
+      end
+    end
+    
+    if frame.rangeTimer then
+      frame.rangeTimer = frame.rangeTimer - elapsed;
+
+      if frame.rangeTimer <= 0 then
+        if IsActionInRange(frame.action) == 0 then
+          frame.icon:SetVertexColor(1.0,0.1,0.1)
+        else
+          ActionButton_UpdateUsable()
+        end
+        frame.rangeTimer = 0.1
+      end
+    end
+  end
+
+  -- Use KeyBound-1.0 for binding, but use Override bindings instead of
+  -- regular bindings to support multiple profile use. This is a little
+  -- weird with the KeyBound dialog box (which has per-char selector as well
+  -- as an OK/Cancel box) but it's the least amount of effort to implement.
+  function GetActionName(f)
+    local b = buttonLookup[f]
+    if b then
+      return format("%s:%s", b.bar:GetName(), b.idx)
+    end
+  end
+
+  function GetHotkey(f)
+    local b = buttonLookup[f]
+    if b then
+      return KB:ToShortKey(b:GetConfig().hotkey)
+    end
+  end
+
+  function SetKey(f, key)
+    local b = buttonLookup[f]
+    if b then
+      local c = b:GetConfig()
+      if c.hotkey then
+        SetOverrideBinding(f, false, c.hotkey, nil)
+      end
+      if key then
+        SetOverrideBindingClick(f, false, key, f:GetName(), nil)
+      end
+      c.hotkey = key
+      b:DisplayHotkey(GetHotkey(f))
+    end
+  end
+
+  function FreeKey(f, key)
+    local b = buttonLookup[f]
+    if b then
+      local c = b:GetConfig()
+      if c.hotkey == key then
+        local action = f:GetActionName()
+        SetOverrideBinding(f, false, c.hotkey, nil)
+        c.hotkey = nil
+        b:DisplayHotkey(nil)
+        return action
+      end
+    end
+    return ReAction:FreeOverrideHotkey(key)
+  end
+
+  function ClearBindings(f)
+    SetKey(f, nil)
+  end
+
+  function GetBindings(f)
+    local b = buttonLookup[f]
+    if b then
+      return b:GetConfig().hotkey
+    end
+  end
+
+  function KBAttach( button )
+    local f = button:GetFrame()
+    f.GetActionName = GetActionName
+    f.GetHotkey     = GetHotkey
+    f.SetKey        = SetKey
+    f.FreeKey       = FreeKey
+    f.ClearBindings = ClearBindings
+    f.GetBindings   = GetBindings
+    buttonLookup[f] = button
+    f:SetKey(button:GetConfig().hotkey)
+    ReAction:RegisterKeybindFrame(f)
+  end
+end
+
+
 function Button:New( bar, idx, config, barConfig )
   -- create new self
   self = setmetatable( { }, {__index = Button} )
@@ -676,8 +820,25 @@
     f:SetParent(parent)
   else
     f = CreateFrame("CheckButton", name, parent, "ActionBarButtonTemplate")
+    -- ditch the old hotkey text because it's tied in ActionButton_Update() to the
+    -- standard binding. We use override bindings.
+    local hotkey = _G[name.."HotKey"]
+    hotkey:SetParent(trash)
+    hotkey = f:CreateFontString(nil, "ARTWORK", "NumberFontNormalSmallGray")
+    hotkey:SetWidth(36)
+    hotkey:SetHeight(18)
+    hotkey:SetJustifyH("RIGHT")
+    hotkey:SetJustifyV("TOP")
+    hotkey:SetPoint("TOPLEFT",f,"TOPLEFT",-2,-2)
+    f.hotkey = hotkey
+    f.icon = _G[name.."Icon"]
+    f.flash = _G[name.."Flash"]
+    f:SetScript("OnUpdate",OnUpdate)
   end
 
+  self.hotkey = f.hotkey
+  self.border = _G[name.."Border"]
+
   f:SetAttribute("action", config.actionID)
   -- install mind control action support for all buttons here just for simplicity
   if self.idx <= 12 then
@@ -697,6 +858,9 @@
   -- show the ID label if applicable
   self:ShowActionIDLabel(ReAction:GetConfigMode())
 
+  -- attach the keybinder
+  KBAttach(self)
+
   self:Refresh()
   return self
 end
@@ -740,6 +904,10 @@
   return self.name
 end
 
+function Button:GetConfig()
+  return self.config
+end
+
 function Button:GetActionID(page)
   if page == nil then
     -- get the effective ID
@@ -856,3 +1024,6 @@
   end
 end
 
+function Button:DisplayHotkey( key )
+  self.hotkey:SetText(key or "")
+end