flickerstreak@122: local ReAction = ReAction flickerstreak@122: local L = ReAction.L flickerstreak@122: local _G = _G flickerstreak@122: local CreateFrame = CreateFrame flickerstreak@122: local floor = math.floor flickerstreak@122: local fmod = math.fmod flickerstreak@122: local format = string.format flickerstreak@122: flickerstreak@122: ReAction:UpdateRevision("$Revision$") flickerstreak@122: flickerstreak@147: local KB = LibStub("LibKeyBound-1.0") flickerstreak@147: flickerstreak@155: ---- Secure snippets ---- flickerstreak@155: local _reaction_init = flickerstreak@155: [[ flickerstreak@155: anchorKeys = newtable("point","relPoint","x","y") flickerstreak@155: flickerstreak@155: state = nil flickerstreak@155: set_state = nil flickerstreak@155: state_override = nil flickerstreak@155: flickerstreak@155: showAll = false flickerstreak@155: hidden = false flickerstreak@155: flickerstreak@155: defaultAlpha = 1.0 flickerstreak@155: defaultScale = 1.0 flickerstreak@155: defaultAnchor = newtable() flickerstreak@155: flickerstreak@155: activeStates = newtable() flickerstreak@155: settings = newtable() flickerstreak@155: extensions = newtable() flickerstreak@155: ]] flickerstreak@155: flickerstreak@155: local _reaction_refresh = flickerstreak@155: [[ flickerstreak@155: local oldState = state flickerstreak@155: state = state_override or set_state or state flickerstreak@155: flickerstreak@155: if state then flickerstreak@155: local settings = settings[state] flickerstreak@155: if settings then flickerstreak@155: -- show/hide flickerstreak@155: local h = settings.hide and not showAll flickerstreak@155: if h ~= hidden then flickerstreak@155: if h then flickerstreak@155: self:Hide() flickerstreak@155: else flickerstreak@155: self:Show() flickerstreak@155: end flickerstreak@155: hidden = h flickerstreak@155: end flickerstreak@155: -- re-anchor flickerstreak@155: local old_anchor = activeStates.anchor flickerstreak@155: activeStates.anchor = settings.anchorEnable and state flickerstreak@155: if old_anchor ~= activeStates.anchor or not set_state then flickerstreak@155: if activeStates.anchor then flickerstreak@155: if settings.anchorPoint then flickerstreak@155: self:ClearAllPoints() flickerstreak@155: local f = self:GetAttribute("frameref-anchor-"..state) flickerstreak@155: if f then flickerstreak@155: self:SetPoint(settings.anchorPoint, f, settings.anchorRelPoint, settings.anchorX, settings.anchorY) flickerstreak@155: end flickerstreak@155: end flickerstreak@155: elseif defaultAnchor.point then flickerstreak@155: self:ClearAllPoints() flickerstreak@155: self:SetPoint(defaultAnchor.point, defaultAnchor.frame, flickerstreak@155: defaultAnchor.relPoint, defaultAnchor.x, defaultAnchor.y) flickerstreak@155: end flickerstreak@155: end flickerstreak@155: -- re-scale flickerstreak@155: local old_scale = activeStates.scale flickerstreak@155: activeStates.scale = settings.enableScale and state flickerstreak@155: if old_scale ~= activeStates.scale or not set_state then flickerstreak@155: self:SetScale(activeStates.scale and settings.scale or defaultScale) flickerstreak@155: end flickerstreak@155: -- alpha flickerstreak@155: local old_alpha = activeStates.alpha flickerstreak@155: activeStates.alpha = settings.enableAlpha and state flickerstreak@155: if old_alpha ~= activeStates.alpha or not set_state then flickerstreak@155: self:SetAlpha(activeStates.alpha and settings.alpha or defaultAlpha) flickerstreak@155: end flickerstreak@155: end flickerstreak@155: end flickerstreak@155: flickerstreak@155: for _, attr in pairs(extensions) do flickerstreak@155: control:RunAttribute(attr) flickerstreak@155: end flickerstreak@155: flickerstreak@155: control:ChildUpdate() flickerstreak@155: flickerstreak@155: if showAll then flickerstreak@155: control:CallMethod("UpdateHiddenLabel", state and settings[state] and settings[state].hide) flickerstreak@155: end flickerstreak@155: flickerstreak@155: if oldState ~= state then flickerstreak@155: control:CallMethod("StateRefresh", state) flickerstreak@155: end flickerstreak@155: ]] flickerstreak@155: flickerstreak@155: local _onstate_reaction = -- function( self, stateid, newstate ) flickerstreak@155: [[ flickerstreak@155: set_state = newstate flickerstreak@155: ]] .. _reaction_refresh flickerstreak@155: flickerstreak@155: local _onstate_showgrid = -- function( self, stateid, newstate ) flickerstreak@155: [[ flickerstreak@155: control:ChildUpdate(stateid,newstate) flickerstreak@155: control:CallMethod("UpdateShowGrid") flickerstreak@155: ]] flickerstreak@155: flickerstreak@155: local _onstate_unitexists = -- function( self, stateid, newstate ) flickerstreak@155: [[ flickerstreak@155: flickerstreak@155: ]] .. _reaction_refresh flickerstreak@155: flickerstreak@155: local _onclick = -- function( self, button, down ) flickerstreak@155: [[ flickerstreak@155: if state_override == button then flickerstreak@155: state_override = nil -- toggle flickerstreak@155: else flickerstreak@155: state_override = button flickerstreak@155: end flickerstreak@155: ]] .. _reaction_refresh flickerstreak@155: flickerstreak@155: flickerstreak@147: ---- Bar class ---- flickerstreak@122: local Bar = { } flickerstreak@122: local weak = { __mode = "k" } flickerstreak@147: local frameList = { } flickerstreak@122: flickerstreak@122: ReAction.Bar = Bar -- export to ReAction flickerstreak@122: flickerstreak@122: function Bar:New( name, config ) flickerstreak@122: if type(config) ~= "table" then flickerstreak@122: error("ReAction.Bar: config table required") flickerstreak@122: end flickerstreak@122: flickerstreak@122: -- create new self flickerstreak@122: self = setmetatable( flickerstreak@122: { flickerstreak@122: config = config, flickerstreak@122: name = name, flickerstreak@122: buttons = setmetatable( { }, weak ), flickerstreak@122: width = config.width or 480, flickerstreak@147: height = config.height or 40, flickerstreak@122: }, flickerstreak@147: {__index = self} ) flickerstreak@122: flickerstreak@122: -- The frame type is 'Button' in order to have an OnClick handler. However, the frame itself is flickerstreak@122: -- not mouse-clickable by the user. flickerstreak@122: local parent = config.parent and (ReAction:GetBar(config.parent) or _G[config.parent]) or UIParent flickerstreak@147: name = name and "ReAction-"..name flickerstreak@147: local f = name and frameList[name] flickerstreak@147: if not f then flickerstreak@147: f = CreateFrame("Button", name, parent, "SecureHandlerStateTemplate, SecureHandlerClickTemplate") flickerstreak@147: if name then flickerstreak@147: frameList[name] = f flickerstreak@147: end flickerstreak@147: end flickerstreak@122: f:SetFrameStrata("MEDIUM") flickerstreak@122: f:SetWidth(self.width) flickerstreak@146: f:SetHeight(self.height) flickerstreak@122: f:SetAlpha(config.alpha or 1.0) flickerstreak@122: f:Show() flickerstreak@122: f:EnableMouse(false) flickerstreak@122: f:SetClampedToScreen(true) flickerstreak@155: ReAction.gridProxy:AddFrame(f) flickerstreak@122: flickerstreak@155: -- secure handlers flickerstreak@155: f:Execute(_reaction_init) flickerstreak@155: f:SetAttribute("_onstate-reaction", _onstate_reaction) flickerstreak@155: f:SetAttribute("_onstate-showgrid", _onstate_showgrid) flickerstreak@155: f:SetAttribute("_onstate-unitexists", _onstate_unitexists) flickerstreak@155: f:SetAttribute("_onclick", _onclick) flickerstreak@155: flickerstreak@155: -- secure handler CallMethod()s flickerstreak@155: f.UpdateShowGrid = function() self:UpdateShowGrid() end flickerstreak@155: f.StateRefresh = function() self:RefreshControls() end flickerstreak@155: f.UpdateHiddenLabel = function(f,hidden) self:SetLabelSubtext(hidden and L["Hidden"]) end flickerstreak@122: flickerstreak@122: -- Override the default frame accessor to provide strict read-only access flickerstreak@122: function self:GetFrame() flickerstreak@122: return f flickerstreak@122: end flickerstreak@122: flickerstreak@122: self:ApplyAnchor() flickerstreak@147: self:SetConfigMode(ReAction:GetConfigMode()) flickerstreak@147: self:SetKeybindMode(ReAction:GetKeybindMode()) flickerstreak@147: flickerstreak@122: ReAction.RegisterCallback(self, "OnConfigModeChanged") flickerstreak@147: KB.RegisterCallback(self, "LIBKEYBOUND_ENABLED") flickerstreak@147: KB.RegisterCallback(self, "LIBKEYBOUND_DISABLED") flickerstreak@147: KB.RegisterCallback(self, "LIBKEYBOUND_MODE_COLOR_CHANGED","LIBKEYBOUND_ENABLED") flickerstreak@122: flickerstreak@122: return self flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:Destroy() flickerstreak@122: local f = self:GetFrame() flickerstreak@122: f:UnregisterAllEvents() flickerstreak@125: self:ShowControls(false) flickerstreak@122: ReAction.UnregisterAllCallbacks(self) flickerstreak@147: KB.UnregisterAllCallbacks(self) flickerstreak@122: ReAction.gridProxy:RemoveFrame(f) flickerstreak@122: f:SetParent(UIParent) flickerstreak@122: f:ClearAllPoints() flickerstreak@147: f:Hide() flickerstreak@122: end flickerstreak@122: flickerstreak@147: -- flickerstreak@147: -- Events flickerstreak@147: -- flickerstreak@147: flickerstreak@147: function Bar:OnConfigModeChanged(event, mode) flickerstreak@147: self:SetConfigMode(mode) flickerstreak@123: end flickerstreak@123: flickerstreak@147: function Bar:LIBKEYBOUND_ENABLED(evt) flickerstreak@147: self:SetKeybindMode(true) flickerstreak@147: end flickerstreak@147: flickerstreak@147: function Bar:LIBKEYBOUND_DISABLED(evt) flickerstreak@147: self:SetKeybindMode(false) flickerstreak@122: end flickerstreak@122: flickerstreak@153: -- flickerstreak@153: -- Accessors flickerstreak@153: -- flickerstreak@153: flickerstreak@153: function Bar:GetName() flickerstreak@153: return self.name flickerstreak@153: end flickerstreak@153: flickerstreak@153: -- only ReAction:RenameBar() should call this function. Calling from any other flickerstreak@153: -- context will desync the bar list in the ReAction class. flickerstreak@153: function Bar:SetName(name) flickerstreak@153: self.name = name flickerstreak@154: if self.overlay then flickerstreak@154: self.overlay:SetLabel(self.name) flickerstreak@154: end flickerstreak@153: end flickerstreak@153: flickerstreak@153: function Bar:GetFrame() flickerstreak@153: -- this method is included for documentation purposes. It is overridden flickerstreak@153: -- for each object in the :New() method. flickerstreak@153: error("Invalid Bar object: used without initialization") flickerstreak@153: end flickerstreak@153: flickerstreak@153: function Bar:GetConfig() flickerstreak@153: return self.config flickerstreak@153: end flickerstreak@153: flickerstreak@153: function Bar:GetAnchor() flickerstreak@122: local c = self.config flickerstreak@153: return (c.point or "CENTER"), flickerstreak@153: (c.anchor or self:GetFrame():GetParent():GetName()), flickerstreak@153: (c.relpoint or c.point or "CENTER"), flickerstreak@153: (c.x or 0), flickerstreak@153: (c.y or 0) flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:SetAnchor(point, frame, relativePoint, x, y) flickerstreak@122: local c = self.config flickerstreak@122: c.point = point or c.point flickerstreak@122: c.anchor = frame or c.anchor flickerstreak@122: c.relpoint = relativePoint or c.relpoint flickerstreak@122: c.x = x or c.x flickerstreak@122: c.y = y or c.y flickerstreak@122: self:ApplyAnchor() flickerstreak@122: ReAction:RefreshBar(self) flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:GetSize() flickerstreak@122: local f = self:GetFrame() flickerstreak@122: return f:GetWidth(), f:GetHeight() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:SetSize(w,h) flickerstreak@122: local f = self:GetFrame() flickerstreak@122: self.config.width = w flickerstreak@122: self.config.height = h flickerstreak@122: f:SetWidth(w) flickerstreak@122: f:SetHeight(h) flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:GetButtonSize() flickerstreak@122: local w = self.config.btnWidth or 32 flickerstreak@122: local h = self.config.btnHeight or 32 flickerstreak@122: -- TODO: get from modules? flickerstreak@122: return w,h flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:SetButtonSize(w,h) flickerstreak@122: if w > 0 and h > 0 then flickerstreak@122: self.config.btnWidth = w flickerstreak@122: self.config.btnHeight = h flickerstreak@122: end flickerstreak@122: ReAction:RefreshBar(self) flickerstreak@122: end flickerstreak@122: flickerstreak@153: function Bar:GetNumButtons() flickerstreak@153: local r,c = self:GetButtonGrid() flickerstreak@153: return r*c flickerstreak@153: end flickerstreak@153: flickerstreak@122: function Bar:GetButtonGrid() flickerstreak@122: local cfg = self.config flickerstreak@122: local r = cfg.btnRows or 1 flickerstreak@122: local c = cfg.btnColumns or 1 flickerstreak@122: local s = cfg.spacing or 4 flickerstreak@122: return r,c,s flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:SetButtonGrid(r,c,s) flickerstreak@122: if r > 0 and c > 0 and s > 0 then flickerstreak@122: local cfg = self.config flickerstreak@122: cfg.btnRows = r flickerstreak@122: cfg.btnColumns = c flickerstreak@122: cfg.spacing = s flickerstreak@122: end flickerstreak@122: ReAction:RefreshBar(self) flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:GetAlpha() flickerstreak@122: return self.config.alpha or 1.0 flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:SetAlpha(value) flickerstreak@122: self.config.alpha = value flickerstreak@122: self:GetFrame():SetAlpha(value or 1.0) flickerstreak@155: self:UpdateDefaultStateAlpha() flickerstreak@122: ReAction:RefreshBar(self) flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:IterateButtons() flickerstreak@155: -- iterator returns button, idx and does NOT iterate in index order flickerstreak@122: return pairs(self.buttons) flickerstreak@122: end flickerstreak@122: flickerstreak@153: -- flickerstreak@153: -- Methods flickerstreak@153: -- flickerstreak@153: flickerstreak@147: function Bar:SetConfigMode(mode) flickerstreak@155: self:SetSecureData("showAll",mode) flickerstreak@155: self:UpdateUnitWatch() flickerstreak@147: self:ShowControls(mode) flickerstreak@147: for b in self:IterateButtons() do flickerstreak@147: b:ShowGridTemp(mode) flickerstreak@147: b:UpdateActionIDLabel(mode) flickerstreak@147: end flickerstreak@147: end flickerstreak@147: flickerstreak@147: function Bar:SetKeybindMode(mode) flickerstreak@155: self:SetSecureData("showAll",mode) flickerstreak@155: self:UpdateUnitWatch() flickerstreak@147: for b in self:IterateButtons() do flickerstreak@147: b:SetKeybindMode(mode) flickerstreak@147: end flickerstreak@147: end flickerstreak@147: flickerstreak@153: function Bar:ApplyAnchor() flickerstreak@153: local f = self:GetFrame() flickerstreak@153: local c = self.config flickerstreak@153: local p = c.point flickerstreak@153: flickerstreak@153: f:SetWidth(c.width) flickerstreak@153: f:SetHeight(c.height) flickerstreak@153: f:ClearAllPoints() flickerstreak@153: flickerstreak@153: if p then flickerstreak@153: local a = f:GetParent() flickerstreak@153: if c.anchor then flickerstreak@153: local bar = ReAction:GetBar(c.anchor) flickerstreak@153: if bar then flickerstreak@153: a = bar:GetFrame() flickerstreak@153: else flickerstreak@153: a = _G[c.anchor] flickerstreak@153: end flickerstreak@153: end flickerstreak@153: local fr = a or f:GetParent() flickerstreak@153: f:SetPoint(p, a or f:GetParent(), c.relpoint, c.x or 0, c.y or 0) flickerstreak@153: else flickerstreak@153: f:SetPoint("CENTER") flickerstreak@153: end flickerstreak@155: flickerstreak@155: self:UpdateDefaultStateAnchor() flickerstreak@153: end flickerstreak@153: flickerstreak@153: function Bar:ClipNButtons( n ) flickerstreak@153: local cfg = self.config flickerstreak@153: local r = cfg.btnRows or 1 flickerstreak@153: local c = cfg.btnColumns or 1 flickerstreak@153: flickerstreak@153: cfg.btnRows = ceil(n/c) flickerstreak@153: cfg.btnColumns = min(n,c) flickerstreak@153: end flickerstreak@153: flickerstreak@153: function Bar:AddButton(idx, button) flickerstreak@153: local f = self:GetFrame() flickerstreak@153: flickerstreak@153: -- store in a weak reverse-index array flickerstreak@153: self.buttons[button] = idx flickerstreak@153: flickerstreak@153: -- Store a properly wrapped reference to the child frame as an attribute flickerstreak@153: -- (accessible via "frameref-btn#") flickerstreak@153: f:SetFrameRef(format("btn%d",idx), button:GetFrame()) flickerstreak@153: end flickerstreak@153: flickerstreak@153: function Bar:RemoveButton(button) flickerstreak@153: local idx = self.buttons[button] flickerstreak@153: if idx then flickerstreak@153: self:GetFrame():SetAttribute(format("frameref-btn%d",idx),nil) flickerstreak@153: self.buttons[button] = nil flickerstreak@153: end flickerstreak@153: end flickerstreak@153: flickerstreak@122: function Bar:PlaceButton(button, baseW, baseH) flickerstreak@122: local idx = self.buttons[button] flickerstreak@122: if idx then flickerstreak@122: local r, c, s = self:GetButtonGrid() flickerstreak@122: local bh, bw = self:GetButtonSize() flickerstreak@122: local row, col = floor((idx-1)/c), fmod((idx-1),c) -- zero-based flickerstreak@122: local x, y = col*bw + (col+0.5)*s, -(row*bh + (row+0.5)*s) flickerstreak@122: local scale = bw/baseW flickerstreak@122: local b = button:GetFrame() flickerstreak@122: flickerstreak@122: b:ClearAllPoints() flickerstreak@122: b:SetPoint("TOPLEFT",x/scale,y/scale) flickerstreak@122: b:SetScale(scale) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Bar:SkinButton() flickerstreak@122: -- does nothing by default flickerstreak@147: end flickerstreak@148: flickerstreak@155: function Bar:UpdateShowGrid() flickerstreak@155: for button in self:IterateButtons() do flickerstreak@155: button:UpdateShowGrid() flickerstreak@155: end flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:UpdateUnitWatch() flickerstreak@155: if self.unitwatch then flickerstreak@155: if self.unitwatchActive and (ReAction:GetConfigMode() or ReAction:GetKeybindMode()) then flickerstreak@155: UnregisterUnitWatch(self:GetFrame()) flickerstreak@155: self.unitwatchActive = false flickerstreak@155: elseif not self.unitwatchActive then flickerstreak@155: RegisterUnitWatch(self:GetFrame()) flickerstreak@155: self.unitwatchActive = true flickerstreak@155: end flickerstreak@155: self:RefreshSecureState() flickerstreak@155: end flickerstreak@155: end flickerstreak@155: flickerstreak@154: function Bar:ShowControls(show) flickerstreak@154: if show then flickerstreak@155: if not self.overlay then flickerstreak@155: self.overlay = Bar.Overlay:New(self) -- see Overlay.lua flickerstreak@154: end flickerstreak@155: self.overlay:Show() flickerstreak@155: self:RefreshSecureState() flickerstreak@155: elseif self.overlay then flickerstreak@155: self.overlay:Hide() flickerstreak@154: end flickerstreak@154: end flickerstreak@154: flickerstreak@154: function Bar:RefreshControls() flickerstreak@154: if self.overlay and self.overlay:IsShown() then flickerstreak@154: self.overlay:RefreshControls() flickerstreak@154: end flickerstreak@154: end flickerstreak@154: flickerstreak@154: function Bar:SetLabelSubtext(text) flickerstreak@154: if self.overlay then flickerstreak@154: self.overlay:SetLabelSubtext(text) flickerstreak@154: end flickerstreak@154: end flickerstreak@154: flickerstreak@154: -- flickerstreak@154: -- Secure state functions flickerstreak@154: -- flickerstreak@154: flickerstreak@155: function Bar:GetSecureState() flickerstreak@155: local env = GetManagedEnvironment(self:GetFrame()) flickerstreak@155: return env and env.state flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:GetStateProperty(state, propname) flickerstreak@155: -- override in modules/State.lua for now flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:SetStateProperty(state, propname, value) flickerstreak@155: -- override in modules/State.lua for now flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:RefreshSecureState() flickerstreak@155: self:GetFrame():Execute(_reaction_refresh) flickerstreak@155: end flickerstreak@155: flickerstreak@155: -- usage: SetSecureData(globalname, [tblkey1, tblkey2, ...], value) flickerstreak@155: function Bar:SetSecureData( ... ) flickerstreak@155: local n = select('#',...) flickerstreak@155: if n < 2 then flickerstreak@155: error("ReAction.Bar:SetSecureData() requires at least 2 arguments") flickerstreak@155: end flickerstreak@155: local f = self:GetFrame() flickerstreak@155: f:SetAttribute("data-depth",n-1) flickerstreak@155: f:SetAttribute("data-value",select(n,...)) flickerstreak@155: for i = 1, n-1 do flickerstreak@155: local key = select(i,...) flickerstreak@155: if key == nil then flickerstreak@155: error("ReAction.Bar:SetSecureData() - nil table key in argument list (#"..i..")") flickerstreak@155: end flickerstreak@155: f:SetAttribute("data-key-"..i, key) flickerstreak@155: end flickerstreak@155: f:Execute( flickerstreak@155: [[ flickerstreak@155: local n = self:GetAttribute("data-depth") flickerstreak@155: if n > 0 then flickerstreak@155: local value = self:GetAttribute("data-value") flickerstreak@155: local t = _G flickerstreak@155: for i = 1, n do flickerstreak@155: local key = self:GetAttribute("data-key-"..i) flickerstreak@155: if not key then return end flickerstreak@155: if not t[key] then flickerstreak@155: t[key] = newtable() flickerstreak@155: end flickerstreak@155: if i == n then flickerstreak@155: t[key] = value flickerstreak@155: else flickerstreak@155: t = t[key] flickerstreak@155: end flickerstreak@155: end flickerstreak@155: end flickerstreak@155: ]]) flickerstreak@155: self:RefreshSecureState() flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:SetSecureStateData( state, key, value ) flickerstreak@155: self:SetSecureData("settings",state,key,value) flickerstreak@155: end flickerstreak@155: flickerstreak@155: -- sets a snippet to be run as an extension to _onstate-reaction flickerstreak@155: function Bar:SetSecureStateExtension( id, snippet ) flickerstreak@155: if id == nil then flickerstreak@155: error("ReAction.Bar:SetSecureStateExtension() requires an id") flickerstreak@155: end flickerstreak@155: local f = self:GetFrame() flickerstreak@155: f:SetAttribute("input-secure-ext-id",id) flickerstreak@155: f:SetAttribute("secure-ext-"..id,snippet) flickerstreak@155: f:Execute( flickerstreak@155: [[ flickerstreak@155: local id = self:GetAttribute("input-secure-ext-id") flickerstreak@155: if id then flickerstreak@155: extensions[id] = self:GetAttribute("secure-ext-"..id) or nil flickerstreak@155: end flickerstreak@155: ]]) flickerstreak@155: self:RefreshSecureState() flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:SetFrameRef( name, refFrame ) flickerstreak@155: if refFrame then flickerstreak@155: local _, explicit = refFrame:IsProtected() flickerstreak@155: if not explicit then flickerstreak@155: refFrame = nil flickerstreak@155: end flickerstreak@155: end flickerstreak@155: if refFrame then flickerstreak@155: self:GetFrame():SetFrameRef(name,refFrame) flickerstreak@155: else flickerstreak@155: self:GetFrame():SetAttribute("frameref-"..name,nil) flickerstreak@155: end flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:SetStateDriver( rule ) flickerstreak@155: if rule then flickerstreak@155: RegisterStateDriver(self:GetFrame(),"reaction",rule) flickerstreak@155: elseif self.statedriver then flickerstreak@155: UnregisterStateDriver(self:GetFrame(),"reaction") flickerstreak@155: end flickerstreak@155: self.statedriver = rule flickerstreak@155: self:RefreshSecureState() flickerstreak@155: end flickerstreak@155: flickerstreak@148: -- pass unit=nil to set up the unit elsewhere, if you want something more complex flickerstreak@148: function Bar:RegisterUnitWatch( unit, enable ) flickerstreak@148: local f = self:GetFrame() flickerstreak@148: if unit then flickerstreak@148: f:SetAttribute("unit",unit) flickerstreak@148: end flickerstreak@148: self.unitwatch = enable flickerstreak@155: self:UpdateUnitWatch() flickerstreak@148: end flickerstreak@148: flickerstreak@155: -- set a keybind to push a value into "state-reaction" attribute flickerstreak@155: function Bar:SetStateKeybind( key, state ) flickerstreak@155: local f = self:GetFrame() flickerstreak@155: local binds = self.statebinds flickerstreak@155: if not binds then flickerstreak@155: binds = { } flickerstreak@155: self.statebinds = binds flickerstreak@155: end flickerstreak@155: flickerstreak@155: -- clear the old binding, if any flickerstreak@155: if binds[state] then flickerstreak@155: SetOverrideBinding(f, false, binds[state], nil) flickerstreak@155: end flickerstreak@155: flickerstreak@155: if key then flickerstreak@155: SetOverrideBinding(f, false, key, state, nil) -- state name is virtual mouse button flickerstreak@155: end flickerstreak@155: binds[state] = key flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:GetStateKeybind( state ) flickerstreak@155: if self.statebinds and state then flickerstreak@155: return self.statebinds[state] flickerstreak@155: end flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:UpdateDefaultStateAnchor() flickerstreak@155: local point, frame, relPoint, x, y = self:GetAnchor() flickerstreak@155: local f = self:GetFrame() flickerstreak@155: f:SetAttribute("defaultAnchor-point",point) flickerstreak@155: f:SetAttribute("defaultAnchor-relPoint",relPoint) flickerstreak@155: f:SetAttribute("defaultAnchor-x",x) flickerstreak@155: f:SetAttribute("defaultAnchor-y",y) flickerstreak@155: self:SetFrameRef("defaultAnchor",_G[frame or "UIParent"]) flickerstreak@155: f:Execute([[ flickerstreak@155: for _, k in pairs(anchorKeys) do flickerstreak@155: defaultAnchor[k] = self:GetAttribute("defaultAnchor-"..k) flickerstreak@155: end flickerstreak@155: defaultAnchor.frame = self:GetAttribute("frameref-defaultAnchor") flickerstreak@155: ]]) flickerstreak@155: end flickerstreak@155: flickerstreak@155: function Bar:UpdateDefaultStateAlpha() flickerstreak@155: local f = self:GetFrame() flickerstreak@155: f:SetAttribute("defaultAlpha",self:GetAlpha()) flickerstreak@155: f:Execute([[ flickerstreak@155: defaultAlpha = self:GetAttribute("defaultAlpha") flickerstreak@155: ]]) flickerstreak@155: end