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