Mercurial > wow > reaction
diff ReAction.lua @ 257:920d17851a93 stable
Merge 1.1 beta 4 to stable
author | Flick |
---|---|
date | Tue, 12 Apr 2011 16:06:31 -0700 |
parents | 47818b3938c9 |
children | 9e708a155ab9 |
line wrap: on
line diff
--- a/ReAction.lua Thu Nov 18 13:11:08 2010 -0800 +++ b/ReAction.lua Tue Apr 12 16:06:31 2011 -0700 @@ -3,59 +3,120 @@ local pairs = pairs local type = type local geterrorhandler = geterrorhandler -local LKB = LibStub("LibKeyBound-1.0") local L = LibStub("AceLocale-3.0"):GetLocale("ReAction") +local LKB = LibStub("LibKeyBound-1.0",true) +if not LKB then + LoadAddOn("LibKeyBound-1.0") + LKB = LibStub("LibKeyBound-1.0") +end ------ Utility ------ -local tcopy -do - function tcopy(x) - if type(x) ~= "table" then - return x - end - local r = {} - for k,v in pairs(x) do - r[k] = tcopy(v) - end - return r +-- make a deep copy of a table +local function tcopy(x) + if type(x) ~= "table" then + return x end + local r = {} + for k,v in pairs(x) do + r[k] = tcopy(v) + end + return r end +-- traverse a table tree by key list and fetch the result or first nil +local function tfetch(t, ...) + for i = 1, select('#', ...) do + t = t and t[select(i, ...)] + end + return t +end + +-- traverse a table tree by key list and build tree as necessary +local function tbuild(t, ...) + for i = 1, select('#', ...) do + local key = select(i, ...) + if not t[key] then t[key] = { } end + t = t[key] + end + return t +end + +-- return a new array of keys of table 't', sorted by comparing +-- sub-fields (obtained via tfetch) of the table values +local function fieldsort( t, ... ) + local r = { } + for k in pairs(t) do + table.insert(r,k) + end + local path = { ... } + table.sort(r, function(lhs, rhs) + local olhs = tfetch(t[lhs], unpack(path)) or 0 + local orhs = tfetch(t[rhs], unpack(path)) or 0 + return olhs < orhs + end) + return r +end + +-- store in the addon table +addonTable.tcopy = tcopy +addonTable.tfetch = tfetch +addonTable.tbuild = tbuild +addonTable.fieldsort = fieldsort + ------ Core ------ local ReAction = LibStub("AceAddon-3.0"):NewAddon( "ReAction", "AceEvent-3.0" ) addonTable.ReAction = ReAction -ReAction.version = "1.1" +ReAction.version = GetAddOnMetadata("ReAction","Version") ReAction.L = L ReAction.LKB = LKB +ReAction.barTypes = { } + ------ Handlers ------ function ReAction:OnInitialize() self.db = LibStub("AceDB-3.0"):New("ReAction_DB", - { - profile = { - bars = { }, - defaultBar = { }, - } - }, + self.defaultProfile, true -- use global 'Default' (locale-specific) ) + self:UpgradeProfile() + self.bars = { } - self.defaultBarConfig = { } + + self.LBF = LibStub("LibButtonFacade",true) + if self.LBF then + self.LBF:RegisterSkinCallback("ReAction", self.OnSkinChanged, self) + end + + -- It's fairly normal to use the Blizzard vehicle bar, and to have + -- your regular buttons in the same location. If you do this, and don't + -- bother to hide your buttons, they'll obscure some parts of the vehicle bar. + VehicleMenuBar:SetFrameLevel(VehicleMenuBar:GetFrameLevel()+3) self.callbacks = LibStub("CallbackHandler-1.0"):New(self) + LKB.RegisterCallback(self,"LIBKEYBOUND_ENABLED") LKB.RegisterCallback(self,"LIBKEYBOUND_DISABLED") LKB.RegisterCallback(self, "LIBKEYBOUND_MODE_COLOR_CHANGED","LIBKEYBOUND_ENABLED") + + -- see Profile.lua for these callback implementations + self.db.RegisterCallback(self,"OnProfileChanged") + self.db.RegisterCallback(self,"OnProfileCopied","OnProfileChanged") + self.db.RegisterCallback(self,"OnNewProfile") + self.db.RegisterCallback(self,"OnProfileReset", "OnNewProfile") + self:RegisterEvent("PLAYER_REGEN_DISABLED") + self:RegisterEvent("UPDATE_SHAPESHIFT_FORMS") + self:InitializeOptions() end function ReAction:OnEnable() self:InitializeBars() + self:UPDATE_SHAPESHIFT_FORMS() -- it doesn't fire on a /reloadui end function ReAction:OnDisable() @@ -71,6 +132,16 @@ end end +function ReAction:UPDATE_SHAPESHIFT_FORMS() + -- Re-parse the rules table according to the new form list. + -- This happens both at initial login (after PLAYER_ENTERING_WORLD) + -- as well as when gaining new abilities. + self.Bar:InitRuleFormats() + for _, bar in self:IterateBars() do + bar:ApplyStates() + end +end + function ReAction:LIBKEYBOUND_ENABLED( evt ) self:SetKeybindMode(true) end @@ -79,6 +150,24 @@ return self:SetKeybindMode(false) end +function ReAction:OnSkinChanged( skinID, gloss, backdrop, group, button, colors ) + if group == nil then + -- don't store global + else + -- 'group' is the bar-name + local bar = self:GetBar(group) + if bar then + local c = bar:GetConfig().ButtonFacade + if c then + c.skinID = skinID + c.gloss = gloss + c.backdrop = backdrop + c.colors = colors + end + end + end +end + ------ Methods ------ @@ -110,31 +199,26 @@ function ReAction:CreateBar(name, config, ...) local profile = self.db.profile - if name then - if self.bars[name] then - self:UserError(format(L["ReAction: name '%s' already in use"],name)) - return nil - end - else - local prefix = L["Bar "] - local i = 1 - repeat - name = prefix..i - i = i + 1 - until self.bars[name] == nil + name = tostring(name) + if not name or name == "" then + error("ReAction:CreateBar() - bar name string required") + elseif self.bars[name] then + self:UserError(format(L["ReAction: name '%s' already in use"],name)) + return nil end + local class if type(config) == "string" then - config = self.defaultBarConfig[config] - if not config then - error(("ReAction:CreateBar() - unknown bar type '%s'"):format(tostring(select(1,...)))) + class = self.barTypes[config] + if not class then + error(("ReAction:CreateBar() - unknown bar type '%s'"):format(config)) end - config = tcopy(config) - config.btnRows = select(1,...) or config.btnRows or 1 - config.btnColumns = select(2,...) or config.btnColumns or 12 - config.btnWidth = select(3,...) or config.btnWidth or 36 - config.btnHeight = select(3,...) or config.btnHeight or 36 - config.spacing = select(4,...) or config.spacing or 3 + config = tcopy(class:GetDefaultBarConfig()) + config.btnRows = select(1,...) or config.btnRows + config.btnColumns = select(2,...) or config.btnColumns + config.btnWidth = select(3,...) or config.btnWidth + config.btnHeight = select(3,...) or config.btnHeight + config.spacing = select(4,...) or config.spacing config.width = config.width or config.btnColumns*(config.btnWidth + config.spacing) + 1 config.height = config.height or config.btnRows*(config.btnHeight + config.spacing) + 1 config.anchor = config.anchor or "UIParent" @@ -142,11 +226,16 @@ config.relpoint = config.relpoint or "BOTTOM" config.y = config.y or 200 config.x = config.x or 0 + else + config = config or profile.bars[name] or { } + if not config or not config.type or not self.barTypes[config.type] then + error(("ReAction: Unable to construct/fetch config table for bar '%s'"):format(name)) + end + class = self.barTypes[config.type] end - config = config or profile.bars[name] or tcopy(profile.defaultBar) profile.bars[name] = config - local bar = self.Bar:New( name, config ) -- ReAction.Bar defined in Bar.lua + local bar = self.Bar:New( name, config, class ) -- ReAction.Bar defined in Bar.lua self.bars[name] = bar self.callbacks:Fire("OnCreateBar", bar, name) if self.configMode then @@ -165,24 +254,18 @@ end end -function ReAction:RefreshBar(x) - local bar, name = self:GetBar(x) - if bar and name then - self.callbacks:Fire("OnRefreshBar", bar, name) - end -end - function ReAction:InitializeBars() if not self.barsInitialized then + self:ManageBlizzardBars() + for name, config in pairs(self.db.profile.bars) do if config then self:CreateBar(name, config) end end - -- re-anchor and refresh in case anchor order does not match init order + -- re-anchor in case anchor order does not match init order for name, bar in pairs(self.bars) do bar:ApplyAnchor() - self.callbacks:Fire("OnRefreshBar", bar, name) end self.barsInitialized = true end @@ -226,35 +309,57 @@ function ReAction:EraseBar(x) local bar, name = self:GetBar(x) if bar and name then - self.callbacks:Fire("OnEraseBar", bar, name) self:DestroyBar(bar) self.db.profile.bars[name] = nil end end -function ReAction:RegisterBarType( name, config, isDefaultChoice ) - self.defaultBarConfig[name] = config - if isDefaultChoice then - self.defaultBarConfigChoice = name +local blizzFrames = { + MainMenuBar, + MultiBarLeft, + MultiBarRight, + MultiBarBottomLeft, + MultiBarBottomRight, +} + +local hideFrame = CreateFrame("Frame") +hideFrame:Hide() +local hiddenParents = { } +local function ManageBlizzFrame(f, hide) + if hide and not hiddenParents[f] then + hiddenParents[f] = f:GetParent() + f:SetParent(hideFrame) + elseif not hide and hiddenParents[f] then + f:SetParent(hiddenParents[f]) + hiddenParents[f] = nil + if f:IsShown() then + f:Show() -- refresh + end end - self:RefreshEditor() end -function ReAction:UnregisterBarType( name ) - self.defaultBarConfig[name] = nil - if self.defaultBarConfigChoice == name then - self.defaultBarConfigChoice = nil +function ReAction:ManageBlizzardBars() + for _, f in pairs(blizzFrames) do + ManageBlizzFrame(f, self.db.profile.options.hideBlizzardBars) end - self:RefreshEditor() + ManageBlizzFrame(VehicleMenuBar, self.db.profile.options.hideBlizzardVehicleBar) +end + +function ReAction:RegisterBarType( class, isDefault ) + local name = class:GetButtonTypeID() + self.barTypes[name] = class + if isDefault then + self.defaultBarType = name + end end function ReAction:IterateBarTypes() - return pairs(self.defaultBarConfig) + return pairs(self.barTypes) end -function ReAction:GetBarTypeConfig(name) - if name then - return self.defaultBarConfig[name] +function ReAction:GetDefaultBarConfig(barType) + if barType and self.barTypes[barType] then + return self.barTypes[barType]:GetDefaultBarConfig() end end @@ -267,7 +372,7 @@ end function ReAction:GetDefaultBarType() - return self.defaultBarConfigChoice + return self.defaultBarType end function ReAction:SetConfigMode( mode ) @@ -302,3 +407,18 @@ function ReAction:GetKeybindMode( mode ) return self.kbMode end + + +-- ConfigMode support +CONFIGMODE_CALLBACKS = CONFIGMODE_CALLBACKS or {} + +function CONFIGMODE_CALLBACKS.ReAction( action, mode ) + if action == "ON" then + ReAction:SetConfigMode(true) + elseif action == "OFF" then + ReAction:SetConfigMode(false) + elseif action == "LISTMODES" then + -- no modes + end +end +