diff libs/ReBound-1.0/ReBound-1.0.lua @ 12:2735edcf9ab7

Version 0.34
author Flick <flickerstreak@gmail.com>
date Wed, 21 Mar 2007 00:13:27 +0000
parents f3a7bfebc283
children 639282f3a0e0
line wrap: on
line diff
--- a/libs/ReBound-1.0/ReBound-1.0.lua	Tue Mar 20 21:38:47 2007 +0000
+++ b/libs/ReBound-1.0/ReBound-1.0.lua	Wed Mar 21 00:13:27 2007 +0000
@@ -1,22 +1,23 @@
 --[[
 Name: ReBound-1.0
-Revision: $Rev: 1 $
+Revision: $Rev: 2 $
 Author: Flick
 Website: 
 Documentation: 
 SVN: 
-Description: Library for point-and-click key binding interfaces
+Description: A library to assist with click-binding
 License: MIT
-Dependencies: AceLibrary, AceEvent-2.0, AceLocale-2.2
+Dependencies: AceLibrary, AceEvent-2.0, AceLocale-2.2, AceOO-2.0
 ]]
 
 
-local version_major, version_minor = "ReBound-1.0", "$Rev: 1 $"
+local version_major, version_minor = "ReBound-1.0", "$Rev: 2 $"
 
 if not AceLibrary then error(version_major .. " requires AceLibrary.") end
 if not AceLibrary:IsNewVersion(version_major, version_minor) then return end
 if not AceLibrary:HasInstance("AceEvent-2.0") then error(version_major .. " requires AceEvent-2.0.") end
 if not AceLibrary:HasInstance("AceLocale-2.2") then error(version_major .. " requires AceLocale-2.2.") end
+if not AceLibrary:HasInstance("AceOO-2.0") then error(version_major .. " requires AceOO-2.0.") end
 
 local L = AceLibrary("AceLocale-2.2"):new("ReBound")
 
@@ -24,16 +25,21 @@
 local colorOff = "|r"
 
 local mouseButtonConvert = {
+  LeftButton = "BUTTON1",
+  RightButton = "BUTTON2",
   MiddleButton = "BUTTON3",
   Button4 = "BUTTON4",
   Button5 = "BUTTON5"
 }
 
+--local BINDING_PENDING = { }  -- a constant
+
 -- localization
 L:RegisterTranslations( "enUS", function()
   return {
     ["none"] = true,
     ["Right-click"] = true,
+    ["Right Click"] = true,
     ["Click to select for binding"] = true,
     ["Shift-click to clear binding"] = true,
     ["Press a key to assign binding"] = true,
@@ -42,15 +48,66 @@
 end )
 
 
+local ReBound = AceLibrary("AceOO-2.0").Class("AceEvent-2.0")
 
+--[[
+  ReBound publishes the following events:
 
-local ReBound = { }
+  -- temporary bindings (prior to SaveBindings() being called)
+  REBOUND_BIND_TEMP   (id, key, targetFrameName, mouseButton)
+  REBOUND_UNBIND_TEMP (id, key)
+
+  -- permanent bindings (fired all at once when SaveBindings() is called)
+  REBOUND_BIND        (id, key, targetFrameName, mouseButton)
+  REBOUND_UNBIND      (id, key)
+
+  These events are published in response to click actions ONLY. This means
+  that if a key is unbound from a click-binding frame, and bound to some 
+  other action, then REBOUND_UNBIND(id,key) will be fired.
+]]
+
+
+--[[
+  Calls to new() which share ids will return an existing object with that id, similar
+  to AceLocale-2.2.
+]]
+local super_new = ReBound.new
+function ReBound:new( id )
+  self.instances = self.instances or { }
+  if self.instances[id] then
+    return self.instances[id]
+  else
+    local i = super_new(self,id)
+    self.instances[id] = i
+    return i
+  end
+end
+
+
+--[[
+  Class object constructor
+
+  arguments:
+    id : the ID that will be provided in events. This can be absolutely 
+         anything, but a string is recommended.
+]]
+local super_init = ReBound.prototype.init
+function ReBound.prototype:init( id )
+  super_init(self)
+
+  self.id = id
+  self.frames = { }
+  self.pending = { }
+  self.bindings = { }
+end
+
+
 
 
 --[[
   Arguments:
   key: A string representation of a key, suitable for passing to SetBinding.
-  target: The frame with an OnClick handler to attach a click-binding to
+  target: The frame with an OnClick handler to which the click-binding should be attached
   [button]: The mouse button to emulate. Default is "LeftButton".
 
   Returns:
@@ -59,9 +116,9 @@
   Notes:
   This does not save the bindings.
 ]]
-function ReBound:SetBinding( key, target, button )
-  if not key then self:error("ReBound:SetBinding() requires a key argument.") end
-  if not target then self:error("ReBound:SetBinding() requires a binding target argument") end
+function ReBound.prototype:SetBinding( key, target, button )
+  if not key then error("ReBound:SetBinding() requires a key argument.") end
+  if not target then error("ReBound:SetBinding() requires a binding target argument") end
   button = button or "LeftButton"
 
   -- prevent setting a binding that's already set
@@ -82,8 +139,11 @@
   -- set the new binding
   SetBindingClick(key, target:GetName(), button)
 
-  -- notify listeners, e.g. for storing the setting
-  self.event:TriggerEvent("REBOUND_BIND", key, target:GetName(), button)
+  -- store the temporary binding as "pending" for later notification
+  table.insert(self.pending, key)
+
+  -- notify listeners, e.g. for displaying the setting
+  self:TriggerEvent("REBOUND_BIND_TEMP", self.id, key, target:GetName(), button)
 end
 
 
@@ -103,8 +163,8 @@
 
   This does NOT save the bindings. Call SaveBindings() to commit the bindings to disk.
 ]]
