annotate classes/Bar.lua @ 156:611e6ce08717

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