changeset 60:44649a10378d

Fixed options handling to create a separate table for each bar instead of a shared table with proxy handler. Also simplified options registration and moved some options around.
author Flick <flickerstreak@gmail.com>
date Sat, 10 May 2008 00:08:01 +0000
parents 7430a8dd4e90
children 2ee41dcd673f
files ReAction.lua lib/embeds.xml locale/enUS.lua modules/ReAction_Action/ReAction_Action.lua modules/ReAction_ConfigUI/ReAction_ConfigUI.lua modules/ReAction_ConfigUI/lib/embeds.xml modules/ReAction_HideBlizzard/ReAction_HideBlizzard.lua modules/ReAction_PetAction/ReAction_PetAction.lua modules/ReAction_PossessBar/ReAction_PossessBar.lua
diffstat 9 files changed, 411 insertions(+), 458 deletions(-) [+]
line wrap: on
line diff
--- a/ReAction.lua	Mon Apr 28 23:34:17 2008 +0000
+++ b/ReAction.lua	Sat May 10 00:08:01 2008 +0000
@@ -150,21 +150,50 @@
   self:RegisterEvent("PLAYER_REGEN_DISABLED")
 
   self.bars = {}
-  self.options = {}
   self.defaultBarConfig = {}
 
-  self:RegisterOptions("global", self, {
-    unlock = {
-      type     = "toggle",
-      handler  = module,
-      name     = L["Unlock Bars"],
-      desc     = L["Unlock bars for dragging and resizing with the mouse"],
-      get      = function() return self.configMode end,
-      set      = function(info, value) self:SetConfigMode(value) end,
-      disabled = InCombatLockdown,
-      order    = 1
+  self.options = {
+    type = "group",
+    name = "ReAction",
+    childGroups = "tab",
+    args = {
+      _desc = {
+        type = "description",
+        name = L["Customizable replacement for Blizzard's Action Bars"],
+        order = 1,
+      },
+      global = {
+        type = "group",
+        name = L["Global Settings"],
+        desc = L["Global configuration settings"],
+        args = { 
+          unlock = {
+            type     = "toggle",
+            handler  = module,
+            name     = L["Unlock Bars"],
+            desc     = L["Unlock bars for dragging and resizing with the mouse"],
+            get      = function() return self.configMode end,
+            set      = function(info, value) self:SetConfigMode(value) end,
+            disabled = InCombatLockdown,
+            order    = 1
+          },
+        },
+        plugins = { },
+        order = 2,
+      },
+      module = {
+        type = "group",
+        childGroups = "select",
+        name = L["Module Settings"],
+        desc = L["Configuration settings for each module"],
+        args = { },
+        plugins = { },
+        order = 3,
+      },
+      profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
     },
-  })
+    plugins = { }
+  }
 
 end
 
@@ -344,25 +373,8 @@
   self:RefreshOptions()
 end
 
--- See modules/ReAction_ConfigUI for valid options contexts.
-function ReAction:RegisterOptions(context, module, opts)
-  if module == nil or context == nil then
-    error("ReAction:RegisterOptions requires a module object and context ID")
-  end
-  if not self.options[context] then
-    self.options[context] = {}
-  end
-  self.options[context][module] = opts
-  self.callbacks:Fire("OnOptionsRegistered", context, module, opts)
-end
-
-function ReAction:GetOptions(context)
-  if context then
-    if not self.options[context] then
-      self.options[context] = { }
-    end
-    return self.options[context]
-  end
+function ReAction:RegisterOptions(module, options, global)
+  self.options.args[global and "global" or "module"].plugins[module:GetName()] = options
 end
 
 function ReAction:RefreshOptions()
--- a/lib/embeds.xml	Mon Apr 28 23:34:17 2008 +0000
+++ b/lib/embeds.xml	Sat May 10 00:08:01 2008 +0000
@@ -7,6 +7,7 @@
   <Include file="AceAddon-3.0\AceAddon-3.0.xml"/>
   <Include file="AceLocale-3.0\AceLocale-3.0.xml"/>
   <Include file="AceDB-3.0\AceDB-3.0.xml"/>
+  <Include file="AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
   <Include file="AceConsole-3.0\AceConsole-3.0.xml"/>
   <Include file="AceEvent-3.0\AceEvent-3.0.xml"/>
 
--- a/locale/enUS.lua	Mon Apr 28 23:34:17 2008 +0000
+++ b/locale/enUS.lua	Sat May 10 00:08:01 2008 +0000
@@ -11,6 +11,13 @@
 "Bar ",
 "ReAction: name already in use",
 "ReAction config mode disabled during combat.",
+"Customizable replacement for Blizzard's Action Bars",
+"Global Settings",
+"Global configuration settings",
+"Unlock Bars",
+"Unlock bars for dragging and resizing with the mouse",
+"Module Settings",
+"Configuration settings for each module",
 
 -- Bar.lua
 "Drag to add/remove buttons",
@@ -37,6 +44,7 @@
 
 -- modules/ReAction_Action
 "Action Bar",
+"Action Bars",
 "Hide Empty Buttons",
 "Action Buttons",
 
@@ -59,13 +67,6 @@
 "Top Right",
 "Bottom Left",
 "Bottom Right",
-"Customizable replacement for Blizzard's Action Bars",
-"Global Settings",
-"Global configuration settings",
-"Unlock Bars",
-"Unlock bars for dragging and resizing with the mouse",
-"Module Settings",
-"Configuration settings for each module",
 "Edit Bars...",
 "Show the ReAction Bar Editor dialogue",
 "Close on Launch",
@@ -99,10 +100,6 @@
 "Spacing",
 "Use the mouse to arrange and resize the bars on screen. Tooltips on bars indicate additional functionality.",
 
-
---"Rename Bar",
---"Set a name for the bar",
-
 -- modules/ReAction_State
 "Dynamic Behavior",
 }) do
