8da63c0 - Add incoming res icon
[wowui.git] / OmaRFConfig / libs / AceGUI-3.0 / widgets / AceGUIWidget-Keybinding.lua
1 --[[-----------------------------------------------------------------------------
2 Keybinding Widget
3 Set Keybindings in the Config UI.
4 -------------------------------------------------------------------------------]]
5 local Type, Version = "Keybinding", 25
6 local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8
9 -- Lua APIs
10 local pairs = pairs
11
12 -- WoW APIs
13 local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
14 local CreateFrame, UIParent = CreateFrame, UIParent
15
16 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
17 -- List them here for Mikk's FindGlobals script
18 -- GLOBALS: NOT_BOUND
19
20 --[[-----------------------------------------------------------------------------
21 Scripts
22 -------------------------------------------------------------------------------]]
23
24 local function Control_OnEnter(frame)
25         frame.obj:Fire("OnEnter")
26 end
27
28 local function Control_OnLeave(frame)
29         frame.obj:Fire("OnLeave")
30 end
31
32 local function Keybinding_OnClick(frame, button)
33         if button == "LeftButton" or button == "RightButton" then
34                 local self = frame.obj
35                 if self.waitingForKey then
36                         frame:EnableKeyboard(false)
37                         frame:EnableMouseWheel(false)
38                         self.msgframe:Hide()
39                         frame:UnlockHighlight()
40                         self.waitingForKey = nil
41                 else
42                         frame:EnableKeyboard(true)
43                         frame:EnableMouseWheel(true)
44                         self.msgframe:Show()
45                         frame:LockHighlight()
46                         self.waitingForKey = true
47                 end
48         end
49         AceGUI:ClearFocus()
50 end
51
52 local ignoreKeys = {
53         ["BUTTON1"] = true, ["BUTTON2"] = true,
54         ["UNKNOWN"] = true,
55         ["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
56         ["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
57 }
58 local function Keybinding_OnKeyDown(frame, key)
59         local self = frame.obj
60         if self.waitingForKey then
61                 local keyPressed = key
62                 if keyPressed == "ESCAPE" then
63                         keyPressed = ""
64                 else
65                         if ignoreKeys[keyPressed] then return end
66                         if IsShiftKeyDown() then
67                                 keyPressed = "SHIFT-"..keyPressed
68                         end
69                         if IsControlKeyDown() then
70                                 keyPressed = "CTRL-"..keyPressed
71                         end
72                         if IsAltKeyDown() then
73                                 keyPressed = "ALT-"..keyPressed
74                         end
75                 end
76
77                 frame:EnableKeyboard(false)
78                 frame:EnableMouseWheel(false)
79                 self.msgframe:Hide()
80                 frame:UnlockHighlight()
81                 self.waitingForKey = nil
82
83                 if not self.disabled then
84                         self:SetKey(keyPressed)
85                         self:Fire("OnKeyChanged", keyPressed)
86                 end
87         end
88 end
89
90 local function Keybinding_OnMouseDown(frame, button)
91         if button == "LeftButton" or button == "RightButton" then
92                 return
93         elseif button == "MiddleButton" then
94                 button = "BUTTON3"
95         elseif button == "Button4" then
96                 button = "BUTTON4"
97         elseif button == "Button5" then
98                 button = "BUTTON5"
99         end
100         Keybinding_OnKeyDown(frame, button)
101 end
102
103 local function Keybinding_OnMouseWheel(frame, direction)
104         local button
105         if direction >= 0 then
106                 button = "MOUSEWHEELUP"
107         else
108                 button = "MOUSEWHEELDOWN"
109         end
110         Keybinding_OnKeyDown(frame, button)
111 end
112
113 --[[-----------------------------------------------------------------------------
114 Methods
115 -------------------------------------------------------------------------------]]
116 local methods = {
117         ["OnAcquire"] = function(self)
118                 self:SetWidth(200)
119                 self:SetLabel("")
120                 self:SetKey("")
121                 self.waitingForKey = nil
122                 self.msgframe:Hide()
123                 self:SetDisabled(false)
124                 self.button:EnableKeyboard(false)
125                 self.button:EnableMouseWheel(false)
126         end,
127
128         -- ["OnRelease"] = nil,
129
130         ["SetDisabled"] = function(self, disabled)
131                 self.disabled = disabled
132                 if disabled then
133                         self.button:Disable()
134                         self.label:SetTextColor(0.5,0.5,0.5)
135                 else
136                         self.button:Enable()
137                         self.label:SetTextColor(1,1,1)
138                 end
139         end,
140
141         ["SetKey"] = function(self, key)
142                 if (key or "") == "" then
143                         self.button:SetText(NOT_BOUND)
144                         self.button:SetNormalFontObject("GameFontNormal")
145                 else
146                         self.button:SetText(key)
147                         self.button:SetNormalFontObject("GameFontHighlight")
148                 end
149         end,
150
151         ["GetKey"] = function(self)
152                 local key = self.button:GetText()
153                 if key == NOT_BOUND then
154                         key = nil
155                 end
156                 return key
157         end,
158
159         ["SetLabel"] = function(self, label)
160                 self.label:SetText(label or "")
161                 if (label or "") == "" then
162                         self.alignoffset = nil
163                         self:SetHeight(24)
164                 else
165                         self.alignoffset = 30
166                         self:SetHeight(44)
167                 end
168         end,
169 }
170
171 --[[-----------------------------------------------------------------------------
172 Constructor
173 -------------------------------------------------------------------------------]]
174
175 local ControlBackdrop  = {
176         bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
177         edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
178         tile = true, tileSize = 16, edgeSize = 16,
179         insets = { left = 3, right = 3, top = 3, bottom = 3 }
180 }
181
182 local function keybindingMsgFixWidth(frame)
183         frame:SetWidth(frame.msg:GetWidth() + 10)
184         frame:SetScript("OnUpdate", nil)
185 end
186
187 local function Constructor()
188         local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
189
190         local frame = CreateFrame("Frame", nil, UIParent)
191         local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate")
192
193         button:EnableMouse(true)
194         button:EnableMouseWheel(false)
195         button:RegisterForClicks("AnyDown")
196         button:SetScript("OnEnter", Control_OnEnter)
197         button:SetScript("OnLeave", Control_OnLeave)
198         button:SetScript("OnClick", Keybinding_OnClick)
199         button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
200         button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
201         button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
202         button:SetPoint("BOTTOMLEFT")
203         button:SetPoint("BOTTOMRIGHT")
204         button:SetHeight(24)
205         button:EnableKeyboard(false)
206
207         local text = button:GetFontString()
208         text:SetPoint("LEFT", 7, 0)
209         text:SetPoint("RIGHT", -7, 0)
210
211         local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
212         label:SetPoint("TOPLEFT")
213         label:SetPoint("TOPRIGHT")
214         label:SetJustifyH("CENTER")
215         label:SetHeight(18)
216
217         local msgframe = CreateFrame("Frame", nil, UIParent)
218         msgframe:SetHeight(30)
219         msgframe:SetBackdrop(ControlBackdrop)
220         msgframe:SetBackdropColor(0,0,0)
221         msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
222         msgframe:SetFrameLevel(1000)
223         msgframe:SetToplevel(true)
224
225         local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
226         msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
227         msgframe.msg = msg
228         msg:SetPoint("TOPLEFT", 5, -5)
229         msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
230         msgframe:SetPoint("BOTTOM", button, "TOP")
231         msgframe:Hide()
232
233         local widget = {
234                 button      = button,
235                 label       = label,
236                 msgframe    = msgframe,
237                 frame       = frame,
238                 alignoffset = 30,
239                 type        = Type
240         }
241         for method, func in pairs(methods) do
242                 widget[method] = func
243         end
244         button.obj = widget
245
246         return AceGUI:RegisterAsWidget(widget)
247 end
248
249 AceGUI:RegisterWidgetType(Type, Constructor, Version)