Mercurial > wow > reaction
diff classes/Bar.lua @ 155:806a61b331a0
Pushed the state implementation into Bar
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Fri, 15 May 2009 22:38:19 +0000 |
parents | df67685b340e |
children | 611e6ce08717 |
line wrap: on
line diff
--- a/classes/Bar.lua Fri May 08 17:30:22 2009 +0000 +++ b/classes/Bar.lua Fri May 15 22:38:19 2009 +0000 @@ -10,6 +10,119 @@ local KB = LibStub("LibKeyBound-1.0") +---- Secure snippets ---- +local _reaction_init = +[[ + anchorKeys = newtable("point","relPoint","x","y") + + state = nil + set_state = nil + state_override = nil + + showAll = false + hidden = false + + defaultAlpha = 1.0 + defaultScale = 1.0 + defaultAnchor = newtable() + + activeStates = newtable() + settings = newtable() + extensions = newtable() +]] + +local _reaction_refresh = +[[ + local oldState = state + state = state_override or set_state or state + + if state then + local settings = settings[state] + if settings then + -- show/hide + local h = settings.hide and not showAll + if h ~= hidden then + if h then + self:Hide() + else + self:Show() + end + hidden = h + end + -- re-anchor + local old_anchor = activeStates.anchor + activeStates.anchor = settings.anchorEnable and state + if old_anchor ~= activeStates.anchor or not set_state then + if activeStates.anchor then + if settings.anchorPoint then + self:ClearAllPoints() + local f = self:GetAttribute("frameref-anchor-"..state) + if f then + self:SetPoint(settings.anchorPoint, f, settings.anchorRelPoint, settings.anchorX, settings.anchorY) + end + end + elseif defaultAnchor.point then + self:ClearAllPoints() + self:SetPoint(defaultAnchor.point, defaultAnchor.frame, + defaultAnchor.relPoint, defaultAnchor.x, defaultAnchor.y) + end + end + -- re-scale + local old_scale = activeStates.scale + activeStates.scale = settings.enableScale and state + if old_scale ~= activeStates.scale or not set_state then + self:SetScale(activeStates.scale and settings.scale or defaultScale) + end + -- alpha + local old_alpha = activeStates.alpha + activeStates.alpha = settings.enableAlpha and state + if old_alpha ~= activeStates.alpha or not set_state then + self:SetAlpha(activeStates.alpha and settings.alpha or defaultAlpha) + end + end + end + + for _, attr in pairs(extensions) do + control:RunAttribute(attr) + end + + control:ChildUpdate() + + if showAll then + control:CallMethod("UpdateHiddenLabel", state and settings[state] and settings[state].hide) + end + + if oldState ~= state then + control:CallMethod("StateRefresh", state) + end +]] + +local _onstate_reaction = -- function( self, stateid, newstate ) +[[ + set_state = newstate +]] .. _reaction_refresh + +local _onstate_showgrid = -- function( self, stateid, newstate ) +[[ + control:ChildUpdate(stateid,newstate) + control:CallMethod("UpdateShowGrid") +]] + +local _onstate_unitexists = -- function( self, stateid, newstate ) +[[ + +]] .. _reaction_refresh + +local _onclick = -- function( self, button, down ) +[[ + if state_override == button then + state_override = nil -- toggle + else + state_override = button + end +]] .. _reaction_refresh + + ---- Bar class ---- local Bar = { } local weak = { __mode = "k" } @@ -51,19 +164,19 @@ f:Show() f:EnableMouse(false) f:SetClampedToScreen(true) + ReAction.gridProxy:AddFrame(f) - f:SetAttribute("_onstate-showgrid", - -- function(self,stateid,newstate) - [[ - control:ChildUpdate(stateid,newstate) - control:CallMethod("UpdateShowGrid") - ]]) - f.UpdateShowGrid = function(frame) - for button in self:IterateButtons() do - button:UpdateShowGrid() - end - end - ReAction.gridProxy:AddFrame(f) + -- secure handlers + f:Execute(_reaction_init) + f:SetAttribute("_onstate-reaction", _onstate_reaction) + f:SetAttribute("_onstate-showgrid", _onstate_showgrid) + f:SetAttribute("_onstate-unitexists", _onstate_unitexists) + f:SetAttribute("_onclick", _onclick) + + -- secure handler CallMethod()s + f.UpdateShowGrid = function() self:UpdateShowGrid() end + f.StateRefresh = function() self:RefreshControls() end + f.UpdateHiddenLabel = function(f,hidden) self:SetLabelSubtext(hidden and L["Hidden"]) end -- Override the default frame accessor to provide strict read-only access function self:GetFrame() @@ -215,11 +328,12 @@ function Bar:SetAlpha(value) self.config.alpha = value self:GetFrame():SetAlpha(value or 1.0) + self:UpdateDefaultStateAlpha() ReAction:RefreshBar(self) end --- iterator returns button, idx and does NOT iterate in index order function Bar:IterateButtons() + -- iterator returns button, idx and does NOT iterate in index order return pairs(self.buttons) end @@ -228,15 +342,9 @@ -- function Bar:SetConfigMode(mode) + self:SetSecureData("showAll",mode) + self:UpdateUnitWatch() self:ShowControls(mode) - if self.unitwatch then - if mode then - UnregisterUnitWatch(self:GetFrame()) - self:GetFrame():Show() - else - RegisterUnitWatch(self:GetFrame()) - end - end for b in self:IterateButtons() do b:ShowGridTemp(mode) b:UpdateActionIDLabel(mode) @@ -244,14 +352,8 @@ end function Bar:SetKeybindMode(mode) - if self.unitwatch then - if mode then - UnregisterUnitWatch(self:GetFrame()) - self:GetFrame():Show() - else - RegisterUnitWatch(self:GetFrame()) - end - end + self:SetSecureData("showAll",mode) + self:UpdateUnitWatch() for b in self:IterateButtons() do b:SetKeybindMode(mode) end @@ -281,6 +383,8 @@ else f:SetPoint("CENTER") end + + self:UpdateDefaultStateAnchor() end function Bar:ClipNButtons( n ) @@ -331,16 +435,34 @@ -- does nothing by default end +function Bar:UpdateShowGrid() + for button in self:IterateButtons() do + button:UpdateShowGrid() + end +end + +function Bar:UpdateUnitWatch() + if self.unitwatch then + if self.unitwatchActive and (ReAction:GetConfigMode() or ReAction:GetKeybindMode()) then + UnregisterUnitWatch(self:GetFrame()) + self.unitwatchActive = false + elseif not self.unitwatchActive then + RegisterUnitWatch(self:GetFrame()) + self.unitwatchActive = true + end + self:RefreshSecureState() + end +end + function Bar:ShowControls(show) - local f = self.overlay if show then - if not f then - f = Bar.Overlay:New(self) -- see Overlay.lua - self.overlay = f + if not self.overlay then + self.overlay = Bar.Overlay:New(self) -- see Overlay.lua end - f:Show() - elseif f then - f:Hide() + self.overlay:Show() + self:RefreshSecureState() + elseif self.overlay then + self.overlay:Hide() end end @@ -360,19 +482,164 @@ -- Secure state functions -- +function Bar:GetSecureState() + local env = GetManagedEnvironment(self:GetFrame()) + return env and env.state +end + +function Bar:GetStateProperty(state, propname) + -- override in modules/State.lua for now +end + +function Bar:SetStateProperty(state, propname, value) + -- override in modules/State.lua for now +end + +function Bar:RefreshSecureState() + self:GetFrame():Execute(_reaction_refresh) +end + +-- usage: SetSecureData(globalname, [tblkey1, tblkey2, ...], value) +function Bar:SetSecureData( ... ) + local n = select('#',...) + if n < 2 then + error("ReAction.Bar:SetSecureData() requires at least 2 arguments") + end + local f = self:GetFrame() + f:SetAttribute("data-depth",n-1) + f:SetAttribute("data-value",select(n,...)) + for i = 1, n-1 do + local key = select(i,...) + if key == nil then + error("ReAction.Bar:SetSecureData() - nil table key in argument list (#"..i..")") + end + f:SetAttribute("data-key-"..i, key) + end + f:Execute( + [[ + local n = self:GetAttribute("data-depth") + if n > 0 then + local value = self:GetAttribute("data-value") + local t = _G + for i = 1, n do + local key = self:GetAttribute("data-key-"..i) + if not key then return end + if not t[key] then + t[key] = newtable() + end + if i == n then + t[key] = value + else + t = t[key] + end + end + end + ]]) + self:RefreshSecureState() +end + +function Bar:SetSecureStateData( state, key, value ) + self:SetSecureData("settings",state,key,value) +end + +-- sets a snippet to be run as an extension to _onstate-reaction +function Bar:SetSecureStateExtension( id, snippet ) + if id == nil then + error("ReAction.Bar:SetSecureStateExtension() requires an id") + end + local f = self:GetFrame() + f:SetAttribute("input-secure-ext-id",id) + f:SetAttribute("secure-ext-"..id,snippet) + f:Execute( + [[ + local id = self:GetAttribute("input-secure-ext-id") + if id then + extensions[id] = self:GetAttribute("secure-ext-"..id) or nil + end + ]]) + self:RefreshSecureState() +end + +function Bar:SetFrameRef( name, refFrame ) + if refFrame then + local _, explicit = refFrame:IsProtected() + if not explicit then + refFrame = nil + end + end + if refFrame then + self:GetFrame():SetFrameRef(name,refFrame) + else + self:GetFrame():SetAttribute("frameref-"..name,nil) + end +end + +function Bar:SetStateDriver( rule ) + if rule then + RegisterStateDriver(self:GetFrame(),"reaction",rule) + elseif self.statedriver then + UnregisterStateDriver(self:GetFrame(),"reaction") + end + self.statedriver = rule + self:RefreshSecureState() +end + -- pass unit=nil to set up the unit elsewhere, if you want something more complex function Bar:RegisterUnitWatch( unit, enable ) local f = self:GetFrame() if unit then f:SetAttribute("unit",unit) end - if not ReAction:GetConfigMode() then - if enable then - RegisterUnitWatch(f) - elseif self.unitwatch then - UnregisterUnitWatch(f) - end - end self.unitwatch = enable + self:UpdateUnitWatch() end +-- set a keybind to push a value into "state-reaction" attribute +function Bar:SetStateKeybind( key, state ) + local f = self:GetFrame() + local binds = self.statebinds + if not binds then + binds = { } + self.statebinds = binds + end + + -- clear the old binding, if any + if binds[state] then + SetOverrideBinding(f, false, binds[state], nil) + end + + if key then + SetOverrideBinding(f, false, key, state, nil) -- state name is virtual mouse button + end + binds[state] = key +end + +function Bar:GetStateKeybind( state ) + if self.statebinds and state then + return self.statebinds[state] + end +end + +function Bar:UpdateDefaultStateAnchor() + local point, frame, relPoint, x, y = self:GetAnchor() + local f = self:GetFrame() + f:SetAttribute("defaultAnchor-point",point) + f:SetAttribute("defaultAnchor-relPoint",relPoint) + f:SetAttribute("defaultAnchor-x",x) + f:SetAttribute("defaultAnchor-y",y) + self:SetFrameRef("defaultAnchor",_G[frame or "UIParent"]) + f:Execute([[ + for _, k in pairs(anchorKeys) do + defaultAnchor[k] = self:GetAttribute("defaultAnchor-"..k) + end + defaultAnchor.frame = self:GetAttribute("frameref-defaultAnchor") + ]]) +end + +function Bar:UpdateDefaultStateAlpha() + local f = self:GetFrame() + f:SetAttribute("defaultAlpha",self:GetAlpha()) + f:Execute([[ + defaultAlpha = self:GetAttribute("defaultAlpha") + ]]) +end