Mercurial > wow > reaction
changeset 17:639282f3a0e0
More cleanup of main.lua, ReBound-1.0.lua
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Fri, 23 Mar 2007 19:28:30 +0000 |
parents | 832aab6fed49 |
children | a805e4464237 |
files | Buttons.lua ReAction.toc libs/ReBound-1.0/ReBound-1.0.lua main.lua |
diffstat | 4 files changed, 256 insertions(+), 168 deletions(-) [+] |
line wrap: on
line diff
--- a/Buttons.lua Thu Mar 22 21:08:43 2007 +0000 +++ b/Buttons.lua Fri Mar 23 19:28:30 2007 +0000 @@ -4,7 +4,7 @@ -- local AceOO = AceLibrary("AceOO-2.0") -local ReBound = AceLibrary("ReBound-1.0"):new("REACTION") +local ReBound = AceLibrary("ReBound-1.0"):new("ReAction") local Action = AceOO.Class( ReAction,
--- a/ReAction.toc Thu Mar 22 21:08:43 2007 +0000 +++ b/ReAction.toc Fri Mar 23 19:28:30 2007 +0000 @@ -42,8 +42,7 @@ Defaults.lua Options.lua +main.lua + KeybindDialog.xml -main.lua - -
--- a/libs/ReBound-1.0/ReBound-1.0.lua Thu Mar 22 21:08:43 2007 +0000 +++ b/libs/ReBound-1.0/ReBound-1.0.lua Fri Mar 23 19:28:30 2007 +0000 @@ -1,27 +1,50 @@ --[[ Name: ReBound-1.0 -Revision: $Rev: 2 $ +Revision: $Rev: 3 $ Author: Flick Website: Documentation: SVN: Description: A library to assist with click-binding License: MIT -Dependencies: AceLibrary, AceEvent-2.0, AceLocale-2.2, AceOO-2.0 +Dependencies: AceLibrary, AceEvent-2.0, AceLocale-2.2, AceOO-2.0, AceConsole-2.0 ]] -local version_major, version_minor = "ReBound-1.0", "$Rev: 2 $" +local version_major, version_minor = "ReBound-1.0", "$Rev: 3 $" 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 -if not AceLibrary:HasInstance("AceOO-2.0") then error(version_major .. " requires AceOO-2.0.") end +for _, lib in pairs({ "AceEvent-2.0", "AceLocale-2.2", "AceOO-2.0", "AceConsole-2.0" }) do + if not AceLibrary:HasInstance(lib) then error(version_major .. " requires "..lib) end +end local L = AceLibrary("AceLocale-2.2"):new("ReBound") +-- localization +L:RegisterTranslations( "enUS", function() + return { + ["none"] = true, + ["Click"] = true, + ["Right-click"] = true, + ["Shift-click"] = true, + ["Shift-right-click"] = true, + ["Right Click"] = true, + ["to select for binding"] = true, + ["to select for alternate (right-click) binding"] = true, + ["to clear binding"] = true, + ["to clear alternate (right-click) binding"] = true, + ["Press a key to assign binding"] = true, + ["is now unbound"] = true, + } +end ) + + + +local kbValidate = AceLibrary("AceConsole-2.0").keybindingValidateFunc + local colorGreen = "|cff00ff00" +local colorOrange = "|cffffcc00" local colorOff = "|r" local mouseButtonConvert = { @@ -32,20 +55,42 @@ Button5 = "BUTTON5" } ---local BINDING_PENDING = { } -- a constant - --- localization -L:RegisterTranslations( "enUS", function() - return { - ["none"] = true, - ["Right-click"] = 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 ) +-- TODO: localize +local keybindAbbreviations = { + [KEY_BACKSPACE] = "BkSp", + [KEY_BUTTON3] = "M-3", + [KEY_BUTTON4] = "M-4", + [KEY_BUTTON5] = "M-5", + [KEY_DOWN] = "Down", + [KEY_ESCAPE] = "Esc", + [KEY_INSERT] = "Ins", + [KEY_LEFT] = "Left", + [KEY_MOUSEWHEELDOWN] = "M-Down", + [KEY_MOUSEWHEELUP] = "M-Up", + [KEY_NUMLOCK] = "NumLk", + [KEY_NUMPAD0] = "Np0", + [KEY_NUMPAD1] = "Np1", + [KEY_NUMPAD2] = "Np2", + [KEY_NUMPAD3] = "Np3", + [KEY_NUMPAD4] = "Np4", + [KEY_NUMPAD5] = "Np5", + [KEY_NUMPAD6] = "Np6", + [KEY_NUMPAD7] = "Np7", + [KEY_NUMPAD8] = "Np8", + [KEY_NUMPAD9] = "Np9", + [KEY_NUMPADDECIMAL] = "Np.", + [KEY_NUMPADDIVIDE] = "Np/", + [KEY_NUMPADMINUS] = "Np-", + [KEY_NUMPADMULTIPLY] = "Np*", + [KEY_NUMPADPLUS] = "Np+", + [KEY_PAGEDOWN] = "PgDn", + [KEY_PAGEUP] = "PgUp", + [KEY_PRINTSCREEN] = "PrScr", + [KEY_RIGHT] = "Right", + [KEY_SCROLLLOCK] = "ScrLk", + [KEY_SPACE] = "Sp", + [KEY_UP] = "Up", +} local ReBound = AceLibrary("AceOO-2.0").Class("AceEvent-2.0") @@ -71,16 +116,12 @@ Calls to new() which share ids will return an existing object with that id, similar to AceLocale-2.2. ]] +ReBound.instances = { } local super_new = ReBound.new function ReBound:new( id ) - self.instances = self.instances or { } - if self.instances[id] then - return self.instances[id] - else - local i = super_new(self,id) - self.instances[id] = i - return i - end + local instances = self.instances + instances[id] = instances[id] or super_new(self,id) + return instances[id] end @@ -91,7 +132,7 @@ id : the ID that will be provided in events. This can be absolutely anything, but a string is recommended. ]] -local super_init = ReBound.prototype.init +local super_init = ReBound.super.prototype.init function ReBound.prototype:init( id ) super_init(self) @@ -109,6 +150,7 @@ key: A string representation of a key, suitable for passing to SetBinding. target: The frame with an OnClick handler to which the click-binding should be attached [button]: The mouse button to emulate. Default is "LeftButton". + [silent]: boolean - whether to suppress messages about keys being unbound. Returns: nothing. @@ -119,6 +161,8 @@ function ReBound.prototype:SetBinding( key, target, button ) if not key then error("ReBound:SetBinding() requires a key argument.") end if not target then error("ReBound:SetBinding() requires a binding target argument") end + if key and not kbValidate(key) then error("ReBound:SetBinding(): invalid key code "..tostring(key)) end + button = button or "LeftButton" -- prevent setting a binding that's already set @@ -131,7 +175,7 @@ -- 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 ) + self:ClearBinding( key, nil, nil, silent ) -- clear the old binding for the target and button (silently) self:ClearBinding( nil, target, button, true ) @@ -214,6 +258,33 @@ --[[ + Gets the localized, abbreviated key cap text for the primary binding on a target. + Abbreviations are more aggressive than the standard Blizzard abbreviation + (which just shortens modifier keys) + + Arguments: + target: target frame to query + [abbrev]: boolean flag to abbreviate the result + [button]: mouse button to emulate ("LeftButton", "RightButton") + + Returns: + abbreviated, localized key label +]] +function ReBound.prototype:GetBindingText( target, abbrev, button ) + local key = self:GetBinding(target,button) + local txt = key and GetBindingText(key, "KEY_", abbrev and 1) or "" + + if txt and abbrev then + -- further abbreviate some key names + txt = string.gsub(txt, "[^%-]+$", keybindAbbreviations) + -- the above does not handle "num pad -" + txt = string.gsub(txt, KEY_NUMPADMINUS, keybindAbbreviations) + end + return txt +end + + +--[[ Publishes permanent binding notification events. ]] local function PublishBindings(self) @@ -308,7 +379,7 @@ --[[ Shows all the registered click binding frames. ]] -function ReBound.prototype:ShowFrames() +function ReBound.prototype:ShowRegisteredFrames() if InCombatLockdown() then -- can't set bindings while in combat, so don't bother showing them UIErrorsFrame:AddMessage(ERR_NOT_IN_COMBAT) @@ -323,7 +394,7 @@ --[[ Hides all the registered click binding frames. ]] -function ReBound.prototype:HideFrames() +function ReBound.prototype:HideRegisteredFrames() -- because these frames aren't protected, there's no restriction -- on hiding them while in combat. for _, f in pairs(self.frames) do @@ -345,8 +416,11 @@ 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:AddLine(colorGreen..L["Click"]..colorOff.." "..L["to select for binding"]) + GameTooltip:AddLine(colorGreen..L["Shift-click"]..colorOff.." "..L["to clear binding"]) + GameTooltip:AddLine("") + GameTooltip:AddLine(colorOrange..L["Right-click"]..colorOff.." "..L["to select for alternate (right-click) binding"]) + GameTooltip:AddLine(colorOrange..L["Shift-right-click"]..colorOff.." "..L["to clear alternate (right-click) binding"]) GameTooltip:Show() end
--- a/main.lua Thu Mar 22 21:08:43 2007 +0000 +++ b/main.lua Fri Mar 23 19:28:30 2007 +0000 @@ -9,7 +9,7 @@ local L = AceLibrary("AceLocale-2.2"):new("ReAction") local dewdrop = AceLibrary("Dewdrop-2.0") local tablet = AceLibrary("Tablet-2.0") -local ReBound = AceLibrary("ReBound-1.0"):new("REACTION") +local ReBound = AceLibrary("ReBound-1.0"):new("ReAction") -- private functions local function tcopy(t) @@ -24,15 +24,15 @@ local EMPTY_BAR_SLOT = -1 -- key binding label constants -BINDING_HEADER_REACTION = L["ReAction"] -BINDING_NAME_REACTION_TOGGLELOCK = L["Toggle ReAction Bar Lock"] -BINDING_NAME_REACTION_TOGGLEKEYBIND = L["ReAction Keybinding Mode"] +BINDING_HEADER_REACTION = L["ReAction"] +BINDING_NAME_REACTION_TOGGLELOCK = L["Toggle ReAction Bar Lock"] +BINDING_NAME_REACTION_TOGGLEKEYBIND = L["ReAction Keybinding Mode"] -- UI panel strings -REACTION_KEYBIND_TITLE = L["ReAction Keybinding"] -REACTION_KEYBIND_SUBTITLE = L["Click Buttons to Set Keybindings"] -REACTION_KEYBIND_DONE = L["Save"] -REACTION_KEYBIND_REVERT = L["Revert"] +REACTION_KEYBIND_TITLE = L["ReAction Keybinding"] +REACTION_KEYBIND_SUBTITLE = L["Click Buttons to Set Keybindings"] +REACTION_KEYBIND_DONE = L["Save"] +REACTION_KEYBIND_REVERT = L["Revert"] @@ -51,38 +51,21 @@ self:RegisterDB("ReActionDB","ReActionDBPC") self:RegisterDefaults("profile", ReAction_DefaultProfile) self:RegisterEvent("PLAYER_REGEN_DISABLED","CombatLockdown") - self:RegisterEvent("PLAYER_ENTERING_WORLD","HideDefaultBars") self:DisableDefaultKeybindings() -- create update function for keybinding frame - ReActionKeybindDialog:SetScript("OnHide", function(frame) - main:SetKeybindMode(false) - if frame.save then - ReBound:SaveBindings() - else - ReBound:RevertBindings() - end - frame.save = false - end ) + ReActionKeybindDialog:SetScript("OnHide", function(frame) main:HideKeybindDialog(frame) end) -- initial non-persistent state self.locked = true + self.keybindMode = false self.bars = { } end --- OnEnable is called at startup and when the profile is changed (via OnProfileEnable) +-- OnEnable is called at PLAYER_LOGIN or when the addon is enabled. function main:OnEnable( ) - if self.db.profile.firstRunDone ~= true then - self.db.profile.bars = tcopy(ReAction_DefaultBlizzardBars) - end - self:DestroyAllBars() - self:SetupBars() - self:UpgradeProfile() - self:SetupKeybindings() - if self.db.profile.firstRunDone ~= true then - self:Unlock() - end - self.db.profile.firstRunDone = true + self:HideDefaultBars() + self:SetupProfile( ) end function main:OnDisable() @@ -94,11 +77,38 @@ self:UnregisterEvent("REBOUND_BIND") self:UnregisterEvent("REBOUND_UNBIND") ReBound:ClearRegisteredBindings() - self:OnEnable() + self:SetupProfile() end -function main:UpgradeProfile() - if self.db.profile.firstRunDone ~= true and #self.db.profile.bindings == 0 then +function main:SetupProfile( ) + local profile = self.db.profile + if profile.firstRunDone ~= true then + profile.bars = tcopy(ReAction_DefaultBlizzardBars) + end + self:DestroyAllBars() + self:UpgradeProfile() + self:HideArt() + self:SetupBars() + self:SetupKeybindings() + if profile.firstRunDone ~= true then + self:Unlock() + profile.firstRunDone = true + end +end + +-- Set a global variable for Bindings.xml (I use 'setglobal' for clarity, it's not strictly necessary) +setglobal("ReActionAddOn", main) + + + + +------------------------------------------------------------ +-- Profile conversion functions (from old profiles) +-- +-- NOTE: these will be REMOVED when alpha testing is over. +------------------------------------------------------------ +function main:UpgradeBindingConfig() + if #self.db.profile.bindings == 0 then for _, bar in pairs(self.bars) do for _, button in pairs(bar.buttons) do local key = ReBound:GetBinding(button:GetActionFrame(),"LeftButton") @@ -110,6 +120,8 @@ end end +function main:UpgradeProfile() +end @@ -155,8 +167,7 @@ -- Key binding functions ------------------------------ function main:DisableDefaultKeybindings() - -- change the labels on all actionbar keybindings in the default - -- interface. + -- change the labels on all actionbar keybindings in the default interface. local label = "|cff999999("..L["Use ReAction"]..")|r" for i = 1, 12 do setglobal("BINDING_NAME_ACTIONBUTTON"..i,label) @@ -169,7 +180,7 @@ end for i = 1, 10 do setglobal("BINDING_NAME_BONUSACTIONBUTTON"..i,label) - setglobal("BINDING_NAME_SHAPESHIFTBUTTON"..i,label) +-- setglobal("BINDING_NAME_SHAPESHIFTBUTTON"..i,label) end BINDING_HEADER_ACTIONBAR = "|cff999999"..L["Action Bar Functions Disabled"].."|r" BINDING_HEADER_MULTIACTIONBAR = "|cff999999"..L["Multi-Action Bar Functions Disabled"].."|r" @@ -181,38 +192,58 @@ if self.db.profile.firstRunDone ~= true then self:StealKeyBindings() else + self:UpgradeBindingConfig() + local needsSave = false for key, binding in pairs(self.db.profile.bindings) do local target = getglobal(binding.target) if target then - ReBound:SetBinding(key, target, binding.button) + if ReBound:GetBinding(target,binding.button) ~= key then + ReBound:SetBinding(key,target,binding.button,true) + needsSave = true + end end end + if needsSave then + ReBound:SaveBindings() + end end - ReBound:SaveBindings() self:RegisterEvent("REBOUND_BIND") self:RegisterEvent("REBOUND_UNBIND") end function main:StealKeyBindings() -- steal the keybindings of the main action bar and assign them to rebar 1, buttons 1-12 - for i = 1, 12 do - local key = GetBindingKey("ACTIONBUTTON"..i) + local bar = self.bars[1] + if bar and bar ~= EMPTY_BAR_SLOT then + for i = 1, 12 do + local key = GetBindingKey("ACTIONBUTTON"..i) + if key and #key > 0 then + local button = bar.buttons[i] + if button then + ReBound:SetBinding(key, button:GetActionFrame(),nil,true) + end + end + end + local key = GetBindingKey("NEXTACTIONPAGE") if key and #key > 0 then - ReBound:ClearBinding(key,nil,nil,true) -- suppress notification printouts - ReBound:SetBinding(key, self.bars[1].buttons[i]:GetActionFrame(), "LeftButton") + ReBound:SetBinding(key, bar.upArrow,nil,true) end + key = GetBindingKey("PREVIOUSACTIONPAGE") + if key and #key > 0 then + ReBound:SetBinding(key, bar.downArrow,nil,true) + end + ReBound:SaveBindings() end - ReBound:SaveBindings() end function main:REBOUND_BIND(id, key, target, button) - if id == "REACTION" and key and target then + if id == "ReAction" and key and target then self.db.profile.bindings[key] = { target = target, button = button } end end function main:REBOUND_UNBIND(id, key) - if id == "REACTION" and key then + if id == "ReAction" and key then self.db.profile.bindings[key] = nil end end @@ -226,30 +257,40 @@ end function main:SetKeybindMode(enabled) - if not InCombatLockdown() then + if InCombatLockdown() then + UIErrorsFrame:AddMessage(ERROR_NOT_IN_COMBAT) + else self.keybindMode = enabled for _, bar in pairs(self.bars) do - for __, button in pairs(bar.buttons) do - if button and button ~= EMPTY_BAR_SLOT then - button:TempShow(enabled) + if bar and bar ~= EMPTY_BAR_SLOT then + for __, button in pairs(bar.buttons) do + if button then + button:TempShow(enabled) + end end end end if enabled then - ReBound:ShowFrames() + ReBound:ShowRegisteredFrames() ReActionKeybindDialog:Show() else - ReBound:HideFrames() + ReBound:HideRegisteredFrames() if ReActionKeybindDialog:IsShown() then ReActionKeybindDialog:Hide() end end - else - UIErrorsFrame:AddMessage(ERROR_NOT_IN_COMBAT) end end - +function main:HideKeybindDialog( frame ) + self:SetKeybindMode(false) + if frame.save then + ReBound:SaveBindings() + else + ReBound:RevertBindings() + end + frame.save = false +end ---------------------------- @@ -299,7 +340,7 @@ end function main:ToggleLocked() - main:SetLocked( not(self.locked) ) + self:SetLocked( not(self.locked) ) end @@ -309,17 +350,21 @@ -------------------------------------------------------- function main:HideArt() if self.db.profile.hideArt then - -- the pet bar is a child of MainMenuBar, and can't be hidden. Need to reparent it + -- the pet bar is a child of MainMenuBar, but can't be hidden because it will + -- break automatic pet bar show/hide. Need to reparent it. PetActionBarFrame:SetParent(UIParent) - MainMenuBar:Hide() -- this also hides the bags, xp bar, lag meter, and micro menu buttons. + -- these two are the pet bar background -- unfortunately UIParent_ManageFramePositions() shows and hides these too -- so they get reparented to MainMenuBar SlidingActionBarTexture0:SetParent(MainMenuBar) SlidingActionBarTexture1:SetParent(MainMenuBar) + + MainMenuBar:Hide() -- this also hides the bags, xp bar, lag meter, and micro menu buttons. else SlidingActionBarTexture0:SetParent(PetActionBarFrame) SlidingActionBarTexture1:SetParent(PetActionBarFrame) + PetActionBarFrame:SetParent(MainMenuBar) MainMenuBar:Show() end end @@ -412,9 +457,8 @@ if InCombatLockdown() then UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT) else - self:DestroyAllBars() self.db.profile.bars = tcopy(ReAction_DefaultBlizzardBars) - self:SetupBars() + self:OnProfileEnable() -- treat it like a profile switch end end @@ -426,16 +470,13 @@ end function main:SetupBars() - -- hide the default Blizzard art, if configued - self:HideArt() - -- set up the bars from the profile -- note the use of table.maxn rather than # or ipairs: -- our array of bars can in fact contain holes for id = 1, table.maxn(self.db.profile.bars) do local config = self.db.profile.bars[id] if config then - self:CreateBar(config, id) + self.bars[id] = self:CreateBar(config, id) end end @@ -449,48 +490,37 @@ end function main:CreateBar( config, id ) + local buttonType = config.btnConfig and config.btnConfig.type and getglobal(config.btnConfig.type) + local subtype = buttonType and buttonType:GetButtonType(config.btnConfig.subtype) + + if not subtype then + self:Print(L["Tried to create a button of unknown type"]) + return + end + local bar = ReBar:new(config, id) - local buttonType = ReAction:GetButtonType(config.btnConfig.subtype) - if buttonType then - self.bars[id] = bar - self.db.profile.bars[id] = config + -- initialize dewdrop menu + dewdrop:Register(bar:GetControlFrame(), + 'children', + function() + dewdrop:FeedAceOptionsTable(ReActionGlobalMenuOptions) + dewdrop:FeedAceOptionsTable(GenerateReActionBarOptions(bar,self)) + dewdrop:FeedAceOptionsTable(subtype:GenerateOptionsTable(config.btnConfig, function() return bar:GetButtonList() end)) + end, + 'cursorX', true, + 'cursorY', true + ) - -- initialize dewdrop menu - local cf = bar:GetControlFrame() - dewdrop:Register(cf, - 'children', - function() - dewdrop:FeedAceOptionsTable(ReActionGlobalMenuOptions) - dewdrop:FeedAceOptionsTable(GenerateReActionBarOptions(bar,self)) - dewdrop:FeedAceOptionsTable(buttonType:GenerateOptionsTable(config.btnConfig, function() return bar:GetButtonList() end)) - end, - 'cursorX', true, - 'cursorY', true - ) + -- register page up/down buttons with ReBound for keybinding + ReBound:Register(bar.upArrow) + ReBound:Register(bar.downArrow) - bar:GetControlFrame():SetScript("OnClick", - function(btn) - if btn == "RightButton" then - dewdrop:Open(cf) - end - end - ) + if not self.locked then + bar:ShowControls() + end - -- register page up/down buttons with ReBound for keybinding - ReBound:Register(bar.upArrow) - ReBound:Register(bar.downArrow) - - if not self.locked then - bar:ShowControls() - end - return bar - else - if bar then - bar:Destroy() - end - error(L["Tried to create a button of unknown type"]) - end + return bar end function main:DestroyBar( id ) @@ -516,21 +546,23 @@ function main:NewBar( type ) if InCombatLockdown() then UIErrorsFrame:AddMessage(SPELL_FAILED_AFFECTING_COMBAT) - else - local t = ReAction:GetButtonType(type) - if t then - local c = tcopy(ReAction_DefaultBarConfig["ReAction"][type]) - local id = nil - for i = 1, table.maxn(self.bars) + 1 do -- there may be holes, so #self.bars won't work - if self.bars[i] == nil or self.bars[i] == EMPTY_BAR_SLOT then - id = i - break - end + return + end + + local t = ReAction:GetButtonType(type) + if t then + local c = tcopy(ReAction_DefaultBarConfig["ReAction"][type]) + local id = nil + for i = 1, table.maxn(self.bars) + 1 do -- there may be holes, so #self.bars won't work + if self.bars[i] == nil or self.bars[i] == EMPTY_BAR_SLOT then + id = i + break end - local bar = self:CreateBar(c, id) - bar:ApplyAnchor() - self:Unlock() end + self.bars[id] = self:CreateBar(c, id) + self.db.profile.bars[id] = c + self.bars[id]:ApplyAnchor() + self:Unlock() end end @@ -550,24 +582,3 @@ - ------------------ --- General utility ------------------ -function main:ToggleIds() - if self.showIds then - ReAction:HideAllIds() - else - ReAction:ShowAllIds() - end - self.showIds = not self.showIds -end - -function main:AreIdsVisible() - return self.showIds -end - --- set a global variable for Bindings.xml -ReActionAddOn = main - -