local y,w="\075\101\121\098\105\110\100\105\110\103",26 local O=LibStub and LibStub("\065\099\101\071\085\073-\051\046\048",true)if not O or(O:GetWidgetVersion(y)or 0)>=w then return end local H=pairs local C,M,T=IsShiftKeyDown,IsControlKeyDown,IsAltKeyDown local I,b=CreateFrame,UIParent local function t(y)y.obj:Fire("\079\110\069\110\116\101\114")end local function z(y)y.obj:Fire("\079\110\076\101\097\118\101")end local function x(y,w)if w=="\076\101\102\116\066\117\116\116\111\110"or w=="\082\105\103\104\116\066\117\116\116\111\110"then local w=y.obj if w.waitingForKey then y:EnableKeyboard(false)y:EnableMouseWheel(false)w.msgframe:Hide()y:UnlockHighlight()w.waitingForKey=nil else y:EnableKeyboard(true)y:EnableMouseWheel(true)w.msgframe:Show()y:LockHighlight()w.waitingForKey=true end end O:ClearFocus()end local e={BUTTON1=true;BUTTON2=true,UNKNOWN=true;LSHIFT=true,LCTRL=true;LALT=true;RSHIFT=true;RCTRL=true;RALT=true}local function W(y,w)local O=y.obj if O.waitingForKey then local H=w if H=="\069\083\067\065\080\069"then H=""else if e[H]then return end if C()then H="\083\072\073\070\084-"..H end if M()then H="\067\084\082\076-"..H end if T()then H="\065\076\084-"..H end end y:EnableKeyboard(false)y:EnableMouseWheel(false)O.msgframe:Hide()y:UnlockHighlight()O.waitingForKey=nil if not O.disabled then O:SetKey(H)O:Fire("\079\110\075\101\121\067\104\097\110\103\101\100",H)end end end local function X(y,w)if w=="\076\101\102\116\066\117\116\116\111\110"or w=="\082\105\103\104\116\066\117\116\116\111\110"then return elseif w=="\077\105\100\100\108\101\066\117\116\116\111\110"then w="\066\085\084\084\079\078\051"elseif w=="\066\117\116\116\111\110\052"then w="\066\085\084\084\079\078\052"elseif w=="\066\117\116\116\111\110\053"then w="\066\085\084\084\079\078\053"end W(y,w)end local function R(y,w)local O if w>=0 then O="\077\079\085\083\069\087\072\069\069\076\085\080"else O="\077\079\085\083\069\087\072\069\069\076\068\079\087\078"end W(y,O)end local D={OnAcquire=function(y)y:SetWidth(200)y:SetLabel("")y:SetKey("")y.waitingForKey=nil y.msgframe:Hide()y:SetDisabled(false)y.button:EnableKeyboard(false)y.button:EnableMouseWheel(false)end;SetDisabled=function(y,w)y.disabled=w if w then y.button:Disable()y.label:SetTextColor(.5,.5,.5)else y.button:Enable()y.label:SetTextColor(1,1,1)end end;SetKey=function(y,w)if(w or"")==""then y.button:SetText(NOT_BOUND)y.button:SetNormalFontObject("\071\097\109\101\070\111\110\116\078\111\114\109\097\108")else y.button:SetText(w)y.button:SetNormalFontObject("\071\097\109\101\070\111\110\116\072\105\103\104\108\105\103\104\116")end end,GetKey=function(y)local w=y.button:GetText()if w==NOT_BOUND then w=nil end return w end;SetLabel=function(y,w)y.label:SetText(w or"")if(w or"")==""then y.alignoffset=nil y:SetHeight(24)else y.alignoffset=30 y:SetHeight(44)end end}local l={bgFile="\073\110\116\101\114\102\097\099\101\092\084\111\111\108\116\105\112\115\092\085\073-\084\111\111\108\116\105\112-\066\097\099\107\103\114\111\117\110\100";edgeFile="\073\110\116\101\114\102\097\099\101\092\084\111\111\108\116\105\112\115\092\085\073-\084\111\111\108\116\105\112-\066\111\114\100\101\114",tile=true;tileSize=16,edgeSize=16;insets={left=3,right=3,top=3,bottom=3}}local function Z(y)y:SetWidth(y.msg:GetWidth()+10)y:SetScript("\079\110\085\112\100\097\116\101",nil)end local function U()local w="\065\099\101\071\085\073\051\048\075\101\121\098\105\110\100\105\110\103\066\117\116\116\111\110"..O:GetNextWidgetNum(y)local C=I("\070\114\097\109\101",nil,b)local M=I("\066\117\116\116\111\110",w,C,"\085\073\080\097\110\101\108\066\117\116\116\111\110\084\101\109\112\108\097\116\101")M:EnableMouse(true)M:EnableMouseWheel(false)M:RegisterForClicks("\065\110\121\068\111\119\110")M:SetScript("\079\110\069\110\116\101\114",t)M:SetScript("\079\110\076\101\097\118\101",z)M:SetScript("\079\110\067\108\105\099\107",x)M:SetScript("\079\110\075\101\121\068\111\119\110",W)M:SetScript("\079\110\077\111\117\115\101\068\111\119\110",X)M:SetScript("\079\110\077\111\117\115\101\087\104\101\101\108",R)M:SetPoint("\066\079\084\084\079\077\076\069\070\084")M:SetPoint("\066\079\084\084\079\077\082\073\071\072\084")M:SetHeight(24)M:EnableKeyboard(false)local T=M:GetFontString()T:SetPoint("\076\069\070\084",7,0)T:SetPoint("\082\073\071\072\084",-7,0)local e=C:CreateFontString(nil,"\079\086\069\082\076\065\089","\071\097\109\101\070\111\110\116\072\105\103\104\108\105\103\104\116")e:SetPoint("\084\079\080\076\069\070\084")e:SetPoint("\084\079\080\082\073\071\072\084")e:SetJustifyH("\067\069\078\084\069\082")e:SetHeight(18)local U=I("\070\114\097\109\101",nil,b,"\066\097\099\107\100\114\111\112\084\101\109\112\108\097\116\101")U:SetHeight(30)U:SetBackdrop(l)U:SetBackdropColor(0,0,0)U:SetFrameStrata("\070\085\076\076\083\067\082\069\069\078\095\068\073\065\076\079\071")U:SetFrameLevel(1000)U:SetToplevel(true)local q=U:CreateFontString(nil,"\079\086\069\082\076\065\089","\071\097\109\101\070\111\110\116\078\111\114\109\097\108")q:SetText("\080\114\101\115\115 \097 \107\101\121 \116\111 \098\105\110\100\044 \069\083\067 \116\111 \099\108\101\097\114 \116\104\101 \098\105\110\100\105\110\103 \111\114 \099\108\105\099\107 \116\104\101 \098\117\116\116\111\110 \097\103\097\105\110 \116\111 \099\097\110\099\101\108\046")U.msg=q q:SetPoint("\084\079\080\076\069\070\084",5,-5)U:SetScript("\079\110\085\112\100\097\116\101",Z)U:SetPoint("\066\079\084\084\079\077",M,"\084\079\080")U:Hide()local u={button=M;label=e;msgframe=U,frame=C;alignoffset=30;type=y}for y,w in H(D)do u[y]=w end M.obj=u return O:RegisterAsWidget(u)end O:RegisterWidgetType(y,U,w)
--[[-----------------------------------------------------------------------------
Keybinding Widget
Set Keybindings in the Config UI.
-------------------------------------------------------------------------------]]
local Type, Version = "Keybinding", 26
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end

