changeset 122:a2d2f23137c8

- Rearranged and consolidated some files in modules directory - Added 'classes' directory, moved Bar and Overlay there - Added Button, ActionButton, and GridProxy classes, not in use yet
author Flick <flickerstreak@gmail.com>
date Mon, 23 Feb 2009 18:56:57 +0000
parents fb6c3a642ae3
children 943eed2c7def
files Bindings.lua ReAction.lua ReAction.toc classes/ActionButton.lua classes/Bar.lua classes/Button.lua classes/GridProxy.lua classes/Overlay.lua classes/classes.xml modules/Bar.lua modules/Bindings.lua modules/LDB.lua modules/Overlay.lua modules/modules.xml
diffstat 14 files changed, 2117 insertions(+), 1048 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Bindings.lua	Mon Feb 23 18:56:57 2009 +0000
@@ -0,0 +1,7 @@
+local L = ReAction.L
+local _G = _G
+
+_G["BINDING_HEADER_REACTION"]             = L["ReAction"]
+
+_G["BINDING_NAME_REACTION_TOGGLELOCK"]    = L["Toggle ReAction Bar Lock"]
+_G["BINDING_NAME_REACTION_TOGGLEKEYBIND"] = L["ReAction Keybinding Mode"]
--- a/ReAction.lua	Mon Feb 09 19:02:58 2009 +0000
+++ b/ReAction.lua	Mon Feb 23 18:56:57 2009 +0000
@@ -522,3 +522,36 @@
     StaticPopup_Show("REACTION_KB_WARN")
   end
 end
+
+-- Export ReAction launcher to LibDataBroker-aware displays
+LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject( "ReAction", 
+  {
+    type = "launcher", 
+    icon = "Interface\\Icons\\INV_Qiraj_JewelEncased",
+
+    OnClick = function( frame, button )
+      if not InCombatLockdown() then
+        if IsAltKeyDown() then
+          ReAction:SetKeybindMode( not ReAction:GetKeybindMode() )
+        elseif IsShiftKeyDown() then
+          ReAction:SetConfigMode( not ReAction:GetConfigMode() )
+        elseif button == "RightButton" then
+          ReAction:ShowEditor()
+        else
+          ReAction:ShowConfig()
+        end
+      else
+        ReAction:UserError(L["ReAction: can't configure in combat"])
+      end
+    end,
+
+      -- this isn't included in the 'launcher' type LDB spec but it seems all launcher displays use it
+    OnTooltipShow = function( tooltip )
+      tooltip:AddLine(format("|cffffffff%s|r %s",L["Click"],L["for global configuration"]))
+      tooltip:AddLine(format("|cffffd200%s|r %s",L["Right-click"],L["for bar editor dialog"]))
+      tooltip:AddLine(format("|cff00ff00%s|r %s",L["Shift-click"],L["to unlock bars"]))
+      tooltip:AddLine(format("|cff00cccc%s|r %s",L["Alt-click"],L["for keybind mode"]))
+    end,
+
+  }
+)
--- a/ReAction.toc	Mon Feb 09 19:02:58 2009 +0000
+++ b/ReAction.toc	Mon Feb 23 18:56:57 2009 +0000
@@ -12,5 +12,9 @@
 
 lib\embeds.xml
 locale\locale.xml
+
 ReAction.lua
+bindings.lua
+
+classes\classes.xml
 modules\modules.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/classes/ActionButton.lua	Mon Feb 23 18:56:57 2009 +0000