--- a/modules/ReAction_Action/ReAction_Action.lua	Mon Apr 28 23:34:17 2008 +0000
+++ b/modules/ReAction_Action/ReAction_Action.lua	Sat May 10 00:08:01 2008 +0000
@@ -27,23 +27,22 @@
     }
   )
   self.buttons = { }
+  self.options = setmetatable({},{__mode="k"})
 
-  ReAction:RegisterOptions("global", self, {
-    hideEmpty = {
-      type = "toggle",
-      name = L["Hide Empty Buttons"],
-      get  = function() return self.db.profile.hideEmptyButtons end,
-      set  = function(info, val) module:SetHideEmptyButtons(val) end,
-    }
-  })
-
-  ReAction:RegisterOptions("bar", self, {
-    type = "group",
-    name = L["Action Buttons"],
-    hidden = "BarOptionsHidden",
-    args = {
-    }
-  })
+  ReAction:RegisterOptions(self, {
+      [moduleID] = {
+        type = "group",
+        name = L["Action Bars"],
+        args = {
+          hideEmpty = {
+            type = "toggle",
+            name = L["Hide Empty Buttons"],
+            get  = function() return self.db.profile.hideEmptyButtons end,
+            set  = function(info, val) module:SetHideEmptyButtons(val) end,
+          }
+        }
+      }
+    })
 end
 
 function module:OnEnable()
@@ -178,9 +177,18 @@
 end
 
 
----- Options handlers ----
-function module:BarOptionsHidden(bar)
-  return bar.config.type ~= moduleID
+---- Options ----
+function module:GetBarOptions(bar)
+  if not self.options[bar] then
+    self.options[bar] = {
+      type = "group",
+      name = L["Action Buttons"],
+      hidden = function() return bar.config.type ~= moduleID end,
+      args = {
+      }
+    }
+  end
+  return self.options[bar]
 end
 
 
--- a/modules/ReAction_ConfigUI/ReAction_ConfigUI.lua	Mon Apr 28 23:34:17 2008 +0000
+++ b/modules/ReAction_ConfigUI/ReAction_ConfigUI.lua	Sat May 10 00:08:01 2008 +0000
@@ -12,17 +12,7 @@
 local AceConfigDialog = LibStub("AceConfigDialog-3.0")
 
 -- some constants
-local pointTable = {
-  CENTER      = L["Center"], 
-  LEFT        = L["Left"],
-  RIGHT       = L["Right"],
-  TOP         = L["Top"],
-  BOTTOM      = L["Bottom"],
-  TOPLEFT     = L["Top Left"],
-  TOPRIGHT    = L["Top Right"],
-  BOTTOMLEFT  = L["Bottom Left"],
-  BOTTOMRIGHT = L["Bottom Right"],
-}
+local configName = "ReAction"
 
 -- module declaration
 local moduleID = "ConfigUI"
@@ -41,203 +31,15 @@
     }
   )
 
-  ReAction.RegisterCallback(self,"OnOptionsRegistered")
+  self:RegisterEvent("PLAYER_REGEN_DISABLED")
+  ReAction.RegisterCallback(self,"OnOptionsRegistered","OnOptionsRefreshed")
   ReAction.RegisterCallback(self,"OnOptionsRefreshed")
-  ReAction.RegisterCallback(self,"OnCreateBar")
-  ReAction.RegisterCallback(self,"OnEraseBar")
-  ReAction.RegisterCallback(self,"OnRenameBar")
   self:InitializeOptions()
