Mercurial > wow > reaction
diff ReAction_Bar.lua @ 25:bf997ea151ca
yet another attempt to add missing files
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Fri, 07 Mar 2008 22:19:03 +0000 |
parents | |
children | f1e838841ce1 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ReAction_Bar.lua Fri Mar 07 22:19:03 2008 +0000 @@ -0,0 +1,380 @@ +--[[ + 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 + + +-- +-- 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 +