diff State.lua @ 101:3699d7dad312

added stateful anchoring
author Flick <flickerstreak@gmail.com>
date Sat, 25 Oct 2008 18:49:18 +0000
parents a44173c7a82c
children 890e4c4ab143
line wrap: on
line diff
--- a/State.lua	Fri Oct 24 23:37:24 2008 +0000
+++ b/State.lua	Sat Oct 25 18:49:18 2008 +0000
@@ -53,6 +53,22 @@
   return r
 end
 
+-- set a frame-ref, if the frame is valid, or set nil to the
+-- corresponding attribute
+local function SetFrameRef(frame, name, refFrame)
+  if refFrame then
+    local _, explicit = refFrame:IsProtected()
+    if not explicit then
+      refFrame = nil
+    end
+  end
+  if refFrame then
+    frame:SetFrameRef(name,refFrame)
+  else
+    frame:SetAttribute("frameref-"..name,nil)
+  end
+end
+
 
 local InitRules, ApplyStates, CleanupStates, SetProperty, GetProperty, RegisterProperty, ShowAll
 
@@ -80,9 +96,28 @@
 
     --keybindState  TODO: broken
 
-      -- the anchoring is handled in a special handler
-    anchorEnable = true,
-    --anchorFrame = true,  TODO: broken
+    anchorEnable = 
+      [[
+        local old_anchor = anchorstate
+        anchorstate = (anchorEnable and anchorEnable[state]) and state
+        if old_anchor ~= anchorstate or not set_state then
+          if anchorstate and anchorPoint then
+            if anchorPoint[state] then
+              self:ClearAllPoints()
+              local f = self:GetAttribute("frameref-anchor-"..anchorstate)
+              if f then
+                self:SetPoint(anchorPoint[state], f, anchorRelPoint[state], anchorX[state], anchorY[state])
+              end
+            end
+          elseif defaultAnchor and defaultAnchor.point then
+            self:ClearAllPoints()
+            self:SetPoint(defaultAnchor.point, defaultAnchor.frame, 
+                          defaultAnchor.relPoint, defaultAnchor.x, defaultAnchor.y)
+          end
+        end
+      ]],
+      -- anchorEnable handles all the other bits
+    anchorFrame = true,
     anchorPoint = true,
     anchorRelPoint = true,
     anchorX = true,
@@ -112,34 +147,17 @@
     local onStateHandler = 
     -- function _onstate-reaction( self, stateid, newstate )
     [[
-      set_state = newstate or set_state
+      set_state = newstate
 
       local oldState = state
       state = state_override or set_state or state
-
       for i = 1, #propfuncs do
         control:RunAttribute("func-"..propfuncs[i])
       end
       
-      if anchorEnable and anchorEnable[state] ~= anchorstate then
-        anchorstate = anchorEnable[state]
-        control:RunAttribute("func-doanchor")
-      end
-
       control:ChildUpdate()
     ]]
 
-    local anchorHandler = 
-    -- function func-doanchor( self )
-    [[
-      -- TODO
-      if anchorstate then
-        -- TODO: get anchor data from state tables
-      else
-        -- TODO: get anchor data from defaults
-      end
-    ]]
-
     local onClickHandler = 
     -- function OnClick( self, button, down )
     [[
@@ -186,14 +204,12 @@
       SetHandlerData(bar, "defaultAnchor", x, "x")
       SetHandlerData(bar, "defaultAnchor", y, "y")
 
-      if frame then
-        local f = bar:GetFrame()
-        f:SetFrameRef("defaultAnchor", f)
-        f:Execute(
-          [[
-            defaultAnchor.frame = self:GetAttribute("frameref-defaultAnchor")
-          ]])
-      end
+      local f = bar:GetFrame()
+      SetFrameRef(f, "defaultAnchor", _G[frame or "UIParent"])
+      f:Execute(
+        [[
+          defaultAnchor.frame = self:GetAttribute("frameref-defaultAnchor")
+        ]])
     end
 
     function RefreshState( bar )
@@ -225,7 +241,6 @@
       f:SetAttribute("prop-func-list", table.concat(props," "))
       f:Execute(stateHandler_propInit)
       f:SetAttribute("reaction-refresh", onStateHandler)
-      f:SetAttribute("func-doanchor", anchorHandler)
       
       if rule and #rule > 0 then
         f:SetAttribute( "_onstate-reaction", onStateHandler )
@@ -411,7 +426,11 @@
     if states then
       for propname in pairs(properties) do
         for name, s in pairs(states) do
-          SetHandlerData(bar, propname, s[propname], name)
+          if propname == "anchorFrame" then
+            SetFrameRef(bar:GetFrame(), "anchor-"..name, _G[s.anchorFrame])
+          else
+            SetHandlerData(bar, propname, s[propname], name)
+          end
         end
       end
       BuildKeybinds(bar, states)
@@ -639,21 +658,22 @@
           inline = true,
           args = {
             anchorEnable = {
-              name  = L["Set New Position"],
+              name  = L["Reposition"],
               order = 1,
               type  = "toggle",
               set   = "SetProp",
               get   = "GetProp",
             },
-            --[[ TODO: broken
             anchorFrame = {
               name   = L["Anchor Frame"],
               order  = 2,
               type   = "select",
               values = "GetAnchorFrames",
-              set    = ???
-              get    = ???
-            },   ]]
+              set    = "SetAnchorFrame",
+              get    = "GetAnchorFrame",
+              disabled = "GetAnchorDisabled",
+              hidden = "GetAnchorDisabled",
+            },
             anchorPoint = {
               name  = L["Point"],
               order = 3,
@@ -994,7 +1014,35 @@
   end
 
   function StateHandler:GetAnchorDisabled()
-    return not GetProperty(self.bar, self:GetName(), "enableAnchor")
+    return not GetProperty(self.bar, self:GetName(), "anchorEnable")
+  end
+
+  function StateHandler:GetAnchorFrames(info)
+    self._anchorframes = self._anchorframes or { }
+    table.wipe(self._anchorframes)
+
+    table.insert(self._anchorframes, "UIParent")
+    for name, bar in ReAction:IterateBars() do
+      table.insert(self._anchorframes, bar:GetFrame():GetName())
+    end
+    return self._anchorframes
+  end
+
+  function StateHandler:GetAnchorFrame(info)
+    local value = self:GetProp(info)
+    for k,v in pairs(self._anchorframes) do
+      if v == value then
+        return k
+      end
+    end
+  end
+
+  function StateHandler:SetAnchorFrame(info, value)
+    local f = _G[self._anchorframes[value]]
+    if f then
+      SetFrameRef(self.bar:GetFrame(), "anchor-"..self:GetName(), f)
+      self:SetProp(info, f:GetName())
+    end
   end
 
   function StateHandler:SetAnchorPointProp(info, value)