Mercurial > wow > reaction
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/ReBound-1.0/ReBound-1.0.lua Tue Mar 20 21:37:38 2007 +0000 @@ -0,0 +1,344 @@ +--[[ +Name: ReBound-1.0 +Revision: $Rev: 1 $ +Author: Flick +Website: +Documentation: +SVN: +Description: Library for point-and-click key binding interfaces +License: MIT +Dependencies: AceLibrary, AceEvent-2.0, AceLocale-2.2 +]] + + +local version_major, version_minor = "ReBound-1.0", "$Rev: 1 $" + +if not AceLibrary then error(version_major .. " requires AceLibrary.") end +if not AceLibrary:IsNewVersion(version_major, version_minor) then return end +if not AceLibrary:HasInstance("AceEvent-2.0") then error(version_major .. " requires AceEvent-2.0.") end +if not AceLibrary:HasInstance("AceLocale-2.2") then error(version_major .. " requires AceLocale-2.2.") end + +local L = AceLibrary("AceLocale-2.2"):new("ReBound") + +local colorGreen = "|cff00ff00" +local colorOff = "|r" + +local mouseButtonConvert = { + MiddleButton = "BUTTON3", + Button4 = "BUTTON4", + Button5 = "BUTTON5" +} + +-- localization +L:RegisterTranslations( "enUS", function() + return { + ["none"] = true, + ["Right-click"] = true, + ["Click to select for binding"] = true, + ["Shift-click to clear binding"] = true, + ["Press a key to assign binding"] = true, + ["is now unbound"] = true, + } +end ) + + + + +local ReBound = { } + + +--[[ + Arguments: + key: A string representation of a key, suitable for passing to SetBinding. + target: The frame with an OnClick handler to attach a click-binding to + [button]: The mouse button to emulate. Default is "LeftButton". + + Returns: + nothing. + + Notes: + This does not save the bindings. +]] +function ReBound:SetBinding( key, target, button ) + if not key then self:error("ReBound:SetBinding() requires a key argument.") end + if not target then self:error("ReBound:SetBinding() requires a binding target argument") end + button = button or "LeftButton" + + -- prevent setting a binding that's already set + local current = { self:GetBinding(target,button) } + for _, b in pairs(current) do + if b == key then + return + end + end + + -- clear the old binding for the key. This isn't strictly necessary, but it allows us to collect + -- notification of the unbinding in one place (ClearBinding). + self:ClearBinding( key ) + + -- clear the old binding for the target and button (silently) + self:ClearBinding( nil, target, button, true ) + + -- set the new binding + SetBindingClick(key, target:GetName(), button) + + -- notify listeners, e.g. for storing the setting + self.event:TriggerEvent("REBOUND_BIND", key, target:GetName(), button) +end + + +--[[ + Arguments: + [key]: A string representation of a key, suitable for passing to SetBinding. This can be nil if target is specified. + [target]: The frame with a click keybinding to search for a key. + [button]: The mouse button to emulate. Default is "LeftButton". Only used with [target]. + [silent]: if true, omits printout. + + Returns: + nothing. + + Notes: + If key is provided, then the binding for that key is cleared. If key is not provided and target is provided, then + all the bindings attached to the click-binding for that target are cleared. + + This does NOT save the bindings. Call SaveBindings() to commit the bindings to disk. +]] +function ReBound:ClearBinding( key, target, button, silent ) + if not target and not key then self:error("ReBound:ClearBinding() requires a key or click-binding target argument") end + button = button or "LeftButton" + + local keys = key and { key } or { self:GetBinding(target,button) } + for _, k in ipairs(keys) do + -- Print a notification message + if k and not silent then + local action = GetBindingAction(k) + if action then + local name = GetBindingText(action,"BINDING_NAME_") + local keyTxt = GetBindingText(k,"KEY_") + -- make click-bindings look prettier + local f, b = name:match("CLICK (.+)\:(.+)") + if f then + name = f + if b ~= "LeftButton" then + if b == "RightButton" then b = "Right Click" end + name = f .."-"..b + end + end + if name and #name > 0 then + UIErrorsFrame:AddMessage(name.." ("..colorGreen..keyTxt..colorOff..") "..L["is now unbound"].."!") + end + end + end + SetBinding(k,nil) + self.event:TriggerEvent("REBOUND_UNBIND", k) + end +end + + +--[[ + Gets the keys bound to clicking a frame. + + Arguments: + target: target frame to query + [button]: mouse button to emulate ("LeftButton", "RightButton") + + Returns: + key1, key2, key3, etc, as strings. +]] +function ReBound:GetBinding( target, button ) + if not target then self:error("ReBound:GetBinding() requires a target frame argument") end + button = button or "LeftButton" + return GetBindingKey("CLICK "..target:GetName()..":"..button) +end + + +--[[ + Registers a target frame by creating a click-binding frame and putting that frame in the list of + registered frames, which can then be all shown/hidden as one unit. + + Arguments: + target = the frame whose OnClick handler should be the target of keybinding + + Returns: + A clickbinder frame. +]] +function ReBound:Register( target ) + local f = self:CreateClickBindingFrame(target) + self.frames[target] = f + return f +end + + +--[[ + Unregisters a target frame by removing it from the internal list. Does nothing to the clickbinding frame. + + Arguments: + target = the frame whose OnClick handler should no longer be the target of keybinding + + Returns: + nothing. +]] +function ReBound:Unregister( target ) + self.frames[target] = nil +end + + +--[[ + Shows all the registered click binding frames. +]] +function ReBound:ShowAll() + if InCombatLockdown() then + -- can't set bindings while in combat, so don't bother showing them + UIErrorsFrame:AddMessage(ERR_NOT_IN_COMBAT) + else + for _, f in pairs(self.frames) do + f:Show() + end + end +end + + +--[[ + Hides all the registered click binding frames. +]] +function ReBound:HideAll() + for _, f in pairs(self.frames) do + f:Hide() + end +end + +-- click binding frame implementation functions +local function ShowTooltip1( self ) + local target = self:GetParent() + + GameTooltip:ClearLines() + GameTooltip:SetOwner(self,"ANCHOR_TOPRIGHT") + -- line 1: button name and current binding + GameTooltip:AddDoubleLine(target:GetName(), colorGreen.."("..(self.ReBound:GetBinding(target,"LeftButton") or L["none"])..")"..colorOff) + -- line 2: current right-click binding (if any) + local binding2 = self.ReBound:GetBinding(target,"RightButton") + if binding2 then + GameTooltip:AddDoubleLine(L["Right-click"]..":", colorGreen.."("..binding2..")"..colorOff) + end + -- line 3: instructions + GameTooltip:AddLine(L["Click to select for binding"]) + GameTooltip:AddLine(L["Shift-click to clear binding"]) + GameTooltip:Show() +end + +local function ShowTooltip2( self ) + if GameTooltip:IsOwned(self) then + local target = self:GetParent() + GameTooltip:ClearLines() + GameTooltip:SetOwner(self) + local clickSuffix = self.selectedButton == "RightButton" and (" ("..L["Right-click"]..")") or "" + -- line 1: button name and binding to be set + GameTooltip:AddDoubleLine(target:GetName()..clickSuffix, colorGreen.."("..(self.ReBound:GetBinding(target,self.selectedButton) or L["none"])..")"..colorOff) + -- line 2: instructions + GameTooltip:AddLine(colorGreen..L["Press a key to assign binding"]..colorOff) + GameTooltip:Show() + end +end + +local function OnClick( self, button ) + if button == "LeftButton" or button == "RightButton" then + if IsShiftKeyDown() then + self.ReBound:ClearBinding( nil, self:GetParent(), button ) + self.selectedButton = nil + self:EnableKeyboard(false) + ShowTooltip1(self) + else + self.selectedButton = button + self:EnableKeyboard(true) + ShowTooltip2(self) + end + elseif self.selectedButton then + self.ReBound:SetBinding( mouseButtonConvert[button], self:GetParent(), self.selectedButton ) + self.selectedButton = nil + self:EnableKeyboard(false) + ShowTooltip1(self) + end +end + +local function OnEnter( self ) + -- clear current binding button + self.selectedButton = nil + -- show tooltip 1 + ShowTooltip1(self) +end + +local function OnLeave( self ) + -- disable keyboard input, if it was enabled + self:EnableKeyboard(false) + -- hide tooltip + if GameTooltip:IsOwned(self) then + GameTooltip:Hide() + end +end + +local function OnKeyDown( self, key ) + if key == nil or key == "UNKNOWN" or key == "SHIFT" or key == "CTRL" or key == "ALT" then + return + end + if IsShiftKeyDown() then key = "SHIFT-"..key end + if IsControlKeyDown() then key = "CTRL-"..key end + if IsAltKeyDown() then key = "ALT-"..key end + + if key ~= "ESCAPE" then + self.ReBound:SetBinding( key, self:GetParent(), self.selectedButton ) + end + + self:EnableKeyboard(false) + self.selectedButton = nil + ShowTooltip1(self) +end + +--[[ + Creates a click-binding frame attached to the target frame, which can be used for point-and-click keybind assignments. The + frame is initially hidden by default. It is not registered with ReBound for automatic show/hide: use Register() for that. + + Arguments: + target - the frame whose OnClick handler should be the target of keybinding + + Returns: + A clickbinder frame. +]] +function ReBound:CreateClickBindingFrame( target ) + local f = CreateFrame("Button", nil, target) + f.ReBound = self + f:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square") + f:SetToplevel(1) + f:SetFrameStrata("DIALOG") + f:RegisterForClicks("AnyUp") + f:SetScript("OnClick", OnClick) + f:SetScript("OnEnter", OnEnter) + f:SetScript("OnLeave", OnLeave) + f:SetScript("OnKeyDown", OnKeyDown) + f:SetAllPoints(target) + f:Hide() + return f +end + + + +-- library setup + +local function activate( self, oldLib, oldDeactivate ) + -- set initial values + self.mode = oldLib and oldLib.mode or "char" + self.frames = { } + + self.event = AceLibrary("AceOO-2.0").Class("AceEvent-2.0"):new() + self.event:RegisterEvent("PLAYER_REGEN_DISABLED", function() self:HideAll() end) + + if oldDeactivate then + oldDeactivate(oldLib) + end +end + +local function deactivate( self ) + self.event:UnregisterEvent("PLAYER_REGEN_DISABLED") +end + +AceLibrary:Register(ReBound, version_major, version_minor, activate, deactivate) +ReBound = nil