-function ReBound:ClearBinding( key, target, button, silent ) 
-  if not target and not key then self:error("ReBound:ClearBinding() requires a key or click-binding target argument") end
+function ReBound.prototype:ClearBinding( key, target, button, silent ) 
+  if not target and not key then error("ReBound:ClearBinding() requires a key or click-binding target argument") end
   button = button or "LeftButton"
 
   local keys = key and { key } or { self:GetBinding(target,button) }
@@ -120,7 +180,7 @@
         if f then
           name = f
           if b ~= "LeftButton" then
-            if b == "RightButton" then b = "Right Click" end
+            if b == "RightButton" then b = L["Right Click"] end
             name = f .."-"..b
           end
         end
@@ -130,13 +190,14 @@
       end
     end
     SetBinding(k,nil)
-    self.event:TriggerEvent("REBOUND_UNBIND", k)
+    table.insert(self.pending,k)
+    self:TriggerEvent("REBOUND_UNBIND_TEMP", self.id, k)
   end
 end
 
 
 --[[
-  Gets the keys bound to clicking a frame.
+  Gets the keys currently click-bound to a frame.
 
   Arguments:
   target: target frame to query
@@ -145,14 +206,66 @@
   Returns:
   key1, key2, key3, etc, as strings.
 ]]
-function ReBound:GetBinding( target, button )
-  if not target then self:error("ReBound:GetBinding() requires a target frame argument") end
+function ReBound.prototype:GetBinding( target, button )
+  if not target then error("ReBound:GetBinding() requires a target frame argument") end
   button = button or "LeftButton"
   return GetBindingKey("CLICK "..target:GetName()..":"..button)
 end
 
 
 --[[
+  Publishes permanent binding notification events.
+]]
+local function PublishBindings(self)
+  for _, key in ipairs(self.pending) do
+    local action = GetBindingAction(key)
+    local frame, button
+    if action then
+      frame, button = action:match("CLICK (.+)\:(.+)")
+    end
+    if frame == nil then
+      self:TriggerEvent("REBOUND_UNBIND", self.id, key)
+    else
+      self:TriggerEvent("REBOUND_BIND", self.id, key, frame, button)
+    end
+  end
+  self.pending = { }
+end
+
+
+--[[
+  Saves the bindings using the current scheme. Also publishes events indicating that the
+  bindings have been saved/cleared permanently.
+]]
+function ReBound.prototype:SaveBindings()
+  SaveBindings(GetCurrentBindingSet()) -- will trigger an UPDATE_BINDINGS event.
+  PublishBindings(self)
+end
+
+
+--[[
+  Reverts the bindings to the ones previously saved. Also publishes events indicating that the 
+  bindings have been reverted.
+]]
+function ReBound.prototype:RevertBindings()
+  LoadBindings(GetCurrentBindingSet()) -- should trigger an UPDATE_BINDINGS event.
+  PublishBindings(self)
+end
+
+
+--[[
+  Clears all bindings associated with registered frames. This is useful, for example, when switching profiles
+  and the keybinding data is stored in the profile.
+]]
+function ReBound.prototype:ClearRegisteredBindings()
+  for f, _ in pairs(self.frames) do
+    self:ClearBinding(nil,f,"LeftButton",true)
+    self:ClearBinding(nil,f,"RightButton",true)
+  end
+end
+
+
+--[[
   Registers a target frame by creating a click-binding frame and putting that frame in the list of 
   registered frames, which can then be all shown/hidden as one unit.
 
@@ -162,7 +275,7 @@
   Returns:
   A clickbinder frame.
 ]]