-  self:RegisterEvent("PLAYER_REGEN_DISABLED")
-end
-
-
--- Creates a dispatcher to act as a handler and translate method calls from 
--- handler:method(info,value) to module:method(bar,value). If the opts table has
--- a handler set, that will be used instead of module.
--- Note: we replace the top level table if it's a group, giving it a new handler.
-local function CreateModuleBarDispatcher(module,bar,opts)
-  local g = { }
-  if opts.type == "group" then
-    for k,v in pairs(opts) do 
-      g[k] = v
-    end
-  else
-    g.type = "group"
-    g.name = module:GetName()
-    g.args = {
-      arg1 = opts
-    }
-  end
-  local handler = opts.handler or module
-  g.handler = setmetatable( {}, { 
-    __index = function(self, idx)
-      local f = rawget(self,idx)
-      if not f then
-        f = function(_, info, ...)
-          return handler[idx](handler, bar, ...)
-        end
-        rawset(self,idx,f)  -- cache for future use
-      end
-      return f
-    end 
-  })
-  return g
-end
-
-
-function module:OnOptionsRegistered(evt, context, module, opts)
-  local c = self.configOptions.args[context]
-  if context == "bar" then
-    for name,bar in pairs(ReAction.bars) do
-      local key = self.barOptMap[name]
-      if key then
-        self.editorOpts.args[key].plugins[module:GetName()] = { [module:GetName()] = CreateModuleBarDispatcher(module,bar,opts) }
-      end
-    end
-  elseif c then
-    for k, v in pairs(opts) do
-      c.args[k] = v
-    end
-  end
 end
 
 function module:OnOptionsRefreshed(evt)
-  AceConfigReg:NotifyChange("ReAction")
-  AceConfigReg:NotifyChange("ReAction-Editor")
-end
-
-function module:OnCreateBar(evt, bar)
-  local name = bar:GetName()
-  -- AceConfig doesn't allow spaces, etc, in arg key names, and they must be
-  -- unique strings. So generate a unique key (it can be whatever) for the bar
-  local args = self.editorOpts.args
-  local key
-  local i = 1
-  repeat
-    key = ("bar%s"):format(i)
-    i = i+1
-  until args[key] == nil
-  self.barOptMap[name] = key
-  args[key] = {
-    type = "group",
-    name = name,
-    childGroups = "tab",
-    args = {
-      general = {
-        type = "group",
-        name = L["General"],
-        order = 1,
-        args = {
-          name = {
-            type = "input",
-            name = L["Rename Bar"],
-            get  = function() return bar:GetName() end,
-            set  = function(info, value) return ReAction:RenameBar(bar, value) end,
-            order = 1,
-          },
-          delete = {
-            type = "execute",
-            name = L["Delete Bar"],
-            desc = function() return bar:GetName() end,
-            confirm = true,
-            func = function() ReAction:EraseBar(bar) end,
-            order = 2
-          },
-          anchor = {
-            type = "group",
-            name = L["Anchor"],
-            inline = true,
-            args = {
-              frame = {
-                type = "input",
-                name = L["Frame"],
-                desc = L["The frame that the bar is anchored to"],
-                get  = function() local _, f = bar:GetAnchor(); return f end,
-                set  = function(info, val) bar:SetAnchor(nil,val) end,
-                validate = function(info, name) 
-                    if name then
-                      local f = ReAction:GetBar(name)
-                      if f then
-                        return true
-                      else
-                        f = _G[name]
-                        if f and type(f) == "table" and f.IsObjectType and f:IsObjectType("Frame") then
-                          return true
-                        end
-                      end
-                    end
-                    return false
-                  end,
-                width = "double",
-                order = 1
-              },
-              point = {
-                type = "select",
-                name = L["Point"],
-                desc = L["Anchor point on the bar frame"],
-                style = "dropdown",
-                get  = function() return bar:GetAnchor() end,
-                set  = function(info, val) bar:SetAnchor(val) end,
-                values = pointTable,
-                order = 2,
-              },
-              relativePoint = {
-                type = "select",
-                name = L["Relative Point"],
-                desc = L["Anchor point on the target frame"],
-                style = "dropdown",
-                get  = function() local p,f,r = bar:GetAnchor(); return r end,
-                set  = function(info, val) bar:SetAnchor(nil,nil,val) end,
-                values = pointTable,
-                order = 3,
-              },
-              x = {
-                type = "input",
-                pattern = "\-?%d+",
-                name = L["X offset"],
-                get = function() local p,f,r,x = bar:GetAnchor(); return ("%d"):format(x) end,
-                set = function(info,val) bar:SetAnchor(nil,nil,nil,val) end,
-                order = 4
-              },
-              y = {
-                type = "input",
-                pattern = "\-?%d+",
-                name = L["Y offset"],
-                get = function() local p,f,r,x,y = bar:GetAnchor(); return ("%d"):format(y) end,
-                set = function(info,val) bar:SetAnchor(nil,nil,nil,nil,val) end,
-                order = 5
-              },
-            },
-            order = 3
-          },
-        },
-      },
-    },
-    plugins = { },
-  }
-
-  -- Create a dispatcher for all the module options tables registered to ReAction under the 'bar' context
-  for module, opts in pairs(ReAction:GetOptions("bar")) do
-    args[key].plugins[module:GetName()] = { [module:GetName()] = CreateModuleBarDispatcher(module, bar, opts) }
-  end
-end
-
-function module:OnEraseBar(evt, name)
-  local key = self.barOptMap[name]
-  self.barOptMap[name] = nil
-  if key then
-    self.editorOpts.args[key] = nil
-    self:RefreshBarEditor()
-  end
-end
-
-function module:OnRenameBar(evt, oldname, newname)
-  local key = self.barOptMap[oldname]
-  self.barOptMap[oldname], self.barOptMap[newname] = nil, key
-  if key then
-    self.editorOpts.args[key].name = newname
-    self:RefreshBarEditor()
-  end
+  AceConfigReg:NotifyChange(configName)
+  if self.editor then self.editor:Refresh() end
 end
 
 function module:PLAYER_REGEN_DISABLED()
