diff classes/Bar.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/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