comparison lib/LibKeyBound-1.0/LibKeyBound-1.0.lua @ 88:fc83b3f5b322

Added keybindings using LibKeyBound-1.0, with modifications for Override bindings instead of standard bindings.
author Flick <flickerstreak@gmail.com>
date Sun, 31 Aug 2008 06:02:18 +0000
parents
children
comparison
equal deleted inserted replaced
87:3499ac7c3a9b 88:fc83b3f5b322
1 --[[
2 Name: LibKeyBound-1.0
3 Revision: $Rev: 76300 $
4 Author(s): Gello, Maul, Toadkiller, Tuller
5 Website: http://www.wowace.com/wiki/LibKeyBound-1.0
6 Documentation: http://www.wowace.com/wiki/LibKeyBound-1.0
7 SVN: http://svn.wowace.com/wowace/trunk/LibKeyBound-1.0
8 Description: An intuitive keybindings system: mouseover frame, click keys or buttons.
9 Dependencies: CallbackHandler-1.0
10 --]]
11
12 local MAJOR = "LibKeyBound-1.0"
13 local MINOR = "$Revision: 76300 $"
14
15 --[[
16 LibKeyBound-1.0
17 ClickBinder by Gello and TrinityBinder by Maul -> keyBound by Tuller -> LibKeyBound library by Toadkiller
18
19 Functions needed to implement
20 button:GetHotkey() - returns the current hotkey assigned to the given button
21
22 Functions to implement if using a custom keybindings system:
23 button:SetKey(key) - binds the given key to the given button
24 button:FreeKey(key) - unbinds the given key from all other buttons
25 button:ClearBindings() - removes all keys bound to the given button
26 button:GetBindings() - returns a string listing all bindings of the given button
27 button:GetActionName() - what we're binding to, used for printing
28 --]]
29
30 local LibKeyBound, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
31
32 if not LibKeyBound then return end -- no upgrade needed
33
34 local _G = _G
35
36 -- CallbackHandler
37 LibKeyBound.events = LibKeyBound.events or _G.LibStub("CallbackHandler-1.0"):New(LibKeyBound)
38
39 local L = LibKeyBoundLocale10
40 LibKeyBound.L = L
41 -- ToDo delete global LibKeyBoundLocale10 at some point
42 LibKeyBound.Binder = LibKeyBound.Binder or {}
43
44 -- #NODOC
45 function LibKeyBound:Initialize()
46 do
47 local f = CreateFrame("Frame", "KeyboundDialog", UIParent)
48 f:SetFrameStrata("DIALOG")
49 f:SetToplevel(true); f:EnableMouse(true)
50 f:SetWidth(360); f:SetHeight(140)
51 f:SetBackdrop{
52 bgFile="Interface\\DialogFrame\\UI-DialogBox-Background" ,
53 edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border",
54 tile = true,
55 insets = {left = 11, right = 12, top = 12, bottom = 11},
56 tileSize = 32,
57 edgeSize = 32,
58 }
59 f:SetPoint("TOP", 0, -24)
60 f:Hide()
61
62 local tr = f:CreateTitleRegion()
63 tr:SetAllPoints(f)
64 f:SetClampedToScreen(true)
65
66 local text = f:CreateFontString("ARTWORK")
67 text:SetFontObject("GameFontHighlight")
68 text:SetPoint("TOP", 0, -16)
69 text:SetWidth(252); text:SetHeight(0)
70 text:SetText(format(L.BindingsHelp, GetBindingText("ESCAPE", "KEY_")))
71
72 -- Per character bindings checkbox
73 local perChar = CreateFrame("CheckButton", "KeyboundDialogCheck", f, "OptionsCheckButtonTemplate")
74 getglobal(perChar:GetName() .. "Text"):SetText(CHARACTER_SPECIFIC_KEYBINDINGS)
75
76 perChar:SetScript("OnShow", function(self)
77 self:SetChecked(GetCurrentBindingSet() == 2)
78 end)
79
80 local current
81 perChar:SetScript("OnClick", function(self)
82 current = (perChar:GetChecked() and 2) or 1
83 LoadBindings(current)
84 end)
85
86 -- local added
87 f:SetScript("OnShow", function(self)
88 -- if (not added) then
89 -- UISpecialFrames[#UISpecialFrames + 1] = self:GetName()
90 -- added = true
91 -- end
92 -- PlaySound("igCharacterInfoOpen")
93 end)
94 f:SetScript("OnHide", function(self)
95 -- PlaySound("igCharacterInfoClose")
96 end)
97
98 -- Okay bindings checkbox
99 local okayBindings = CreateFrame("CheckButton", "KeyboundDialogOkay", f, "OptionsButtonTemplate")
100 getglobal(okayBindings:GetName() .. "Text"):SetText(OKAY)
101 okayBindings:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -12, 14)
102
103 okayBindings:SetScript("OnClick", function(self)
104 current = (perChar:GetChecked() and 2) or 1
105 if InCombatLockdown() then
106 self:RegisterEvent("PLAYER_REGEN_ENABLED")
107 else
108 -- DEFAULT_CHAT_FRAME:AddMessage("okayBindings " .. tostring(current))
109 SaveBindings(current)
110 LibKeyBound:Deactivate()
111 end
112 end)
113
114 okayBindings:SetScript("OnHide", function(self)
115 current = (perChar:GetChecked() and 2) or 1
116 if InCombatLockdown() then
117 self:RegisterEvent("PLAYER_REGEN_ENABLED")
118 else
119 SaveBindings(current)
120 end
121 end)
122
123 okayBindings:SetScript("OnEvent", function(self, event)
124 -- DEFAULT_CHAT_FRAME:AddMessage("okayBindings delayed " .. tostring(current))
125 SaveBindings(current)
126 self:UnregisterEvent(event)
127 LibKeyBound:Deactivate()
128 end)
129
130 -- Cancel bindings checkbox
131 local cancelBindings = CreateFrame("CheckButton", "KeyboundDialogCancel", f, "OptionsButtonTemplate")
132 getglobal(cancelBindings:GetName() .. "Text"):SetText(CANCEL)
133 cancelBindings:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 12, 14)
134
135 cancelBindings:SetScript("OnClick", function(self)
136 if InCombatLockdown() then
137 self:RegisterEvent("PLAYER_REGEN_ENABLED")
138 else
139 -- DEFAULT_CHAT_FRAME:AddMessage("cancelBindings ")
140 LoadBindings(GetCurrentBindingSet())
141 LibKeyBound:Deactivate()
142 end
143 end)
144
145 cancelBindings:SetScript("OnEvent", function(self, event)
146 -- DEFAULT_CHAT_FRAME:AddMessage("cancelBindings delayed ")
147 LoadBindings(GetCurrentBindingSet())
148 self:UnregisterEvent(event)
149 LibKeyBound:Deactivate()
150 end)
151
152 perChar:SetPoint("BOTTOMLEFT", cancelBindings, "TOPLEFT", 0, 4)
153
154 self.dialog = f
155 end
156
157 SlashCmdList["LibKeyBoundSlashCOMMAND"] = function() self:Toggle() end
158 SLASH_LibKeyBoundSlashCOMMAND1 = "/libkeybound"
159 SLASH_LibKeyBoundSlashCOMMAND2 = "/kb"
160 SLASH_LibKeyBoundSlashCOMMAND3 = "/lkb"
161
162 LibKeyBound.initialized = true
163 end
164
165
166 -- Default color to indicate bindable frames in your mod.
167 LibKeyBound.colorKeyBoundMode = LibKeyBound.colorKeyBoundMode or { 0, 1, 1, 0.5 }
168
169 --[[
170 LibKeyBound:SetColorKeyBoundMode([r][, g][, b][, a])
171 --]]
172 --[[
173 Arguments:
174 number - red, default 0
175 number - green, default 0
176 number - blue, default 0
177 number - alpha, default 1
178
179 Example:
180 if (MyMod.keyBoundMode) then
181 overlayFrame:SetBackdropColor(LibKeyBound:GetColorKeyBoundMode())
182 end
183 ...
184 local r, g, b, a = LibKeyBound:GetColorKeyBoundMode()
185
186 Notes:
187 * Returns the color to use on your participating buttons during KeyBound Mode
188 * Values are unpacked and ready to use as color arguments
189 --]]
190 function LibKeyBound:SetColorKeyBoundMode(r, g, b, a)
191 r, g, b, a = r or 0, g or 0, b or 0, a or 1
192 LibKeyBound.colorKeyBoundMode[1] = r
193 LibKeyBound.colorKeyBoundMode[2] = g
194 LibKeyBound.colorKeyBoundMode[3] = b
195 LibKeyBound.colorKeyBoundMode[4] = a
196 LibKeyBound.events:Fire("LIBKEYBOUND_MODE_COLOR_CHANGED")
197 end
198
199 --[[
200 Returns:
201 * number - red
202 * number - green
203 * number - blue
204 * number - alpha
205
206 Example:
207 if (MyMod.keyBoundMode) then
208 overlayFrame:SetBackdropColor(LibKeyBound:GetColorKeyBoundMode())
209 end
210 ...
211 local r, g, b, a = LibKeyBound:GetColorKeyBoundMode()
212
213 Notes:
214 * Returns the color to use on your participating buttons during KeyBound Mode
215 * Values are unpacked and ready to use as color arguments
216 --]]
217 function LibKeyBound:GetColorKeyBoundMode()
218 return unpack(LibKeyBound.colorKeyBoundMode)
219 end
220
221
222 function LibKeyBound:PLAYER_REGEN_ENABLED()
223 if self.enabled then
224 UIErrorsFrame:AddMessage(L.CombatBindingsEnabled, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
225 self.dialog:Hide()
226 end
227 end
228
229 function LibKeyBound:PLAYER_REGEN_DISABLED()
230 if self.enabled then
231 self:Set(nil)
232 UIErrorsFrame:AddMessage(L.CombatBindingsDisabled, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
233 self.dialog:Show()
234 end
235 end
236
237
238 --[[
239 Notes:
240 * Switches KeyBound Mode between on and off
241
242 Example:
243 local LibKeyBound = LibStub("LibKeyBound-1.0")
244 LibKeyBound:Toggle()
245 --]]
246 function LibKeyBound:Toggle()
247 if (LibKeyBound:IsShown()) then
248 LibKeyBound:Deactivate()
249 else
250 LibKeyBound:Activate()
251 end
252 end
253
254
255 --[[
256 Notes:
257 * Switches KeyBound Mode to on
258
259 Example:
260 local LibKeyBound = LibStub("LibKeyBound-1.0")
261 LibKeyBound:Activate()
262 --]]
263 function LibKeyBound:Activate()
264 if not self:IsShown() then
265 if InCombatLockdown() then
266 UIErrorsFrame:AddMessage(L.CannotBindInCombat, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
267 else
268 self.enabled = true
269 if not self.frame then
270 self.frame = LibKeyBound.Binder:Create()
271 end
272 self:Set(nil)
273 self.dialog:Show()
274 self.events:Fire("LIBKEYBOUND_ENABLED")
275 end
276 end
277 end
278
279
280 --[[
281 Notes:
282 * Switches KeyBound Mode to off
283
284 Example:
285 local LibKeyBound = LibStub("LibKeyBound-1.0")
286 LibKeyBound:Deactivate()
287 --]]
288 function LibKeyBound:Deactivate()
289 if self:IsShown() then
290 self.enabled = nil
291 self:Set(nil)
292 self.dialog:Hide()
293
294 self.events:Fire("LIBKEYBOUND_DISABLED")
295 end
296 end
297
298
299 --[[
300 Returns:
301 boolean - true if KeyBound Mode is currently on
302
303 Example:
304 local LibKeyBound = LibStub("LibKeyBound-1.0")
305 local isKeyBoundMode = LibKeyBound:IsShown()
306 if (isKeyBoundMode) then
307 -- Do something
308 else
309 -- Do another thing
310 end
311
312 Notes:
313 * Is KeyBound Mode currently on
314 --]]
315 function LibKeyBound:IsShown()
316 return self.enabled
317 end
318
319
320 --[[
321 Arguments:
322 table - the button frame
323
324 Example:
325 local button = this
326 LibKeyBound:Set(button)
327
328 Notes:
329 * Sets up button for keybinding
330 * Call this in your OnEnter script for the button
331 * Current bindings are shown in the tooltip
332 * Primary binding is shown in green in the button text
333 --]]
334 function LibKeyBound:Set(button)
335 local bindFrame = self.frame
336
337 if button and self:IsShown() and not InCombatLockdown() then
338 bindFrame.button = button
339 bindFrame:SetAllPoints(button)
340
341 bindFrame.text:SetFontObject("GameFontNormalLarge")
342 bindFrame.text:SetText(button:GetHotkey())
343 if bindFrame.text:GetStringWidth() > bindFrame:GetWidth() then
344 bindFrame.text:SetFontObject("GameFontNormal")
345 end
346 bindFrame:Show()
347 bindFrame:OnEnter()
348 elseif bindFrame then
349 bindFrame.button = nil
350 bindFrame:ClearAllPoints()
351 bindFrame:Hide()
352 end
353 end
354
355
356 --[[
357 Arguments:
358 string - the keyString to shorten
359
360 Returns:
361 string - the shortened displayString
362
363 Example:
364 local key1 = GetBindingKey(button:GetName())
365 local displayKey = LibKeyBound:ToShortKey(key1)
366 return displayKey
367
368 Notes:
369 * Shortens the key text (returned from GetBindingKey etc.)
370 * Result is suitable for display on a button
371 * Can be used for your button:GetHotkey() return value
372 --]]
373 function LibKeyBound:ToShortKey(key)
374 if key then
375 key = key:upper()
376 key = key:gsub(" ", "")
377 key = key:gsub("ALT%-", L["Alt"])
378 key = key:gsub("CTRL%-", L["Ctrl"])
379 key = key:gsub("SHIFT%-", L["Shift"])
380 key = key:gsub("NUMPAD", L["NumPad"])
381
382 key = key:gsub("PLUS", "%+")
383 key = key:gsub("MINUS", "%-")
384 key = key:gsub("MULTIPLY", "%*")
385 key = key:gsub("DIVIDE", "%/")
386
387 key = key:gsub("BACKSPACE", L["Backspace"])
388 key = key:gsub("BUTTON3", L["Button3"])
389 key = key:gsub("BUTTON4", L["Button4"])
390 key = key:gsub("BUTTON5", L["Button5"])
391 key = key:gsub("CAPSLOCK", L["Capslock"])
392 key = key:gsub("CLEAR", L["Clear"])
393 key = key:gsub("DELETE", L["Delete"])
394 key = key:gsub("END", L["End"])
395 key = key:gsub("HOME", L["Home"])
396 key = key:gsub("INSERT", L["Insert"])
397 key = key:gsub("MOUSEWHEELDOWN", L["Mouse Wheel Down"])
398 key = key:gsub("MOUSEWHEELUP", L["Mouse Wheel Up"])
399 key = key:gsub("NUMLOCK", L["Num Lock"])
400 key = key:gsub("PAGEDOWN", L["Page Down"])
401 key = key:gsub("PAGEUP", L["Page Up"])
402 key = key:gsub("SCROLLLOCK", L["Scroll Lock"])
403 key = key:gsub("SPACEBAR", L["Spacebar"])
404 key = key:gsub("TAB", L["Tab"])
405
406 key = key:gsub("DOWNARROW", L["Down Arrow"])
407 key = key:gsub("LEFTARROW", L["Left Arrow"])
408 key = key:gsub("RIGHTARROW", L["Right Arrow"])
409 key = key:gsub("UPARROW", L["Up Arrow"])
410
411 return key
412 end
413 end
414
415
416 --[[ Binder Widget ]]--
417
418 function LibKeyBound.Binder:Create()
419 local binder = CreateFrame("Button")
420 binder:RegisterForClicks("anyUp")
421 binder:SetFrameStrata("DIALOG")
422 binder:EnableKeyboard(true)
423 binder:EnableMouseWheel(true)
424
425 for k,v in pairs(self) do
426 binder[k] = v
427 end
428
429 local bg = binder:CreateTexture()
430 bg:SetTexture(0, 0, 0, 0.5)
431 bg:SetAllPoints(binder)
432
433 local text = binder:CreateFontString("OVERLAY")
434 text:SetFontObject("GameFontNormalLarge")
435 text:SetTextColor(0, 1, 0)
436 text:SetAllPoints(binder)
437 binder.text = text
438
439 binder:SetScript("OnClick", self.OnKeyDown)
440 binder:SetScript("OnKeyDown", self.OnKeyDown)
441 binder:SetScript("OnMouseWheel", self.OnMouseWheel)
442 binder:SetScript("OnEnter", self.OnEnter)
443 binder:SetScript("OnLeave", self.OnLeave)
444 binder:SetScript("OnHide", self.OnHide)
445 binder:Hide()
446
447 return binder
448 end
449
450 function LibKeyBound.Binder:OnHide()
451 LibKeyBound:Set(nil)
452 end
453
454 function LibKeyBound.Binder:OnKeyDown(key)
455 local button = self.button
456 if not button then return end
457
458 if (key == "UNKNOWN" or key == "LSHIFT" or key == "RSHIFT" or
459 key == "LCTRL" or key == "RCTRL" or key == "LALT" or key == "RALT" or
460 key == "LeftButton" or key == "RightButton") then
461 return
462 end
463
464 local screenshotKey = GetBindingKey("SCREENSHOT")
465 if screenshotKey and key == screenshotKey then
466 Screenshot()
467 return
468 end
469
470 local openChatKey = GetBindingKey("OPENCHAT")
471 if openChatKey and key == openChatKey then
472 ChatFrameEditBox:Show()
473 return
474 end
475
476 if key == "MiddleButton" then
477 key = "BUTTON3"
478 elseif key == "Button4" then
479 key = "BUTTON4"
480 elseif key == "Button5" then
481 key = "BUTTON5"
482 end
483
484 if key == "ESCAPE" then
485 self:ClearBindings(button)
486 LibKeyBound:Set(button)
487 return
488 end
489
490 if IsShiftKeyDown() then
491 key = "SHIFT-" .. key
492 end
493 if IsControlKeyDown() then
494 key = "CTRL-" .. key
495 end
496 if IsAltKeyDown() then
497 key = "ALT-" .. key
498 end
499
500 if MouseIsOver(button) then
501 self:SetKey(button, key)
502 LibKeyBound:Set(button)
503 end
504 end
505
506 function LibKeyBound.Binder:OnMouseWheel(arg1)
507 if arg1 > 0 then
508 self:OnKeyDown("MOUSEWHEELUP")
509 else
510 self:OnKeyDown("MOUSEWHEELDOWN")
511 end
512 end
513
514 function LibKeyBound.Binder:OnEnter()
515 local button = self.button
516 if button and not InCombatLockdown() then
517 if self:GetRight() >= (GetScreenWidth() / 2) then
518 GameTooltip:SetOwner(self, "ANCHOR_LEFT")
519 else
520 GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
521 end
522
523 if button.GetActionName then
524 GameTooltip:SetText(button:GetActionName(), 1, 1, 1)
525 else
526 GameTooltip:SetText(button:GetName(), 1, 1, 1)
527 end
528
529 local bindings = self:GetBindings(button)
530 if bindings then
531 GameTooltip:AddLine(bindings, 0, 1, 0)
532 GameTooltip:AddLine(L.ClearTip)
533 else
534 GameTooltip:AddLine(L.NoKeysBoundTip, 0, 1, 0)
535 end
536 GameTooltip:Show()
537 else
538 GameTooltip:Hide()
539 end
540 end
541
542 function LibKeyBound.Binder:OnLeave()
543 LibKeyBound:Set(nil)
544 GameTooltip:Hide()
545 end
546
547
548 --[[ Update Functions ]]--
549
550 function LibKeyBound.Binder:ToBinding(button)
551 return format("CLICK %s:LeftButton", button:GetName())
552 end
553
554 function LibKeyBound.Binder:FreeKey(button, key)
555 local msg
556 if button.FreeKey then
557 local action = button:FreeKey(key)
558 if button:FreeKey(key) then
559 msg = format(L.UnboundKey, GetBindingText(key, "KEY_"), action)
560 end
561 else
562 local action = GetBindingAction(key)
563 if action and action ~= "" and action ~= self:ToBinding(button) then
564 msg = format(L.UnboundKey, GetBindingText(key, "KEY_"), action)
565 end
566 end
567
568 if msg then
569 UIErrorsFrame:AddMessage(msg, 1, 0.82, 0, 1, UIERRORS_HOLD_TIME)
570 end
571 end
572
573 function LibKeyBound.Binder:SetKey(button, key)
574 if InCombatLockdown() then
575 UIErrorsFrame:AddMessage(L.CannotBindInCombat, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
576 else
577 self:FreeKey(button, key)
578
579 if button.SetKey then
580 button:SetKey(key)
581 else
582 SetBindingClick(key, button:GetName(), "LeftButton")
583 end
584
585 local msg
586 if button.GetActionName then
587 msg = format(L.BoundKey, GetBindingText(key, "KEY_"), button:GetActionName())
588 else
589 msg = format(L.BoundKey, GetBindingText(key, "KEY_"), button:GetName())
590 end
591 UIErrorsFrame:AddMessage(msg, 1, 1, 1, 1, UIERRORS_HOLD_TIME)
592 end
593 end
594
595 function LibKeyBound.Binder:ClearBindings(button)
596 if InCombatLockdown() then
597 UIErrorsFrame:AddMessage(L.CannotBindInCombat, 1, 0.3, 0.3, 1, UIERRORS_HOLD_TIME)
598 else
599 if button.ClearBindings then
600 button:ClearBindings()
601 else
602 local binding = self:ToBinding(button)
603 while (GetBindingKey(binding)) do
604 SetBinding(GetBindingKey(binding), nil)
605 end
606 end
607
608 local msg
609 if button.GetActionName then
610 msg = format(L.ClearedBindings, button:GetActionName())
611 else
612 msg = format(L.ClearedBindings, button:GetName())
613 end
614 UIErrorsFrame:AddMessage(msg, 1, 1, 1, 1, UIERRORS_HOLD_TIME)
615 end
616 end
617
618 function LibKeyBound.Binder:GetBindings(button)
619 if button.GetBindings then
620 return button:GetBindings()
621 end
622
623 local keys
624 local binding = self:ToBinding(button)
625 for i = 1, select("#", GetBindingKey(binding)) do
626 local hotKey = select(i, GetBindingKey(binding))
627 if keys then
628 keys = keys .. ", " .. GetBindingText(hotKey, "KEY_")
629 else
630 keys = GetBindingText(hotKey, "KEY_")
631 end
632 end
633
634 return keys
635 end
636
637 LibKeyBound.EventButton = LibKeyBound.EventButton or CreateFrame("Frame")
638 do
639 local EventButton = LibKeyBound.EventButton
640 EventButton:UnregisterAllEvents()
641 EventButton:SetScript("OnEvent", function(self, event, addon)
642 if (event == "PLAYER_REGEN_DISABLED") then
643 LibKeyBound:PLAYER_REGEN_DISABLED()
644 elseif (event == "PLAYER_REGEN_ENABLED") then
645 LibKeyBound:PLAYER_REGEN_ENABLED()
646 elseif (event == "PLAYER_LOGIN" and not LibKeyBound.initialized) then
647 LibKeyBound:Initialize()
648 EventButton:UnregisterEvent("PLAYER_LOGIN")
649 end
650 end)
651
652 if IsLoggedIn() and not LibKeyBound.initialized then
653 LibKeyBound:Initialize()
654 elseif not LibKeyBound.initialized then
655 EventButton:RegisterEvent("PLAYER_LOGIN")
656 end
657 EventButton:RegisterEvent("PLAYER_REGEN_ENABLED")
658 EventButton:RegisterEvent("PLAYER_REGEN_DISABLED")
659 end