@@ -252,84 +54,11 @@
 end
 
 function module:OpenConfig()
-  InterfaceOptionsFrame_OpenToFrame("ReAction")
-end
-
-function module:LaunchBarEditor(bar)
-  if InCombatLockdown() then
-    self:UserError(L["ReAction config mode disabled during combat."])
-  else
-    if not self.editor then
-      -- use a local container to work around AceConfigDialog closing
-      -- both the bar editor and the global options when interface options is closed
-      local ed = LibStub("AceGUI-3.0"):Create("Frame")
-      ed.frame:SetClampedToScreen(true)
-      local old_OnUpdate = ed.frame:GetScript("OnUpdate")
-      ed.frame:SetScript("OnUpdate", function(dt)
-          if old_OnUpdate then
-            old_OnUpdate(dt)
-          end
-          if ed.closePending then
-            InterfaceOptionsFrame:Hide()
-            ed.closePending = false
-          end
-          if ed.selfClosePending then
-            ed:Hide()
-            AceConfigReg:NotifyChange("ReAction")
-            ed.selfClosePending = false
-          end
-        end )
-      ed:SetCallback("OnClose", 
-        function() 
-          ReAction:SetConfigMode(false)
-        end )
-      self.editor = ed
-      AceConfigDialog:SetDefaultSize("ReAction-Editor", 640, 420)
-    end
-
-    AceConfigDialog:Open("ReAction-Editor", self.editor)
-    ReAction:SetConfigMode(true)
-  end
-end
-
-function module:RefreshBarEditor()
-  AceConfigReg:NotifyChange("ReAction-Editor")
-  if self.editor and self.editor.frame:IsShown() then
-    AceConfigDialog:Open("ReAction-Editor", self.editor)
-  end
-end
-
-function module:GetBarTypes()
-  local opts = self.optBarTypes or { }
-  self.optBarTypes = { }
-  for k,v in pairs(opts) do
-    opts[k] = nil
-  end
-  for k in pairs(ReAction.defaultBarConfig) do
-    opts[k] = k
-  end
-  return opts
-end
-
-function module:CreateBar()
-  if self.tmpBarName and self.tmpBarName ~= "" then
-    ReAction:CreateBar(self.tmpBarName, self.tmpBarType or ReAction.defaultBarConfigChoice, self.tmpBarRows, self.tmpBarCols, self.tmpBarSize, self.tmpBarSpacing)
-    self.tmpBarName = nil
-  end
+  InterfaceOptionsFrame_OpenToFrame(configName)
 end
 
 function module:InitializeOptions()
-  -- general config options
-  local opts = {
-    type = "group",
-    name = "ReAction",
-    childGroups = "tab",
-    args = {
-      _desc = {
-        type = "description",
-        name = L["Customizable replacement for Blizzard's Action Bars"],
-        order = 1,
-      },
+  ReAction:RegisterOptions(self, {
       _launchEditor = {
         type = "execute",
         handler = self,
@@ -354,67 +83,70 @@
         set  = function(info, val) self.db.profile.closeOnLaunch = val end,
         order = 3,
       },
-      global = {
-        type = "group",
-        name = L["Global Settings"],
-        desc = L["Global configuration settings"],
-        args = { },
-        order = 3,
-      },
-      _profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(ReAction.db),
-      module = {
-        type = "group",
-        childGroups = "select",
-        name = L["Module Settings"],
-        desc = L["Configuration settings for each module"],
-        args = { },
-        order = -1,
-      },
-    },
-    plugins = { }
-  }
-  self.configOptions = opts
-  opts.args._profile.order = -2
-  AceConfigReg:RegisterOptionsTable("ReAction",opts)
-  self.frame = AceConfigDialog:AddToBlizOptions("ReAction", "ReAction")
+    }, true) -- global
+
+  AceConfigReg:RegisterOptionsTable(configName,ReAction.options)
+  self.frame = AceConfigDialog:AddToBlizOptions(configName, configName)
   self.frame.obj:SetCallback("default", 
     function() 
       ReAction.db:ResetProfile()
-      module:OpenConfig()
+      self:OnOptionsRefreshed()
     end )