-- Lua APIs
local pairs = pairs

-- WoW APIs
local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
local CreateFrame, UIParent = CreateFrame, UIParent

--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]

local function Control_OnEnter(frame)
	frame.obj:Fire("OnEnter")
end

local function Control_OnLeave(frame)
	frame.obj:Fire("OnLeave")
end

local function Keybinding_OnClick(frame, button)
	if button == "LeftButton" or button == "RightButton" then
		local self = frame.obj
		if self.waitingForKey then
			frame:EnableKeyboard(false)
			frame:EnableMouseWheel(false)
			self.msgframe:Hide()
			frame:UnlockHighlight()
			self.waitingForKey = nil
		else
			frame:EnableKeyboard(true)
			frame:EnableMouseWheel(true)
			self.msgframe:Show()
			frame:LockHighlight()
			self.waitingForKey = true
		end
	end
	AceGUI:ClearFocus()
end

local ignoreKeys = {
	["BUTTON1"] = true, ["BUTTON2"] = true,
	["UNKNOWN"] = true,
	["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
	["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
}
local function Keybinding_OnKeyDown(frame, key)
	local self = frame.obj
	if self.waitingForKey then
		local keyPressed = key
		if keyPressed == "ESCAPE" then
			keyPressed = ""
		else
			if ignoreKeys[keyPressed] then return end
			if IsShiftKeyDown() then
				keyPressed = "SHIFT-"..keyPressed
			end
			if IsControlKeyDown() then
				keyPressed = "CTRL-"..keyPressed
			end
			if IsAltKeyDown() then
				keyPressed = "ALT-"..keyPressed
			end
		end

		frame:EnableKeyboard(false)
		frame:EnableMouseWheel(false)
		self.msgframe:Hide()
		frame:UnlockHighlight()
		self.waitingForKey = nil

		if not self.disabled then
			self:SetKey(keyPressed)
			self:Fire("OnKeyChanged", keyPressed)
		end
	end
end

local function Keybinding_OnMouseDown(frame, button)
	if button == "LeftButton" or button == "RightButton" then
		return
	elseif button == "MiddleButton" then
		button = "BUTTON3"
	elseif button == "Button4" then
		button = "BUTTON4"
	elseif button == "Button5" then
		button = "BUTTON5"
	end
	Keybinding_OnKeyDown(frame, button)
end

local function Keybinding_OnMouseWheel(frame, direction)
	local button
	if direction >= 0 then
		button = "MOUSEWHEELUP"
	else
		button = "MOUSEWHEELDOWN"
	end
	Keybinding_OnKeyDown(frame, button)
end

--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
	["OnAcquire"] = function(self)
		self:SetWidth(200)
		self:SetLabel("")
		self:SetKey("")
		self.waitingForKey = nil
		self.msgframe:Hide()
		self:SetDisabled(false)
		self.button:EnableKeyboard(false)
		self.button:EnableMouseWheel(false)
	end,

	-- ["OnRelease"] = nil,

	["SetDisabled"] = function(self, disabled)
		self.disabled = disabled
		if disabled then
			self.button:Disable()
			self.label:SetTextColor(0.5,0.5,0.5)
		else
			self.button:Enable()
			self.label:SetTextColor(1,1,1)
		end
	end,

	["SetKey"] = function(self, key)
		if (key or "") == "" then
			self.button:SetText(NOT_BOUND)
			self.button:SetNormalFontObject("GameFontNormal")
		else
			self.button:SetText(key)
			self.button:SetNormalFontObject("GameFontHighlight")
		end
	end,

	["GetKey"] = function(self)
		local key = self.button:GetText()
		if key == NOT_BOUND then
			key = nil
		end
		return key
	end,

	["SetLabel"] = function(self, label)
		self.label:SetText(label or "")
		if (label or "") == "" then
			self.alignoffset = nil
			self:SetHeight(24)
		else
			self.alignoffset = 30
			self:SetHeight(44)
		end
	end,
}

--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]

