Mercurial > wow > reaction
comparison libs/ReBound-1.0/ReBound-1.0.lua @ 12:2735edcf9ab7
Version 0.34
| author | Flick <flickerstreak@gmail.com> |
|---|---|
| date | Wed, 21 Mar 2007 00:13:27 +0000 |
| parents | f3a7bfebc283 |
| children | 639282f3a0e0 |
comparison
equal
deleted
inserted
replaced
| 11:88df7235ad8b | 12:2735edcf9ab7 |
|---|---|
| 1 --[[ | 1 --[[ |
| 2 Name: ReBound-1.0 | 2 Name: ReBound-1.0 |
| 3 Revision: $Rev: 1 $ | 3 Revision: $Rev: 2 $ |
| 4 Author: Flick | 4 Author: Flick |
| 5 Website: | 5 Website: |
| 6 Documentation: | 6 Documentation: |
| 7 SVN: | 7 SVN: |
| 8 Description: Library for point-and-click key binding interfaces | 8 Description: A library to assist with click-binding |
| 9 License: MIT | 9 License: MIT |
| 10 Dependencies: AceLibrary, AceEvent-2.0, AceLocale-2.2 | 10 Dependencies: AceLibrary, AceEvent-2.0, AceLocale-2.2, AceOO-2.0 |
| 11 ]] | 11 ]] |
| 12 | 12 |
| 13 | 13 |
| 14 local version_major, version_minor = "ReBound-1.0", "$Rev: 1 $" | 14 local version_major, version_minor = "ReBound-1.0", "$Rev: 2 $" |
| 15 | 15 |
| 16 if not AceLibrary then error(version_major .. " requires AceLibrary.") end | 16 if not AceLibrary then error(version_major .. " requires AceLibrary.") end |
| 17 if not AceLibrary:IsNewVersion(version_major, version_minor) then return end | 17 if not AceLibrary:IsNewVersion(version_major, version_minor) then return end |
| 18 if not AceLibrary:HasInstance("AceEvent-2.0") then error(version_major .. " requires AceEvent-2.0.") end | 18 if not AceLibrary:HasInstance("AceEvent-2.0") then error(version_major .. " requires AceEvent-2.0.") end |
| 19 if not AceLibrary:HasInstance("AceLocale-2.2") then error(version_major .. " requires AceLocale-2.2.") end | 19 if not AceLibrary:HasInstance("AceLocale-2.2") then error(version_major .. " requires AceLocale-2.2.") end |
| 20 if not AceLibrary:HasInstance("AceOO-2.0") then error(version_major .. " requires AceOO-2.0.") end | |
| 20 | 21 |
| 21 local L = AceLibrary("AceLocale-2.2"):new("ReBound") | 22 local L = AceLibrary("AceLocale-2.2"):new("ReBound") |
| 22 | 23 |
| 23 local colorGreen = "|cff00ff00" | 24 local colorGreen = "|cff00ff00" |
| 24 local colorOff = "|r" | 25 local colorOff = "|r" |
| 25 | 26 |
| 26 local mouseButtonConvert = { | 27 local mouseButtonConvert = { |
| 28 LeftButton = "BUTTON1", | |
| 29 RightButton = "BUTTON2", | |
| 27 MiddleButton = "BUTTON3", | 30 MiddleButton = "BUTTON3", |
| 28 Button4 = "BUTTON4", | 31 Button4 = "BUTTON4", |
| 29 Button5 = "BUTTON5" | 32 Button5 = "BUTTON5" |
| 30 } | 33 } |
| 34 | |
| 35 --local BINDING_PENDING = { } -- a constant | |
| 31 | 36 |
| 32 -- localization | 37 -- localization |
| 33 L:RegisterTranslations( "enUS", function() | 38 L:RegisterTranslations( "enUS", function() |
| 34 return { | 39 return { |
| 35 ["none"] = true, | 40 ["none"] = true, |
| 36 ["Right-click"] = true, | 41 ["Right-click"] = true, |
| 42 ["Right Click"] = true, | |
| 37 ["Click to select for binding"] = true, | 43 ["Click to select for binding"] = true, |
| 38 ["Shift-click to clear binding"] = true, | 44 ["Shift-click to clear binding"] = true, |
| 39 ["Press a key to assign binding"] = true, | 45 ["Press a key to assign binding"] = true, |
| 40 ["is now unbound"] = true, | 46 ["is now unbound"] = true, |
| 41 } | 47 } |
| 42 end ) | 48 end ) |
| 43 | 49 |
| 44 | 50 |
| 45 | 51 local ReBound = AceLibrary("AceOO-2.0").Class("AceEvent-2.0") |
| 46 | 52 |
| 47 local ReBound = { } | 53 --[[ |
| 54 ReBound publishes the following events: | |
| 55 | |
| 56 -- temporary bindings (prior to SaveBindings() being called) | |
| 57 REBOUND_BIND_TEMP (id, key, targetFrameName, mouseButton) | |
| 58 REBOUND_UNBIND_TEMP (id, key) | |
| 59 | |
| 60 -- permanent bindings (fired all at once when SaveBindings() is called) | |
| 61 REBOUND_BIND (id, key, targetFrameName, mouseButton) | |
| 62 REBOUND_UNBIND (id, key) | |
| 63 | |
| 64 These events are published in response to click actions ONLY. This means | |
| 65 that if a key is unbound from a click-binding frame, and bound to some | |
| 66 other action, then REBOUND_UNBIND(id,key) will be fired. | |
| 67 ]] | |
| 68 | |
| 69 | |
| 70 --[[ | |
| 71 Calls to new() which share ids will return an existing object with that id, similar | |
| 72 to AceLocale-2.2. | |
| 73 ]] | |
| 74 local super_new = ReBound.new | |
| 75 function ReBound:new( id ) | |
| 76 self.instances = self.instances or { } | |
| 77 if self.instances[id] then | |
| 78 return self.instances[id] | |
| 79 else | |
| 80 local i = super_new(self,id) | |
| 81 self.instances[id] = i | |
| 82 return i | |
| 83 end | |
| 84 end | |
| 85 | |
| 86 | |
| 87 --[[ | |
| 88 Class object constructor | |
| 89 | |
| 90 arguments: | |
| 91 id : the ID that will be provided in events. This can be absolutely | |
| 92 anything, but a string is recommended. | |
| 93 ]] | |
| 94 local super_init = ReBound.prototype.init | |
| 95 function ReBound.prototype:init( id ) | |
| 96 super_init(self) | |
| 97 | |
| 98 self.id = id | |
| 99 self.frames = { } | |
| 100 self.pending = { } | |
| 101 self.bindings = { } | |
| 102 end | |
| 103 | |
| 104 | |
| 48 | 105 |
| 49 | 106 |
| 50 --[[ | 107 --[[ |
| 51 Arguments: | 108 Arguments: |
| 52 key: A string representation of a key, suitable for passing to SetBinding. | 109 key: A string representation of a key, suitable for passing to SetBinding. |
| 53 target: The frame with an OnClick handler to attach a click-binding to | 110 target: The frame with an OnClick handler to which the click-binding should be attached |
| 54 [button]: The mouse button to emulate. Default is "LeftButton". | 111 [button]: The mouse button to emulate. Default is "LeftButton". |
| 55 | 112 |
| 56 Returns: | 113 Returns: |
| 57 nothing. | 114 nothing. |
| 58 | 115 |
| 59 Notes: | 116 Notes: |
| 60 This does not save the bindings. | 117 This does not save the bindings. |
| 61 ]] | 118 ]] |
| 62 function ReBound:SetBinding( key, target, button ) | 119 function ReBound.prototype:SetBinding( key, target, button ) |
| 63 if not key then self:error("ReBound:SetBinding() requires a key argument.") end | 120 if not key then error("ReBound:SetBinding() requires a key argument.") end |
| 64 if not target then self:error("ReBound:SetBinding() requires a binding target argument") end | 121 if not target then error("ReBound:SetBinding() requires a binding target argument") end |
| 65 button = button or "LeftButton" | 122 button = button or "LeftButton" |
| 66 | 123 |
| 67 -- prevent setting a binding that's already set | 124 -- prevent setting a binding that's already set |
| 68 local current = { self:GetBinding(target,button) } | 125 local current = { self:GetBinding(target,button) } |
| 69 for _, b in pairs(current) do | 126 for _, b in pairs(current) do |
| 80 self:ClearBinding( nil, target, button, true ) | 137 self:ClearBinding( nil, target, button, true ) |
| 81 | 138 |
| 82 -- set the new binding | 139 -- set the new binding |
| 83 SetBindingClick(key, target:GetName(), button) | 140 SetBindingClick(key, target:GetName(), button) |
| 84 | 141 |
| 85 -- notify listeners, e.g. for storing the setting | 142 -- store the temporary binding as "pending" for later notification |
| 86 self.event:TriggerEvent("REBOUND_BIND", key, target:GetName(), button) | 143 table.insert(self.pending, key) |
| 144 | |
| 145 -- notify listeners, e.g. for displaying the setting | |
| 146 self:TriggerEvent("REBOUND_BIND_TEMP", self.id, key, target:GetName(), button) | |
| 87 end | 147 end |
| 88 | 148 |
| 89 | 149 |
| 90 --[[ | 150 --[[ |
| 91 Arguments: | 151 Arguments: |
| 101 If key is provided, then the binding for that key is cleared. If key is not provided and target is provided, then | 161 If key is provided, then the binding for that key is cleared. If key is not provided and target is provided, then |
| 102 all the bindings attached to the click-binding for that target are cleared. | 162 all the bindings attached to the click-binding for that target are cleared. |
| 103 | 163 |
| 104 This does NOT save the bindings. Call SaveBindings() to commit the bindings to disk. | 164 This does NOT save the bindings. Call SaveBindings() to commit the bindings to disk. |
| 105 ]] | 165 ]] |
| 106 function ReBound:ClearBinding( key, target, button, silent ) | 166 function ReBound.prototype:ClearBinding( key, target, button, silent ) |
| 107 if not target and not key then self:error("ReBound:ClearBinding() requires a key or click-binding target argument") end | 167 if not target and not key then error("ReBound:ClearBinding() requires a key or click-binding target argument") end |
| 108 button = button or "LeftButton" | 168 button = button or "LeftButton" |
| 109 | 169 |
| 110 local keys = key and { key } or { self:GetBinding(target,button) } | 170 local keys = key and { key } or { self:GetBinding(target,button) } |
| 111 for _, k in ipairs(keys) do | 171 for _, k in ipairs(keys) do |
| 112 -- Print a notification message | 172 -- Print a notification message |
| 118 -- make click-bindings look prettier | 178 -- make click-bindings look prettier |
| 119 local f, b = name:match("CLICK (.+)\:(.+)") | 179 local f, b = name:match("CLICK (.+)\:(.+)") |
| 120 if f then | 180 if f then |
| 121 name = f | 181 name = f |
| 122 if b ~= "LeftButton" then | 182 if b ~= "LeftButton" then |
| 123 if b == "RightButton" then b = "Right Click" end | 183 if b == "RightButton" then b = L["Right Click"] end |
| 124 name = f .."-"..b | 184 name = f .."-"..b |
| 125 end | 185 end |
| 126 end | 186 end |
| 127 if name and #name > 0 then | 187 if name and #name > 0 then |
| 128 UIErrorsFrame:AddMessage(name.." ("..colorGreen..keyTxt..colorOff..") "..L["is now unbound"].."!") | 188 UIErrorsFrame:AddMessage(name.." ("..colorGreen..keyTxt..colorOff..") "..L["is now unbound"].."!") |
| 129 end | 189 end |
| 130 end | 190 end |
| 131 end | 191 end |
| 132 SetBinding(k,nil) | 192 SetBinding(k,nil) |
| 133 self.event:TriggerEvent("REBOUND_UNBIND", k) | 193 table.insert(self.pending,k) |
| 134 end | 194 self:TriggerEvent("REBOUND_UNBIND_TEMP", self.id, k) |
| 135 end | 195 end |
| 136 | 196 end |
| 137 | 197 |
| 138 --[[ | 198 |
| 139 Gets the keys bound to clicking a frame. | 199 --[[ |
| 200 Gets the keys currently click-bound to a frame. | |
| 140 | 201 |
| 141 Arguments: | 202 Arguments: |
| 142 target: target frame to query | 203 target: target frame to query |
| 143 [button]: mouse button to emulate ("LeftButton", "RightButton") | 204 [button]: mouse button to emulate ("LeftButton", "RightButton") |
| 144 | 205 |
| 145 Returns: | 206 Returns: |
| 146 key1, key2, key3, etc, as strings. | 207 key1, key2, key3, etc, as strings. |
| 147 ]] | 208 ]] |
| 148 function ReBound:GetBinding( target, button ) | 209 function ReBound.prototype:GetBinding( target, button ) |
| 149 if not target then self:error("ReBound:GetBinding() requires a target frame argument") end | 210 if not target then error("ReBound:GetBinding() requires a target frame argument") end |
| 150 button = button or "LeftButton" | 211 button = button or "LeftButton" |
| 151 return GetBindingKey("CLICK "..target:GetName()..":"..button) | 212 return GetBindingKey("CLICK "..target:GetName()..":"..button) |
| 152 end | 213 end |
| 153 | 214 |
| 154 | 215 |
| 155 --[[ | 216 --[[ |
| 217 Publishes permanent binding notification events. | |
| 218 ]] | |
| 219 local function PublishBindings(self) | |
| 220 for _, key in ipairs(self.pending) do | |
| 221 local action = GetBindingAction(key) | |
| 222 local frame, button | |
| 223 if action then | |
| 224 frame, button = action:match("CLICK (.+)\:(.+)") | |
| 225 end | |
| 226 if frame == nil then | |
| 227 self:TriggerEvent("REBOUND_UNBIND", self.id, key) | |
| 228 else | |
| 229 self:TriggerEvent("REBOUND_BIND", self.id, key, frame, button) | |
| 230 end | |
| 231 end | |
| 232 self.pending = { } | |
| 233 end | |
| 234 | |
| 235 | |
| 236 --[[ | |
| 237 Saves the bindings using the current scheme. Also publishes events indicating that the | |
| 238 bindings have been saved/cleared permanently. | |
| 239 ]] | |
| 240 function ReBound.prototype:SaveBindings() | |
| 241 SaveBindings(GetCurrentBindingSet()) -- will trigger an UPDATE_BINDINGS event. | |
| 242 PublishBindings(self) | |
| 243 end | |
| 244 | |
| 245 | |
| 246 --[[ | |
| 247 Reverts the bindings to the ones previously saved. Also publishes events indicating that the | |
| 248 bindings have been reverted. | |
| 249 ]] | |
| 250 function ReBound.prototype:RevertBindings() | |
| 251 LoadBindings(GetCurrentBindingSet()) -- should trigger an UPDATE_BINDINGS event. | |
| 252 PublishBindings(self) | |
| 253 end | |
| 254 | |
| 255 | |
| 256 --[[ | |
| 257 Clears all bindings associated with registered frames. This is useful, for example, when switching profiles | |
| 258 and the keybinding data is stored in the profile. | |
| 259 ]] | |
| 260 function ReBound.prototype:ClearRegisteredBindings() | |
| 261 for f, _ in pairs(self.frames) do | |
| 262 self:ClearBinding(nil,f,"LeftButton",true) | |
| 263 self:ClearBinding(nil,f,"RightButton",true) | |
| 264 end | |
| 265 end | |
| 266 | |
| 267 | |
| 268 --[[ | |
| 156 Registers a target frame by creating a click-binding frame and putting that frame in the list of | 269 Registers a target frame by creating a click-binding frame and putting that frame in the list of |
| 157 registered frames, which can then be all shown/hidden as one unit. | 270 registered frames, which can then be all shown/hidden as one unit. |
| 158 | 271 |
| 159 Arguments: | 272 Arguments: |
| 160 target = the frame whose OnClick handler should be the target of keybinding | 273 target = the frame whose OnClick handler should be the target of keybinding |
| 161 | 274 |
| 162 Returns: | 275 Returns: |
| 163 A clickbinder frame. | 276 A clickbinder frame. |
| 164 ]] | 277 ]] |
| 165 function ReBound:Register( target ) | 278 function ReBound.prototype:Register( target ) |
| 166 local f = self:CreateClickBindingFrame(target) | 279 local f = self:CreateClickBindingFrame(target) |
| 167 self.frames[target] = f | 280 self.frames[target] = f |
| 168 return f | 281 return f |
| 169 end | 282 end |
| 170 | 283 |
| 171 | 284 |
| 172 --[[ | 285 --[[ |
| 173 Unregisters a target frame by removing it from the internal list. Does nothing to the clickbinding frame. | 286 Unregisters a target frame by removing it from the internal list. Does nothing to the clickbinding frame. |
| 174 | 287 |
| 175 Arguments: | 288 Arguments: |
| 176 target = the frame whose OnClick handler should no longer be the target of keybinding | 289 target = the frame whose OnClick handler should no longer be managed. do NOT pass the clickbinding frame. |
| 177 | 290 |
| 178 Returns: | 291 Returns: |
| 179 nothing. | 292 nothing. |
| 180 ]] | 293 ]] |
| 181 function ReBound:Unregister( target ) | 294 function ReBound.prototype:Unregister( target ) |
| 182 self.frames[target] = nil | 295 self.frames[target] = nil |
| 183 end | 296 end |
| 184 | 297 |
| 185 | 298 |
| 186 --[[ | 299 --[[ |
| 300 Unregisters all registered frames. | |
| 301 ]] | |
| 302 function ReBound.prototype:UnregisterAll() | |
| 303 self.frames = { } | |
| 304 end | |
| 305 | |
| 306 | |
| 307 | |
| 308 --[[ | |
| 187 Shows all the registered click binding frames. | 309 Shows all the registered click binding frames. |
| 188 ]] | 310 ]] |
| 189 function ReBound:ShowAll() | 311 function ReBound.prototype:ShowFrames() |
| 190 if InCombatLockdown() then | 312 if InCombatLockdown() then |
| 191 -- can't set bindings while in combat, so don't bother showing them | 313 -- can't set bindings while in combat, so don't bother showing them |
| 192 UIErrorsFrame:AddMessage(ERR_NOT_IN_COMBAT) | 314 UIErrorsFrame:AddMessage(ERR_NOT_IN_COMBAT) |
| 193 else | 315 else |
| 194 for _, f in pairs(self.frames) do | 316 for _, f in pairs(self.frames) do |
| 199 | 321 |
| 200 | 322 |
| 201 --[[ | 323 --[[ |
| 202 Hides all the registered click binding frames. | 324 Hides all the registered click binding frames. |
| 203 ]] | 325 ]] |
| 204 function ReBound:HideAll() | 326 function ReBound.prototype:HideFrames() |
| 327 -- because these frames aren't protected, there's no restriction | |
| 328 -- on hiding them while in combat. | |
| 205 for _, f in pairs(self.frames) do | 329 for _, f in pairs(self.frames) do |
| 206 f:Hide() | 330 f:Hide() |
| 207 end | 331 end |
| 208 end | 332 end |
| 209 | 333 |
| 301 target - the frame whose OnClick handler should be the target of keybinding | 425 target - the frame whose OnClick handler should be the target of keybinding |
| 302 | 426 |
| 303 Returns: | 427 Returns: |
| 304 A clickbinder frame. | 428 A clickbinder frame. |
| 305 ]] | 429 ]] |
| 306 function ReBound:CreateClickBindingFrame( target ) | 430 function ReBound.prototype:CreateClickBindingFrame( target ) |
| 307 local f = CreateFrame("Button", nil, target) | 431 local f = CreateFrame("Button", nil, target) |
| 308 f.ReBound = self | 432 f.ReBound = self |
| 309 f:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square") | 433 f:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square") |
| 310 f:SetToplevel(1) | 434 f:SetToplevel(1) |
| 311 f:SetFrameStrata("DIALOG") | 435 f:SetFrameStrata("DIALOG") |
| 322 | 446 |
| 323 | 447 |
| 324 -- library setup | 448 -- library setup |
| 325 | 449 |
| 326 local function activate( self, oldLib, oldDeactivate ) | 450 local function activate( self, oldLib, oldDeactivate ) |
| 327 -- set initial values | 451 -- copy the list of active instances |
| 328 self.mode = oldLib and oldLib.mode or "char" | 452 self.instances = { } |
| 329 self.frames = { } | 453 if oldLib and oldLib.instances then |
| 330 | 454 for k,v in pairs(oldLib.instances) do |
| 331 self.event = AceLibrary("AceOO-2.0").Class("AceEvent-2.0"):new() | 455 self.instances[k] = v |
| 332 self.event:RegisterEvent("PLAYER_REGEN_DISABLED", function() self:HideAll() end) | 456 end |
| 333 | 457 end |
| 458 | |
| 334 if oldDeactivate then | 459 if oldDeactivate then |
| 335 oldDeactivate(oldLib) | 460 oldDeactivate(oldLib) |
| 336 end | 461 end |
| 337 end | 462 end |
| 338 | 463 |
| 339 local function deactivate( self ) | 464 AceLibrary:Register(ReBound, version_major, version_minor, activate) |
| 340 self.event:UnregisterEvent("PLAYER_REGEN_DISABLED") | |
| 341 end | |
| 342 | |
| 343 AceLibrary:Register(ReBound, version_major, version_minor, activate, deactivate) | |
| 344 ReBound = nil | 465 ReBound = nil |