+end
 
-  -- import options from registered modules
-  for c, tbl in pairs(opts.args) do
-    for _, m in pairs(ReAction:GetOptions(c)) do
-      for k, v in pairs(m) do
-        tbl.args[k] = v
+
+
+
+-- Bar Editor --
+local function NewEditor()
+  -- private variables
+  local editorName = "ReAction-Editor"
+  local barOptMap = { }
+  local tmp = { }
+  local pointTable = {
+    CENTER      = L["Center"], 
+    LEFT        = L["Left"],
+    RIGHT       = L["Right"],
+    TOP         = L["Top"],
+    BOTTOM      = L["Bottom"],
+    TOPLEFT     = L["Top Left"],
+    TOPRIGHT    = L["Top Right"],
+    BOTTOMLEFT  = L["Bottom Left"],
+    BOTTOMRIGHT = L["Bottom Right"],
+  }
+
+
+  -- use a local GUI container to work around AceConfigDialog closing
+  -- both the bar editor and the global options when interface options is closed
+  local editor = LibStub("AceGUI-3.0"):Create("Frame")
+  local frame = editor.frame
+  frame:SetClampedToScreen(true)
+  local old_OnUpdate = frame:GetScript("OnUpdate")
+  frame:SetScript("OnUpdate", function(dt)
+      if old_OnUpdate then
+        old_OnUpdate(dt)
       end
-    end
-  end
+      if editor.closePending then
+        InterfaceOptionsFrame:Hide()
+        editor.closePending = false
+      end
+      if editor.selfClosePending then
+        ed:Hide()
+        AceConfigReg:NotifyChange(configName)
+        editor.selfClosePending = false
+      end
+    end )
+  editor:SetCallback("OnClose", 
+    function() 
+      ReAction:SetConfigMode(false)
+    end )
+  AceConfigDialog:SetDefaultSize(editorName, 700, 420)
+  
 