@@ -0,0 +1,693 @@
+local ReAction = ReAction
+local L = ReAction.L
+local _G = _G
+local CreateFrame = CreateFrame
+local GetBindingKey = GetBindingKey
+local format = string.format
+local IsUsableAction = IsUsableAction
+local IsEquippedAction = IsEquippedAction
+local IsConsumableAction = IsConsumableAction
+local IsStackableAction = IsStackableAction
+local GetActionText = GetActionText
+local GetCVar = GetCVar
+local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor
+local IsCurrentAction = IsCurrentAction
+local IsAutoRepeatAction = IsAutoRepeatAction
+local IsUsableAction = IsUsableAction
+local IsAttackAction = IsAttackAction
+local CooldownFrame_SetTimer = CooldownFrame_SetTimer
+local GetActionCooldown = GetActionCooldown
+local GetActionTexture = GetActionTexture
+local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME
+local TOOLTIP_UPDATE_TIME = TOOLTIP_UPDATE_TIME
+local IsActionInRange = IsActionInRange
+local InCombatLockdown = InCombatLockdown
+local HasAction = HasAction
+
+ReAction:UpdateRevision("$Revision: 154 $")
+
+--
+-- Secure snippets
+-- These are run within the context of the bar's sandbox, as the
+-- buttons themselves do not have their own sandbox.
+--
+local _onstate_mc = -- function(self, stateid, newstate)
+[[
+  local oldMcVehicleState = mcVehicleState
+  mcVehicleState = newstate
+  control:ChildUpdate()
+  if oldMcVehicleState == "vehicle" or mcVehicleState == "vehicle" then
+    control:ChildUpdate("vehicle")
+  end
+]]
+
+local _childupdate = -- function(self, snippetid, message)
+[[
+  local action = nil
+  if (doVehicle and mcVehicleState == "vehicle") or
+     (doMindControl and mcVehicleState == "mc") then
+    local idx = self:GetAttribute("bar-idx")
+    if idx and idx <= 12 then
+      action = 120 + idx
+    else
+      action = 0
+    end
+  elseif page and state and page[state] then
+    action = self:GetAttribute("action-page"..page[state])
+  else
+    action = self:GetAttribute("default-action")
+  end
+
+  self:SetAttribute("action",action)
+  local hasaction = (action > 120) or self:GetAttribute("hasaction-"..action)
+
+  if (self:GetAttribute("showgrid") + self:GetAttribute("showgrid-temp") == 0) and not hasaction then
+    self:Hide()
+  else
+    self:Show()
+  end
+]]
+
+local _childupdate_vehicleExit =  -- function(self, snippetid, message)
+[[
+  local show = (mcVehicleState == "vehicle")
+  if show then
+    self:SetAttribute("type","macro")
+    self:SetAttribute("macrotext","/run VehicleExit()")
+    self:Show()
+  else
+    self:SetAttribute("type","action")
+  end
+  control:CallMethod("ShowVehicleExit",show)
+]]
+
+local _childupdate_showgrid = -- function(self, snippetid, message)
+[[
+  self:SetAttribute("showgrid-temp",message or 0)
+  local count = (message or 0) + (self:GetAttribute("showgrid") or 0)
+  if count == 0 then
+    local action = self:GetAttribute("action")
+    local hasaction = (action > 120) or self:GetAttribute("hasaction-"..action)
+    if hasaction then
+      self:Show()
+    else
+      self:Hide()
+    end
+  else
+    self:Show()
+  end
+]]
+
+local _onDragStart = -- function(self, button, kind, value, ...)
+[[
+  if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then
+    return kind, value, ...
+  else
+    -- don't make any assumptions about hiding on grid show here, as we don't know if the 
+    -- drag gets cancelled later. 
+    return "action", self:GetAttribute("action")
+  end
+]]
+
+local _onReceiveDrag = -- function(self, button, kind, value, ...)
+[[
+  if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then
+    return kind, value, ...
+  else
+    if kind == "spell" or kind == "item" or kind == "macro" then
+      -- assume it's a valid action
+      self:SetAttribute("hasaction-"..self:GetAttribute("action"),true)
+    end
+    return "action", self:GetAttribute("action")
+  end
+]]
+
+--
+-- private
+--
+local eventList = {
+  "PLAYER_REGEN_ENABLED",
+  "PLAYER_ENTERING_WORLD",
+  "ACTIONBAR_PAGE_CHANGED",
+  "ACTIONBAR_SLOT_CHANGED",
+  "UPDATE_BINDINGS",
+  "ACTIONBAR_UPDATE_STATE",
+  "ACTIONBAR_UPDATE_USABLE",
+  "ACTIONBAR_UPDATE_COOLDOWN",
+  "UPDATE_INVENTORY_ALERTS",
+  "PLAYER_TARGET_CHANGED",
+  "TRADE_SKILL_SHOW",
+  "TRADE_SKILL_CLOSE",
+  "PLAYER_ENTER_COMBAT",
+  "PLAYER_LEAVE_COMBAT",
+  "START_AUTOREPEAT_SPELL",
+  "STOP_AUTOREPEAT_SPELL",
+  "UNIT_ENTERED_VEHICLE",
+  "UNIT_EXITED_VEHICLE",
+  "COMPANION_UPDATE",
+}
+
+--
+-- Action Button class
+--
+local Super = ReAction.Button
+local Action = setmetatable( { }, { __index = Super } )
+ReAction.Button.Action = Action
+
+function Action:New( idx, config, bar, idHint )
+  self = Super.New(
+    self,
+    format("ReAction_%s_Action_%d",bar:GetName(),idx), 
+    config, 
+    bar, 
+    idx, 
+    "ActionButtonTemplate, SecureActionButtonTemplate" )
+
+  local f = self:GetFrame()
+  local barFrame = bar:GetFrame()
+
+  local frames = { }
+  self.frames = frames
+  frames.icon          = _G[name.."Icon"]
+  frames.flash         = _G[name.."Flash"]
+  frames.hotkey        = _G[name.."HotKey"]
+  frames.count         = _G[name.."Count"]
+  frames.name          = _G[name.."Name"]
+  frames.border        = _G[name.."Border"]
+  frames.cooldown      = _G[name.."Cooldown"]
+  frames.normalTexture = _G[name.."NormalTexture"]
+
+  self.hotkey = frames.hotkey -- alias for Button methods
+  self.border = frames.border -- alias for Button methods
+
+  self.rangeTimer = TOOLTIP_UPDATE_TIME
+
+  -- set up the base action ID
+  self:SetActionIDPool("action",120)
+  config.actionID = self:AcquireActionID(config.actionID, idHint)
+  self.actionID = config.actionID
+  self.nPages = 1
+
+  -- attribute setup
+  f:SetAttribute("type","action")
+  f:SetAttribute("checkselfcast", true)
+  f:SetAttribute("checkfocuscast", true)
+  f:SetAttribute("useparent-unit", true)
+  f:SetAttribute("action", config.actionID)
+  f:SetAttribute("default-action", config.actionID)
+  f:SetAttribute("showgrid",0)
+  f:SetAttribute("showgrid-temp",0)
+  f:SetAttribute("bar-idx",idx)
+
+  -- non secure scripts
+  f:SetScript("OnEvent", function(frame, ...) self:OnEvent(...) end)
+  f:SetScript("OnEnter", function(frame) self:OnEnter() end)
+  f:SetScript("OnLeave", function(frame) self:OnLeave() end)
+  f:SetScript("OnAttributeChanged", function(frame, attr, value) self:OnAttributeChanged(attr, value) end)
+  f:SetScript("PostClick", function(frame, ...) self:PostClick(...) end)
+  f:SetScript("OnUpdate", function(frame, elapsed) self:OnUpdate(elapsed) end)
+  f:SetScript("OnDragStart", function(frame) self:OnDragStart() end)
+  f:SetScript("OnReceiveDrag", function(frame), self:OnReceiveDrag() end)
+
+  -- secure handlers
+  f:SetAttribute("_childupate", _childupdate)
+  f:SetAttribute("_childupdate-showgrid",_childupdate_showgrid)
+  barFrame:WrapScript(f, "OnDragStart", _onDragStart)
+  barFrame:WrapScript(f, "OnReceiveDrag", _onReceiveDrag)
+  if idx == 7 then
+    -- install vehicle-exit button on 7th button (only)
+    f:SetAttribute("_childupdate-vehicle", _childupdate_vehicleExit)
+    local button = self
+    function barFrame:ShowVehicleExit(show)
+      button:ShowVehicleExit(show)
+    end
+  end
+
+  -- event registration
+  f:RegisterForDrag("LeftButton", "RightButton")
+  f:RegisterForClicks("AnyUp")
+  for _, evt in pairs(eventList) do
+    f:RegisterEvent(evt)
+  end
+
+  -- attach to skinner
+  bar:SkinButton(self)
+
+  -- initial display
+  self:ShowGrid(not barFrame:GetConfig().hideEmpty)
+  if ReAction:GetConfigMode() then
+    self:ShowGrid(true)
+  end
+
+  self:Refresh()
+end
+
+function Action:Destroy()
+  local f = self:GetFrame()
+
+  f:UnregisterAllEvents()
+
+  f:SetAttribute("_childupdate-vehicle",nil)
+
+  self:ReleaseActionID(config.actionID)
+  if self.config.pageactions then
+    for _, id in ipairs(self.config.pageactions) do
+      self:ReleaseActionID(id)
+    end
+  end
+  
+  Super:Destroy()
+end
+
+function Action:Refresh()
+  self.bar:PlaceButton(self, 36, 36)
+  self:RefreshPages()
+  self:UpdateAction()
+end
+
+function Action:UpdateAll()
+  self:UpdateActionIDLabel(ReAction:GetConfigMode())
+  self:UpdateHotkey()
+  self:UpdateShowGrid()
+  self:UpdateIcon()
+  self:UpdateBorder()
+  self:UpdateMacroText()
+  self:UpdateCount()
+  self:UpdateTooltip()
+  self:UpdateCheckedState()
+  self:UpdateUsable()
+  self:UpdateCooldown()
+  self:UpdateFlash()
+end
+
+function Action:UpdateAction()
+  local action = self:GetActionID()
+  if action ~= self.actionID then
+    self.actionID = action
+    self:UpdateAll()
+  end
+end
+
+function Action:UpdateShowGrid()
+  -- this is a little bit complicated because there's no
+  -- secure driver to handle show/hide grid events.
+  if InCombatLockdown() then
+    self.showgridPending = true  -- handle after combat
+  else
+    self.showgridPending = false
+    -- check if each action has an action or not, and flag an attribute
+    -- so that the showgrid secure handler can make decisions accordingly
+    local f = self:GetFrame()
+    f:SetAttribute("hasaction-"..self.config.actionID, HasAction(self.config.actionID))
+    for i = 1, self.nPages do
+      f:SetAttribute("hasaction-"..self.config.pageactions[i], HasAction(self.config.pageactions[i])
+    end
+    -- the following is an out-of-combat show/hide to supplement the secure
+    -- handling and clean up after it when it guesses
+    if HasAction(self.actionID) then
+      f:Show()
+    else
+      f:Hide()
+    end
+  end
+end
+
+function Action:UpdateIcon()
+  local action = self.actionID
+  local texture = GetActionTexture(action)
+  local icon = self.frames.icon
+  local hotkey = self.frames.hotkey
+  local f = self:GetFrame()
+  if texture then
+    icon:SetTexture(texture)
+    icon:Show()
+    self.rangeTimer = -1
+    f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
+    hotkey:SetVertexColor(1.0, 1.0, 1.0)
+  else
+    icon:Hide()
+    self.frames.cooldown:Hide()
+    self.rangeTimer = nil
+    f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
+    hotkey:SetVertexColor(0.6, 0.6, 0.6)
+    end
+  end
+end
+
+function Action:UpdateBorder()
+  local action = self.actionID
+  if ReAction:GetKeybindMode() then
+    self:UpdateKeybindModeDisplay(true)
+  elseif IsEquippedAction(action) then
+    self.frames.border:SetVertexColor(0, 1.0, 0, 0.35)
+    self.frames.border:Show()
+  else
+    self.frames.border:Hide()
+  end
+end
+
+function Action:UpdateMacroText()
+  local action = self.actionID
+  if not IsConsumableAction(action) and not IsStackableAction(action) then
+    self.frames.name:SetText(GetActionText(action))
+  else
+    self.frames.name:SetText("")
+  end
+end
+
+function Action:UpdateCount()
+  local action = self.actionID
+  if IsConsumableAction(action) or IsStackableAction(action) then
+    self.frames.count:SetText(GetActionCount(action))
+  else
+    self.frames.count:SetText("")
+  end
+end
+
+function Action:UpdateTooltip()
+  local f = self:GetFrame()
+  if GameTooltip:GetOwner() == f then
+    self:SetTooltip()
+  end
+end
+
+function Action:SetTooltip()
+  local f = self:GetFrame()
+  if GetCVar("UberTooltips") == "1" then
+    GameTooltip_SetDefaultAnchor(GameTooltip, f)
+  else
+    GameTooltip:SetOwner(f)
+  end
+  GameTooltip:SetAction(self.actionID)
+end
+
+function Action:UpdateCheckedState()
+  local action = self.actionID
+  if IsCurrentAction(action) or IsAutoRepeatAction(action) then
+    self:GetFrame():SetChecked(1)
+  else
+    self:GetFrame():SetChecked(0)
+  end
+end
+
+function Action:UpdateUsable()
+  local isUsable, notEnoughMana = IsUsableAction(self.actionID)
+  if isUsable then
+    self.frames.icon:SetVertexColor(1.0, 1.0, 1.0)
+    self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
+  elseif notEnoughMana then
+    self.frames.icon:SetVertexColor(0.5, 0.5, 1.0)
+    self.frames.normalTexture:SetVertexColor(0.5, 0.5, 1.0)
+  else
+    self.frames.icon:SetVertexColor(0.4, 0.4, 0.4)
+    self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
+  end
+end
+
+function Action:UpdateCooldown()
+  CooldownFrame_SetTimer(self.frames.cooldown, GetActionCooldown(self.actionID))
+end
+
+function Action:UpdateFlash()
+  local action = self.actionID
+  self:SetFlash( (IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action) )
+end
+
+function Action:SetFlash(flash)
+  if self.flashing ~= flash then
+    self.flashing = flash
+    self.flashtime = 0
+    if not flash then
+      self.frames.flash:Hide()
+    end
+    self:UpdateCheckedState()
+  end
+end
+
+function Action:RunFlash(elapsed)
+  if self.flashing then
+    local flashtime = self.flashtime - elapsed
+    self.flashtime = flashtime
+    if flashtime <= 0 then
+      local overtime = -flashtime
+      if overtime >= ATTACK_BUTTON_FLASH_TIME then
+        overtime = 0
+      end
+      flashtime = ATTACK_BUTTON_FLASH_TIME - overtime
+      local flash = self.frames.flash
+      if flash:IsShown() then
+        flash:Hide()
+      else
+        flash:Show()
+      end
+    end
+  end
+end
+
+function Action:RunRangeFinder(elapsed)
+  local rangeTimer = self.rangeTimer
+  if rangeTimer then
+    rangeTimer = rangeTimer - elapsed
+    self.rangeTimer = rangeTimer
+    if rangeTimer <= 0 then
+      if IsActionInRange(self.actionID) == 0 then
+        self.frames.icon:SetVertexColor(1.0,0.1,0.1)
+      else
+        self:UpdateUsable()
+      end
+      frame.rangeTimer = TOOLTIP_UPDATE_TIME
+    end
+  end
+end
+
+function Action:GetActionID(page)
+  if page == nil then
+    -- get the effective ID
+    return self:GetFrame():GetAttribute("action")
+  else
+    if page == 1 then
+      return self.config.actionID
+    else
+      return self.config.pageactions and self.config.pageactions[page] or self.config.actionID
+    end
+  end
+end
+
+function Action:SetActionID( id, page )
+  id = tonumber(id)
+  page = tonumber(page)
+  if id == nil or id < 1 or id > 120 then
+    error("Action:SetActionID - invalid action ID")
+  end
+  if page and page ~= 1 then
+    if not self.config.pageactions then
+      self.config.pageactions = { }
+    end
+    self:ReleaseActionID(self.config.pageactions[page])
+    self.config.pageactions[page] = id
+    self:AcquireActionID(self.config.pageactions[page])
+    self.frame:SetAttribute("action-page"..page,id)
+  else
+    self:ReleaseActionID(self.config.actionID)
+    self.config.actionID = id
+    self:AcquireActionID(self.config.actionID)
+    self.frame:SetAttribute("action",id)
+    self.frame:SetAttribute("default-action",id)
+    if self.config.pageactions then
+      self.config.pageactions[1] = id
+      self.frame:SetAttribute("action-page1",id)
+    end
+  end
+end
+
+function Action:RefreshPages( force )
+  local nPages = self.bar:GetConfig().nPages
+  if nPages and (nPages ~= self.nPages or force) then
+    local f = self:GetFrame()
+    local c = self.config.pageactions
+    if nPages > 1 and not c then
+      c = { }
+      self.config.pageactions = c
+    end
+    for i = 1, nPages do
+      if i > 1 then
+        c[i] = self:AcquireActionID(c[i], self.config.actionID + (i-1)*self.bar:GetNumButtons())
+      else
+        c[i] = self.config.actionID  -- page 1 is the same as the base actionID
+      end
+      f:SetAttribute(("action-page%d"):format(i),c[i])
+    end
+    for i = nPages+1, #c do
+      self:ReleaseActionID(c[i])
+      c[i] = nil
+      f:SetAttribute(("action-page%d"):format(i),nil)
+    end
+    self.nPages = nPages
+  end
+end
+
+function Action:SetupBarHeader( bar ) -- call this as a static method
+  local f = bar:GetFrame()
+  local c = bar:GetConfig()
+  f:SetAttribute("mindcontrol",c.mindcontrol)
+  f:SetAttribute("vehicle",c.vehicle)
+  f:Execute(
+    [[
+    doMindControl = self:GetAttribute("mindcontrol")
+    doVehicle = self:GetAttribute("vehicle")
+    control:ChildUpdate()
+    ]])
+
+  f:SetAttribute("_onstate-mc", _onstate_mc)
+  RegisterStateDriver(f, "mc", "[target=vehicle,exists] vehicle; [bonusbar:5] mc; none")
+
+  f:SetAttribute("lockbuttons",c.lockButtons)
+  f:SetAttribute("lockbuttonscombat",c.lockButtonsCombat)
+  f:Execute(
+    [[
+      lockButtons = self:GetAttribute("lockbuttons")
+      lockButtonsCombat = self:GetAttribute("lockbuttonscombat")
+    ]])
+end
+
+
+function Action:ShowVehicleExit(show)
+  local f = self:GetFrame()
+  local tx = f.vehicleExitTexture
+  if show then
+    if not tx then
+      tx = f:CreateTexture(nil,"ARTWORK")
+      tx:SetAllPoints()
+        -- copied from Blizzard/VehicleMenuBar.lua SkinsData
+      tx:SetTexture("Interface\\Vehicles\\UI-Vehicles-Button-Exit-Up")
+      tx:SetTexCoord(0.140625, 0.859375, 0.140625, 0.859375)
+      f.vehicleExitTexture = tx
+    end
+    tx:Show()
+    f.vehicleExitMode = true
+  elseif tx then
+    tx:SetTexCoord(0,1,0,1)
+    tx:Hide()
+    f.vehicleExitMode = false
+  end
+end
+
+function Action:OnEnter( )
+  self:SetTooltip()
+end
+
+function Action:OnLeave( )
+  GameTooltip:Hide()
+end
+
+function Action:OnAttributeChanged( attr, value )
+  self:UpdateAction()
+end
+
+function Action:PostClick( )
+  self:UpdateCheckedState()
+end
+
+function Action:OnUpdate( elapsed )
+  self:RunFlash(elapsed)
+  self:RunRangeFinder(elapsed)
+end
+
+function Action:OnDragStart()
+  self:UpdateCheckedState()
+  self:UpdateFlash()
+end
+
+function Action:OnReceiveDrag()
+  self:UpdateCheckedState()
+  self:UpdateFlash()
+end
+
+function Action:OnEvent(event, ...)
+  if self[event] then
+    self[event](self, event, ...)
+  end
+end
+
+function Action:ACTIONBAR_SLOT_CHANGED(event, action)
+  if action == 0 or action == self.actionID then
+    self:UpdateAction()
+  end
+end
+
+function Action:PLAYER_ENTERING_WORLD()
+  self:UpdateAction()
+end
+
+function Action:ACTIONBAR_PAGE_CHANGED()
+  self:UpdateAction()
+end
+
+function Action:UPDATE_BONUS_ACTIONBAR()
+  self:UpdateAction()
+end
+
+function Action:UPDATE_BINDINGS()
+  self:UpdateHotkey()
+end
+
+function Action:PLAYER_TARGET_CHANGED()
+  self.rangeTimer = -1
+end
+
+function Action:ACTIONBAR_UPDATE_STATE()
+  self:UpdateCheckedState()
+end
+Action.TRADE_SKILL_SHOW = Action.ACTIONBAR_UPDATE_STATE
+Action.TRADE_SKILL_CLOSE = Action.ACTIONBAR_UPDATE_STATE
+
+function Action:UNIT_ENTERED_VEHICLE(event,unit)
+  if unit == "player" then
+    self:UpdateCheckedState()
+  end
+end
+Action.UNIT_EXITED_VEHICLE = Action.UNIT_ENTERED_VEHICLE
+
+function Action:COMPANION_UPDATE(event,unit)
+  if unit == "mount" then
+    self:UpdateCheckedState()
+  end
+end
+
+function Action:ACTIONBAR_UPDATE_USABLE()
+  self:UpdateUsable()
+end
+
+function Action:ACTIONBAR_UPDATE_COOLDOWN()
+  self:UpdateCooldown()
+end
+
+function Action:PLAYER_ENTER_COMBAT()
+  if IsAttackAction(self.actionID) then
+    self:SetFlash(true)
+  end
+end
+
+function Action:PLAYER_LEAVE_COMBAT()
+  if IsAttackAction(self.actionID) then
+    self:SetFlash(false)
+  end
+end
+
+function Action:START_AUTOREPEAT_SPELL()
+  if IsAutoRepeatAction(self.actionID) then
+    self:SetFlash(true)
+  end
+end
+
+function Action:STOP_AUTOREPEAT_SPELL()
+  if not IsAttackAction(self.actionID) then
+    self:SetFlash(false)
+  end
+end
+
+function Action:PLAYER_REGEN_ENABLED()
+  if self.showgridPending then
+    self:UpdateShowGrid()
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/classes/Bar.lua	Mon Feb 23 18:56:57 2009 +0000
@@ -0,0 +1,259 @@
+local ReAction = ReAction
+local L = ReAction.L
+local _G = _G
+local CreateFrame = CreateFrame
+local floor = math.floor
+local fmod = math.fmod
+local format = string.format
+
+ReAction:UpdateRevision("$Revision$")
+
+local Bar   = { }
+local proto = { __index = Bar }
+local weak  = { __mode = "k" }
+
+ReAction.Bar = Bar -- export to ReAction
+
+function Bar:New( name, config )
+  if type(config) ~= "table" then
+    error("ReAction.Bar: config table required")
+  end
+
+  -- create new self
+  self = setmetatable( 
+    { 
+      config  = config,
+      name    = name,
+      buttons = setmetatable( { }, weak ),
+      width   = config.width or 480,
+      height  = config.height or 40
+    }, 
+    proto )
+  
+  -- The frame type is 'Button' in order to have an OnClick handler. However, the frame itself is
+  -- not mouse-clickable by the user.
+  local parent = config.parent and (ReAction:GetBar(config.parent) or _G[config.parent]) or UIParent
+  local f = CreateFrame("Button", name and format("ReAction-%s",name), parent,
+                        "SecureHandlerStateTemplate, SecureHandlerClickTemplate")
+  f:SetFrameStrata("MEDIUM")
+  f:SetWidth(self.width)
+  f:SetWidth(self.height)
+  f:SetAlpha(config.alpha or 1.0)
+  f:Show()
+  f:EnableMouse(false)
+  f:SetClampedToScreen(true)
+
+  f:SetAttribute("_onstate-showgrid",
+    -- function(self,stateid,newstate)
+    [[
+      control:ChildUpdate(stateid,newstate)
+      control:CallMethod("UpdateShowGrid")
+    ]])
+  f.UpdateShowGrid = function(frame)
+    for button in self:IterateButtons() do
+      button:UpdateShowGrid()
+    end
+  end
+  ReAction.gridProxy:AddFrame(f)
+
+  -- Override the default frame accessor to provide strict read-only access
+  function self:GetFrame()
+    return f
+  end
+
+  self:ApplyAnchor()
+  ReAction.RegisterCallback(self, "OnConfigModeChanged")
+
+  return self
+end
+
+function Bar:Destroy()
+  local f = self:GetFrame()
+  f:UnregisterAllEvents()
+  ReAction.UnregisterAllCallbacks(self)
+  ReAction.gridProxy:RemoveFrame(f)
+  f:Hide()
+  f:SetParent(UIParent)
+  f:ClearAllPoints()
+end
+
+function Bar:OnConfigModeChanged(event, mode)
+  self:ShowControls(mode) -- Bar:ShowControls() defined in Overlay.lua
+end
+
+function Bar:ApplyAnchor()
+  local f = self:GetFrame()
+  local c = self.config
+  local p = c.point
+
+  f:SetWidth(c.width)
+  f:SetHeight(c.height)
+  f:ClearAllPoints()
+  
+  if p then
+    local a = f:GetParent()
+    if c.anchor then
+      local bar = ReAction:GetBar(c.anchor)
+      if bar then
+        a = bar:GetFrame()
+      else
+        a = _G[c.anchor]
+      end
+    end
+    local fr = a or f:GetParent()
+    f:SetPoint(p, a or f:GetParent(), c.relpoint, c.x or 0, c.y or 0)
+  else
+    f:SetPoint("CENTER")
+  end
+end
+
+function Bar:SetAnchor(point, frame, relativePoint, x, y)
+  local c = self.config
+  c.point = point or c.point
+  c.anchor = frame or c.anchor
+  c.relpoint = relativePoint or c.relpoint
+  c.x = x or c.x
+  c.y = y or c.y
+  self:ApplyAnchor()
+  ReAction:RefreshBar(self)
+end
+
+function Bar:GetAnchor()
+  local c = self.config
+  return (c.point or "CENTER"), 
+         (c.anchor or self:GetFrame():GetParent():GetName()), 
+         (c.relpoint or c.point or "CENTER"), 
+         (c.x or 0), 
+         (c.y or 0)
+end
+
+function Bar:GetSize()
+  local f = self:GetFrame()
+  return f:GetWidth(), f:GetHeight()
+end
+
+function Bar:SetSize(w,h)
+  local f = self:GetFrame()
+  self.config.width = w
+  self.config.height = h
+  f:SetWidth(w)
+  f:SetHeight(h)
+end
+
+function Bar:GetButtonSize()
+  local w = self.config.btnWidth or 32
+  local h = self.config.btnHeight or 32
+  -- TODO: get from modules?
+  return w,h
+end
+
+function Bar:SetButtonSize(w,h)
+  if w > 0 and h > 0 then
+    self.config.btnWidth = w
+    self.config.btnHeight = h
+  end
+  ReAction:RefreshBar(self)
+end
+
+function Bar:GetButtonGrid()
+  local cfg = self.config
+  local r = cfg.btnRows or 1
+  local c = cfg.btnColumns or 1
+  local s = cfg.spacing or 4
+  return r,c,s
+end
+
+function Bar:GetNumButtons()
+  local r,c = self:GetButtonGrid()
+  return r*c
+end
+
+function Bar:SetButtonGrid(r,c,s)
+  if r > 0 and c > 0 and s > 0 then
+    local cfg = self.config
+    cfg.btnRows = r
+    cfg.btnColumns = c
+    cfg.spacing = s
+  end
+  ReAction:RefreshBar(self)
+end
+
+function Bar:ClipNButtons( n )
+  local cfg = self.config
+  local r = cfg.btnRows or 1
+  local c = cfg.btnColumns or 1
+
+  cfg.btnRows = ceil(n/c)
+  cfg.btnColumns = min(n,c)
+end
+
+function Bar:GetName()
+  return self.name
+end
+
+function Bar:GetFrame()
+  -- this method is included for documentation purposes. It is overridden
+  -- for each object in the :New() method.
+  error("Invalid Bar object: used without initialization")
+end
+
+-- only ReAction:RenameBar() should call this function. Calling from any other
+-- context will desync the bar list in the ReAction class.
+function Bar:SetName(name)
+  self.name = name
+  self:SetLabel(self.name) -- Bar:SetLabel() defined in Overlay.lua
+end
+
+function Bar:GetAlpha()
+  return self.config.alpha or 1.0
+end
+
+function Bar:SetAlpha(value)
+  self.config.alpha = value
+  self:GetFrame():SetAlpha(value or 1.0)
+  ReAction:RefreshBar(self)
+end
+
+function Bar:AddButton(idx, button)
+  local f = self:GetFrame()
+
+  -- store in a weak reverse-index array
+  self.buttons[button] = idx
+
+  -- Store a properly wrapped reference to the child frame as an attribute 
+  -- (accessible via "frameref-btn#")
+  f:SetFrameRef(format("btn%d",idx), button:GetFrame())
+end
+
+function Bar:RemoveButton(button)
+  local idx = self.buttons[button]
+  if idx then
+    self:GetFrame():SetAttribute(format("frameref-btn%d",idx),nil)
+    self.buttons[button] = nil
+  end
+end
+
+-- iterator returns button, idx and does NOT iterate in index order
+function Bar:IterateButtons()
+  return pairs(self.buttons)
+end
+
+function Bar:PlaceButton(button, baseW, baseH)
+  local idx = self.buttons[button]
+  if idx then 
+    local r, c, s = self:GetButtonGrid()
+    local bh, bw = self:GetButtonSize()
+    local row, col = floor((idx-1)/c), fmod((idx-1),c) -- zero-based
+    local x, y = col*bw + (col+0.5)*s, -(row*bh + (row+0.5)*s)
+    local scale = bw/baseW
+    local b = button:GetFrame()
+
+    b:ClearAllPoints()
+    b:SetPoint("TOPLEFT",x/scale,y/scale)
+    b:SetScale(scale)
+  end
+end
+
+function Bar:SkinButton()
+  -- does nothing by default
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/classes/Button.lua	Mon Feb 23 18:56:57 2009 +0000
@@ -0,0 +1,277 @@
+--[[
+  ReAction Button base class
+--]]
+
+-- local imports
+local ReAction = ReAction
+local L = ReAction.L
+local _G = _G
+local CreateFrame = CreateFrame
+local GetBindingKey = GetBindingKey
+local format = string.format
+
+ReAction:UpdateRevision("$Revision: 154 $")
+
+-- libraries
+local KB = LibStub("LibKeyBound-1.0")
+local LBF = LibStub("LibButtonFacade",true) -- optional
+
+-- private
+local trash = CreateFrame("Frame")
+local frameList = { }
+local idPools = { }
+
+local function kb_onEnter( frame )
+  KB:Set(frame)
+end
+
+-- Button class
+local Button = { } 
+
+ReAction.Button = Button -- export to ReAction
+
+function Button:New( name, config, bar, idx, inherits, buttonType )
+  buttonType = buttonType or "CheckButton"
+
+  -- create new self
+  self = setmetatable( 
+    { 
+      bar = bar,
+      idx = idx,
+      config = config,
+      name = name,
+    }, 
+    { __index = self } )
+
+  -- have to recycle frames with the same name: CreateFrame() doesn't overwrite
+  -- existing globals. Can't set to nil in the global because it's then tainted.
+  -- Caller is responsible for ensuring global uniqueness of names.
+  local f = name and frameList[name]
+  if f then
+    f:SetParent(bar:GetFrame())
+  else
+    f = CreateFrame(buttonType, name, bar:GetFrame(), inherits)
+    if name then
+      frameList[name] = f
+    end
+  end
+
+  self.frame = f
+
+  if config then
+    config.name = name
+  end
+
+  -- install LibKeyBound handlers onto frame
+  function f:GetActionName()
+    return format("%s:%s", bar:GetName(), idx)
+  end
+
+  local clickBinding = format("CLICK %s:LeftButton", name)
+  function f:GetHotkey()
+    return KB:ToShortKey(GetBindingKey(clickBinding))
+  end
+
+  return self
+end
+
+function Button:Destroy()
+  local f = self.frame
+  gridProxy:RemoveGridFrame(f)
+  f:Hide()
+  f:SetParent(trash)
+  f:ClearAllPoints()
+end
+
+function Button:GetFrame()
+  return self.frame
+end
+
+function Button:GetName()
+  return self.name
+end
+
+function Button:GetConfig()
+  return self.config
+end
+
+function Button:GetActionID()
+  -- derived classes should override this
+  return nil
+end
+
+function Button:SetActionIDPool( poolID, maxID )
+  self.actionPoolID = poolID
+  self.actionMaxID = maxID
+end
+
+function Button:AcquireActionID( id, hint, unique )
+  local poolID = self.actionPoolID
+  local maxID = self.actionMaxID
+  if not poolID or not maxID then
+    error("AcquireActionID: must setup pool first with SetActionIDPool")
+  end
+  local pool = pools[poolID]
+  if not pool then
+    pool = { nWraps = 0, useCount = { } }
+    for i = 1, maxID do
+      pool.useCount[i] = 0
+    end
+    pools[poolID] = pool
+  end
+  local useCount = pool.useCount
+  if id == nil then
+    repeat
+      local nWraps = pool.nWraps
+      if useCount[hint] == nil or useCount[hint] == nWraps then
+        id = hint
+      else
+        local start = hint or 1
+        for i = start, maxID do
+          if useCount[i] == nil or useCount[i] == nWraps then
+            id = i
+            break
+          end
+        end
+        if not id then
+          for i = 1, start do
+            if useCount[i] == nil or useCount[i] == nWraps then
+              id = i
+              break
+            end
+          end
+        end
+      end
+      if id == nil then
+        if unique then
+          return nil
+        end
+        pool.nWraps = nWraps + 1
+      end
+    until id 
+  end
+  useCount[id] = (useCount[id] or 0) + 1
+  return id
+end
+
+function Button:ReleaseActionID( id )
+  local poolID = self.actionPoolID
+  if not poolID  then
+    error("ReleaseActionID: must setup pool first with SetActionIDPool")
+  end
+  local pool = pools[poolID]
+  if pool and id and pool.useCount[id] then
+    pool.useCount[id] = pool.useCount[id] - 1
+    pool.nWraps = min(pool.useCount[id], pool.nWraps)
+  end
+end
+
+function Button:Refresh()
+  self.bar:PlaceButton( self, self.frame:GetWidth(), self.frame:GetHeight() )
+end
+
+function Button:SetKeybindMode( mode )
+  local f = self.frame
+  if mode then
+    self.oldOnEnter = f:GetScript("OnEnter")
+    f:SetScript("OnEnter", kb_onEnter)
+  else
+    f:SetScript("OnEnter", self.oldOnEnter)
+    self.oldOnEnter = nil
+  end
+  self:UpdateKeybindModeDisplay( mode )
+end
+
+function Button:UpdateKeybindModeDisplay( mode )
+  self.border = self.border or _G[format("%sBorder",tostring(self:GetName()))]
+  if self.border then
+    if mode then
+      self.border:SetVertexColor(KB:GetColorKeyBoundMode())
+      self.border:Show()
+    else
+      self.border:Hide()
+    end
+  end
+end
+
+function Button:UpdateHotkey( hotkey )
+  hotkey = hotkey or self.hotkey
+  if not hotkey then
+    hotkey = _G[format("%sHotKey", tostring(self:GetName()))]
+    self.hotkey = hotkey
+  end
+  if hotkey then
+    local txt = self.frame:GetHotkey()
+    hotkey:SetText( txt )
+    if txt == nil or txt == "" then
+      hotkey:Hide()
+    else
+      hotkey:Show()
+    end
+  end
+end
+
+function Button:GetActionIDLabel( create )
+  local f = self.frame
+  if not f.actionIDLabel and create then
+    local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
+    label:SetAllPoints()
+    label:SetJustifyH("CENTER")
+    label:SetShadowColor(0,0,0,1)
+    label:SetShadowOffset(2,-2)
+    f.actionIDLabel = label -- store the label with the frame for recycling
+  end
+  return f.actionIDLabel
+end
+
+function Button:UpdateActionIDLabel( show )
+  local label = self:GetActionIDLabel( show )
+  if label then
+    if show then
+      local id = self:GetActionID()
+      if id then
+        label:SetText(tostring(id))
+        label:Show()
+        return
+      end
+    end
+    label:Hide()
+  end
+end
+
+function Button:SetNormalVertexColor( r, g, b, a )
+  if LBF then
+    LBF:SetNormalVertexColor(self.frame, r, g, b, a)
+  else
+    self.frame:GetNormalTexture():SetVertexColor(r,g,b,a)
+  end
+end
+
+function Button:GetNormalVertexColor()
+  if LBF then
+    return LBF:GetNormalVertexColor(self.frame)
+  else
+    return self.frame:GetNormalTexture():GetVertexColor()
+  end
+end
+
+function Button:ShowGrid( show )
+  if not InCombatLockdown() then
+    local f = self.frame
+    local count = f:GetAttribute("showgrid")
+    if show then
+      count = count + 1
+    else
+      count = count - 1
+    end
+    if count < 0 then
+      count = 0
+    end
+    f:SetAttribute("showgrid",count)
+    self:UpdateShowGrid()
+  end
+end
+
+function Button:UpdateShowGrid()
+ -- does nothing by default
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/classes/GridProxy.lua	Mon Feb 23 18:56:57 2009 +0000
@@ -0,0 +1,65 @@
+--
+-- A hack for a ShowGrid secure handler, using a bastardized Blizzard ActionBarButton.
+--
+local gridProxy = { }
+ReAction.gridProxy = gridProxy
+
+local f = CreateFrame("CheckButton",nil,UIParent,"ActionBarButtonTemplate, SecureHandlerAttributeTemplate")
+  -- SecureHandlerAttributeTemplate overwrites the onAttributeChanged handler, as it's last in the list
+f:UnregisterAllEvents()
+f:SetScript("OnEnter",nil)
+f:SetScript("OnLeave",nil)
+f:SetScript("PostClick",nil)
+f:SetScript("OnDragStart",nil)
+f:SetScript("OnReceiveDrag",nil)
+f:SetScript("OnUpdate",nil)
+f:EnableMouse(false)
+for _, child in ipairs({f:GetChildren()}) do
+  child:Hide()
+end
+for _, region in ipairs({f:GetRegions()}) do
+  region:Hide()
+end
+f:SetPoint("TOPLEFT")
+f:Hide()
+
+-- The existing onEvent handler will set the 'showgrid' attribute
+-- on this frame. Re-register for those events, but don't touch the
+-- onEvent handler, to keep it secure.
+f:RegisterEvent("ACTIONBAR_SHOWGRID");
+f:RegisterEvent("ACTIONBAR_HIDEGRID");
+
+f:Execute(
+  [[
+    frames = newtable()
+  ]])
+
+-- shuttle 'showgrid' to the registered frames via state-showgrid attribute
+f:SetAttribute("_onattributechanged", 
+  -- function _onattributechanged(self,name,value)
+  [[
+    if name == "showgrid" then
+      for _, f in pairs(frames) do
+        f:SetAttribute("state-showgrid",value)
+      end
+    end
+  ]])
+
+function gridProxy:AddFrame(frame)
+  f:SetFrameRef("add",frame)
+  f:SetAttribute("frame-add-id",frame:GetName())
+  f:Execute(
+    [[
+      frames[self:GetAttribute("frame-add-id")] = self:GetFrameRef("add")
+    ]])
+end
+
+function gridProxy:RemoveFrame(frame)
+  f:SetAttribute("frame-remove-id",frame:GetName())
+  f:Execute(
+    [[
+      frames[self:GetAttribute("frame-remove-id")] = nil
+    ]])
+end
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/classes/Overlay.lua	Mon Feb 23 18:56:57 2009 +0000
@@ -0,0 +1,769 @@
+local ReAction               = ReAction
+local L                      = ReAction.L
+local CreateFrame            = CreateFrame
+local InCombatLockdown       = InCombatLockdown
+local floor                  = math.floor
+local min                    = math.min
+local format                 = string.format
+local GameTooltip            = GameTooltip
+local Bar                    = ReAction.Bar
+local GetSize                = Bar.GetSize
+local SetSize                = Bar.SetSize
+local GetButtonSize          = Bar.GetButtonSize
+local GetButtonGrid          = Bar.GetButtonGrid
+local SetButtonSize          = Bar.SetButtonSize
+local SetButtonGrid          = Bar.SetButtonGrid
+local ApplyAnchor            = Bar.ApplyAnchor
+local GameTooltipTextRight1  = GameTooltipTextRight1
+local GameTooltipTextRight2  = GameTooltipTextRight2
+local GameTooltipTextRight3  = GameTooltipTextRight3
+
+local KB = LibStub("LibKeyBound-1.0")
+
+ReAction:UpdateRevision("$Revision$")
+
+
+--
+-- Wrap some of the bar manipulators to make them state-aware
+--
+local function SetAnchor( bar, point, frame, relPoint, x, y )
+  local state = bar:GetState()
+  if state then
+    local anchorstate = bar:GetStateProperty(state, "anchorEnable")
+    if anchorstate then
+      bar:SetStateProperty(state, "anchorFrame", frame)
+      bar:SetStateProperty(state, "anchorPoint", point)
+      bar:SetStateProperty(state, "anchorRelPoint", relPoint)
+      bar:SetStateProperty(state, "anchorX", x or 0)
+      bar:SetStateProperty(state, "anchorY", y or 0)
+      bar:SetAnchor(bar:GetAnchor())
+      return
+    end
+  end
+  bar:SetAnchor(point, frame, relPoint, x, y)
+end
+
+local function GetStateScale( bar )
+  local state = bar:GetState()
+  if state and bar:GetStateProperty(state, "enableScale") then
+    return bar:GetStateProperty(state, "scale")
+  end
+end
+
+local function SetStateScale( bar, scale )
+  local state = bar:GetState()
+  if state and bar:GetStateProperty(state, "enableScale") then
+    bar:SetStateProperty(state, "scale", scale)
+  end
+end
+
+
+--
+-- Bar config overlay
+--
+
+local function GetNormalTextColor()
+  return 1.0, 1.0, 1.0, 1.0
+end
+
+local function GetAnchoredTextColor()
+  return 1.0, 1.0, 1.0, 1.0
+end
+
+local function GetNormalBgColor()
+  return 0.7, 0.7, 1.0, 0.3
+end
+
+local function GetAnchoredBgColor()
+  return 0.9, 0.2, 0.7, 0.3
+end
+
+local function StoreSize(bar)
+  local f = bar:GetFrame()
+  SetSize( bar, f:GetWidth(), f:GetHeight() )
+end
+
+local function StoreExtents(bar)
+  local f = bar:GetFrame()
+  local p, fr, rp, x, y = f:GetPoint(1)
+  fr = fr and fr:GetName() or "UIParent"
+  SetAnchor( bar, p, fr, rp, x, y )
+  SetSize( bar, f:GetWidth(), f:GetHeight() )
+end
+
+local function RecomputeButtonSize(bar)
+  local w, h = GetSize(bar)
+  local bw, bh = GetButtonSize(bar)
+  local r, c, s = GetButtonGrid(bar)
+
+  local scaleW = (floor(w/c) - s) / bw
+  local scaleH = (floor(h/r) - s) / bh
+  local scale = min(scaleW, scaleH)
+
+  SetButtonSize(bar, scale * bw, scale * bh, s)
+end
+
+local function ComputeBarScale(bar)
+  local w, h = bar.controlFrame:GetWidth() - 8, bar.controlFrame:GetHeight() - 8
+  local bw, bh = GetButtonSize(bar)
+  local r, c, s = GetButtonGrid(bar)
+
+  local scaleW = w / (c*(bw+s))
+  local scaleH = h / (r*(bh+s))
+  local scale = min(scaleW, scaleH)
+
+  if scale > 2.5 then
+    scale = 2.5
+  elseif scale < 0.25 then
+    scale = 0.25
+  end
+
+  return scale
+end
+
+local function RecomputeButtonSpacing(bar)
+  local w, h = GetSize(bar)
+  local bw, bh = GetButtonSize(bar)
+  local r, c, s = GetButtonGrid(bar)
+
+  SetButtonGrid(bar,r,c,min(floor(w/c) - bw, floor(h/r) - bh))
+end
+
+local function RecomputeGrid(bar)
+  local w, h = GetSize(bar)
+  local bw, bh = GetButtonSize(bar)
+  local r, c, s = GetButtonGrid(bar)
+
+  SetButtonGrid(bar, floor(h/(bh+s)), floor(w/(bw+s)), s)
+end
+
+local function ClampToButtons(bar)
+  local bw, bh = GetButtonSize(bar)
+  local r, c, s = GetButtonGrid(bar)
+  SetSize(bar, (bw+s)*c + 1, (bh+s)*r + 1)
+end
+
+local function HideGameTooltip()
+  GameTooltip:Hide()
+end
+
+local anchorInside  = { inside = true }
+local anchorOutside = { outside = true }
+local edges = { "BOTTOM", "TOP", "LEFT", "RIGHT" }
+local oppositeEdges = {
+  TOP = "BOTTOM",
+  BOTTOM = "TOP",
+  LEFT = "RIGHT",
+  RIGHT = "LEFT"
+}
+local pointsOnEdge = {
+  BOTTOM = { "BOTTOM", "BOTTOMLEFT",  "BOTTOMRIGHT",  },
+  TOP    = { "TOP",    "TOPLEFT",     "TOPRIGHT",     },
+  RIGHT  = { "RIGHT",  "BOTTOMRIGHT", "TOPRIGHT",     },
+  LEFT   = { "LEFT",   "BOTTOMLEFT",  "TOPLEFT",      },
+}
+local edgeSelector = {
+  BOTTOM = 1,  -- select x of x,y
+  TOP    = 1,  -- select x of x,y
+  LEFT   = 2,  -- select y of x,y
+  RIGHT  = 2,  -- select y of x,y  
+}
+local snapPoints = {
+  [anchorOutside] = {
+    BOTTOMLEFT  = {"BOTTOMRIGHT","TOPLEFT","TOPRIGHT"},
+    BOTTOM      = {"TOP"},
+    BOTTOMRIGHT = {"BOTTOMLEFT","TOPRIGHT","TOPLEFT"},
+    RIGHT       = {"LEFT"},
+    TOPRIGHT    = {"TOPLEFT","BOTTOMRIGHT","BOTTOMLEFT"},
+    TOP         = {"BOTTOM"},
+    TOPLEFT     = {"TOPRIGHT","BOTTOMLEFT","BOTTOMRIGHT"},
+    LEFT        = {"RIGHT"},
+    CENTER      = {"CENTER"}
+  },
+  [anchorInside] = {
+    BOTTOMLEFT  = {"BOTTOMLEFT"},
+    BOTTOM      = {"BOTTOM"},
+    BOTTOMRIGHT = {"BOTTOMRIGHT"},
+    RIGHT       = {"RIGHT"},
+    TOPRIGHT    = {"TOPRIGHT"},
+    TOP         = {"TOP"},
+    TOPLEFT     = {"TOPLEFT"},
+    LEFT        = {"LEFT"},
+    CENTER      = {"CENTER"}
+  }
+}
+local insidePointOffsetFuncs = {
+  BOTTOMLEFT  = function(x, y) return x, y end,
+  BOTTOM      = function(x, y) return 0, y end,
+  BOTTOMRIGHT = function(x, y) return -x, y end,
+  RIGHT       = function(x, y) return -x, 0 end,
+  TOPRIGHT    = function(x, y) return -x, -y end,
+  TOP         = function(x, y) return 0, -y end,
+  TOPLEFT     = function(x, y) return x, -y end,
+  LEFT        = function(x, y) return x, 0 end,
+  CENTER      = function(x, y) return x, y end,
+}
+local pointCoordFuncs = {
+  BOTTOMLEFT  = function(f) return f:GetLeft(),  f:GetBottom() end,
+  BOTTOM      = function(f) return nil,          f:GetBottom() end,
+  BOTTOMRIGHT = function(f) return f:GetRight(), f:GetBottom() end,
+  RIGHT       = function(f) return f:GetRight(), nil end,
+  TOPRIGHT    = function(f) return f:GetRight(), f:GetTop() end,
+  TOP         = function(f) return nil,          f:GetTop() end,
+  TOPLEFT     = function(f) return f:GetLeft(),  f:GetTop() end,
+  LEFT        = function(f) return f:GetLeft(),  nil end,
+  CENTER      = function(f) return f:GetCenter() end,
+}
+local edgeBoundsFuncs = {
+  BOTTOM = function(f) return f:GetLeft(), f:GetRight() end,
+  LEFT   = function(f) return f:GetBottom(), f:GetTop() end
+}
+edgeBoundsFuncs.TOP   = edgeBoundsFuncs.BOTTOM
+edgeBoundsFuncs.RIGHT = edgeBoundsFuncs.LEFT
+local cornerTexCoords = {
+              -- ULx, ULy, LLx, LLy, URx, URy, LRx, LRy
+  TOPLEFT     = { 1,   1,   1,   0,   0,   1,   0,   0 },
+  TOPRIGHT    = { 1,   0,   0,   0,   1,   1,   0,   1 },
+  BOTTOMLEFT  = { 0,   1,   1,   1,   0,   0,   1,   0 },
+  BOTTOMRIGHT = { 0,   0,   0,   1,   1,   0,   1,   1 },
+}
+
+-- Returns absolute coordinates x,y of the named point 'p' of frame 'f'
+local function GetPointCoords( f, p )
+  local x, y = pointCoordFuncs[p](f)
+  if not(x and y) then
+    local cx, cy = f:GetCenter()
+    x = x or cx
+    y = y or cy
+  end
+  return x, y
+end
+
+
+-- Returns true if frame 'f1' can be anchored to frame 'f2'
+local function CheckAnchorable( f1, f2 )
+  -- can't anchor a frame to itself or to nil
+  if f1 == f2 or f2 == nil then
+    return false
+  end
+  
+  -- can always anchor to UIParent
+  if f2 == UIParent then
+    return true
+  end
+  
+  -- also can't do circular anchoring of frames 
+  -- walk the anchor chain, which generally shouldn't be that expensive
+  -- (who nests draggables that deep anyway?)
+  for i = 1, f2:GetNumPoints() do
+    local _, f = f2:GetPoint(i)
+    if not f then f = f2:GetParent() end
+    return CheckAnchorable(f1,f)
+  end
+  
+  return true
+end
+
+-- Returns true if frames f1 and f2 specified edges overlap
+local function CheckEdgeOverlap( f1, f2, e )
+  local l1, u1 = edgeBoundsFuncs[e](f1)
+  local l2, u2 = edgeBoundsFuncs[e](f2)
+  return l1 <= l2 and l2 <= u1 or l2 <= l1 and l1 <= u2
+end
+
+-- Returns true if point p1 on frame f1 overlaps edge e2 on frame f2
+local function CheckPointEdgeOverlap( f1, p1, f2, e2 )
+  local l, u = edgeBoundsFuncs[e2](f2)
+  local x, y = GetPointCoords(f1,p1)
+  x = select(edgeSelector[e2], x, y)
+  return l <= x and x <= u
+end
+
+-- Returns the distance between corresponding edges. It is 
+-- assumed that the passed in edges e1 and e2 are the same or opposites
+local function GetEdgeDistance( f1, f2, e1, e2 )
+  local x1, y1 = pointCoordFuncs[e1](f1)
+  local x2, y2 = pointCoordFuncs[e2](f2)
+  return math.abs((x1 or y1) - (x2 or y2))
+end
+
+local globalSnapTargets = { [UIParent] = anchorInside }
+
+local function GetClosestFrameEdge(f1,f2,a)
+  local dist, edge, opp
+  if f2:IsVisible() and CheckAnchorable(f1,f2) then
+    for _, e in pairs(edges) do
+      local o = a.inside and e or oppositeEdges[e]
+      if CheckEdgeOverlap(f1,f2,e) then
+        local d = GetEdgeDistance(f1, f2, e, o)
+        if not dist or (d < dist) then
+          dist, edge, opp = d, e, o
+        end
+      end
+    end
+  end
+  return dist, edge, opp
+end
+
+local function GetClosestVisibleEdge( f )
+  local r, o, e1, e2
+  local a = anchorOutside
+  for _, b in ReAction:IterateBars() do
+    local d, e, opp = GetClosestFrameEdge(f,b:GetFrame(),a)
+    if d and (not r or d < r) then
+      r, o, e1, e2 = d, b:GetFrame(), e, opp
+    end
+  end
+  for f2, a2 in pairs(globalSnapTargets) do
+    local d, e, opp = GetClosestFrameEdge(f,f2,a2)
+    if d and (not r or d < r) then
+      r, o, e1, e2, a = d, f2, e, opp, a2
+    end
+  end
+  return o, e1, e2, a
+end
+
+local function GetClosestVisiblePoint(f1)
+  local f2, e1, e2, a = GetClosestVisibleEdge(f1)
+  if f2 then
+    local rsq, p, rp, x, y
+    -- iterate pointsOnEdge in order and use < to prefer edge centers to corners
+    for _, p1 in ipairs(pointsOnEdge[e1]) do
+      if CheckPointEdgeOverlap(f1,p1,f2,e2) then
+        for _, p2 in pairs(snapPoints[a][p1]) do
+          local x1, y1 = GetPointCoords(f1,p1)
+          local x2, y2 = GetPointCoords(f2,p2)
+          local dx = x1 - x2
+          local dy = y1 - y2
+          local rsq2 = dx*dx + dy*dy
+          if not rsq or rsq2 < rsq then
+            rsq, p, rp, x, y = rsq2, p1, p2, dx, dy
+          end
+        end
+      end
+    end
+    return f2, p, rp, x, y
+  end
+end
+
+local function GetClosestPointSnapped(f1, rx, ry, xOff, yOff)
+  local o, p, rp, x, y = GetClosestVisiblePoint(f1)
+  local s = false
+
+  local insideOffsetFunc = p and insidePointOffsetFuncs[p]
+  local coordFunc = p and pointCoordFuncs[p]
+  if not insideOffsetFunc or not coordFunc then
+    return
+  end
+  
+  local sx, sy = insideOffsetFunc(xOff or 0, yOff or 0)
+  local xx, yy = coordFunc(f1)
+  if xx and yy then
+    if math.abs(x) <= rx then
+      if math.abs(y) <= ry then
+        x = sx
+        y = sy
+        s = true
+      elseif CheckEdgeOverlap(f1,o,"LEFT") then
+        x = sx
+        s = true
+      end
+    elseif math.abs(y) <= ry and CheckEdgeOverlap(f1,o,"TOP") then
+      y = sy
+      s = true
+    end
+  elseif xx then
+    if math.abs(x) <= rx then
+      x = sx
+      s = true
+      if math.abs(y) <= ry then
+        y = sy
+      end
+    end
+  elseif yy then
+    if math.abs(y) <= ry then
+      y = sy
+      s = true
+      if math.abs(x) <= rx then
+        x = sx
+      end
+    end
+  end
+
+  -- correct for some Lua oddities with doubles
+  if x == -0 then x = 0 end
+  if y == -0 then y = 0 end
+  
+  if s then
+    return o, p, rp, math.floor(x), math.floor(y)
+  end
+end
+
+local function CreateSnapIndicator()
+  local si = CreateFrame("Frame",nil,UIParent)
+  si:SetFrameStrata("HIGH")
+  si:SetHeight(16)
+  si:SetWidth(16)
+  local tex = si:CreateTexture()
+  tex:SetAllPoints()
+  tex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock")
+  tex:SetBlendMode("ADD")
+  tex:SetDrawLayer("OVERLAY")
+  return si
+end
+
+local si1 = CreateSnapIndicator()
+local si2 = CreateSnapIndicator()
+
+local function DisplaySnapIndicator( f, rx, ry, xOff, yOff )
+  local o, p, rp, x, y, snap = GetClosestPointSnapped(f, rx, ry, xOff, yOff)
+  if o then
+    si1:ClearAllPoints()
+    si2:ClearAllPoints()
+    si1:SetPoint("CENTER", f, p, 0, 0)
+    local xx, yy = pointCoordFuncs[rp](o)
+    x = math.abs(x) <=rx and xx and 0 or x
+    y = math.abs(y) <=ry and yy and 0 or y
+    si2:SetPoint("CENTER", o, rp, x, y)
+    si1:Show()
+    si2:Show()
+  else
+    if si1:IsVisible() then
+      si1:Hide()
+      si2:Hide()
+    end
+  end
+  return o, p
+end
+
+local function HideSnapIndicator()
+  if si1:IsVisible() then
+    si1:Hide()
+    si2:Hide()
+  end
+end
+
+local function UpdateLabelString(bar)
+  local label = bar.controlLabelString
+  if label then
+    local name = bar.labelName
+    if name and bar.labelSubtext then
+      name = format("%s (%s)", name, bar.labelSubtext)
+    end
+    label:SetText(name or "")
+  end
+end
+
+local function CreateControls(bar)
+  local f = bar:GetFrame()
+
+  f:SetMovable(true)
+  f:SetResizable(true)
+
+  -- child of UIParent so that alpha and scale doesn't propagate to it
+  local overlay = CreateFrame("Button", nil, UIParent)
+  overlay:EnableMouse(true)
+  overlay:SetFrameLevel(3) -- set it above the buttons
+  overlay:SetPoint("TOPLEFT", f, "TOPLEFT", -4, 4)
+  overlay:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 4, -4)
+  overlay:SetBackdrop({
+    edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+    tile = true,
+    tileSize = 16,
+    edgeSize = 16,
+    insets = { left = 0, right = 0, top = 0, bottom = 0 },
+  })
+
+  -- textures
+  local bgTex = overlay:CreateTexture(nil,"BACKGROUND")
+  bgTex:SetTexture(0.7,0.7,1.0,0.2)
+  bgTex:SetPoint("TOPLEFT",4,-4)
+  bgTex:SetPoint("BOTTOMRIGHT",-4,4)
+  local hTex = overlay:CreateTexture(nil,"HIGHLIGHT")
+  hTex:SetTexture(0.7,0.7,1.0,0.2)
+  hTex:SetPoint("TOPLEFT",4,-4)
+  hTex:SetPoint("BOTTOMRIGHT",-4,4)
+  hTex:SetBlendMode("ADD")
+  local aTex = overlay:CreateTexture(nil,"ARTWORK")
+  aTex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock")
+  aTex:SetWidth(16)
+  aTex:SetHeight(16)
+  aTex:Hide()
+
+  -- label
+  local label = overlay:CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
+  label:SetAllPoints()
+  label:SetJustifyH("CENTER")
+  label:SetShadowColor(0,0,0,1)
+  label:SetShadowOffset(3,-3)
+  label:SetTextColor(GetNormalTextColor())
+  label:SetText(bar:GetName())
+  label:Show()
+  bar.controlLabelString = label  -- so that bar:SetLabel() can update it
+
+  local function UpdateAnchorDecoration()
+    local point, anchor, relPoint, x, y = f:GetPoint(1)
+    if point then
+      local ofsx, ofsy = insidePointOffsetFuncs[point](x,y)
+      if (anchor and anchor ~= UIParent) or (ofsx == 0 and ofsy == 0) then
+        bgTex:SetTexture( GetAnchoredBgColor() )
+        hTex:SetTexture( GetAnchoredBgColor() )
+        label:SetTextColor( GetAnchoredTextColor() )
+        aTex:ClearAllPoints()
+        aTex:SetPoint(point)
+        aTex:Show()
+        return
+      end
+    end
+    bgTex:SetTexture( GetNormalBgColor() )
+    hTex:SetTexture( GetNormalBgColor() )
+    label:SetTextColor( GetNormalTextColor() )
+    aTex:Hide()
+  end
+
+  local function StopResize()
+    f:StopMovingOrSizing()
+    f.isMoving = false
+    f:SetScript("OnUpdate",nil)
+    StoreSize(bar)
+    ClampToButtons(bar)
+    ReAction:RefreshOptions()
+  end
+
+  local function CornerUpdate()
+    local bw, bh = GetButtonSize(bar)
+    local r, c, s = GetButtonGrid(bar)
+    local ss = GetStateScale(bar)
+    if IsShiftKeyDown() then
+      if ss then
+        f:SetMinResize( ((s+bw)*c*0.25)/ss, ((s+bh)*r*0.25)/ss )
+        f:SetMaxResize( ((s+bw)*c*2.5 + 1)/ss, ((s+bh)*r*2.5 + 1)/ss )
+        scale = ComputeBarScale(bar)
+      else
+        f:SetMinResize( (s+12)*c+1, (s+12)*r+1 )
+        f:SetMaxResize( (s+128)*c+1, (s+128)*r+1 )
+        RecomputeButtonSize(bar)
+      end
+    elseif not ss and IsAltKeyDown() then
+      f:SetMinResize( bw*c, bh*r )
+      f:SetMaxResize( 2*bw*c, 2*bh*r )
+      RecomputeButtonSpacing(bar)
+    else
+      f:SetMinResize( bw+s+1, bh+s+1 )
+      f:SetMaxResize( 50*(bw+s)+1, 50*(bh+s)+1 )
+      RecomputeGrid(bar)
+    end
+    GameTooltipTextRight2:SetText(format("%d x %d",r,c))
+
+    local ss = GetStateScale(bar)
+    local state = bar:GetState()
+    if ss then
+      GameTooltipTextRight4:SetText(format("%d%%", scale*100))
+    else
+      local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh)
+      GameTooltipTextRight3:SetText(size)
+      GameTooltipTextRight4:SetText(tostring(s))
+    end
+  end
+
+  -- corner drag handles
+  for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do
+    local corner = CreateFrame("Frame",nil,overlay)
+    corner:EnableMouse(true)
+    corner:SetWidth(16)
+    corner:SetHeight(16)
+    corner:SetPoint(point)
+
+    local tex = corner:CreateTexture(nil,"HIGHLIGHT")
+    tex:SetTexture("Interface\\AddOns\\ReAction\\img\\corner")
+    tex:SetTexCoord(unpack(cornerTexCoords[point]))
+    tex:SetBlendMode("ADD")
+    tex:SetAlpha(0.6)
+    tex:SetAllPoints()
+    
+    corner:SetScript("OnMouseDown",
+      function(_,btn)
+        f:SetScript("OnUpdate", CornerUpdate)
+        f:StartSizing(point)
+      end
+    )
+    corner:SetScript("OnMouseUp",
+      function()
+        local ss = GetStateScale(bar)
+        if ss then
+          local state = bar:GetState()
+          SetStateScale(bar, ComputeBarScale(bar))
+        end
+        StopResize()
+      end)
+    corner:SetScript("OnEnter",
+      function()
+        local bw, bh = GetButtonSize(bar)
+        local r, c, s = bar:GetButtonGrid()
+        local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh)
+        local ss = GetStateScale(bar)
+        local state = bar:GetState()
+        GameTooltip:SetOwner(f, "ANCHOR_"..point)
+        if ss then
+          GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state))
+        else
+          GameTooltip:AddLine(bar:GetName())
+        end
+        GameTooltip:AddDoubleLine(format("|cffcccccc%s|r %s",L["Drag"],L["to add/remove buttons:"]), format("%d x %d",r,c))
+        if ss then
+          GameTooltip:AddLine(L["State Scale Override"])
+          GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to change scale:"]), format("%d%%", bar:GetStateProperty(state,"scale")*100))
+        else
+          GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to resize buttons:"]), tostring(floor(size)))
+          GameTooltip:AddDoubleLine(format("|cff0033cc%s|r %s",L["Hold Alt"],  L["to change spacing:"]), tostring(floor(s)))
+        end
+        GameTooltip:Show()
+      end
+    )
+    corner:SetScript("OnLeave", 
+      function()
+        GameTooltip:Hide()
+        f:SetScript("OnUpdate",nil)
+      end
+    )
+  end
+
+  overlay:RegisterForDrag("LeftButton")
+  overlay:RegisterForClicks("RightButtonUp")
+  
+  overlay:SetScript("OnDragStart",
+    function()
+      f:StartMoving()
+      f.isMoving = true
+      local w,h = bar:GetButtonSize()
+      f:ClearAllPoints()
+      UpdateAnchorDecoration()
+      f:SetScript("OnUpdate", function()
+          if IsShiftKeyDown() then
+            local f, p = DisplaySnapIndicator(f,w,h)
+          else
+            HideSnapIndicator()
+          end
+        end)
+    end
+  )
+
+  local function UpdateDragTooltip()
+    GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT")
+    local ss = GetStateScale(bar)
+    local state = bar:GetState()
+    if ss then
+      GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state))
+    else
+      GameTooltip:AddLine(bar:GetName())
+    end
+    GameTooltip:AddLine(format("|cffcccccc%s|r %s",L["Drag"],L["to move"]))
+    GameTooltip:AddLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to anchor to nearby frames"]))
+    GameTooltip:AddLine(format("|cff00cccc%s|r %s",L["Right-click"],L["for options..."]))
+    local point, frame, relpoint, x, y = bar:GetFrame():GetPoint(1)
+    if point then
+      local ofsx, ofsy = insidePointOffsetFuncs[point](x,y)
+      if (frame and frame ~= UIParent) or (ofsx == 0 and ofsy == 0) then
+        frame = frame or UIParent
+        GameTooltip:AddLine(format("%s <%s>",L["Currently anchored to"],frame:GetName()))
+      end
+    end
+    GameTooltip:Show()
+  end
+
+  overlay:SetScript("OnDragStop",
+    function()
+      f:StopMovingOrSizing()
+      f.isMoving = false
+      f:SetScript("OnUpdate",nil)
+
+      if IsShiftKeyDown() then
+        local w, h = bar:GetButtonSize()
+        local a, p, rp, x, y = GetClosestPointSnapped(f,w,h)
+        if a then
+          f:ClearAllPoints()
+          f:SetPoint(p,a,rp,x,y)
+        end
+        HideSnapIndicator()
+      end
+
+      StoreExtents(bar)
+      ReAction:RefreshOptions()
+      UpdateDragTooltip()
+      UpdateAnchorDecoration()
+    end
+  )
+
+  overlay:SetScript("OnEnter",
+    function()
+      UpdateDragTooltip()
+    end
+  )
+
+  overlay:SetScript("OnLeave", HideGameTooltip)
+
+  overlay:SetScript("OnClick",
+    function()
+      ReAction:ShowEditor(bar)
+    end
+  )
+
+  function overlay:LIBKEYBOUND_ENABLED(evt)
+    self:SetFrameLevel(1)
+  end
+
+  function overlay:LIBKEYBOUND_DISABLED(evt)
+    self:SetFrameLevel(3)
+  end
+
+  function overlay:RefreshControls()
+    UpdateAnchorDecoration()
+  end
+
+  overlay:SetScript("OnShow", overlay.RefreshControls)
+
+  KB.RegisterCallback(overlay,"LIBKEYBOUND_ENABLED")
+  KB.RegisterCallback(overlay,"LIBKEYBOUND_DISABLED")
+
+  if ReAction:GetKeybindMode() then
+    overlay:SetFrameLevel(1)
+  end
+
+  bar:SetLabel(bar:GetName())
+  UpdateLabelString(bar)
+  UpdateAnchorDecoration()
+
+  return overlay
+end
+
+
+-- export methods to the Bar prototype
+
+function Bar:ShowControls(show)
+  local f = self.controlFrame
+  if show then
+    if not f then
+      f = CreateControls(self)
+      self.controlFrame = f
+    end
+    f:Show()
+  elseif f then
+    f:Hide()
+  end
+end
+
+function Bar:RefreshControls()
+  if self.controlFrame and self.controlFrame:IsShown() then
+    self.controlFrame:RefreshControls()
+  end
+end
+
+function Bar:SetLabel(name)
+  self.labelName = name
+  UpdateLabelString(self)
+end
+
+function Bar:SetLabelSubtext(text)
+  self.labelSubtext = text
+  UpdateLabelString(self)
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/classes/classes.xml	Mon Feb 23 18:56:57 2009 +0000
@@ -0,0 +1,10 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+    xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
+
+<Script file="GridProxy.lua"/>
+<Script file="Bar.lua"/>
+<Script file="Overlay.lua"/>
+<Script file="Button.lua"/>
+
+</Ui>
\ No newline at end of file
--- a/modules/Bar.lua	Mon Feb 09 19:02:58 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-local ReAction = ReAction
-local L = ReAction.L
-local _G = _G
-local CreateFrame = CreateFrame
-local floor = math.floor
-local fmod = math.fmod
-local format = string.format
-
-ReAction:UpdateRevision("$Revision$")
-
-local Bar   = { }
-local proto = { __index = Bar }
-local weak  = { __mode = "k" }
-
-ReAction.Bar = Bar -- export to ReAction
-
-function Bar:New( name, config )
-  if type(config) ~= "table" then
-    error("ReAction.Bar: config table required")
-  end
-
-  -- create new self
-  self = setmetatable( 
-    { 
-      config  = config,
-      name    = name,
-      buttons = setmetatable( { }, weak ),
-      width   = config.width or 480,
-      height  = config.height or 40
-    }, 
-    proto )
-  
-  -- The frame type is 'Button' in order to have an OnClick handler. However, the frame itself is
-  -- not mouse-clickable by the user.
-  local parent = config.parent and (ReAction:GetBar(config.parent) or _G[config.parent]) or UIParent
-  local f = CreateFrame("Button", name and format("ReAction-%s",name), parent,
-                        "SecureHandlerStateTemplate, SecureHandlerClickTemplate")
-  f:SetFrameStrata("MEDIUM")
-  f:SetWidth(self.width)
-  f:SetWidth(self.height)
-  f:SetAlpha(config.alpha or 1.0)
-  f:Show()
-  f:EnableMouse(false)
-  f:SetClampedToScreen(true)
-
-  -- Override the default frame accessor to provide strict read-only access
-  function self:GetFrame()
-    return f
-  end
-
-  self:ApplyAnchor()
-  ReAction.RegisterCallback(self, "OnConfigModeChanged")
-
-  return self
-end
-
-function Bar:Destroy()
-  local f = self:GetFrame()
-  f:UnregisterAllEvents()
-  ReAction.UnregisterAllCallbacks(self)
-  f:Hide()
-  f:SetParent(UIParent)
-  f:ClearAllPoints()
-end
-
-function Bar:OnConfigModeChanged(event, mode)
-  self:ShowControls(mode) -- Bar:ShowControls() defined in Overlay.lua
-end
-
-function Bar:ApplyAnchor()
-  local f = self:GetFrame()
-  local c = self.config
-  local p = c.point
-
-  f:SetWidth(c.width)
-  f:SetHeight(c.height)
-  f:ClearAllPoints()
-  
-  if p then
-    local a = f:GetParent()
-    if c.anchor then
-      local bar = ReAction:GetBar(c.anchor)
-      if bar then
-        a = bar:GetFrame()
-      else
-        a = _G[c.anchor]
-      end
-    end
-    local fr = a or f:GetParent()
-    f:SetPoint(p, a or f:GetParent(), c.relpoint, c.x or 0, c.y or 0)
-  else
-    f:SetPoint("CENTER")
-  end
-end
-
-function Bar:SetAnchor(point, frame, relativePoint, x, y)
-  local c = self.config
-  c.point = point or c.point
-  c.anchor = frame or c.anchor
-  c.relpoint = relativePoint or c.relpoint
-  c.x = x or c.x
-  c.y = y or c.y
-  self:ApplyAnchor()
-  ReAction:RefreshBar(self)
-end
-
-function Bar:GetAnchor()
-  local c = self.config
-  return (c.point or "CENTER"), 
-         (c.anchor or self:GetFrame():GetParent():GetName()), 
-         (c.relpoint or c.point or "CENTER"), 
-         (c.x or 0), 
-         (c.y or 0)
-end
-
-function Bar:GetSize()
-  local f = self:GetFrame()
-  return f:GetWidth(), f:GetHeight()
-end
-
-function Bar:SetSize(w,h)
-  local f = self:GetFrame()
-  self.config.width = w
-  self.config.height = h
-  f:SetWidth(w)
-  f:SetHeight(h)
-end
-
-function Bar:GetButtonSize()
-  local w = self.config.btnWidth or 32
-  local h = self.config.btnHeight or 32
-  -- TODO: get from modules?
-  return w,h
-end
-
-function Bar:SetButtonSize(w,h)
-  if w > 0 and h > 0 then
-    self.config.btnWidth = w
-    self.config.btnHeight = h
-  end
-  ReAction:RefreshBar(self)
-end
-
-function Bar:GetButtonGrid()
-  local cfg = self.config
-  local r = cfg.btnRows or 1
-  local c = cfg.btnColumns or 1
-  local s = cfg.spacing or 4
-  return r,c,s
-end
-
-function Bar:GetNumButtons()
-  local r,c = self:GetButtonGrid()
-  return r*c
-end
-
-function Bar:SetButtonGrid(r,c,s)
-  if r > 0 and c > 0 and s > 0 then
-    local cfg = self.config
-    cfg.btnRows = r
-    cfg.btnColumns = c
-    cfg.spacing = s
-  end
-  ReAction:RefreshBar(self)
-end
-
-function Bar:ClipNButtons( n )
-  local cfg = self.config
-  local r = cfg.btnRows or 1
-  local c = cfg.btnColumns or 1
-
-  cfg.btnRows = ceil(n/c)
-  cfg.btnColumns = min(n,c)
-end
-
-function Bar:GetName()
-  return self.name
-end
-
-function Bar:GetFrame()
-  -- this method is included for documentation purposes. It is overridden
-  -- for each object in the :New() method.
-  error("Invalid Bar object: used without initialization")
-end
-
--- only ReAction:RenameBar() should call this function. Calling from any other
--- context will desync the bar list in the ReAction class.
-function Bar:SetName(name)
-  self.name = name
-  self:SetLabel(self.name) -- Bar:SetLabel() defined in Overlay.lua
-end
-
-function Bar:GetAlpha()
-  return self.config.alpha or 1.0
-end
-
-function Bar:SetAlpha(value)
-  self.config.alpha = value
-  self:GetFrame():SetAlpha(value or 1.0)
-  ReAction:RefreshBar(self)
-end
-
-function Bar:AddButton(idx, button)
-  local f = self:GetFrame()
-
-  -- store in a weak reverse-index array
-  self.buttons[button] = idx
-
-  -- Store a properly wrapped reference to the child frame as an attribute 
-  -- (accessible via "frameref-btn#")
-  f:SetFrameRef(format("btn%d",idx), button:GetFrame())
-end
-
-function Bar:RemoveButton(button)
-  local idx = self.buttons[button]
-  if idx then
-    self:GetFrame():SetAttribute(format("frameref-btn%d",idx),nil)
-    self.buttons[button] = nil
-  end
-end
-
--- iterator returns button, idx and does NOT iterate in index order
-function Bar:IterateButtons()
-  return pairs(self.buttons)
-end
-
-function Bar:PlaceButton(button, baseW, baseH)
-  local idx = self.buttons[button]
-  if idx then 
-    local r, c, s = self:GetButtonGrid()
-    local bh, bw = self:GetButtonSize()
-    local row, col = floor((idx-1)/c), fmod((idx-1),c) -- zero-based
-    local x, y = col*bw + (col+0.5)*s, -(row*bh + (row+0.5)*s)
-    local scale = bw/baseW
-    local b = button:GetFrame()
-
-    b:ClearAllPoints()
-    b:SetPoint("TOPLEFT",x/scale,y/scale)
-    b:SetScale(scale)
-  end
-end
-
-function Bar:SkinButton()
-  -- does nothing by default
-end
\ No newline at end of file
--- a/modules/Bindings.lua	Mon Feb 09 19:02:58 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-local L = ReAction.L
-local _G = _G
-
-_G["BINDING_HEADER_REACTION"]             = L["ReAction"]
-
-_G["BINDING_NAME_REACTION_TOGGLELOCK"]    = L["Toggle ReAction Bar Lock"]
-_G["BINDING_NAME_REACTION_TOGGLEKEYBIND"] = L["ReAction Keybinding Mode"]
--- a/modules/LDB.lua	Mon Feb 09 19:02:58 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-local ReAction = ReAction
-local L = ReAction.L
-local format = string.format
-
--- Export ReAction launcher to LibDataBroker-aware displays
-LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject( "ReAction", 
-  {
-    type = "launcher", 
-    icon = "Interface\\Icons\\INV_Qiraj_JewelEncased",
-
-    OnClick = function( frame, button )
-      if not InCombatLockdown() then
-        if IsAltKeyDown() then
-          ReAction:SetKeybindMode( not ReAction:GetKeybindMode() )
-        elseif IsShiftKeyDown() then
-          ReAction:SetConfigMode( not ReAction:GetConfigMode() )
-        elseif button == "RightButton" then
-          ReAction:ShowEditor()
-        else
-          ReAction:ShowConfig()
-        end
-      else
-        ReAction:UserError(L["ReAction: can't configure in combat"])
-      end
-    end,
-
-      -- this isn't included in the 'launcher' type LDB spec but it seems all launcher displays use it
-    OnTooltipShow = function( tooltip )
-      tooltip:AddLine(format("|cffffffff%s|r %s",L["Click"],L["for global configuration"]))
-      tooltip:AddLine(format("|cffffd200%s|r %s",L["Right-click"],L["for bar editor dialog"]))
-      tooltip:AddLine(format("|cff00ff00%s|r %s",L["Shift-click"],L["to unlock bars"]))
-      tooltip:AddLine(format("|cff00cccc%s|r %s",L["Alt-click"],L["for keybind mode"]))
-    end,
-
-  }
-)
--- a/modules/Overlay.lua	Mon Feb 09 19:02:58 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,769 +0,0 @@
-local ReAction               = ReAction
-local L                      = ReAction.L
-local CreateFrame            = CreateFrame
-local InCombatLockdown       = InCombatLockdown
-local floor                  = math.floor
-local min                    = math.min
-local format                 = string.format
-local GameTooltip            = GameTooltip
-local Bar                    = ReAction.Bar
-local GetSize                = Bar.GetSize
-local SetSize                = Bar.SetSize
-local GetButtonSize          = Bar.GetButtonSize
-local GetButtonGrid          = Bar.GetButtonGrid
-local SetButtonSize          = Bar.SetButtonSize
-local SetButtonGrid          = Bar.SetButtonGrid
-local ApplyAnchor            = Bar.ApplyAnchor
-local GameTooltipTextRight1  = GameTooltipTextRight1
-local GameTooltipTextRight2  = GameTooltipTextRight2
-local GameTooltipTextRight3  = GameTooltipTextRight3
-
-local KB = LibStub("LibKeyBound-1.0")
-
-ReAction:UpdateRevision("$Revision$")
-
-
---
--- Wrap some of the bar manipulators to make them state-aware
---
-local function SetAnchor( bar, point, frame, relPoint, x, y )
-  local state = bar:GetState()
-  if state then
-    local anchorstate = bar:GetStateProperty(state, "anchorEnable")
-    if anchorstate then
-      bar:SetStateProperty(state, "anchorFrame", frame)
-      bar:SetStateProperty(state, "anchorPoint", point)
-      bar:SetStateProperty(state, "anchorRelPoint", relPoint)
-      bar:SetStateProperty(state, "anchorX", x or 0)
-      bar:SetStateProperty(state, "anchorY", y or 0)
-      bar:SetAnchor(bar:GetAnchor())
-      return
-    end
-  end
-  bar:SetAnchor(point, frame, relPoint, x, y)
-end
-
-local function GetStateScale( bar )
-  local state = bar:GetState()
-  if state and bar:GetStateProperty(state, "enableScale") then
-    return bar:GetStateProperty(state, "scale")
-  end
-end
-
-local function SetStateScale( bar, scale )
-  local state = bar:GetState()
-  if state and bar:GetStateProperty(state, "enableScale") then
-    bar:SetStateProperty(state, "scale", scale)
-  end
-end
-
-
---
--- Bar config overlay
---
-
-local function GetNormalTextColor()
-  return 1.0, 1.0, 1.0, 1.0
-end
-
-local function GetAnchoredTextColor()
-  return 1.0, 1.0, 1.0, 1.0
-end
-
-local function GetNormalBgColor()
-  return 0.7, 0.7, 1.0, 0.3
-end
-
-local function GetAnchoredBgColor()
-  return 0.9, 0.2, 0.7, 0.3
-end
-
-local function StoreSize(bar)
-  local f = bar:GetFrame()
-  SetSize( bar, f:GetWidth(), f:GetHeight() )
-end
-
-local function StoreExtents(bar)
-  local f = bar:GetFrame()
-  local p, fr, rp, x, y = f:GetPoint(1)
-  fr = fr and fr:GetName() or "UIParent"
-  SetAnchor( bar, p, fr, rp, x, y )
-  SetSize( bar, f:GetWidth(), f:GetHeight() )
-end
-
-local function RecomputeButtonSize(bar)
-  local w, h = GetSize(bar)
-  local bw, bh = GetButtonSize(bar)
-  local r, c, s = GetButtonGrid(bar)
-
-  local scaleW = (floor(w/c) - s) / bw
-  local scaleH = (floor(h/r) - s) / bh
-  local scale = min(scaleW, scaleH)
-
-  SetButtonSize(bar, scale * bw, scale * bh, s)
-end
-
-local function ComputeBarScale(bar)
-  local w, h = bar.controlFrame:GetWidth() - 8, bar.controlFrame:GetHeight() - 8
-  local bw, bh = GetButtonSize(bar)
-  local r, c, s = GetButtonGrid(bar)
-
-  local scaleW = w / (c*(bw+s))
-  local scaleH = h / (r*(bh+s))
-  local scale = min(scaleW, scaleH)
-
-  if scale > 2.5 then
-    scale = 2.5
-  elseif scale < 0.25 then
-    scale = 0.25
-  end
-
-  return scale
-end
-
-local function RecomputeButtonSpacing(bar)
-  local w, h = GetSize(bar)
-  local bw, bh = GetButtonSize(bar)
-  local r, c, s = GetButtonGrid(bar)
-
-  SetButtonGrid(bar,r,c,min(floor(w/c) - bw, floor(h/r) - bh))
-end
-
-local function RecomputeGrid(bar)
-  local w, h = GetSize(bar)
-  local bw, bh = GetButtonSize(bar)
-  local r, c, s = GetButtonGrid(bar)
-
-  SetButtonGrid(bar, floor(h/(bh+s)), floor(w/(bw+s)), s)
-end
-
-local function ClampToButtons(bar)
-  local bw, bh = GetButtonSize(bar)
-  local r, c, s = GetButtonGrid(bar)
-  SetSize(bar, (bw+s)*c + 1, (bh+s)*r + 1)
-end
-
-local function HideGameTooltip()
-  GameTooltip:Hide()
-end
-
-local anchorInside  = { inside = true }
-local anchorOutside = { outside = true }
-local edges = { "BOTTOM", "TOP", "LEFT", "RIGHT" }
-local oppositeEdges = {
-  TOP = "BOTTOM",
-  BOTTOM = "TOP",
-  LEFT = "RIGHT",
-  RIGHT = "LEFT"
-}
-local pointsOnEdge = {
-  BOTTOM = { "BOTTOM", "BOTTOMLEFT",  "BOTTOMRIGHT",  },
-  TOP    = { "TOP",    "TOPLEFT",     "TOPRIGHT",     },
-  RIGHT  = { "RIGHT",  "BOTTOMRIGHT", "TOPRIGHT",     },
-  LEFT   = { "LEFT",   "BOTTOMLEFT",  "TOPLEFT",      },
-}
-local edgeSelector = {
-  BOTTOM = 1,  -- select x of x,y
-  TOP    = 1,  -- select x of x,y
-  LEFT   = 2,  -- select y of x,y
-  RIGHT  = 2,  -- select y of x,y  
-}
-local snapPoints = {
-  [anchorOutside] = {
-    BOTTOMLEFT  = {"BOTTOMRIGHT","TOPLEFT","TOPRIGHT"},
-    BOTTOM      = {"TOP"},
-    BOTTOMRIGHT = {"BOTTOMLEFT","TOPRIGHT","TOPLEFT"},
-    RIGHT       = {"LEFT"},
-    TOPRIGHT    = {"TOPLEFT","BOTTOMRIGHT","BOTTOMLEFT"},
-    TOP         = {"BOTTOM"},
-    TOPLEFT     = {"TOPRIGHT","BOTTOMLEFT","BOTTOMRIGHT"},
-    LEFT        = {"RIGHT"},
-    CENTER      = {"CENTER"}
-  },
-  [anchorInside] = {
-    BOTTOMLEFT  = {"BOTTOMLEFT"},
-    BOTTOM      = {"BOTTOM"},
-    BOTTOMRIGHT = {"BOTTOMRIGHT"},
-    RIGHT       = {"RIGHT"},
-    TOPRIGHT    = {"TOPRIGHT"},
-    TOP         = {"TOP"},
-    TOPLEFT     = {"TOPLEFT"},
-    LEFT        = {"LEFT"},
-    CENTER      = {"CENTER"}
-  }
-}
-local insidePointOffsetFuncs = {
-  BOTTOMLEFT  = function(x, y) return x, y end,
-  BOTTOM      = function(x, y) return 0, y end,
-  BOTTOMRIGHT = function(x, y) return -x, y end,
-  RIGHT       = function(x, y) return -x, 0 end,
-  TOPRIGHT    = function(x, y) return -x, -y end,
-  TOP         = function(x, y) return 0, -y end,
-  TOPLEFT     = function(x, y) return x, -y end,
-  LEFT        = function(x, y) return x, 0 end,
-  CENTER      = function(x, y) return x, y end,
-}
-local pointCoordFuncs = {
-  BOTTOMLEFT  = function(f) return f:GetLeft(),  f:GetBottom() end,
-  BOTTOM      = function(f) return nil,          f:GetBottom() end,
-  BOTTOMRIGHT = function(f) return f:GetRight(), f:GetBottom() end,
-  RIGHT       = function(f) return f:GetRight(), nil end,
-  TOPRIGHT    = function(f) return f:GetRight(), f:GetTop() end,
-  TOP         = function(f) return nil,          f:GetTop() end,
-  TOPLEFT     = function(f) return f:GetLeft(),  f:GetTop() end,
-  LEFT        = function(f) return f:GetLeft(),  nil end,
-  CENTER      = function(f) return f:GetCenter() end,
-}
-local edgeBoundsFuncs = {
-  BOTTOM = function(f) return f:GetLeft(), f:GetRight() end,
-  LEFT   = function(f) return f:GetBottom(), f:GetTop() end
-}
-edgeBoundsFuncs.TOP   = edgeBoundsFuncs.BOTTOM
-edgeBoundsFuncs.RIGHT = edgeBoundsFuncs.LEFT
-local cornerTexCoords = {
-              -- ULx, ULy, LLx, LLy, URx, URy, LRx, LRy
-  TOPLEFT     = { 1,   1,   1,   0,   0,   1,   0,   0 },
-  TOPRIGHT    = { 1,   0,   0,   0,   1,   1,   0,   1 },
-  BOTTOMLEFT  = { 0,   1,   1,   1,   0,   0,   1,   0 },
-  BOTTOMRIGHT = { 0,   0,   0,   1,   1,   0,   1,   1 },
-}
-
--- Returns absolute coordinates x,y of the named point 'p' of frame 'f'
-local function GetPointCoords( f, p )
-  local x, y = pointCoordFuncs[p](f)
-  if not(x and y) then
-    local cx, cy = f:GetCenter()
-    x = x or cx
-    y = y or cy
-  end
-  return x, y
-end
-
-
--- Returns true if frame 'f1' can be anchored to frame 'f2'
-local function CheckAnchorable( f1, f2 )
-  -- can't anchor a frame to itself or to nil
-  if f1 == f2 or f2 == nil then
-    return false
-  end
-  
-  -- can always anchor to UIParent
-  if f2 == UIParent then
-    return true
-  end
-  
-  -- also can't do circular anchoring of frames 
-  -- walk the anchor chain, which generally shouldn't be that expensive
-  -- (who nests draggables that deep anyway?)
-  for i = 1, f2:GetNumPoints() do
-    local _, f = f2:GetPoint(i)
-    if not f then f = f2:GetParent() end
-    return CheckAnchorable(f1,f)
-  end
-  
-  return true
-end
-
--- Returns true if frames f1 and f2 specified edges overlap
-local function CheckEdgeOverlap( f1, f2, e )
-  local l1, u1 = edgeBoundsFuncs[e](f1)
-  local l2, u2 = edgeBoundsFuncs[e](f2)
-  return l1 <= l2 and l2 <= u1 or l2 <= l1 and l1 <= u2
-end
-
--- Returns true if point p1 on frame f1 overlaps edge e2 on frame f2
-local function CheckPointEdgeOverlap( f1, p1, f2, e2 )
-  local l, u = edgeBoundsFuncs[e2](f2)
-  local x, y = GetPointCoords(f1,p1)
-  x = select(edgeSelector[e2], x, y)
-  return l <= x and x <= u
-end
-
--- Returns the distance between corresponding edges. It is 
--- assumed that the passed in edges e1 and e2 are the same or opposites
-local function GetEdgeDistance( f1, f2, e1, e2 )
-  local x1, y1 = pointCoordFuncs[e1](f1)
-  local x2, y2 = pointCoordFuncs[e2](f2)
-  return math.abs((x1 or y1) - (x2 or y2))
-end
-
-local globalSnapTargets = { [UIParent] = anchorInside }
-
-local function GetClosestFrameEdge(f1,f2,a)
-  local dist, edge, opp
-  if f2:IsVisible() and CheckAnchorable(f1,f2) then
-    for _, e in pairs(edges) do
-      local o = a.inside and e or oppositeEdges[e]
-      if CheckEdgeOverlap(f1,f2,e) then
-        local d = GetEdgeDistance(f1, f2, e, o)
-        if not dist or (d < dist) then
-          dist, edge, opp = d, e, o
-        end
-      end
-    end
-  end
-  return dist, edge, opp
-end
-
-local function GetClosestVisibleEdge( f )
-  local r, o, e1, e2
-  local a = anchorOutside
-  for _, b in ReAction:IterateBars() do
-    local d, e, opp = GetClosestFrameEdge(f,b:GetFrame(),a)
-    if d and (not r or d < r) then
-      r, o, e1, e2 = d, b:GetFrame(), e, opp
-    end
-  end
-  for f2, a2 in pairs(globalSnapTargets) do
-    local d, e, opp = GetClosestFrameEdge(f,f2,a2)
-    if d and (not r or d < r) then
-      r, o, e1, e2, a = d, f2, e, opp, a2
-    end
-  end
-  return o, e1, e2, a
-end
-
-local function GetClosestVisiblePoint(f1)
-  local f2, e1, e2, a = GetClosestVisibleEdge(f1)
-  if f2 then
-    local rsq, p, rp, x, y
-    -- iterate pointsOnEdge in order and use < to prefer edge centers to corners
-    for _, p1 in ipairs(pointsOnEdge[e1]) do
-      if CheckPointEdgeOverlap(f1,p1,f2,e2) then
-        for _, p2 in pairs(snapPoints[a][p1]) do
-          local x1, y1 = GetPointCoords(f1,p1)
-          local x2, y2 = GetPointCoords(f2,p2)
-          local dx = x1 - x2
-          local dy = y1 - y2
-          local rsq2 = dx*dx + dy*dy
-          if not rsq or rsq2 < rsq then
-            rsq, p, rp, x, y = rsq2, p1, p2, dx, dy
-          end
-        end
-      end
-    end
-    return f2, p, rp, x, y
-  end
-end
-
-local function GetClosestPointSnapped(f1, rx, ry, xOff, yOff)
-  local o, p, rp, x, y = GetClosestVisiblePoint(f1)
-  local s = false
-
-  local insideOffsetFunc = p and insidePointOffsetFuncs[p]
-  local coordFunc = p and pointCoordFuncs[p]
-  if not insideOffsetFunc or not coordFunc then
-    return
-  end
-  
-  local sx, sy = insideOffsetFunc(xOff or 0, yOff or 0)
-  local xx, yy = coordFunc(f1)
-  if xx and yy then
-    if math.abs(x) <= rx then
-      if math.abs(y) <= ry then
-        x = sx
-        y = sy
-        s = true
-      elseif CheckEdgeOverlap(f1,o,"LEFT") then
-        x = sx
-        s = true
-      end
-    elseif math.abs(y) <= ry and CheckEdgeOverlap(f1,o,"TOP") then
-      y = sy
-      s = true
-    end
-  elseif xx then
-    if math.abs(x) <= rx then
-      x = sx
-      s = true
-      if math.abs(y) <= ry then
-        y = sy
-      end
-    end
-  elseif yy then
-    if math.abs(y) <= ry then
-      y = sy
-      s = true
-      if math.abs(x) <= rx then
-        x = sx
-      end
-    end
-  end
-
-  -- correct for some Lua oddities with doubles
-  if x == -0 then x = 0 end
-  if y == -0 then y = 0 end
-  
-  if s then
-    return o, p, rp, math.floor(x), math.floor(y)
-  end
-end
-
-local function CreateSnapIndicator()
-  local si = CreateFrame("Frame",nil,UIParent)
-  si:SetFrameStrata("HIGH")
-  si:SetHeight(16)
-  si:SetWidth(16)
-  local tex = si:CreateTexture()
-  tex:SetAllPoints()
-  tex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock")
-  tex:SetBlendMode("ADD")
-  tex:SetDrawLayer("OVERLAY")
-  return si
-end
-
-local si1 = CreateSnapIndicator()
-local si2 = CreateSnapIndicator()
-
-local function DisplaySnapIndicator( f, rx, ry, xOff, yOff )
-  local o, p, rp, x, y, snap = GetClosestPointSnapped(f, rx, ry, xOff, yOff)
-  if o then
-    si1:ClearAllPoints()
-    si2:ClearAllPoints()
-    si1:SetPoint("CENTER", f, p, 0, 0)
-    local xx, yy = pointCoordFuncs[rp](o)
-    x = math.abs(x) <=rx and xx and 0 or x
-    y = math.abs(y) <=ry and yy and 0 or y
-    si2:SetPoint("CENTER", o, rp, x, y)
-    si1:Show()
-    si2:Show()
-  else
-    if si1:IsVisible() then
-      si1:Hide()
-      si2:Hide()
-    end
-  end
-  return o, p
-end
-
-local function HideSnapIndicator()
-  if si1:IsVisible() then
-    si1:Hide()
-    si2:Hide()
-  end
-end
-
-local function UpdateLabelString(bar)
-  local label = bar.controlLabelString
-  if label then
-    local name = bar.labelName
-    if name and bar.labelSubtext then
-      name = format("%s (%s)", name, bar.labelSubtext)
-    end
-    label:SetText(name or "")
-  end
-end
-
-local function CreateControls(bar)
-  local f = bar:GetFrame()
-
-  f:SetMovable(true)
-  f:SetResizable(true)
-
-  -- child of UIParent so that alpha and scale doesn't propagate to it
-  local overlay = CreateFrame("Button", nil, UIParent)
-  overlay:EnableMouse(true)
-  overlay:SetFrameLevel(3) -- set it above the buttons
-  overlay:SetPoint("TOPLEFT", f, "TOPLEFT", -4, 4)
-  overlay:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 4, -4)
-  overlay:SetBackdrop({
-    edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
-    tile = true,
-    tileSize = 16,
-    edgeSize = 16,
-    insets = { left = 0, right = 0, top = 0, bottom = 0 },
-  })
-
-  -- textures
-  local bgTex = overlay:CreateTexture(nil,"BACKGROUND")
-  bgTex:SetTexture(0.7,0.7,1.0,0.2)
-  bgTex:SetPoint("TOPLEFT",4,-4)
-  bgTex:SetPoint("BOTTOMRIGHT",-4,4)
-  local hTex = overlay:CreateTexture(nil,"HIGHLIGHT")
-  hTex:SetTexture(0.7,0.7,1.0,0.2)
-  hTex:SetPoint("TOPLEFT",4,-4)
-  hTex:SetPoint("BOTTOMRIGHT",-4,4)
-  hTex:SetBlendMode("ADD")
-  local aTex = overlay:CreateTexture(nil,"ARTWORK")
-  aTex:SetTexture("Interface\\AddOns\\ReAction\\img\\lock")
-  aTex:SetWidth(16)
-  aTex:SetHeight(16)
-  aTex:Hide()
-
-  -- label
-  local label = overlay:CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
-  label:SetAllPoints()
-  label:SetJustifyH("CENTER")
-  label:SetShadowColor(0,0,0,1)
-  label:SetShadowOffset(3,-3)
-  label:SetTextColor(GetNormalTextColor())
-  label:SetText(bar:GetName())
-  label:Show()
-  bar.controlLabelString = label  -- so that bar:SetLabel() can update it
-
-  local function UpdateAnchorDecoration()
-    local point, anchor, relPoint, x, y = f:GetPoint(1)
-    if point then
-      local ofsx, ofsy = insidePointOffsetFuncs[point](x,y)
-      if (anchor and anchor ~= UIParent) or (ofsx == 0 and ofsy == 0) then
-        bgTex:SetTexture( GetAnchoredBgColor() )
-        hTex:SetTexture( GetAnchoredBgColor() )
-        label:SetTextColor( GetAnchoredTextColor() )
-        aTex:ClearAllPoints()
-        aTex:SetPoint(point)
-        aTex:Show()
-        return
-      end
-    end
-    bgTex:SetTexture( GetNormalBgColor() )
-    hTex:SetTexture( GetNormalBgColor() )
-    label:SetTextColor( GetNormalTextColor() )
-    aTex:Hide()
-  end
-
-  local function StopResize()
-    f:StopMovingOrSizing()
-    f.isMoving = false
-    f:SetScript("OnUpdate",nil)
-    StoreSize(bar)
-    ClampToButtons(bar)
-    ReAction:RefreshOptions()
-  end
-
-  local function CornerUpdate()
-    local bw, bh = GetButtonSize(bar)
-    local r, c, s = GetButtonGrid(bar)
-    local ss = GetStateScale(bar)
-    if IsShiftKeyDown() then
-      if ss then
-        f:SetMinResize( ((s+bw)*c*0.25)/ss, ((s+bh)*r*0.25)/ss )
-        f:SetMaxResize( ((s+bw)*c*2.5 + 1)/ss, ((s+bh)*r*2.5 + 1)/ss )
-        scale = ComputeBarScale(bar)
-      else
-        f:SetMinResize( (s+12)*c+1, (s+12)*r+1 )
-        f:SetMaxResize( (s+128)*c+1, (s+128)*r+1 )
-        RecomputeButtonSize(bar)
-      end
-    elseif not ss and IsAltKeyDown() then
-      f:SetMinResize( bw*c, bh*r )
-      f:SetMaxResize( 2*bw*c, 2*bh*r )
-      RecomputeButtonSpacing(bar)
-    else
-      f:SetMinResize( bw+s+1, bh+s+1 )
-      f:SetMaxResize( 50*(bw+s)+1, 50*(bh+s)+1 )
-      RecomputeGrid(bar)
-    end
-    GameTooltipTextRight2:SetText(format("%d x %d",r,c))
-
-    local ss = GetStateScale(bar)
-    local state = bar:GetState()
-    if ss then
-      GameTooltipTextRight4:SetText(format("%d%%", scale*100))
-    else
-      local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh)
-      GameTooltipTextRight3:SetText(size)
-      GameTooltipTextRight4:SetText(tostring(s))
-    end
-  end
-
-  -- corner drag handles
-  for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do
-    local corner = CreateFrame("Frame",nil,overlay)
-    corner:EnableMouse(true)
-    corner:SetWidth(16)
-    corner:SetHeight(16)
-    corner:SetPoint(point)
-
-    local tex = corner:CreateTexture(nil,"HIGHLIGHT")
-    tex:SetTexture("Interface\\AddOns\\ReAction\\img\\corner")
-    tex:SetTexCoord(unpack(cornerTexCoords[point]))
-    tex:SetBlendMode("ADD")
-    tex:SetAlpha(0.6)
-    tex:SetAllPoints()
-    
-    corner:SetScript("OnMouseDown",
-      function(_,btn)
-        f:SetScript("OnUpdate", CornerUpdate)
-        f:StartSizing(point)
-      end
-    )
-    corner:SetScript("OnMouseUp",
-      function()
-        local ss = GetStateScale(bar)
-        if ss then
-          local state = bar:GetState()
-          SetStateScale(bar, ComputeBarScale(bar))
-        end
-        StopResize()
-      end)
-    corner:SetScript("OnEnter",
-      function()
-        local bw, bh = GetButtonSize(bar)
-        local r, c, s = bar:GetButtonGrid()
-        local size = (bw == bh) and tostring(bw) or format("%d x %d",bw,bh)
-        local ss = GetStateScale(bar)
-        local state = bar:GetState()
-        GameTooltip:SetOwner(f, "ANCHOR_"..point)
-        if ss then
-          GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state))
-        else
-          GameTooltip:AddLine(bar:GetName())
-        end
-        GameTooltip:AddDoubleLine(format("|cffcccccc%s|r %s",L["Drag"],L["to add/remove buttons:"]), format("%d x %d",r,c))
-        if ss then
-          GameTooltip:AddLine(L["State Scale Override"])
-          GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to change scale:"]), format("%d%%", bar:GetStateProperty(state,"scale")*100))
-        else
-          GameTooltip:AddDoubleLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to resize buttons:"]), tostring(floor(size)))
-          GameTooltip:AddDoubleLine(format("|cff0033cc%s|r %s",L["Hold Alt"],  L["to change spacing:"]), tostring(floor(s)))
-        end
-        GameTooltip:Show()
-      end
-    )
-    corner:SetScript("OnLeave", 
-      function()
-        GameTooltip:Hide()
-        f:SetScript("OnUpdate",nil)
-      end
-    )
-  end
-
-  overlay:RegisterForDrag("LeftButton")
-  overlay:RegisterForClicks("RightButtonUp")
-  
-  overlay:SetScript("OnDragStart",
-    function()
-      f:StartMoving()
-      f.isMoving = true
-      local w,h = bar:GetButtonSize()
-      f:ClearAllPoints()
-      UpdateAnchorDecoration()
-      f:SetScript("OnUpdate", function()
-          if IsShiftKeyDown() then
-            local f, p = DisplaySnapIndicator(f,w,h)
-          else
-            HideSnapIndicator()
-          end
-        end)
-    end
-  )
-
-  local function UpdateDragTooltip()
-    GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT")
-    local ss = GetStateScale(bar)
-    local state = bar:GetState()
-    if ss then
-      GameTooltip:AddLine(format("%s (%s: %s)", bar:GetName(), L["State"], state))
-    else
-      GameTooltip:AddLine(bar:GetName())
-    end
-    GameTooltip:AddLine(format("|cffcccccc%s|r %s",L["Drag"],L["to move"]))
-    GameTooltip:AddLine(format("|cff00ff00%s|r %s",L["Hold Shift"],L["to anchor to nearby frames"]))
-    GameTooltip:AddLine(format("|cff00cccc%s|r %s",L["Right-click"],L["for options..."]))
-    local point, frame, relpoint, x, y = bar:GetFrame():GetPoint(1)
-    if point then
-      local ofsx, ofsy = insidePointOffsetFuncs[point](x,y)
-      if (frame and frame ~= UIParent) or (ofsx == 0 and ofsy == 0) then
-        frame = frame or UIParent
-        GameTooltip:AddLine(format("%s <%s>",L["Currently anchored to"],frame:GetName()))
-      end
-    end
-    GameTooltip:Show()
-  end
-
-  overlay:SetScript("OnDragStop",
-    function()
-      f:StopMovingOrSizing()
-      f.isMoving = false
-      f:SetScript("OnUpdate",nil)
-
-      if IsShiftKeyDown() then
-        local w, h = bar:GetButtonSize()
-        local a, p, rp, x, y = GetClosestPointSnapped(f,w,h)
-        if a then
-          f:ClearAllPoints()
-          f:SetPoint(p,a,rp,x,y)
-        end
-        HideSnapIndicator()
-      end
-
-      StoreExtents(bar)
-      ReAction:RefreshOptions()
-      UpdateDragTooltip()
-      UpdateAnchorDecoration()
-    end
-  )
-
-  overlay:SetScript("OnEnter",
-    function()
-      UpdateDragTooltip()
-    end
-  )
-
-  overlay:SetScript("OnLeave", HideGameTooltip)
-
-  overlay:SetScript("OnClick",
-    function()
-      ReAction:ShowEditor(bar)
-    end
-  )
-
-  function overlay:LIBKEYBOUND_ENABLED(evt)
-    self:SetFrameLevel(1)
-  end
-
-  function overlay:LIBKEYBOUND_DISABLED(evt)
-    self:SetFrameLevel(3)
-  end
-
-  function overlay:RefreshControls()
-    UpdateAnchorDecoration()
-  end
-
-  overlay:SetScript("OnShow", overlay.RefreshControls)
-
-  KB.RegisterCallback(overlay,"LIBKEYBOUND_ENABLED")
-  KB.RegisterCallback(overlay,"LIBKEYBOUND_DISABLED")
-
-  if ReAction:GetKeybindMode() then
-    overlay:SetFrameLevel(1)
-  end
-
-  bar:SetLabel(bar:GetName())
-  UpdateLabelString(bar)
-  UpdateAnchorDecoration()
-
-  return overlay
-end
-
-
--- export methods to the Bar prototype
-
-function Bar:ShowControls(show)
-  local f = self.controlFrame
-  if show then
-    if not f then
-      f = CreateControls(self)
-      self.controlFrame = f
-    end
-    f:Show()
-  elseif f then
-    f:Hide()
-  end
-end
-
-function Bar:RefreshControls()
-  if self.controlFrame and self.controlFrame:IsShown() then
-    self.controlFrame:RefreshControls()
-  end
-end
-
-function Bar:SetLabel(name)
-  self.labelName = name
-  UpdateLabelString(self)
-end
-
-function Bar:SetLabelSubtext(text)
-  self.labelSubtext = text
-  UpdateLabelString(self)
-end
--- a/modules/modules.xml	Mon Feb 09 19:02:58 2009 +0000
+++ b/modules/modules.xml	Mon Feb 23 18:56:57 2009 +0000
@@ -2,12 +2,8 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
 
-<Script file="bindings.lua"/>
-<Script file="Bar.lua"/>
-<Script file="Overlay.lua"/>
 <Script file="ConfigUI.lua"/>
 <Script file="State.lua"/>
-<Script file="LDB.lua"/>
 <Script file="LBF.lua"/>
 <Script file="HideBlizzard.lua"/>
 <Script file="Action.lua"/>