Mercurial > wow > reaction
view ReAction_Bar.lua @ 27:f1e838841ce1
Rearranged file tree, removed unused code for 1.x start-point
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Tue, 11 Mar 2008 21:39:34 +0000 |
parents | bf997ea151ca |
children |
line wrap: on
line source
--[[ ReAction bar module. This is the heart of ReAction, the bar management module. Many of its functions turn around and iterate all modules registered to the ReAction parent core. Also defined in this file is the Bar class implementation, which can be used by other modules to manipulate the action bars. Many of the module iterated calls pass a bar or list of bars as an argument. Module methods called by the Bar module: module:ApplyToBar(bar) module:RemoveFromBar(bar) module:RefreshBar(bar) module:ApplyConfigMode(mode,listOfBars) module:GetBarNameModifier(bar) module:EraseBarConfig(barName) useful Bar object API (partial list): f = bar:GetFrame() -- f is derived from SecureStateDriver bar:RefreshLayout() w,h = bar:GetSize() r,c,s = bar:GetButtonGrid() -- #rows, #columns, inter-button spacing name = bar:GetName() bar:PlaceButton(frame, idx, baseSizeX, baseSizeY) -- idx is 1-based --]] -- local imports local ReAction = ReAction local L = ReAction.L local _G = _G local AceOO = AceLibrary("AceOO-2.0") local CreateFrame = CreateFrame local geterrorhandler = geterrorhandler local pcall = pcall local print = ReAction.print -- update ReAction revision if this file is newer local revision = tonumber(("$Revision: 1 $"):match("%d+")) if revision > ReAction.revision then Reaction.revision = revision end local moduleID = "Bar" -- -- Bar module declaration -- local module = ReAction:NewModule( moduleID ) -- -- Bar class declaration -- local BarClass = AceOO.Class() local Bar = BarClass.prototype module.BarClass = BarClass -- -- local utility -- local function deepCopy(x) if type(x) ~= "table" then return x end local r = {} for k,v in pairs(x) do r[k] = deepCopy(v) end return r end -- -- Bar module implementation -- function module:OnInitialize() self.db = ReAction:AcquireDBNamespace(moduleID) ReAction:RegisterDefaults(moduleID,"profile", { bars = { }, defaultBar = { } } ) self.bars = {} end function module:OnEnable() self:InitializeBars() end function module:OnDisable() self:TearDownBars() end function module:OnProfileEnable() self:InitializeBars() end function module:OnProfileDisable() self:TearDownBars() end function module:InitializeBars() if not(self.inited) then for name, config in pairs(self.db.profile.bars) do if config then self:CreateBar(name, config) end end self:CallMethodOnAllBars("ApplyAnchor") -- re-anchor in the case of oddball ordering self.inited = true end end function module:TearDownBars() for name, bar in pairs(self.bars) do if bar then self.bars[name] = self:DeleteBar(bar) end end self.inited = false end -- Gets config from existing DB name or default if not supplied -- Saves to DB if name not known function module:CreateBar(name, config) local profile = self.db.profile if not name then i = 1 repeat name = L["Bar "]..i i = i + 1 until self.bars[name] == nil end config = config or profile.bars[name] or deepCopy(profile.defaultBar) if not profile.bars[name] then profile.bars[name] = config end local bar = self.BarClass:new( name, config ) ReAction:CallMethodOnAllModules("ApplyToBar", bar) self.bars[name] = bar return bar end local SelectBar do SelectBar = function(x) local bar, name if type(x) == "string" then name = x bar = module:GetBar(name) elseif AceOO.inherits(x,BarClass) then bar = x for k,v in pairs(module.bars) do if v == bar then name = k end end else error("bad argument to SelectBar") end return bar, name end end -- Takes either a bar name string or a bar object. -- Does NOT destroy the DB entry, this function is only used for -- enable/disable and profile switching. To remove a bar permanently, -- use EraseBar() instead. function module:DeleteBar(x) local bar, name = SelectBar(x) if name and bar then self.bars[name] = nil ReAction:CallMethodOnAllModules("RemoveFromBar", bar) bar:Destroy() end end function module:EraseBar(x) local bar, name = SelectBar(x) if name and bar then self:DeleteBar(bar) self.db.profile.bars[name] = nil ReAction:CallMethodOnAllModules("EraseBarConfig", name) end end function module:GetBar(name) return self.bars[name] end function module:RenameBar(x, newname) local bar, name = SelectBar(x) if bar and name and newname then if self.bars[newname] then error(L["ReAction: name already in use"]) end self.bars[newname] = self.bars[name] self.bars[name] = nil bar:SetName(newname) local cfg = self.db.profile.bars cfg[newname], cfg[name] = cfg[name], nil end end function module:CallMethodOnAllBars(method,...) local m if type(method) == "function" then m = method elseif type(method) ~= "string" then error("Invalid method passed to ReAction_Bar:CallMethodOnAllBars()") end for _, bar in pairs(self.bars) do if bar then local m = m or bar[method] if m then local success,err = pcall(m,bar,...) if not success then geterrorhandler()(err) end end end end end function module:GetBarMenuOptions(bar) if not(bar.modMenuOpts[moduleID]) then bar.modMenuOpts[moduleID] = { delete = { type = "execute", name = L["Delete Bar"], desc = L["Remove the bar from the current profile"], func = function() self:EraseBar(bar) end, order = 1 }, } end return bar.modMenuOpts[moduleID] end function module:GetBarConfigOptions(bar, cfgModule) if not(bar.modConfigOpts[moduleID]) then bar.modConfigOpts[moduleID] = { delete = { type = "execute", name = L["Delete Bar"], desc = L["Remove the bar from the current profile"], func = function() self:EraseBar(bar); cfgModule:RefreshConfig() end }, rename = { type = "text", name = L["Rename Bar"], desc = L["Set a name for the bar"], get = "GetName", set = function(name) self:RenameBar(bar,name); cfgModule:RefreshConfig() end } } end return bar.modConfigOpts[moduleID] end -- -- Bar class implementation -- function Bar:init( name, config ) BarClass.super.prototype.init(self) self.name, self.config = name, config if type(config) ~= "table" then error("ReAction:Bar: config table required") end local f = CreateFrame("Frame",nil,config.parent or UIParent,"SecureStateDriverTemplate") f:SetFrameStrata("MEDIUM") config.width = config.width or 400 config.height = config.height or 80 f:SetWidth(config.width) f:SetWidth(config.height) self.frame = f self:RefreshLayout() self:ApplyAnchor() f:Show() end function Bar:Destroy() local f = self.frame f:UnregisterAllEvents() f:Hide() f:SetParent(UIParent) f:ClearAllPoints() self.labelString = nil self.controlFrame = nil self.frame = nil self.config = nil end function Bar:RefreshLayout() ReAction:CallMethodOnAllModules("RefreshBar", self) end function Bar:ApplyAnchor() local f, config = self.frame, self.config f:SetWidth(config.width) f:SetHeight(config.height) local anchor = config.anchor if anchor then local anchorTo if config.anchorTo then anchorTo = module:GetBar(config.anchorTo) or _G[config.anchorTo] end f:SetPoint(anchor, anchorTo, config.relativePoint, config.x or 0, config.y or 0) else f:SetPoint("CENTER") end end function Bar:GetFrame() return self.frame end function Bar:GetSize() return self.frame:GetWidth() or 200, self.frame:GetHeight() or 200 end function Bar:SetSize(w,h) self.config.width = w self.config.height = 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 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: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 end -- This should only be called from module:RenameBar(), otherwise -- the bar's internal name and the module's list of bars by name -- can get out of sync. function Bar:SetName( name ) name = name or "" self.name = name end function Bar:GetName() return self.name end function Bar:PlaceButton(f, idx, baseW, baseH) local r, c, s = self:GetButtonGrid() local bh, bw = self:GetButtonSize() local row, col = floor((idx-1)/c), mod((idx-1),c) -- zero-based local x, y = col*bw + (col+0.5)*s, row*bh + (row+0.5)*s local scale = bw/baseW f:ClearAllPoints() f:SetPoint("TOPLEFT",x/scale,-y/scale) f:SetScale(scale) -- f:Show() end