-  ReAction:RegisterOptions("module",self, {
-    configUI = {
-      type = "group",
-      name = "Config UI",
-      desc = "description",
-      args = {
-        foo = {
-          type = "toggle",
-          handler = self,
-          name = "foo",
-          desc = "description",
-          get = function() return true end,
-          set = function() end,
-        }
-      }
-    },
-  })
-
-  -- bar editor options
-  local editorOpts = {
+  local options = {
     type = "group",
     name = ("ReAction - %s"):format(L["Bar Editor"]),
-    handler = self,
+    handler = editor,
     childGroups = "tree",
     args = {
       desc = {
@@ -427,12 +159,12 @@
         name = L["Global Config"],
         desc = L["Opens ReAction global configuration settings panel"],
         func = function()
-            self:OpenConfig()
+            module:OpenConfig()
             -- you can't close a dialog in response to an options click, because the end of the 
             -- handler for all the button events calls lib:Open()
             -- So, schedule a close on the next OnUpdate
-            if self.db.profile.editorCloseOnLaunch then
-              self.editor.selfClosePending = true
+            if module.db.profile.editorCloseOnLaunch then
+              editor.selfClosePending = true
             end
           end,
         order = 2
@@ -441,8 +173,8 @@
         type = "toggle",
         name = L["Close on Launch"],
         desc = L["Close the Bar Editor when opening the ReAction global Interface Options"],
-        get  = function() return self.db.profile.editorCloseOnLaunch end,
-        set  = function(info, val) self.db.profile.editorCloseOnLaunch = val end,
+        get  = function() return module.db.profile.editorCloseOnLaunch end,
+        set  = function(info, val) module.db.profile.editorCloseOnLaunch = val end,
         order = 3,
       },
       new = {
@@ -459,21 +191,21 @@
             type = "input",
             name = L["Bar Name"],
             desc = L["Enter a name for your new action bar"],
-            get  = function() return self.tmpBarName or "" end,
-            set  = function(info, val) self.tmpBarName = val end,
+            get  = function() return tmp.barName or "" end,
+            set  = function(info, val) tmp.barName = val end,
             order = 2,
           },
           type = {
             type = "select",
             name = L["Button Type"],
-            get  = function() return self.tmpBarType or ReAction.defaultBarConfigChoice or "" end,
+            get  = function() return tmp.barType or ReAction.defaultBarConfigChoice or "" end,
             set  = function(info, val) 
                      local c = ReAction.defaultBarConfig[val]
-                     self.tmpBarType = val 
-                     self.tmpBarSize = c.defaultButtonSize or self.tmpBarSize
-                     self.tmpBarRows = c.defaultBarRows or self.tmpBarRows
-                     self.tmpBarCols = c.defaultBarCols or self.tmpBarCols
-                     self.tmpBarSpacing = c.defaultBarSpacing or self.tmpBarSpacing
+                     tmp.barType = val 
+                     tmp.barSize = c.defaultButtonSize or tmp.barSize
+                     tmp.barRows = c.defaultBarRows or tmp.barRows
+                     tmp.barCols = c.defaultBarCols or tmp.barCols
+                     tmp.barSpacing = c.defaultBarSpacing or tmp.barSpacing
                    end,
             values = "GetBarTypes",
             order = 3,
@@ -491,8 +223,8 @@
               rows = {
                 type = "range",
                 name = L["Rows"],
-                get  = function() return self.tmpBarRows or 1 end,
-                set  = function(info, val) self.tmpBarRows = val end,
+                get  = function() return tmp.barRows or 1 end,
+                set  = function(info, val) tmp.barRows = val end,
                 width = "half",
                 min = 1,
                 max = 32,
@@ -502,8 +234,8 @@
               cols = {
                 type = "range",
                 name = L["Columns"],
-                get  = function() return self.tmpBarCols or 12 end,
-                set  = function(info, val) self.tmpBarCols = val end,
+                get  = function() return tmp.barCols or 12 end,
+                set  = function(info, val) tmp.barCols = val end,
                 width = "half",
                 min = 1, 
                 max = 32,
@@ -513,8 +245,8 @@
               sz = {
                 type = "range",
                 name = L["Size"],
-                get  = function() return self.tmpBarSize or 36 end,
-                set  = function(info, val) self.tmpBarSize = val end,
+                get  = function() return tmp.barSize or 36 end,
+                set  = function(info, val) tmp.barSize = val end,
                 width = "half",
                 min = 10,
                 max = 72,
@@ -524,8 +256,8 @@
               spacing = {
                 type = "range",
                 name = L["Spacing"],
-                get  = function() return self.tmpBarSpacing or 3 end,
-                set  = function(info, val) self.tmpBarSpacing = val end,
+                get  = function() return tmp.barSpacing or 3 end,
+                set  = function(info, val) tmp.barSpacing = val end,
                 width = "half",
                 min = 0,
                 max = 24,
@@ -551,8 +283,201 @@
       }
     }
   }
-  self.editorOpts = editorOpts
-  self.barOptMap = { }
-  AceConfigReg:RegisterOptionsTable("ReAction-Editor",editorOpts)
+  AceConfigReg:RegisterOptionsTable(editorName, options)
+
+  function editor:Open()
+    AceConfigDialog:Open(editorName,self)
+  end
+
+  function editor:Refresh()
+    AceConfigReg:NotifyChange(editorName)
+    if frame:IsShown() then
+      self:Open() -- do I need this?
+    end
+  end
+
+  function editor:CreateBarTree(bar)
+    local name = bar:GetName()
+    -- AceConfig doesn't allow spaces, etc, in arg key names, and they must be
+    -- unique strings. So generate a unique key (it can be whatever) for the bar
+    local args = options.args
+    local key
+    local i = 1
+    repeat
+      key = ("bar%s"):format(i)
+      i = i+1
+    until args[key] == nil
+    barOptMap[name] = key
+    args[key] = {
+      type = "group",
+      name = name,
+      childGroups = "tab",
+      args = {
+        general = {
+          type = "group",
+          name = L["General"],
+          order = 1,
+          args = {
+            name = {
+              type = "input",
+              name = L["Rename Bar"],
+              get  = function() return bar:GetName() end,
+              set  = function(info, value) return ReAction:RenameBar(bar, value) end,
+              order = 1,
+            },
+            delete = {
+              type = "execute",
+              name = L["Delete Bar"],
+              desc = function() return bar:GetName() end,
+              confirm = true,
+              func = function() ReAction:EraseBar(bar) end,
+              order = 2
+            },
+            anchor = {
+              type = "group",
+              name = L["Anchor"],
+              inline = true,
+              args = {
+                frame = {
+                  type = "input",
+                  name = L["Frame"],
+                  desc = L["The frame that the bar is anchored to"],
+                  get  = function() local _, f = bar:GetAnchor(); return f end,
+                  set  = function(info, val) bar:SetAnchor(nil,val) end,
+                  validate = function(info, name) 
+                      if name then
+                        local f = ReAction:GetBar(name)
+                        if f then
+                          return true
+                        else
+                          f = _G[name]
+                          if f and type(f) == "table" and f.IsObjectType and f:IsObjectType("Frame") then
+                            return true
+                          end
+                        end
+                      end
+                      return false
+                    end,
+                  width = "double",
+                  order = 1
+                },
+                point = {
+                  type = "select",
+                  name = L["Point"],
+                  desc = L["Anchor point on the bar frame"],
+                  style = "dropdown",
+                  get  = function() return bar:GetAnchor() end,
+                  set  = function(info, val) bar:SetAnchor(val) end,
+                  values = pointTable,
+                  order = 2,
+                },
+                relativePoint = {
+                  type = "select",
+                  name = L["Relative Point"],
+                  desc = L["Anchor point on the target frame"],
+                  style = "dropdown",
+                  get  = function() local p,f,r = bar:GetAnchor(); return r end,
+                  set  = function(info, val) bar:SetAnchor(nil,nil,val) end,
+                  values = pointTable,
+                  order = 3,
+                },
+                x = {
+                  type = "input",
+                  pattern = "\-?%d+",
+                  name = L["X offset"],
+                  get = function() local p,f,r,x = bar:GetAnchor(); return ("%d"):format(x) end,
+                  set = function(info,val) bar:SetAnchor(nil,nil,nil,val) end,
+                  order = 4
+                },
+                y = {
+                  type = "input",
+                  pattern = "\-?%d+",
+                  name = L["Y offset"],
+                  get = function() local p,f,r,x,y = bar:GetAnchor(); return ("%d"):format(y) end,
+                  set = function(info,val) bar:SetAnchor(nil,nil,nil,nil,val) end,
+                  order = 5
+                },
+              },
+              order = 3
+            },
+          },
+        },
+      }
+    }
+    self:RefreshBarTree(bar)
+  end
+
+  function editor:RefreshBarTree(bar)
+    local opts = options.args[barOptMap[bar:GetName()]]
+    opts.plugins = { }
+    for name, module in ReAction:IterateModules() do
+      if module.GetBarOptions then
+        opts.plugins[module:GetName()] = { [module:GetName()] = module:GetBarOptions(bar) }
+      end
+    end
+  end
+
+  function editor:OnCreateBar(evt, bar)
+    self:CreateBarTree(bar)
+  end
+
+  function editor:OnEraseBar(evt, name)
+    local key = barOptMap[name]
+    barOptMap[name] = nil
+    if key then
+      options.args[key] = nil
+      self:Refresh()
+    end
+  end
+
+  function editor:OnRenameBar(evt, oldname, newname)
+    local key = barOptMap[oldname]
+    barOptMap[oldname], barOptMap[newname] = nil, key
+    if key then
+      options.args[key].name = newname
+      self:Refresh()
+    end
+  end
+  
+  local _scratch = { }
+  function editor:GetBarTypes()
+    for k,v in pairs(_scratch) do
+      _scratch[k] = nil
+    end
+    for k in pairs(ReAction.defaultBarConfig) do
+      _scratch[k] = k
+    end
+    return _scratch
+  end
+
+  function editor:CreateBar()
+    if tmp.barName and tmp.barName ~= "" then
+      ReAction:CreateBar(tmp.barName, tmp.barType or ReAction.defaultBarConfigChoice, tmp.barRows, tmp.barCols, tmp.barSize, tmp.barSpacing)
+      tmp.barName = nil
+    end
+  end
+
+  ReAction.RegisterCallback(editor,"OnCreateBar")
+  ReAction.RegisterCallback(editor,"OnEraseBar")
+  ReAction.RegisterCallback(editor,"OnRenameBar")
+
+  for name, bar in pairs(ReAction.bars) do
+    editor:CreateBarTree(bar)
+  end
+
+  return editor
 end
 
+
+function module:LaunchBarEditor(bar)
+  if InCombatLockdown() then
+    self:UserError(L["ReAction config mode disabled during combat."])
+  else
+    if not self.editor then
+      self.editor = NewEditor()
+    end
+    self.editor:Open()
+    ReAction:SetConfigMode(true)
+  end
+end
+
--- a/modules/ReAction_ConfigUI/lib/embeds.xml	Mon Apr 28 23:34:17 2008 +0000
+++ b/modules/ReAction_ConfigUI/lib/embeds.xml	Sat May 10 00:08:01 2008 +0000
@@ -5,7 +5,6 @@
   <Include file="AceGUI-3.0\AceGUI-3.0.xml"/>
   <Include file="AceConfigRegistry-3.0\AceConfigRegistry-3.0.xml"/>
   <Include file="AceConfigDialog-3.0\AceConfigDialog-3.0.xml"/>
-  <Include file="AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
 
 </Ui>
  
\ No newline at end of file
--- a/modules/ReAction_HideBlizzard/ReAction_HideBlizzard.lua	Mon Apr 28 23:34:17 2008 +0000
+++ b/modules/ReAction_HideBlizzard/ReAction_HideBlizzard.lua	Sat May 10 00:08:01 2008 +0000
@@ -29,23 +29,25 @@
 
   self.hiddenFrame = CreateFrame("Frame")
   self.hiddenFrame:Hide()
+
+  ReAction:RegisterOptions(self, {
+      hideBlizzard = {
+        type = "toggle",
+        handler = self,
+        name = L["Hide Blizzard Action Bars"],
+        desc = L["Hide the default main bar and extra action bars"],
+        get  = "IsHidden",
+        set  = function(info,value) self:SetHidden(value) end,
+        disabled = InCombatLockdown
+      },
+    }, true) -- global
+
 end
 
 function module:OnEnable()
   if self.db.profile.hide then
     self:HideAll(true)
   end
-  ReAction:RegisterOptions("global", self, {
-    hideBlizzard = {
-      type = "toggle",
-      handler = self,
-      name = L["Hide Blizzard Action Bars"],
-      desc = L["Hide the default main bar and extra action bars"],
-      get  = "IsHidden",
-      set  = function(info,value) self:SetHidden(value) end,
-      disabled = InCombatLockdown
-    }
-  })
 
   -- reroute blizzard action bar config to ReAction config window
   InterfaceOptionsActionBarsPanel:HookScript("OnShow", 
--- a/modules/ReAction_PetAction/ReAction_PetAction.lua	Mon Apr 28 23:34:17 2008 +0000
+++ b/modules/ReAction_PetAction/ReAction_PetAction.lua	Sat May 10 00:08:01 2008 +0000
@@ -27,17 +27,7 @@
     }
   )
   self.buttons = { }
-
-  ReAction:RegisterOptions("global", self, {
-  })
-
-  ReAction:RegisterOptions("bar", self, {
-    type = "group",
-    name = L["Pet Buttons"],
-    hidden = "BarOptionsHidden",
-    args = {
-    }
-  })
+  self.options = setmetatable({},{__mode="k"})
 end
 
 function module:OnEnable()
@@ -133,7 +123,6 @@
           if mode then
             self:showActionIDLabel(b)
           else
-            ReAction:Print("Hiding action id "..b:GetActionID())
             self:hideActionIDLabel(b)
           end
         end
@@ -166,14 +155,21 @@
 function module:hideActionIDLabel(button)
   if button:GetFrame().actionIDLabel then
     button:GetFrame().actionIDLabel:Hide()
-  else
-    ReAction:Print("actionIDLabel not found")
   end
 end
 
----- Options handlers ----
-function module:BarOptionsHidden(bar)
-  return bar.config.type ~= moduleID
+---- Options ----
+function module:GetBarOptions(bar)
+  if not self.options[bar] then
+    self.options[bar] = {
+      type = "group",
+      name = L["Pet Buttons"],
+      hidden = function() return bar.config.type ~= moduleID end,
+      args = {
+      }
+    }
+  end
+  return self.options[bar]
 end
 
 
--- a/modules/ReAction_PossessBar/ReAction_PossessBar.lua	Mon Apr 28 23:34:17 2008 +0000
+++ b/modules/ReAction_PossessBar/ReAction_PossessBar.lua	Sat May 10 00:08:01 2008 +0000
@@ -26,23 +26,22 @@
     }
   )
   self.buttons = { }
+  self.options = setmetatable({},{__mode="k"})
 
-  ReAction:RegisterOptions("global", self, {
-    hideEmptyPossess = {
-      type = "toggle",
-      name = L["Hide Empty Possess Bar Buttons"],
-      get  = function() return self.db.profile.hideEmptyButtons end,
-      set  = function(info, val) module:SetHideEmptyButtons(val) end,
-    }
-  })
-
-  ReAction:RegisterOptions("bar", self, {
-    type = "group",
-    name = L["Possess Buttons"],
-    hidden = "BarOptionsHidden",
-    args = {
-    }
-  })
+  ReAction:RegisterOptions(self, {
+      [moduleID] = {
+        type = "group",
+        name = L["Possess Bar"],
+        args = {
+          hideEmptyPossess = {
+            type = "toggle",
+            name = L["Hide Empty Possess Bar Buttons"],
+            get  = function() return self.db.profile.hideEmptyButtons end,
+            set  = function(info, val) module:SetHideEmptyButtons(val) end,
+          }
+        }
+      }
+    })
 end
 
 function module:OnEnable()
@@ -256,9 +255,18 @@
   end
 end
 
----- Options handlers ----
-function module:BarOptionsHidden(bar)
-  return bar.config.type ~= moduleID
+---- Options ----
+function module:GetBarOptions(bar)
+  if not self.options[bar] then
+    self.options[bar] = {
+      type = "group",
+      name = L["Possess Buttons"],
+      hidden = function() return bar.config.type ~= moduleID end,
+      args = {
+      }
+    }
+  end
+  return self.options[bar]
 end