Mercurial > wow > reaction
comparison libs/ReBound-1.0/ReBound-1.0.lua @ 10:f3a7bfebc283
Version 0.33
| author | Flick <flickerstreak@gmail.com> |
|---|---|
| date | Tue, 20 Mar 2007 21:37:38 +0000 |
| parents | |
| children | 2735edcf9ab7 |
comparison
equal
deleted
inserted
replaced
| 9:650f75d08952 | 10:f3a7bfebc283 |
|---|---|
| 1 --[[ | |
| 2 Name: ReBound-1.0 | |
| 3 Revision: $Rev: 1 $ | |
| 4 Author: Flick | |
| 5 Website: | |
| 6 Documentation: | |
| 7 SVN: | |
| 8 Description: Library for point-and-click key binding interfaces | |
| 9 License: MIT | |
| 10 Dependencies: AceLibrary, AceEvent-2.0, AceLocale-2.2 | |
| 11 ]] | |
| 12 | |
| 13 | |
| 14 local version_major, version_minor = "ReBound-1.0", "$Rev: 1 $" | |
| 15 | |
| 16 if not AceLibrary then error(version_major .. " requires AceLibrary.") 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 | |
| 19 if not AceLibrary:HasInstance("AceLocale-2.2") then error(version_major .. " requires AceLocale-2.2.") end | |
| 20 | |
| 21 local L = AceLibrary("AceLocale-2.2"):new("ReBound") | |
| 22 | |
| 23 local colorGreen = "|cff00ff00" | |
| 24 local colorOff = "|r" | |
| 25 | |
| 26 local mouseButtonConvert = { | |
| 27 MiddleButton = "BUTTON3", | |
| 28 Button4 = "BUTTON4", | |
| 29 Button5 = "BUTTON5" | |
| 30 } | |
| 31 | |
| 32 -- localization | |
| 33 L:RegisterTranslations( "enUS", function() | |
| 34 return { | |
| 35 ["none"] = true, | |
| 36 ["Right-click"] = true, | |
| 37 ["Click to select for binding"] = true, | |
| 38 ["Shift-click to clear binding"] = true, | |
| 39 ["Press a key to assign binding"] = true, | |
| 40 ["is now unbound"] = true, | |
| 41 } | |
| 42 end ) | |
| 43 | |
| 44 | |
| 45 | |
| 46 | |
| 47 local ReBound = { } | |
| 48 | |
| 49 | |
| 50 --[[ | |
| 51 Arguments: | |
| 52 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 | |
| 54 [button]: The mouse button to emulate. Default is "LeftButton". | |
| 55 | |
| 56 Returns: | |
| 57 nothing. | |
| 58 | |
| 59 Notes: | |
| 60 This does not save the bindings. | |
| 61 ]] | |
| 62 function ReBound:SetBinding( key, target, button ) | |
| 63 if not key then self:error("ReBound:SetBinding() requires a key argument.") end | |
| 64 if not target then self:error("ReBound:SetBinding() requires a binding target argument") end | |
| 65 button = button or "LeftButton" | |
| 66 | |
| 67 -- prevent setting a binding that's already set | |
| 68 local current = { self:GetBinding(target,button) } | |
| 69 for _, b in pairs(current) do | |
| 70 if b == key then | |
| 71 return | |
| 72 end | |
| 73 end | |
| 74 | |
| 75 -- clear the old binding for the key. This isn't strictly necessary, but it allows us to collect | |
| 76 -- notification of the unbinding in one place (ClearBinding). | |
| 77 self:ClearBinding( key ) | |
| 78 | |
| 79 -- clear the old binding for the target and button (silently) | |
| 80 self:ClearBinding( nil, target, button, true ) | |
| 81 | |
| 82 -- set the new binding | |
| 83 SetBindingClick(key, target:GetName(), button) | |
| 84 | |
| 85 -- notify listeners, e.g. for storing the setting | |
| 86 self.event:TriggerEvent("REBOUND_BIND", key, target:GetName(), button) | |
| 87 end | |
| 88 | |
| 89 | |
| 90 --[[ | |
| 91 Arguments: | |
| 92 [key]: A string representation of a key, suitable for passing to SetBinding. This can be nil if target is specified. | |
| 93 [target]: The frame with a click keybinding to search for a key. | |
| 94 [button]: The mouse button to emulate. Default is "LeftButton". Only used with [target]. | |
| 95 [silent]: if true, omits printout. | |
| 96 | |
| 97 Returns: | |
| 98 nothing. | |
| 99 | |
| 100 Notes: | |
| 101 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. | |
| 103 | |
| 104 This does NOT save the bindings. Call SaveBindings() to commit the bindings to disk. | |
| 105 ]] | |
| 106 function ReBound: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 | |
| 108 button = button or "LeftButton" | |
| 109 | |
| 110 local keys = key and { key } or { self:GetBinding(target,button) } | |
| 111 for _, k in ipairs(keys) do | |
| 112 -- Print a notification message | |
| 113 if k and not silent then | |
| 114 local action = GetBindingAction(k) | |
| 115 if action then | |
| 116 local name = GetBindingText(action,"BINDING_NAME_") | |
| 117 local keyTxt = GetBindingText(k,"KEY_") | |
| 118 -- make click-bindings look prettier | |
| 119 local f, b = name:match("CLICK (.+)\:(.+)") | |
| 120 if f then | |
| 121 name = f | |
| 122 if b ~= "LeftButton" then | |
| 123 if b == "RightButton" then b = "Right Click" end | |
| 124 name = f .."-"..b | |
| 125 end | |
| 126 end | |
| 127 if name and #name > 0 then | |
| 128 UIErrorsFrame:AddMessage(name.." ("..colorGreen..keyTxt..colorOff..") "..L["is now unbound"].."!") | |
| 129 end | |
| 130 end | |
| 131 end | |
| 132 SetBinding(k,nil) | |
| 133 self.event:TriggerEvent("REBOUND_UNBIND", k) | |
| 134 end | |
| 135 end | |
| 136 | |
| 137 | |
| 138 --[[ | |
| 139 Gets the keys bound to clicking a frame. | |
| 140 | |
| 141 Arguments: | |
| 142 target: target frame to query | |
| 143 [button]: mouse button to emulate ("LeftButton", "RightButton") | |
| 144 | |
| 145 Returns: | |
| 146 key1, key2, key3, etc, as strings. | |
| 147 ]] | |
| 148 function ReBound:GetBinding( target, button ) | |
| 149 if not target then self:error("ReBound:GetBinding() requires a target frame argument") end | |
| 150 button = button or "LeftButton" | |
| 151 return GetBindingKey("CLICK "..target:GetName()..":"..button) | |
| 152 end | |
| 153 | |
| 154 | |
| 155 --[[ | |
| 156 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. | |
| 158 | |
| 159 Arguments: | |
| 160 target = the frame whose OnClick handler should be the target of keybinding | |
| 161 | |
| 162 Returns: | |
| 163 A clickbinder frame. | |
| 164 ]] | |
| 165 function ReBound:Register( target ) | |
| 166 local f = self:CreateClickBindingFrame(target) | |
| 167 self.frames[target] = f | |
| 168 return f | |
| 169 end | |
| 170 | |
| 171 | |
| 172 --[[ | |
| 173 Unregisters a target frame by removing it from the internal list. Does nothing to the clickbinding frame. | |
| 174 | |
| 175 Arguments: | |
| 176 target = the frame whose OnClick handler should no longer be the target of keybinding | |
| 177 | |
| 178 Returns: | |
| 179 nothing. | |
| 180 ]] | |
| 181 function ReBound:Unregister( target ) | |
| 182 self.frames[target] = nil | |
| 183 end | |
| 184 | |
| 185 | |
| 186 --[[ | |
| 187 Shows all the registered click binding frames. | |
| 188 ]] | |
| 189 function ReBound:ShowAll() | |
| 190 if InCombatLockdown() then | |
| 191 -- can't set bindings while in combat, so don't bother showing them | |
| 192 UIErrorsFrame:AddMessage(ERR_NOT_IN_COMBAT) | |
| 193 else | |
| 194 for _, f in pairs(self.frames) do | |
| 195 f:Show() | |
| 196 end | |
| 197 end | |
| 198 end | |
| 199 | |
| 200 | |
| 201 --[[ | |
| 202 Hides all the registered click binding frames. | |
| 203 ]] | |
| 204 function ReBound:HideAll() | |
| 205 for _, f in pairs(self.frames) do | |
| 206 f:Hide() | |
| 207 end | |
| 208 end | |
| 209 | |
| 210 -- click binding frame implementation functions | |
| 211 local function ShowTooltip1( self ) | |
| 212 local target = self:GetParent() | |
| 213 | |
| 214 GameTooltip:ClearLines() | |
| 215 GameTooltip:SetOwner(self,"ANCHOR_TOPRIGHT") | |
| 216 -- line 1: button name and current binding | |
| 217 GameTooltip:AddDoubleLine(target:GetName(), colorGreen.."("..(self.ReBound:GetBinding(target,"LeftButton") or L["none"])..")"..colorOff) | |
| 218 -- line 2: current right-click binding (if any) | |
| 219 local binding2 = self.ReBound:GetBinding(target,"RightButton") | |
| 220 if binding2 then | |
| 221 GameTooltip:AddDoubleLine(L["Right-click"]..":", colorGreen.."("..binding2..")"..colorOff) | |
| 222 end | |
| 223 -- line 3: instructions | |
| 224 GameTooltip:AddLine(L["Click to select for binding"]) | |
| 225 GameTooltip:AddLine(L["Shift-click to clear binding"]) | |
| 226 GameTooltip:Show() | |
| 227 end | |
| 228 | |
| 229 local function ShowTooltip2( self ) | |
| 230 if GameTooltip:IsOwned(self) then | |
| 231 local target = self:GetParent() | |
| 232 GameTooltip:ClearLines() | |
| 233 GameTooltip:SetOwner(self) | |
| 234 local clickSuffix = self.selectedButton == "RightButton" and (" ("..L["Right-click"]..")") or "" | |
| 235 -- line 1: button name and binding to be set | |
| 236 GameTooltip:AddDoubleLine(target:GetName()..clickSuffix, colorGreen.."("..(self.ReBound:GetBinding(target,self.selectedButton) or L["none"])..")"..colorOff) | |
| 237 -- line 2: instructions | |
| 238 GameTooltip:AddLine(colorGreen..L["Press a key to assign binding"]..colorOff) | |
| 239 GameTooltip:Show() | |
| 240 end | |
| 241 end | |
| 242 | |
| 243 local function OnClick( self, button ) | |
| 244 if button == "LeftButton" or button == "RightButton" then | |
| 245 if IsShiftKeyDown() then | |
| 246 self.ReBound:ClearBinding( nil, self:GetParent(), button ) | |
| 247 self.selectedButton = nil | |
| 248 self:EnableKeyboard(false) | |
| 249 ShowTooltip1(self) | |
| 250 else | |
| 251 self.selectedButton = button | |
| 252 self:EnableKeyboard(true) | |
| 253 ShowTooltip2(self) | |
| 254 end | |
| 255 elseif self.selectedButton then | |
| 256 self.ReBound:SetBinding( mouseButtonConvert[button], self:GetParent(), self.selectedButton ) | |
| 257 self.selectedButton = nil | |
| 258 self:EnableKeyboard(false) | |
| 259 ShowTooltip1(self) | |
| 260 end | |
| 261 end | |
| 262 | |
| 263 local function OnEnter( self ) | |
| 264 -- clear current binding button | |
| 265 self.selectedButton = nil | |
| 266 -- show tooltip 1 | |
| 267 ShowTooltip1(self) | |
| 268 end | |
| 269 | |
| 270 local function OnLeave( self ) | |
| 271 -- disable keyboard input, if it was enabled | |
| 272 self:EnableKeyboard(false) | |
| 273 -- hide tooltip | |
| 274 if GameTooltip:IsOwned(self) then | |
| 275 GameTooltip:Hide() | |
| 276 end | |
| 277 end | |
| 278 | |
| 279 local function OnKeyDown( self, key ) | |
| 280 if key == nil or key == "UNKNOWN" or key == "SHIFT" or key == "CTRL" or key == "ALT" then | |
| 281 return | |
| 282 end | |
| 283 if IsShiftKeyDown() then key = "SHIFT-"..key end | |
| 284 if IsControlKeyDown() then key = "CTRL-"..key end | |
| 285 if IsAltKeyDown() then key = "ALT-"..key end | |
| 286 | |
| 287 if key ~= "ESCAPE" then | |
| 288 self.ReBound:SetBinding( key, self:GetParent(), self.selectedButton ) | |
| 289 end | |
| 290 | |
| 291 self:EnableKeyboard(false) | |
| 292 self.selectedButton = nil | |
| 293 ShowTooltip1(self) | |
| 294 end | |
| 295 | |
| 296 --[[ | |
| 297 Creates a click-binding frame attached to the target frame, which can be used for point-and-click keybind assignments. The | |
| 298 frame is initially hidden by default. It is not registered with ReBound for automatic show/hide: use Register() for that. | |
| 299 | |
| 300 Arguments: | |
| 301 target - the frame whose OnClick handler should be the target of keybinding | |
| 302 | |
| 303 Returns: | |
| 304 A clickbinder frame. | |
| 305 ]] | |
| 306 function ReBound:CreateClickBindingFrame( target ) | |
| 307 local f = CreateFrame("Button", nil, target) | |
| 308 f.ReBound = self | |
| 309 f:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square") | |
| 310 f:SetToplevel(1) | |
| 311 f:SetFrameStrata("DIALOG") | |
| 312 f:RegisterForClicks("AnyUp") | |
| 313 f:SetScript("OnClick", OnClick) | |
| 314 f:SetScript("OnEnter", OnEnter) | |
| 315 f:SetScript("OnLeave", OnLeave) | |
| 316 f:SetScript("OnKeyDown", OnKeyDown) | |
| 317 f:SetAllPoints(target) | |
| 318 f:Hide() | |
| 319 return f | |
| 320 end | |
| 321 | |
| 322 | |
| 323 | |
| 324 -- library setup | |
| 325 | |
| 326 local function activate( self, oldLib, oldDeactivate ) | |
| 327 -- set initial values | |
| 328 self.mode = oldLib and oldLib.mode or "char" | |
| 329 self.frames = { } | |
| 330 | |
| 331 self.event = AceLibrary("AceOO-2.0").Class("AceEvent-2.0"):new() | |
| 332 self.event:RegisterEvent("PLAYER_REGEN_DISABLED", function() self:HideAll() end) | |
| 333 | |
| 334 if oldDeactivate then | |
| 335 oldDeactivate(oldLib) | |
| 336 end | |
| 337 end | |
| 338 | |
| 339 local function deactivate( self ) | |
| 340 self.event:UnregisterEvent("PLAYER_REGEN_DISABLED") | |
| 341 end | |
| 342 | |
| 343 AceLibrary:Register(ReBound, version_major, version_minor, activate, deactivate) | |
| 344 ReBound = nil |
