annotate 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
rev   line source
flickerstreak@122 1 local ReAction = ReAction
flickerstreak@122 2 local L = ReAction.L
flickerstreak@122 3 local _G = _G
flickerstreak@122 4 local CreateFrame = CreateFrame
flickerstreak@122 5 local floor = math.floor
flickerstreak@122 6 local fmod = math.fmod
flickerstreak@122 7 local format = string.format
flickerstreak@122 8
flickerstreak@122 9 ReAction:UpdateRevision("$Revision$")
flickerstreak@122 10
flickerstreak@147 11 local KB = LibStub("LibKeyBound-1.0")
flickerstreak@147 12
flickerstreak@155 13 ---- Secure snippets ----
flickerstreak@155 14 local _reaction_init =
flickerstreak@155 15 [[
flickerstreak@155 16 anchorKeys = newtable("point","relPoint","x","y")
flickerstreak@155 17
flickerstreak@155 18 state = nil
flickerstreak@155 19 set_state = nil
flickerstreak@155 20 state_override = nil
flickerstreak@155 21
flickerstreak@155 22 showAll = false
flickerstreak@155 23 hidden = false
flickerstreak@155 24
flickerstreak@155 25 defaultAlpha = 1.0
flickerstreak@155 26 defaultScale = 1.0
flickerstreak@155 27 defaultAnchor = newtable()
flickerstreak@155 28
flickerstreak@155 29 activeStates = newtable()
flickerstreak@155 30 settings = newtable()
flickerstreak@155 31 extensions = newtable()
flickerstreak@155 32 ]]
flickerstreak@155 33
flickerstreak@155 34 local _reaction_refresh =
flickerstreak@155 35 [[
flickerstreak@155 36 local oldState = state
flickerstreak@155 37 state = state_override or set_state or state
flickerstreak@155 38
flickerstreak@155 39 if state then
flickerstreak@155 40 local settings = settings[state]
flickerstreak@155 41 if settings then
flickerstreak@155 42 -- show/hide
flickerstreak@155 43 local h = settings.hide and not showAll
flickerstreak@155 44 if h ~= hidden then
flickerstreak@155 45 if h then
flickerstreak@155 46 self:Hide()
flickerstreak@155 47 else
flickerstreak@155 48 self:Show()
flickerstreak@155 49 end
flickerstreak@155 50 hidden = h
flickerstreak@155 51 end
flickerstreak@155 52 -- re-anchor
flickerstreak@155 53 local old_anchor = activeStates.anchor
flickerstreak@155 54 activeStates.anchor = settings.anchorEnable and state
flickerstreak@155 55 if old_anchor ~= activeStates.anchor or not set_state then
flickerstreak@155 56 if activeStates.anchor then
flickerstreak@155 57 if settings.anchorPoint then
flickerstreak@155 58 self:ClearAllPoints()
flickerstreak@155 59 local f = self:GetAttribute("frameref-anchor-"..state)
flickerstreak@155 60 if f then
flickerstreak@155 61 self:SetPoint(settings.anchorPoint, f, settings.anchorRelPoint, settings.anchorX, settings.anchorY)
flickerstreak@155 62 end
flickerstreak@155 63 end
flickerstreak@155 64 elseif defaultAnchor.point then
flickerstreak@155 65 self:ClearAllPoints()
flickerstreak@155 66 self:SetPoint(defaultAnchor.point, defaultAnchor.frame,
flickerstreak@155 67 defaultAnchor.relPoint, defaultAnchor.x, defaultAnchor.y)
flickerstreak@155 68 end
flickerstreak@155 69 end
flickerstreak@155 70 -- re-scale
flickerstreak@155 71 local old_scale = activeStates.scale
flickerstreak@155 72 activeStates.scale = settings.enableScale and state
flickerstreak@155 73 if old_scale ~= activeStates.scale or not set_state then
flickerstreak@155 74 self:SetScale(activeStates.scale and settings.scale or defaultScale)
flickerstreak@155 75 end
flickerstreak@155 76 -- alpha
flickerstreak@155 77 local old_alpha = activeStates.alpha
flickerstreak@155 78 activeStates.alpha = settings.enableAlpha and state
flickerstreak@155 79 if old_alpha ~= activeStates.alpha or not set_state then
flickerstreak@155 80 self:SetAlpha(activeStates.alpha and settings.alpha or defaultAlpha)
flickerstreak@155 81 end
flickerstreak@155 82 end
flickerstreak@155 83 end
flickerstreak@155 84
flickerstreak@155 85 for _, attr in pairs(extensions) do
flickerstreak@155 86 control:RunAttribute(attr)
flickerstreak@155 87 end
flickerstreak@155 88
flickerstreak@155 89 control:ChildUpdate()
flickerstreak@155 90
flickerstreak@155 91 if showAll then
flickerstreak@155 92 control:CallMethod("UpdateHiddenLabel", state and settings[state] and settings[state].hide)
flickerstreak@155 93 end
flickerstreak@155 94
flickerstreak@155 95 if oldState ~= state then
flickerstreak@155 96 control:CallMethod("StateRefresh", state)
flickerstreak@155 97 end
flickerstreak@155 98 ]]
flickerstreak@155 99
flickerstreak@155 100 local _onstate_reaction = -- function( self, stateid, newstate )
flickerstreak@155 101 [[
flickerstreak@155 102 set_state = newstate
flickerstreak@155 103 ]] .. _reaction_refresh
flickerstreak@155 104
flickerstreak@155 105 local _onstate_showgrid = -- function( self, stateid, newstate )
flickerstreak@155 106 [[
flickerstreak@155 107 control:ChildUpdate(stateid,newstate)
flickerstreak@155 108 control:CallMethod("UpdateShowGrid")
flickerstreak@155 109 ]]
flickerstreak@155 110
flickerstreak@155 111 local _onstate_unitexists = -- function( self, stateid, newstate )
flickerstreak@155 112 [[
flickerstreak@155 113
flickerstreak@155 114 ]] .. _reaction_refresh
flickerstreak@155 115
flickerstreak@155 116 local _onclick = -- function( self, button, down )
flickerstreak@155 117 [[
flickerstreak@155 118 if state_override == button then
flickerstreak@155 119 state_override = nil -- toggle
flickerstreak@155 120 else
flickerstreak@155 121 state_override = button
flickerstreak@155 122 end
flickerstreak@155 123 ]] .. _reaction_refresh
flickerstreak@155 124
flickerstreak@155 125
flickerstreak@147 126 ---- Bar class ----
flickerstreak@122 127 local Bar = { }
flickerstreak@122 128 local weak = { __mode = "k" }
flickerstreak@147 129 local frameList = { }
flickerstreak@122 130
flickerstreak@122 131 ReAction.Bar = Bar -- export to ReAction
flickerstreak@122 132
flickerstreak@122 133 function Bar:New( name, config )
flickerstreak@122 134 if type(config) ~= "table" then
flickerstreak@122 135 error("ReAction.Bar: config table required")
flickerstreak@122 136 end
flickerstreak@122 137
flickerstreak@122 138 -- create new self
flickerstreak@122 139 self = setmetatable(
flickerstreak@122 140 {
flickerstreak@122 141 config = config,
flickerstreak@122 142 name = name,
flickerstreak@122 143 buttons = setmetatable( { }, weak ),
flickerstreak@122 144 width = config.width or 480,
flickerstreak@147 145 height = config.height or 40,
flickerstreak@122 146 },
flickerstreak@147 147 {__index = self} )
flickerstreak@122 148
flickerstreak@122 149 -- The frame type is 'Button' in order to have an OnClick handler. However, the frame itself is
flickerstreak@122 150 -- not mouse-clickable by the user.
flickerstreak@122 151 local parent = config.parent and (ReAction:GetBar(config.parent) or _G[config.parent]) or UIParent
flickerstreak@147 152 name = name and "ReAction-"..name
flickerstreak@147 153 local f = name and frameList[name]
flickerstreak@147 154 if not f then
flickerstreak@147 155 f = CreateFrame("Button", name, parent, "SecureHandlerStateTemplate, SecureHandlerClickTemplate")
flickerstreak@147 156 if name then
flickerstreak@147 157 frameList[name] = f
flickerstreak@147 158 end
flickerstreak@147 159 end
flickerstreak@122 160 f:SetFrameStrata("MEDIUM")
flickerstreak@122 161 f:SetWidth(self.width)
flickerstreak@146 162 f:SetHeight(self.height)
flickerstreak@122 163 f:SetAlpha(config.alpha or 1.0)
flickerstreak@122 164 f:Show()
flickerstreak@122 165 f:EnableMouse(false)
flickerstreak@122 166 f:SetClampedToScreen(true)
flickerstreak@155 167 ReAction.gridProxy:AddFrame(f)
flickerstreak@122 168
flickerstreak@155 169 -- secure handlers
flickerstreak@155 170 f:Execute(_reaction_init)
flickerstreak@155 171 f:SetAttribute("_onstate-reaction", _onstate_reaction)
flickerstreak@155 172 f:SetAttribute("_onstate-showgrid", _onstate_showgrid)
flickerstreak@155 173 f:SetAttribute("_onstate-unitexists", _onstate_unitexists)
flickerstreak@155 174 f:SetAttribute("_onclick", _onclick)
flickerstreak@155 175
flickerstreak@155 176 -- secure handler CallMethod()s
flickerstreak@155 177 f.UpdateShowGrid = function() self:UpdateShowGrid() end
flickerstreak@155 178 f.StateRefresh = function() self:RefreshControls() end
flickerstreak@155 179 f.UpdateHiddenLabel = function(f,hidden) self:SetLabelSubtext(hidden and L["Hidden"]) end
flickerstreak@122 180
flickerstreak@122 181 -- Override the default frame accessor to provide strict read-only access
flickerstreak@122 182 function self:GetFrame()
flickerstreak@122 183 return f
flickerstreak@122 184 end
flickerstreak@122 185
flickerstreak@122 186 self:ApplyAnchor()
flickerstreak@147 187 self:SetConfigMode(ReAction:GetConfigMode())
flickerstreak@147 188 self:SetKeybindMode(ReAction:GetKeybindMode())
flickerstreak@147 189
flickerstreak@122 190 ReAction.RegisterCallback(self, "OnConfigModeChanged")
flickerstreak@147 191 KB.RegisterCallback(self, "LIBKEYBOUND_ENABLED")
flickerstreak@147 192 KB.RegisterCallback(self, "LIBKEYBOUND_DISABLED")
flickerstreak@147 193 KB.RegisterCallback(self, "LIBKEYBOUND_MODE_COLOR_CHANGED","LIBKEYBOUND_ENABLED")
flickerstreak@122 194
flickerstreak@122 195 return self
flickerstreak@122 196 end
flickerstreak@122 197
flickerstreak@122 198 function Bar:Destroy()
flickerstreak@122 199 local f = self:GetFrame()
flickerstreak@122 200 f:UnregisterAllEvents()
flickerstreak@125 201 self:ShowControls(false)
flickerstreak@122 202 ReAction.UnregisterAllCallbacks(self)
flickerstreak@147 203 KB.UnregisterAllCallbacks(self)
flickerstreak@122 204 ReAction.gridProxy:RemoveFrame(f)
flickerstreak@122 205 f:SetParent(UIParent)
flickerstreak@122 206 f:ClearAllPoints()
flickerstreak@147 207 f:Hide()
flickerstreak@122 208 end
flickerstreak@122 209
flickerstreak@147 210 --
flickerstreak@147 211 -- Events
flickerstreak@147 212 --
flickerstreak@147 213
flickerstreak@147 214 function Bar:OnConfigModeChanged(event, mode)
flickerstreak@147 215 self:SetConfigMode(mode)
flickerstreak@123 216 end
flickerstreak@123 217
flickerstreak@147 218 function Bar:LIBKEYBOUND_ENABLED(evt)
flickerstreak@147 219 self:SetKeybindMode(true)
flickerstreak@147 220 end
flickerstreak@147 221
flickerstreak@147 222 function Bar:LIBKEYBOUND_DISABLED(evt)
flickerstreak@147 223 self:SetKeybindMode(false)
flickerstreak@122 224 end
flickerstreak@122 225
flickerstreak@153 226 --
flickerstreak@153 227 -- Accessors
flickerstreak@153 228 --
flickerstreak@153 229
flickerstreak@153 230 function Bar:GetName()
flickerstreak@153 231 return self.name
flickerstreak@153 232 end
flickerstreak@153 233
flickerstreak@153 234 -- only ReAction:RenameBar() should call this function. Calling from any other
flickerstreak@153 235 -- context will desync the bar list in the ReAction class.
flickerstreak@153 236 function Bar:SetName(name)
flickerstreak@153 237 self.name = name
flickerstreak@154 238 if self.overlay then
flickerstreak@154 239 self.overlay:SetLabel(self.name)
flickerstreak@154 240 end
flickerstreak@153 241 end
flickerstreak@153 242
flickerstreak@153 243 function Bar:GetFrame()
flickerstreak@153 244 -- this method is included for documentation purposes. It is overridden
flickerstreak@153 245 -- for each object in the :New() method.
flickerstreak@153 246 error("Invalid Bar object: used without initialization")
flickerstreak@153 247 end
flickerstreak@153 248
flickerstreak@153 249 function Bar:GetConfig()
flickerstreak@153 250 return self.config
flickerstreak@153 251 end
flickerstreak@153 252
flickerstreak@153 253 function Bar:GetAnchor()
flickerstreak@122 254 local c = self.config
flickerstreak@153 255 return (c.point or "CENTER"),
flickerstreak@153 256 (c.anchor or self:GetFrame():GetParent():GetName()),
flickerstreak@153 257 (c.relpoint or c.point or "CENTER"),
flickerstreak@153 258 (c.x or 0),
flickerstreak@153 259 (c.y or 0)
flickerstreak@122 260 end
flickerstreak@122 261
flickerstreak@122 262 function Bar:SetAnchor(point, frame, relativePoint, x, y)
flickerstreak@122 263 local c = self.config
flickerstreak@122 264 c.point = point or c.point
flickerstreak@122 265 c.anchor = frame or c.anchor
flickerstreak@122 266 c.relpoint = relativePoint or c.relpoint
flickerstreak@122 267 c.x = x or c.x
flickerstreak@122 268 c.y = y or c.y
flickerstreak@122 269 self:ApplyAnchor()
flickerstreak@122 270 ReAction:RefreshBar(self)
flickerstreak@122 271 end
flickerstreak@122 272
flickerstreak@122 273 function Bar:GetSize()
flickerstreak@122 274 local f = self:GetFrame()
flickerstreak@122 275 return f:GetWidth(), f:GetHeight()
flickerstreak@122 276 end
flickerstreak@122 277
flickerstreak@122 278 function Bar:SetSize(w,h)
flickerstreak@122 279 local f = self:GetFrame()
flickerstreak@122 280 self.config.width = w
flickerstreak@122 281 self.config.height = h
flickerstreak@122 282 f:SetWidth(w)
flickerstreak@122 283 f:SetHeight(h)
flickerstreak@122 284 end
flickerstreak@122 285
flickerstreak@122 286 function Bar:GetButtonSize()
flickerstreak@122 287 local w = self.config.btnWidth or 32
flickerstreak@122 288 local h = self.config.btnHeight or 32
flickerstreak@122 289 -- TODO: get from modules?
flickerstreak@122 290 return w,h
flickerstreak@122 291 end
flickerstreak@122 292
flickerstreak@122 293 function Bar:SetButtonSize(w,h)
flickerstreak@122 294 if w > 0 and h > 0 then
flickerstreak@122 295 self.config.btnWidth = w
flickerstreak@122 296 self.config.btnHeight = h
flickerstreak@122 297 end
flickerstreak@122 298 ReAction:RefreshBar(self)
flickerstreak@122 299 end
flickerstreak@122 300
flickerstreak@153 301 function Bar:GetNumButtons()
flickerstreak@153 302 local r,c = self:GetButtonGrid()
flickerstreak@153 303 return r*c
flickerstreak@153 304 end
flickerstreak@153 305
flickerstreak@122 306 function Bar:GetButtonGrid()
flickerstreak@122 307 local cfg = self.config
flickerstreak@122 308 local r = cfg.btnRows or 1
flickerstreak@122 309 local c = cfg.btnColumns or 1
flickerstreak@122 310 local s = cfg.spacing or 4
flickerstreak@122 311 return r,c,s
flickerstreak@122 312 end
flickerstreak@122 313
flickerstreak@122 314 function Bar:SetButtonGrid(r,c,s)
flickerstreak@122 315 if r > 0 and c > 0 and s > 0 then
flickerstreak@122 316 local cfg = self.config
flickerstreak@122 317 cfg.btnRows = r
flickerstreak@122 318 cfg.btnColumns = c
flickerstreak@122 319 cfg.spacing = s
flickerstreak@122 320 end
flickerstreak@122 321 ReAction:RefreshBar(self)
flickerstreak@122 322 end
flickerstreak@122 323
flickerstreak@122 324 function Bar:GetAlpha()
flickerstreak@122 325 return self.config.alpha or 1.0
flickerstreak@122 326 end
flickerstreak@122 327
flickerstreak@122 328 function Bar:SetAlpha(value)
flickerstreak@122 329 self.config.alpha = value
flickerstreak@122 330 self:GetFrame():SetAlpha(value or 1.0)
flickerstreak@155 331 self:UpdateDefaultStateAlpha()
flickerstreak@122 332 ReAction:RefreshBar(self)
flickerstreak@122 333 end
flickerstreak@122 334
flickerstreak@122 335 function Bar:IterateButtons()
flickerstreak@155 336 -- iterator returns button, idx and does NOT iterate in index order
flickerstreak@122 337 return pairs(self.buttons)
flickerstreak@122 338 end
flickerstreak@122 339
flickerstreak@153 340 --
flickerstreak@153 341 -- Methods
flickerstreak@153 342 --
flickerstreak@153 343
flickerstreak@147 344 function Bar:SetConfigMode(mode)
flickerstreak@155 345 self:SetSecureData("showAll",mode)
flickerstreak@155 346 self:UpdateUnitWatch()
flickerstreak@147 347 self:ShowControls(mode)
flickerstreak@147 348 for b in self:IterateButtons() do
flickerstreak@147 349 b:ShowGridTemp(mode)
flickerstreak@147 350 b:UpdateActionIDLabel(mode)
flickerstreak@147 351 end
flickerstreak@147 352 end
flickerstreak@147 353
flickerstreak@147 354 function Bar:SetKeybindMode(mode)
flickerstreak@155 355 self:SetSecureData("showAll",mode)
flickerstreak@155 356 self:UpdateUnitWatch()
flickerstreak@147 357 for b in self:IterateButtons() do
flickerstreak@147 358 b:SetKeybindMode(mode)
flickerstreak@147 359 end
flickerstreak@147 360 end
flickerstreak@147 361
flickerstreak@153 362 function Bar:ApplyAnchor()
flickerstreak@153 363 local f = self:GetFrame()
flickerstreak@153 364 local c = self.config
flickerstreak@153 365 local p = c.point
flickerstreak@153 366
flickerstreak@153 367 f:SetWidth(c.width)
flickerstreak@153 368 f:SetHeight(c.height)
flickerstreak@153 369 f:ClearAllPoints()
flickerstreak@153 370
flickerstreak@153 371 if p then
flickerstreak@153 372 local a = f:GetParent()
flickerstreak@153 373 if c.anchor then
flickerstreak@153 374 local bar = ReAction:GetBar(c.anchor)
flickerstreak@153 375 if bar then
flickerstreak@153 376 a = bar:GetFrame()
flickerstreak@153 377 else
flickerstreak@153 378 a = _G[c.anchor]
flickerstreak@153 379 end
flickerstreak@153 380 end
flickerstreak@153 381 local fr = a or f:GetParent()
flickerstreak@153 382 f:SetPoint(p, a or f:GetParent(), c.relpoint, c.x or 0, c.y or 0)
flickerstreak@153 383 else
flickerstreak@153 384 f:SetPoint("CENTER")
flickerstreak@153 385 end
flickerstreak@155 386
flickerstreak@155 387 self:UpdateDefaultStateAnchor()
flickerstreak@153 388 end
flickerstreak@153 389
flickerstreak@153 390 function Bar:ClipNButtons( n )
flickerstreak@153 391 local cfg = self.config
flickerstreak@153 392 local r = cfg.btnRows or 1
flickerstreak@153 393 local c = cfg.btnColumns or 1
flickerstreak@153 394
flickerstreak@153 395 cfg.btnRows = ceil(n/c)
flickerstreak@153 396 cfg.btnColumns = min(n,c)
flickerstreak@153 397 end
flickerstreak@153 398
flickerstreak@153 399 function Bar:AddButton(idx, button)
flickerstreak@153 400 local f = self:GetFrame()
flickerstreak@153 401
flickerstreak@153 402 -- store in a weak reverse-index array
flickerstreak@153 403 self.buttons[button] = idx
flickerstreak@153 404
flickerstreak@153 405 -- Store a properly wrapped reference to the child frame as an attribute
flickerstreak@153 406 -- (accessible via "frameref-btn#")
flickerstreak@153 407 f:SetFrameRef(format("btn%d",idx), button:GetFrame())
flickerstreak@153 408 end
flickerstreak@153 409
flickerstreak@153 410 function Bar:RemoveButton(button)
flickerstreak@153 411 local idx = self.buttons[button]
flickerstreak@153 412 if idx then
flickerstreak@153 413 self:GetFrame():SetAttribute(format("frameref-btn%d",idx),nil)
flickerstreak@153 414 self.buttons[button] = nil
flickerstreak@153 415 end
flickerstreak@153 416 end
flickerstreak@153 417
flickerstreak@122 418 function Bar:PlaceButton(button, baseW, baseH)
flickerstreak@122 419 local idx = self.buttons[button]
flickerstreak@122 420 if idx then
flickerstreak@122 421 local r, c, s = self:GetButtonGrid()
flickerstreak@122 422 local bh, bw = self:GetButtonSize()
flickerstreak@122 423 local row, col = floor((idx-1)/c), fmod((idx-1),c) -- zero-based
flickerstreak@122 424 local x, y = col*bw + (col+0.5)*s, -(row*bh + (row+0.5)*s)
flickerstreak@122 425 local scale = bw/baseW
flickerstreak@122 426 local b = button:GetFrame()
flickerstreak@122 427
flickerstreak@122 428 b:ClearAllPoints()
flickerstreak@122 429 b:SetPoint("TOPLEFT",x/scale,y/scale)
flickerstreak@122 430 b:SetScale(scale)
flickerstreak@122 431 end
flickerstreak@122 432 end
flickerstreak@122 433
flickerstreak@122 434 function Bar:SkinButton()
flickerstreak@122 435 -- does nothing by default
flickerstreak@147 436 end
flickerstreak@148 437
flickerstreak@155 438 function Bar:UpdateShowGrid()
flickerstreak@155 439 for button in self:IterateButtons() do
flickerstreak@155 440 button:UpdateShowGrid()
flickerstreak@155 441 end
flickerstreak@155 442 end
flickerstreak@155 443
flickerstreak@155 444 function Bar:UpdateUnitWatch()
flickerstreak@155 445 if self.unitwatch then
flickerstreak@155 446 if self.unitwatchActive and (ReAction:GetConfigMode() or ReAction:GetKeybindMode()) then
flickerstreak@155 447 UnregisterUnitWatch(self:GetFrame())
flickerstreak@155 448 self.unitwatchActive = false
flickerstreak@155 449 elseif not self.unitwatchActive then
flickerstreak@155 450 RegisterUnitWatch(self:GetFrame())
flickerstreak@155 451 self.unitwatchActive = true
flickerstreak@155 452 end
flickerstreak@155 453 self:RefreshSecureState()
flickerstreak@155 454 end
flickerstreak@155 455 end
flickerstreak@155 456
flickerstreak@154 457 function Bar:ShowControls(show)
flickerstreak@154 458 if show then
flickerstreak@155 459 if not self.overlay then
flickerstreak@155 460 self.overlay = Bar.Overlay:New(self) -- see Overlay.lua
flickerstreak@154 461 end
flickerstreak@155 462 self.overlay:Show()
flickerstreak@155 463 self:RefreshSecureState()
flickerstreak@155 464 elseif self.overlay then
flickerstreak@155 465 self.overlay:Hide()
flickerstreak@154 466 end
flickerstreak@154 467 end
flickerstreak@154 468
flickerstreak@154 469 function Bar:RefreshControls()
flickerstreak@154 470 if self.overlay and self.overlay:IsShown() then
flickerstreak@154 471 self.overlay:RefreshControls()
flickerstreak@154 472 end
flickerstreak@154 473 end
flickerstreak@154 474
flickerstreak@154 475 function Bar:SetLabelSubtext(text)
flickerstreak@154 476 if self.overlay then
flickerstreak@154 477 self.overlay:SetLabelSubtext(text)
flickerstreak@154 478 end
flickerstreak@154 479 end
flickerstreak@154 480
flickerstreak@154 481 --
flickerstreak@154 482 -- Secure state functions
flickerstreak@154 483 --
flickerstreak@154 484
flickerstreak@155 485 function Bar:GetSecureState()
flickerstreak@155 486 local env = GetManagedEnvironment(self:GetFrame())
flickerstreak@155 487 return env and env.state
flickerstreak@155 488 end
flickerstreak@155 489
flickerstreak@155 490 function Bar:GetStateProperty(state, propname)
flickerstreak@155 491 -- override in modules/State.lua for now
flickerstreak@155 492 end
flickerstreak@155 493
flickerstreak@155 494 function Bar:SetStateProperty(state, propname, value)
flickerstreak@155 495 -- override in modules/State.lua for now
flickerstreak@155 496 end
flickerstreak@155 497
flickerstreak@155 498 function Bar:RefreshSecureState()
flickerstreak@155 499 self:GetFrame():Execute(_reaction_refresh)
flickerstreak@155 500 end
flickerstreak@155 501
flickerstreak@155 502 -- usage: SetSecureData(globalname, [tblkey1, tblkey2, ...], value)
flickerstreak@155 503 function Bar:SetSecureData( ... )
flickerstreak@155 504 local n = select('#',...)
flickerstreak@155 505 if n < 2 then
flickerstreak@155 506 error("ReAction.Bar:SetSecureData() requires at least 2 arguments")
flickerstreak@155 507 end
flickerstreak@155 508 local f = self:GetFrame()
flickerstreak@155 509 f:SetAttribute("data-depth",n-1)
flickerstreak@155 510 f:SetAttribute("data-value",select(n,...))
flickerstreak@155 511 for i = 1, n-1 do
flickerstreak@155 512 local key = select(i,...)
flickerstreak@155 513 if key == nil then
flickerstreak@155 514 error("ReAction.Bar:SetSecureData() - nil table key in argument list (#"..i..")")
flickerstreak@155 515 end
flickerstreak@155 516 f:SetAttribute("data-key-"..i, key)
flickerstreak@155 517 end
flickerstreak@155 518 f:Execute(
flickerstreak@155 519 [[
flickerstreak@155 520 local n = self:GetAttribute("data-depth")
flickerstreak@155 521 if n > 0 then
flickerstreak@155 522 local value = self:GetAttribute("data-value")
flickerstreak@155 523 local t = _G
flickerstreak@155 524 for i = 1, n do
flickerstreak@155 525 local key = self:GetAttribute("data-key-"..i)
flickerstreak@155 526 if not key then return end
flickerstreak@155 527 if not t[key] then
flickerstreak@155 528 t[key] = newtable()
flickerstreak@155 529 end
flickerstreak@155 530 if i == n then
flickerstreak@155 531 t[key] = value
flickerstreak@155 532 else
flickerstreak@155 533 t = t[key]
flickerstreak@155 534 end
flickerstreak@155 535 end
flickerstreak@155 536 end
flickerstreak@155 537 ]])
flickerstreak@155 538 self:RefreshSecureState()
flickerstreak@155 539 end
flickerstreak@155 540
flickerstreak@155 541 function Bar:SetSecureStateData( state, key, value )
flickerstreak@155 542 self:SetSecureData("settings",state,key,value)
flickerstreak@155 543 end
flickerstreak@155 544
flickerstreak@155 545 -- sets a snippet to be run as an extension to _onstate-reaction
flickerstreak@155 546 function Bar:SetSecureStateExtension( id, snippet )
flickerstreak@155 547 if id == nil then
flickerstreak@155 548 error("ReAction.Bar:SetSecureStateExtension() requires an id")
flickerstreak@155 549 end
flickerstreak@155 550 local f = self:GetFrame()
flickerstreak@155 551 f:SetAttribute("input-secure-ext-id",id)
flickerstreak@155 552 f:SetAttribute("secure-ext-"..id,snippet)
flickerstreak@155 553 f:Execute(
flickerstreak@155 554 [[
flickerstreak@155 555 local id = self:GetAttribute("input-secure-ext-id")
flickerstreak@155 556 if id then
flickerstreak@155 557 extensions[id] = self:GetAttribute("secure-ext-"..id) or nil
flickerstreak@155 558 end
flickerstreak@155 559 ]])
flickerstreak@155 560 self:RefreshSecureState()
flickerstreak@155 561 end
flickerstreak@155 562
flickerstreak@155 563 function Bar:SetFrameRef( name, refFrame )
flickerstreak@155 564 if refFrame then
flickerstreak@155 565 local _, explicit = refFrame:IsProtected()
flickerstreak@155 566 if not explicit then
flickerstreak@155 567 refFrame = nil
flickerstreak@155 568 end
flickerstreak@155 569 end
flickerstreak@155 570 if refFrame then
flickerstreak@155 571 self:GetFrame():SetFrameRef(name,refFrame)
flickerstreak@155 572 else
flickerstreak@155 573 self:GetFrame():SetAttribute("frameref-"..name,nil)
flickerstreak@155 574 end
flickerstreak@155 575 end
flickerstreak@155 576
flickerstreak@155 577 function Bar:SetStateDriver( rule )
flickerstreak@155 578 if rule then
flickerstreak@155 579 RegisterStateDriver(self:GetFrame(),"reaction",rule)
flickerstreak@155 580 elseif self.statedriver then
flickerstreak@155 581 UnregisterStateDriver(self:GetFrame(),"reaction")
flickerstreak@155 582 end
flickerstreak@155 583 self.statedriver = rule
flickerstreak@155 584 self:RefreshSecureState()
flickerstreak@155 585 end
flickerstreak@155 586
flickerstreak@148 587 -- pass unit=nil to set up the unit elsewhere, if you want something more complex
flickerstreak@148 588 function Bar:RegisterUnitWatch( unit, enable )
flickerstreak@148 589 local f = self:GetFrame()
flickerstreak@148 590 if unit then
flickerstreak@148 591 f:SetAttribute("unit",unit)
flickerstreak@148 592 end
flickerstreak@148 593 self.unitwatch = enable
flickerstreak@155 594 self:UpdateUnitWatch()
flickerstreak@148 595 end
flickerstreak@148 596
flickerstreak@155 597 -- set a keybind to push a value into "state-reaction" attribute
flickerstreak@155 598 function Bar:SetStateKeybind( key, state )
flickerstreak@155 599 local f = self:GetFrame()
flickerstreak@155 600 local binds = self.statebinds
flickerstreak@155 601 if not binds then
flickerstreak@155 602 binds = { }
flickerstreak@155 603 self.statebinds = binds
flickerstreak@155 604 end
flickerstreak@155 605
flickerstreak@155 606 -- clear the old binding, if any
flickerstreak@155 607 if binds[state] then
flickerstreak@155 608 SetOverrideBinding(f, false, binds[state], nil)
flickerstreak@155 609 end
flickerstreak@155 610
flickerstreak@155 611 if key then
flickerstreak@155 612 SetOverrideBinding(f, false, key, state, nil) -- state name is virtual mouse button
flickerstreak@155 613 end
flickerstreak@155 614 binds[state] = key
flickerstreak@155 615 end
flickerstreak@155 616
flickerstreak@155 617 function Bar:GetStateKeybind( state )
flickerstreak@155 618 if self.statebinds and state then
flickerstreak@155 619 return self.statebinds[state]
flickerstreak@155 620 end
flickerstreak@155 621 end
flickerstreak@155 622
flickerstreak@155 623 function Bar:UpdateDefaultStateAnchor()
flickerstreak@155 624 local point, frame, relPoint, x, y = self:GetAnchor()
flickerstreak@155 625 local f = self:GetFrame()
flickerstreak@155 626 f:SetAttribute("defaultAnchor-point",point)
flickerstreak@155 627 f:SetAttribute("defaultAnchor-relPoint",relPoint)
flickerstreak@155 628 f:SetAttribute("defaultAnchor-x",x)
flickerstreak@155 629 f:SetAttribute("defaultAnchor-y",y)
flickerstreak@155 630 self:SetFrameRef("defaultAnchor",_G[frame or "UIParent"])
flickerstreak@155 631 f:Execute([[
flickerstreak@155 632 for _, k in pairs(anchorKeys) do
flickerstreak@155 633 defaultAnchor[k] = self:GetAttribute("defaultAnchor-"..k)
flickerstreak@155 634 end
flickerstreak@155 635 defaultAnchor.frame = self:GetAttribute("frameref-defaultAnchor")
flickerstreak@155 636 ]])
flickerstreak@155 637 end
flickerstreak@155 638
flickerstreak@155 639 function Bar:UpdateDefaultStateAlpha()
flickerstreak@155 640 local f = self:GetFrame()
flickerstreak@155 641 f:SetAttribute("defaultAlpha",self:GetAlpha())
flickerstreak@155 642 f:Execute([[
flickerstreak@155 643 defaultAlpha = self:GetAttribute("defaultAlpha")
flickerstreak@155 644 ]])
flickerstreak@155 645 end