-function ReBound:Register( target )
+function ReBound.prototype:Register( target )
   local f = self:CreateClickBindingFrame(target)
   self.frames[target] = f
   return f
@@ -173,20 +286,29 @@
   Unregisters a target frame by removing it from the internal list. Does nothing to the clickbinding frame.
 
   Arguments:
-  target = the frame whose OnClick handler should no longer be the target of keybinding
+  target = the frame whose OnClick handler should no longer be managed. do NOT pass the clickbinding frame.
 
   Returns:
   nothing.
 ]]
-function ReBound:Unregister( target )
+function ReBound.prototype:Unregister( target )
   self.frames[target] = nil
 end
 
 
 --[[
+  Unregisters all registered frames.
+]]
+function ReBound.prototype:UnregisterAll()
+  self.frames = { }
+end
+
+
+
+--[[
   Shows all the registered click binding frames.
 ]]
-function ReBound:ShowAll()
+function ReBound.prototype:ShowFrames()
   if InCombatLockdown() then
     -- can't set bindings while in combat, so don't bother showing them
     UIErrorsFrame:AddMessage(ERR_NOT_IN_COMBAT)
@@ -201,7 +323,9 @@
 --[[
   Hides all the registered click binding frames.
 ]]
-function ReBound:HideAll()
+function ReBound.prototype:HideFrames()
+  -- because these frames aren't protected, there's no restriction 
+  -- on hiding them while in combat.
   for _, f in pairs(self.frames) do
     f:Hide()
   end
@@ -303,7 +427,7 @@
   Returns:
   A clickbinder frame.
 ]]
-function ReBound:CreateClickBindingFrame( target )
+function ReBound.prototype:CreateClickBindingFrame( target )
   local f = CreateFrame("Button", nil, target)
   f.ReBound = self
   f:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
@@ -324,21 +448,18 @@
 -- library setup
 
 local function activate( self, oldLib, oldDeactivate )
-  -- set initial values
-  self.mode = oldLib and oldLib.mode or "char"
-  self.frames = { }
-
-  self.event = AceLibrary("AceOO-2.0").Class("AceEvent-2.0"):new()
-  self.event:RegisterEvent("PLAYER_REGEN_DISABLED", function() self:HideAll() end)
-
+  -- copy the list of active instances
+  self.instances = { }
+  if oldLib and oldLib.instances then
+    for k,v in pairs(oldLib.instances) do
+      self.instances[k] = v
+    end
+  end
+  
   if oldDeactivate then
     oldDeactivate(oldLib)
   end
 end
 
-local function deactivate( self )
-  self.event:UnregisterEvent("PLAYER_REGEN_DISABLED")
-end
-
-AceLibrary:Register(ReBound, version_major, version_minor, activate, deactivate)
+AceLibrary:Register(ReBound, version_major, version_minor, activate)
 ReBound = nil