local ControlBackdrop  = {
	bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
	tile = true, tileSize = 16, edgeSize = 16,
	insets = { left = 3, right = 3, top = 3, bottom = 3 }
}

local function keybindingMsgFixWidth(frame)
	frame:SetWidth(frame.msg:GetWidth() + 10)
	frame:SetScript("OnUpdate", nil)
end

local function Constructor()
	local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)

	local frame = CreateFrame("Frame", nil, UIParent)
	local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate")

	button:EnableMouse(true)
	button:EnableMouseWheel(false)
	button:RegisterForClicks("AnyDown")
	button:SetScript("OnEnter", Control_OnEnter)
	button:SetScript("OnLeave", Control_OnLeave)
	button:SetScript("OnClick", Keybinding_OnClick)
	button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
	button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
	button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
	button:SetPoint("BOTTOMLEFT")
	button:SetPoint("BOTTOMRIGHT")
	button:SetHeight(24)
	button:EnableKeyboard(false)

	local text = button:GetFontString()
	text:SetPoint("LEFT", 7, 0)
	text:SetPoint("RIGHT", -7, 0)

	local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
	label:SetPoint("TOPLEFT")
	label:SetPoint("TOPRIGHT")
	label:SetJustifyH("CENTER")
	label:SetHeight(18)

	local msgframe = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
	msgframe:SetHeight(30)
	msgframe:SetBackdrop(ControlBackdrop)
	msgframe:SetBackdropColor(0,0,0)
	msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
	msgframe:SetFrameLevel(1000)
	msgframe:SetToplevel(true)

	local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
	msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
	msgframe.msg = msg
	msg:SetPoint("TOPLEFT", 5, -5)
	msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
	msgframe:SetPoint("BOTTOM", button, "TOP")
	msgframe:Hide()

	local widget = {
		button      = button,
		label       = label,
		msgframe    = msgframe,
		frame       = frame,
		alignoffset = 30,
		type        = Type
	}
	for method, func in pairs(methods) do
		widget[method] = func
	end
	button.obj = widget

	return AceGUI:RegisterAsWidget(widget)
end

AceGUI:RegisterWidgetType(Type, Constructor, Version)
