diff classes/Button.lua @ 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
children 943eed2c7def
line wrap: on
line diff
--- /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