View Single Post
01-25-17, 04:33 PM   #7
Šynasty
A Fallenroot Satyr
Join Date: May 2010
Posts: 23
Looking at both below, which would be the best candidate for adding to or taking from?

If it's a lot more than copy paste (which it probably is seeing that I'm clueless) then I'm out of luck I guess :'(

If I could combine the two and make a new addon, I'm sure many more people would love to have and give 100% credit to the originals, I think everyone would be happy.


Mouse Look Lock

Lua Code:
  1. --[[------------------------------------------------------------
  2.     Mouse Look v7.0
  3.    
  4.     By Trimble Epic
  5.    
  6.     This mod allows a button to be mapped to allow
  7.     WoW to simulate the Mouselook mode found in DAoC.
  8.    
  9.     The code below is a work-around for the
  10.     way WoW handles it's mouse controlled camera functions
  11.    
  12.     Revision History
  13.     7.0 Jul 29 '16  Updated TOC for use with 7.0 Legion
  14.     6.0 Nov 13 '14  Updated TOC for use with 6.0 Wod
  15.     5.1 Aug 11 '14  Updated TOC for use with 5.4 Cata
  16.             Also added many new user interface windows to automatically pop up cursor.
  17.  
  18.     5.0 Aug 29 '12  Updated TOC for use with 5.0.4 Mists of Pandaria
  19.  
  20.     4.0 Oct 12 '10  Updated the addon to fix some code issues.  Blizzard removed "this", as well as
  21.             a few other "features" like values passed as "arg1" in XML code.  I also updated
  22.             the TOC for use with 4.0.1
  23.     3.2 Aug 16 '09
  24.             Updated TOC for use with 3.2
  25.     3.1 Apr 15 '09
  26.             Updated TOC for use with 3.1
  27.     2.2 Oct 14 '08
  28.             Updated TOC for use with 3.0.2
  29.     2.1 Aug 4 '08
  30.             Updated TOC for use with 2.4
  31.             Fixed bug associated with sRaidFrames (wouldn't return to mouselook mode)
  32.             Fixed bug so that mouselook setting is started when entering the world
  33.     1.6 Nov 3
  34.             Updated TOC for use with patch 1.12
  35.     1.5 Mar 29
  36.             Updated TOC for use with patch 1.10
  37.             Changed essential functions used to engage and disengage mouselook to comply with new 1.10 rules
  38.     1.4 Jun 20
  39.             Updated TOC for use with version 1500 of game client
  40.     1.3 Feb 22
  41.             Updated TOC for use with version 4216 of game client
  42.     1.2 Feb 15
  43.             Updated TOC for use with version 4211 of game client
  44.             Reworked Lua file to contain all code internally to reduce stray code in bindings.xml
  45.             Reworked bindings.xml to be cleaner and leaner
  46.             Added some code in an attempt to fix 'walklock' issue.
  47.     1.1 I wasn't keeping track of changes prior to 1.2, but it should be sufficient to say that
  48.             1.1 was pretty much a stable release.
  49.  
  50.     Todo notes:
  51.     Implement MouseOverFrame function and increase update speed
  52.    
  53. --------------------------------------------------------------]]
  54.  
  55. local Version = '7.0'
  56. local Debugging = false
  57. local MouseLook_TempLockout = false
  58. local MouseLook_LastUpdate = 0
  59. local MouseLook_UpdateFrequency = 0.2  ---> Adjust this number UP to improve frame rate.
  60.  
  61. BINDING_HEADER_MouseLook            = 'MouseLook'
  62. BINDING_NAME_MouseLook_mode_toggle  = "MouseLook toggle" -- are these needed?
  63. BINDING_NAME_MouseLook_momentary    = "MouseLook momentary"
  64.  
  65.  
  66. --List of frames that should automatically undo mouselook while they are up
  67. local MouseLook_FramesToCheck = {
  68.     "AuctionFrame",       "BankFrame",          "BattlefieldFrame",   "CharacterFrame",
  69.     "ChatMenu",           "EmoteMenu",          "LanguageMenu",       "VoiceMacroMenu",
  70.     "ClassTrainerFrame",  "CoinPickupFrame",    "CraftFrame",         "FriendsFrame",
  71.     "GameMenuFrame",      "GossipFrame",        "GuildRegistrarFrame","HelpFrame",
  72.     "InspectFrame",       "KeyBindingFrame",    "LoXXXotFrame",       "MacroFrame",
  73.     "MailFrame",          "MerchantFrame",      "OptionsFrame",       "PaperDollFrame",
  74.     "PetPaperDollFrame",  "PetRenamePopup",     "PetStable",          "QuestFrame",
  75.     "QuestLogFrame",      "RaidFrame",          "ReputationFrame",    "ScriptErrors",
  76.     "SkillFrame",         "SoundOptionsFrame",  "SpellBookFrame",     "StackSplitFrame",
  77.     "StatsFrame",         "SuggestFrame",       "TabardFrame",        "TalentFrame",
  78.     "TalentTrainerFrame", "TaxiFrame",          "TradeFrame",         "TradeSkillFrame",
  79.     "TutorialFrame",      "UIOptionsFrame",     "UnitPopup",          "WorldMapFrame",
  80.     "CosmosMasterFrame",  "CosmosDropDown",     "ChooseItemsFrame",   "ImprovedErrorFrame",
  81.     "TicTacToeFrame",     "OthelloFrame",       "MinesweeperFrame",   "GamesListFrame",
  82.     "ConnectFrame",       "ChessFrame",         "QuestShareFrame",    "TotemStomperFrame",
  83.     "StaticPopXXXup1",       "StaticPopup2",       "StaticPopup3",       "StaticPopup4",
  84.     "DropDownList1",      "DropDownList2",      "DropDownList3",      "WantAds",
  85.     "CosmosDropDownBis",  "InventoryManagerFrame", "InspectPaperDollFrame",
  86.     "ContainerFrame1",    "ContainerFrame2", "ContainerFrame3", "ContainerFrame4",
  87.     "ContainerFrame5",    "ContainerFrame6",    "ContainerFrame7",    "ContainerFrame8",
  88.     "ContainerFrame9",    "ContainerFrame10",   "ContainerFrame11",   "ContainerFrame12",
  89.     "ContainerFrame13",   "ContainerFrame14",   "ContainerFrame15",   "ContainerFrame16",
  90.     "ContainerFrame17",   "AutoPotion_Template_Dialog","NxSocial",    "ARKINV_Frame1",
  91.     "AchievementFrame",   "LookingForGuildFrame", "PVPUIFrame",       "GuildFrame",
  92.     "WorldMapFrame",      "VideoOptionsFrame",  "InterfaceOptionsFrame",
  93.         "ACP_AddonList",      "PlayerTalentFrame",  "PVEFrame",           "EncounterJournal",
  94.     "PetJournalParent",   "AccountantFrame",
  95.     --   "NxMap1",  (carbonite's world map breaks mouselook)
  96.     -- "StoreFrame", (causes taint??!??  wtf, blizzard?)
  97.     }
  98.  
  99. --List of frames that mouse might be over (Yes, these could badly use some cleanup)
  100. local MouseLook_FramesToCheckForMouse = {
  101.     "BonusActionBarFrame",
  102.     "BuffFrame",
  103.     "CastingBarFrame",
  104.     "ChatFrameMenuButton", "ChatFrameEditBox",
  105.     "ChatFrame1Tab", "ChatFrame2Tab", "ChatFrame3Tab", "ChatFrame4Tab", "ChatFrame5Tab", "ChatFrame6Tab", "ChatFrame7Tab",
  106.     "ChatFrame1BottomButton", "ChatFrame2BottomButton", "ChatFrame3BottomButton", "ChatFrame4BottomButton", "ChatFrame5BottomButton", "ChatFrame6BottomButton", "ChatFrame7BottomButton",
  107.     "ChatFrame1DownButton", "ChatFrame2DownButton", "ChatFrame3DownButton", "ChatFrame4DownButton", "ChatFrame5DownButton", "ChatFrame6DownButton", "ChatFrame7DownButton",
  108.     "ChatFrame1UpButton", "ChatFrame2UpButton", "ChatFrame3UpButton", "ChatFrame4UpButton", "ChatFrame5UpButton", "ChatFrame6UpButton", "ChatFrame7UpButton",
  109.     "CoinPickupFrame",
  110.     "ColorPickerFrame",
  111.     "DialogBoxFrame",
  112.     "DurabilityFrame",
  113.     "GameTimeFrame",
  114.     "ItemTextFrame",
  115.     "MainMenuBar",
  116.     "MinimapCluster",
  117.     "PartyFrame",
  118.     "PetActionBarFrame", "PetFrame", "PetitionFrame",
  119.     "PlayerFrame",
  120.     "QuestTimerFrame",
  121.     "TargetFrame",
  122.     "UnitFrame",
  123.     "AutoFollowStatus",
  124.     "SecondBar",
  125.     "ClockFrame",
  126.     "CosmosTooltip",
  127.     "CombatStatsDataFrame",
  128.     "CombatStatsFrame",
  129.     "DPSPLUS_PlayerFrame",
  130.     "ItemBuffBar",
  131.     "ItemBuffButton1", "ItemBuffButton2", "ItemBuffButton3", "ItemBuffButton4", "ItemBuffButton5", "ItemBuffButton6",
  132.     "KillCountFrame", "KillCountFrame2",
  133.     "InventoryManagerTooltip",
  134.     "MonitorStatus",
  135.     "SideBar", "SideBar2",
  136.     "TargetDistanceFrame",
  137.     "TargetStatsTooltip",
  138.     "HealomaticMainFrame",
  139.     }
  140.  
  141. local function ML_debug(...)
  142.    
  143.     if not DEFAULT_CHAT_FRAME or not Debugging then return end
  144.    
  145.     local msg = ''
  146.    
  147.     for k,v in ipairs(arg) do
  148.        
  149.         msg = msg .. tostring(v) .. ' : '
  150.        
  151.     end
  152.    
  153.     DEFAULT_CHAT_FRAME:AddMessage(msg)
  154.    
  155. end
  156.  
  157. local function Print(text)
  158.    
  159.     if not DEFAULT_CHAT_FRAME then return end
  160.    
  161.     DEFAULT_CHAT_FRAME:AddMessage(text)
  162.    
  163. end
  164.  
  165. local function UnmouseableFrameOnScreen()
  166.    
  167.     for index in pairs(MouseLook_FramesToCheck) do
  168.        
  169.         local curFrame = getglobal(MouseLook_FramesToCheck[index])
  170.         if (curFrame and curFrame:IsVisible()) then
  171.             --ML_debug("Frame on screen : " .. MouseLook_FramesToCheck[index])
  172.             return true
  173.         end
  174.        
  175.     end
  176.    
  177. end
  178.  
  179. local function MouseIsOverFrame()
  180.    
  181.     for index in pairs(MouseLook_FramesToCheckForMouse) do
  182.        
  183.         local curFrameName = MouseLook_FramesToCheckForMouse[index]
  184.         local curFrame = getglobal(curFrameName)
  185.        
  186.         if  curFrame
  187.         and curFrame:IsVisible() then
  188.            
  189.             local xPos, yPos = GetCursorPosition()
  190.            
  191.             local top    = curFrame:GetTop()    * UIParent:GetScale() + 10
  192.             local right  = curFrame:GetRight()  * UIParent:GetScale() + 10
  193.             local left   = curFrame:GetLeft()   * UIParent:GetScale() - 10
  194.             local bottom = curFrame:GetBottom() * UIParent:GetScale() - 10
  195.            
  196.             if string.find(curFrameName, "ChatFrame") then
  197.                 top = top + 10
  198.                 left = left - 10
  199.             end
  200.            
  201.             if  xPos and yPos
  202.             and left and right
  203.             and top  and bottom then
  204.                
  205.                 if  (xPos >= left)
  206.                 and (xPos <= right)
  207.                 and (yPos >= bottom)
  208.                 and (yPos <= top) then
  209.                    
  210.                     --ML_debug("Mouse is over frame : " .. curFrameName)
  211.                     return true
  212.                    
  213.                 end
  214.                
  215.             end
  216.            
  217.         end
  218.        
  219.     end
  220.    
  221. end
  222.  
  223.  
  224. function MouseLook_OnUpdate(self,elapsed,...)
  225.    
  226.    
  227.     MouseLook_LastUpdate = MouseLook_LastUpdate + elapsed
  228.    
  229.     if (MouseLook_LastUpdate >= MouseLook_UpdateFrequency) then
  230.        
  231.         MouseLook_LastUpdate = 0
  232.        
  233.         if MouseLookOn
  234.         and not MouseLook_MomentaryPointer then
  235.            
  236.             if CursorHasItem()
  237.             or UnmouseableFrameOnScreen()
  238.             or MouseIsOverFrame() then
  239.                
  240.                 if not MouseLook_TempLockout then
  241.                    
  242.                     --IsMouselooking() -- also for mouselook tools ;)
  243.                     MouselookStop()
  244.                     --Print("MouselookStop()")
  245.                     --SetBinding("BUTTON1","CAMERAORSELECTORMOVE")
  246.                     --SetBinding("BUTTON2","TURNORACTION")
  247.                     MouseLook_TempLockout = true
  248.                    
  249.                    
  250.                 end
  251.                
  252.             else
  253.                
  254.                 if MouseLook_TempLockout then
  255.                    
  256.                     MouselookStart()
  257.                     --Print("MouselookStart()")
  258.                     --SetBinding("BUTTON1","MOVEBACKWARD")
  259.                     --SetBinding("BUTTON2","MOVEFORWARD")
  260.                     MouseLook_TempLockout = false
  261.                    
  262.                 end
  263.                
  264.             end
  265.            
  266.         end
  267.        
  268.     end
  269.    
  270. end
  271.  
  272. function MouseLook_Toggle()
  273.    
  274.     if not MouseLookOn then
  275.        
  276.         MouselookStart()
  277.         --SetBinding("BUTTON1","MOVEBACKWARD")
  278.         --SetBinding("BUTTON2","MOVEFORWARD")
  279.         MouseLookOn = true
  280.        
  281.     else
  282.        
  283.         MouselookStop()
  284.         --SetBinding("BUTTON1","CAMERAORSELECTORMOVE")
  285.         --SetBinding("BUTTON2","TURNORACTION")
  286.         MouseLookOn = false
  287.        
  288.        
  289.     end
  290.    
  291. end
  292.  
  293. local oldMouseDown
  294. local oldMouseUp
  295. local mouse_button_down
  296.  
  297. local function status(bool)
  298.    
  299.     if bool then return "true" else return "false" end
  300.    
  301. end
  302.  
  303. function MouseLook_Momentary(keystate)
  304.    
  305.     if MouseLookOn then
  306.        
  307.         if ( keystate == "down" ) then
  308.            
  309.             MouselookStop()
  310.             --Print("MouselookStop()")
  311.             --SetBinding("BUTTON1","CAMERAORSELECTORMOVE")
  312.             --SetBinding("BUTTON2","TURNORACTION")
  313.             MouseLook_MomentaryPointer = true
  314.             --Print("Down")
  315.            
  316.         else
  317.            
  318.             --if mouse_button_down then
  319.                
  320.             --  waiting_to_reset = true
  321.             --  Print("1")
  322.             --else
  323.                
  324.                 if not MouseLook_TempLockout then
  325.                    
  326.                     MouselookStart()
  327.                     --Print("MouselookStart()")
  328.                     --SetBinding("BUTTON1","MOVEBACKWARD")
  329.                     --SetBinding("BUTTON2","MOVEFORWARD")
  330.                     --Print("2")
  331.                 else
  332.                     --Print("3")
  333.                    
  334.                 end
  335.                
  336.                 MouseLook_MomentaryPointer = false
  337.                
  338.             --end
  339.             --Print("up")
  340.            
  341.         end
  342.        
  343.     end
  344.    
  345. end
  346.  
  347.  
  348. function MouseLook_OnLoad(self,...)
  349.    
  350.     MouseLookFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
  351.     MouseLookFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
  352.     MouseLookFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  353.    
  354.     oldMouseDown=WorldFrame:GetScript("OnMouseDown")
  355.     oldMouseUp = WorldFrame:GetScript("OnMouseUp")
  356.     WorldFrame:SetScript("OnMouseDown",MouseDown)
  357.     WorldFrame:SetScript("OnMouseUp",MouseUp)
  358.    
  359.     SetMouselookOverrideBinding("BUTTON1", "MOVEBACKWARD")
  360.     SetMouselookOverrideBinding("BUTTON2", "MOVEFORWARD")
  361.     --Print("on load")
  362. end;
  363.  
  364.  
  365. function MouseDown(...)
  366. -- need to determine WHICH mousebutton is down.  it's in arg2.   how do I read it?  i forgot.  actually, it doesn't really matter anymore.
  367.    
  368.     if mouse_button_down then
  369.        
  370.         --both_buttons_down = true
  371.         --Print("MouseDown() mouse_button_down true")
  372.        
  373.     else
  374.        
  375.         mouse_button_down = true
  376.         --Print("MouseDown() mouse_button_down false")
  377.        
  378.     end
  379.    
  380.     if oldMouseDown then oldMouseDown(args) end
  381.    
  382. end
  383.  
  384. function MouseUp(...)
  385.    
  386.     if both_buttons_down then
  387.        
  388.         both_buttons_down = false
  389.         --Print("MouseUp() both_buttons_down true")
  390.        
  391.     else
  392.        
  393.         mouse_button_down = false
  394.         --Print("MouseUp() both_buttons_down false")
  395.         if waiting_to_reset then
  396.            
  397.             MouseLook_TempLockout = true
  398.            
  399.             MouseLook_MomentaryPointer = false
  400.            
  401.             waiting_to_reset = false
  402.            
  403.         end
  404.        
  405.     end
  406.    
  407.     if oldMouseUp then oldMouseUp(args) end
  408.    
  409. end
  410.  
  411. function MouseLook_OnEvent(self,event,...)
  412.    
  413.     --Print("on event:" ..event)
  414.    
  415.     if event == "PLAYER_ENTERING_WORLD" then
  416.        
  417.         --Print("PLAYER_ENTERING_WORLD event")
  418.        
  419.         if MouseLookOn then
  420.            
  421.             --Print("Trying to automatically start Mouselook")
  422.             MouselookStart()
  423.             --Print("MouselookStart()")
  424.             --SetBinding("BUTTON1","MOVEBACKWARD")
  425.             --SetBinding("BUTTON2","MOVEFORWARD")
  426.            
  427.         end
  428.        
  429.     end
  430.    
  431.     if event == "PLAYER_REGEN_DISABLED" then
  432.        
  433.         if MouseLookOn then
  434.            
  435.             --SetBinding("BUTTON1","CAMERAORSELECTORMOVE")
  436.             --SetBinding("BUTTON2","TURNORACTION")
  437.            
  438.         end
  439.        
  440.     end
  441.    
  442.     if event == "PLAYER_REGEN_ENABLED" then
  443.        
  444.         if MouseLookOn then
  445.            
  446.             --SetBinding("BUTTON1","MOVEBACKWARD")
  447.             --SetBinding("BUTTON2","MOVEFORWARD")
  448.            
  449.         end
  450.        
  451.     end
  452.    
  453. end


MouseLookHandler

Lua Code:
  1. _G["BINDING_HEADER_MOUSELOOKHANDLER"] = "MouselookHandler"
  2. _G["BINDING_NAME_INVERTMOUSELOOK"]    = "Invert Mouselook"
  3. _G["BINDING_NAME_TOGGLEMOUSELOOK"]    = "Toggle Mouselook"
  4. _G["BINDING_NAME_LOCKMOUSELOOK"]      = "Enable Mouselook"
  5. _G["BINDING_NAME_UNLOCKMOUSELOOK"]    = "Disable Mouselook"
  6.  
  7. MouselookHandler = LibStub("AceAddon-3.0"):NewAddon("MouselookHandler", "AceConsole-3.0")
  8. MouselookHandler._G = _G
  9.  
  10. -- Set the environment of the current function to the global table MouselookHandler.
  11. -- See: [url]http://www.lua.org/pil/14.3.html[/url]
  12. setfenv(1, MouselookHandler)
  13.  
  14. local MouselookHandler = _G.MouselookHandler
  15. local LibStub = _G.LibStub
  16.  
  17. local AceConfig = LibStub("AceConfig-3.0")
  18. local AceConfigDialog = LibStub("AceConfigDialog-3.0")
  19. local AceConfigRegistry = LibStub("AceConfigRegistry-3.0")
  20. local AceDBOptions = LibStub("AceDBOptions-3.0")
  21.  
  22. local IsMouselooking = _G.IsMouselooking
  23. local MouselookStart, MouselookStop = _G.MouselookStart, _G.MouselookStop
  24.  
  25. local modName = "MouselookHandler"
  26.  
  27. local customFunction, stateHandler, customEventFrame
  28. function MouselookHandler:predFun()
  29.   return false
  30. end
  31.  
  32. turnOrActionActive, cameraOrSelectOrMoveActive = false, false
  33. clauseText = nil
  34.  
  35. enabled, inverted = false, false
  36.  
  37. local function defer()
  38.   if not db.profile.useDeferWorkaround then return end
  39.   for i = 1, 5 do
  40.     if _G.IsMouseButtonDown(i) then return true end
  41.   end
  42. end
  43.  
  44. -- Starts and stops mouselook if the API function IsMouselooking() doesn't match up with this mods
  45. -- saved state.
  46. local function rematch()
  47.   if defer() then return end
  48.  
  49.   if turnOrActionActive or cameraOrSelectOrMoveActive then return end
  50.  
  51.   if db.profile.useSpellTargetingOverride and _G.SpellIsTargeting() then
  52.     MouselookStop(); return
  53.   end
  54.  
  55.   if not IsMouselooking() then
  56.     if shouldMouselook and not _G.GetCurrentKeyBoardFocus() then
  57.       MouselookStart()
  58.     end
  59.   elseif IsMouselooking() then
  60.     if not shouldMouselook or _G.GetCurrentKeyBoardFocus() then
  61.       MouselookStop()
  62.     end
  63.   end
  64. end
  65.  
  66. function update(event, ...)
  67.   local shouldMouselookOld = shouldMouselook
  68.   shouldMouselook = MouselookHandler:predFun(enabled, inverted, clauseText, event, ...)
  69.   if shouldMouselook ~= shouldMouselookOld then
  70.     rematch()
  71.   end
  72. end
  73.  
  74. function invert()
  75.   inverted = true
  76.   update()
  77. end
  78.  
  79. function revert()
  80.   inverted = false
  81.   update()
  82. end
  83.  
  84. function toggle()
  85.   enabled = not enabled
  86.   update()
  87. end
  88.  
  89. function lock()
  90.   enabled = true
  91.   update()
  92. end
  93.  
  94. function unlock()
  95.   enabled = false
  96.   update()
  97. end
  98.  
  99. local handlerFrame = _G.CreateFrame("Frame", modName .. "handlerFrame")
  100.  
  101. -- [url]http://www.wowinterface.com/forums/showthread.php?p=267998[/url]
  102. handlerFrame:SetScript("OnEvent", function(self, event, ...)
  103.   return self[event] and self[event](self, ...)
  104. end)
  105.  
  106. function handlerFrame:onUpdate(...)
  107.   rematch()
  108.   --_G.assert(_G.GetBindingAction("BUTTON1", true))
  109.   --_G.print(_G.GetMouseFocus():GetName())
  110.   --_G.print(_G.IsMouseButtonDown(1), _G.IsMouseButtonDown(2))
  111. end
  112.  
  113. handlerFrame:SetScript("OnUpdate", handlerFrame.onUpdate)
  114.  
  115. _G.hooksecurefunc("TurnOrActionStart", function()
  116.   turnOrActionActive = true
  117. end)
  118.  
  119. _G.hooksecurefunc("TurnOrActionStop", function()
  120.   turnOrActionActive = false
  121. end)
  122.  
  123. _G.hooksecurefunc("CameraOrSelectOrMoveStart", function()
  124.   cameraOrSelectOrMoveActive = true
  125. end)
  126.  
  127. _G.hooksecurefunc("CameraOrSelectOrMoveStop", function()
  128.   cameraOrSelectOrMoveActive = false
  129. end)
  130.  
  131. function handlerFrame:PLAYER_ENTERING_WORLD()
  132.   rematch()
  133. end
  134.  
  135. function handlerFrame:PLAYER_LOGIN()
  136.   -- Nothing here yet.
  137. end
  138.  
  139. function handlerFrame:ADDON_LOADED()
  140.   --_G.print("MouselookHandler loaded!")
  141.  
  142.   -- [url]http://wowprogramming.com/utils/xmlbrowser/live/FrameXML/CinematicFrame.lua[/url]
  143.   -- [url]http://wowprogramming.com/utils/xmlbrowser/live/FrameXML/CinematicFrame.xml[/url]
  144.   -- [url]http://wowprogramming.com/docs/widgets/MovieFrame[/url]
  145.   -- [url]http://wowprogramming.com/utils/xmlbrowser/live/FrameXML/MovieFrame.lua[/url]
  146.   -- [url]http://wowprogramming.com/utils/xmlbrowser/live/FrameXML/MovieFrame.xml[/url]
  147.  
  148.   --[[
  149.   _G.assert(_G.CinematicFrame)
  150.   _G.assert(_G.CinematicFrameCloseDialog)
  151.   --_G.assert(_G.CinematicFrame.closeDialog)
  152.   _G.assert(_G.MovieFrame)
  153.   _G.assert(_G.MovieFrame.CloseDialog)
  154.   ]]
  155.  
  156.   _G.CinematicFrameCloseDialog:HookScript("OnShow", function(self)
  157.     handlerFrame:SetScript("OnUpdate", nil)
  158.     if _G.IsMouselooking() then
  159.       _G.MouselookStop()
  160.     end
  161.   end)
  162.  
  163.   _G.MovieFrame.CloseDialog:HookScript("OnShow", function(self)
  164.     handlerFrame:SetScript("OnUpdate", nil)
  165.     if _G.IsMouselooking() then
  166.       _G.MouselookStop()
  167.     end
  168.   end)
  169.  
  170.   _G.CinematicFrameCloseDialog:HookScript("OnHide", function(self)
  171.     handlerFrame:SetScript("OnUpdate", handlerFrame.onUpdate)
  172.     rematch()
  173.   end)
  174.  
  175.   _G.MovieFrame.CloseDialog:HookScript("OnHide", function(self)
  176.     handlerFrame:SetScript("OnUpdate", handlerFrame.onUpdate)
  177.     rematch()
  178.   end)
  179.  
  180.   self:UnregisterEvent("ADDON_LOADED")
  181.   self.ADDON_LOADED = nil
  182. end
  183.  
  184. handlerFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
  185. handlerFrame:RegisterEvent("PLAYER_LOGIN")
  186. handlerFrame:RegisterEvent("ADDON_LOADED")
  187.  
  188. --------------------------------------------------------------------------------
  189. -- < in-game configuration UI code > -------------------------------------------
  190. --------------------------------------------------------------------------------
  191.  
  192. local function applyOverrideBindings(info, val)
  193.   if db.profile.useOverrideBindings then
  194.     for key, command in _G.pairs(db.profile.mouseOverrideBindings) do
  195.       _G.SetMouselookOverrideBinding(key, command == "" and nil or command)
  196.     end
  197.   else
  198.     for key, _ in _G.pairs(db.profile.mouseOverrideBindings) do
  199.       _G.SetMouselookOverrideBinding(key, nil)
  200.     end
  201.   end
  202. end
  203.  
  204. local function setUseOverrideBindings(info, val)
  205.   db.profile.useOverrideBindings = val
  206.   applyOverrideBindings()
  207. end
  208.  
  209. local function getUseOverrideBindings(info)
  210.   return db.profile.useOverrideBindings
  211. end
  212.  
  213. -- "Hint: Use info[#info] to get the leaf node name, info[#info-1] for the parent, and so on!"
  214. -- [url]http://www.wowace.com/addons/ace3/pages/ace-config-3-0-options-tables/#w-callback-arguments[/url]
  215.  
  216. local suggestedCommands = {}
  217. for _, v in _G.ipairs({"UNLOCKMOUSELOOK", "MOVEFORWARD", "MOVEBACKWARD", "TOGGLEAUTORUN",
  218.   "STRAFELEFT", "STRAFERIGHT"}) do
  219.   suggestedCommands[v] = _G.GetBindingText(v, "BINDING_NAME_")
  220. end
  221.  
  222. -- The key in the "Override bindings" section of the options frame that's currently being
  223. -- configured.
  224. local selectedKey
  225.  
  226. local function validateCustomFunction(info, input)
  227.   local chunk, errorMessage = _G.loadstring(input)
  228.   if not chunk then
  229.     MouselookHandler:Print(errorMessage)
  230.     return errorMessage
  231.   else
  232.     chunk()
  233.     if _G.type(predFun) ~= "function" then
  234.       MouselookHandler:Print("Your Lua code should define a function \'MouselookHandler:predFun\'!")
  235.       return "Your Lua code should define a function \'MouselookHandler:predFun\'!"
  236.     else
  237.       return true
  238.     end
  239.   end
  240. end
  241.  
  242. local function setCustomFunction(info, input)
  243.   db.profile.customFunction = input
  244. end
  245.  
  246. local function getCustomFunction(info)
  247.   return db.profile.customFunction
  248. end
  249.  
  250. local function setMacroText(info, input)
  251.   _G.RegisterStateDriver(stateHandler, "mouselookstate", input)
  252.   db.profile.macroText = input
  253. end
  254.  
  255. local function getMacroText(info)
  256.   return db.profile.macroText
  257. end
  258.  
  259. local function setEventList(info, input)
  260.   for event in _G.string.gmatch(db.profile.eventList, "[^%s]+") do
  261.     customEventFrame:UnregisterEvent(event)
  262.   end
  263.   for event in _G.string.gmatch(input, "[^%s]+") do
  264.     customEventFrame:RegisterEvent(event)
  265.   end
  266.   db.profile.eventList = input
  267. end
  268.  
  269. local function getEventList(info)
  270.   return db.profile.eventList
  271. end
  272.  
  273. -- Array containing all the keys from db.profile.mouseOverrideBindings.
  274. local overrideKeys = {}
  275.  
  276. local deferText = [[When clicking and holding any mouse button while ]]
  277.   .. [[mouselooking, but only releasing it after stopping mouselooking, the ]]
  278.   .. [[mouse button's binding won't be run on release.]] .. '\n'
  279.   .. [[    For example, consider having "BUTTON1" bound to "STRAFELEFT". ]]
  280.   .. [[Now, when mouselook is active and the left mouse button is pressed ]]
  281.   .. [[and held, stopping mouselook will result in releasing the mouse ]]
  282.   .. [[button to no longer have it's effect of cancelling strafing. ]]
  283.  .. [[Instead, the player will be locked into strafing left until ]]
  284.  .. [[clicking the left mouse button again.]] .. '\n'
  285.  .. [[    This setting will cause slightly less obnoxious behavior: it will ]]
  286.  .. [[defer stopping mouselook until all mouse buttons have been released.]]
  287.  
  288. local bindText = [[Enable to define a set of keybindings that only apply while mouselooking. ]]
  289.  .. [[For example, you could strafe with the left (BUTTON1) and right (BUTTON2) mouse buttons.]]
  290.  
  291. local spellTargetingOverrideText = [[Disable mouselook while a spell is awaiting a target.]]
  292.  
  293. local options = {
  294.  type = "group",
  295.  name = "MouselookHandler Options",
  296.  handler = MouselookHandler,
  297.  childGroups = "tree",
  298.  args = {
  299.    general = {
  300.      type = "group",
  301.      name = "General",
  302.      order = 100,
  303.      args = {
  304.        deferHeader = {
  305.          type = "header",
  306.          name = "Defer stopping mouselook",
  307.          order = 0,
  308.        },
  309.        deferDescription = {
  310.          type = "description",
  311.          name = deferText,
  312.          fontSize = "medium",
  313.          order = 1,
  314.        },
  315.        deferToggle = {
  316.          type = "toggle",
  317.          name = "Enable defer workaround",
  318.          width = "full",
  319.          set = function(info, val) db.profile.useDeferWorkaround = val end,
  320.          get = function(info) return db.profile.useDeferWorkaround  end,
  321.          order = 2,
  322.        },
  323.        spellTargetingOverrideHeader = {
  324.          type = "header",
  325.          name = "Disable while targeting spell",
  326.          order = 6,
  327.        },
  328.        spellTargetingOverrideDescription = {
  329.          type = "description",
  330.          name = spellTargetingOverrideText,
  331.          fontSize = "medium",
  332.          order = 7,
  333.        },
  334.        spellTargetingOverrideToggle = {
  335.          type = "toggle",
  336.          name = "Enable",
  337.          width = "full",
  338.          set = function(info, val) db.profile.useSpellTargetingOverride = val end,
  339.          get = function(info) return db.profile.useSpellTargetingOverride end,
  340.          order = 8,
  341.        },
  342.      },
  343.    },
  344.    overrideBindings = {
  345.      type = "group",
  346.      name = "Override bindings",
  347.      order = 110,
  348.      args = {
  349.        overrideBindingsHeader = {
  350.          type = "header",
  351.          name = "Mouselook override bindings",
  352.          order = 100,
  353.        },
  354.        overrideBindingsDescription = {
  355.          type = "description",
  356.          name = bindText,
  357.          fontSize = "medium",
  358.          order = 110,
  359.        },
  360.        overrideBindingsToggle = {
  361.          type = "toggle",
  362.          name = "Use override bindings",
  363.          width = "full",
  364.          set = setUseOverrideBindings,
  365.          get = getUseOverrideBindings,
  366.          order = 120,
  367.        },
  368.        bindingTableHeader = {
  369.          type = "header",
  370.          name = "Binding table",
  371.          order = 130,
  372.        },
  373.        bindingTableDescription = {
  374.          type = "description",
  375.          name = "You can either create a new override binding by entering a binding key " ..
  376.                 "(|cFF3366BBhttp://wowprogramming.com/docs/api_types#binding|r) in the " ..
  377.                 "editbox, or select an existing override binding from the dropdown menu to " ..
  378.                 "review or modify it.",
  379.          fontSize = "medium",
  380.          order = 140,
  381.        },
  382.        newBindingInput = {
  383.          type = "input",
  384.          name = "New",
  385.          desc = "Create a new mouselook override binding.",
  386.          set = function(info, val)
  387.                  val = _G.string.upper(val)
  388.                  if not db.profile.mouseOverrideBindings[val] then
  389.                    db.profile.mouseOverrideBindings[val] = ""
  390.                    --overrideKeys[#overrideKeys + 1] = val
  391.                    _G.table.insert(overrideKeys, val)
  392.                    -- [url]http://stackoverflow.com/questions/2038418/associatively-sorting-a-table-by-v[/url]
  393.                    _G.table.sort(overrideKeys, function(a, b)
  394.                      return a < b
  395.                    end)
  396.                  end
  397.                  for i = 0, #overrideKeys do
  398.                    if overrideKeys[i] == val then
  399.                      selectedKey = i
  400.                      return
  401.                    end
  402.                  end
  403.                end,
  404.          get = nil,
  405.          order = 150,
  406.        },
  407.        bindingTableDropdown = {
  408.          type = "select",
  409.          style = "dropdown",
  410.          name = "Key",
  411.          desc = "Select one of your existing mouselook override bindings.",
  412.          width = "normal",
  413.          values = function() return overrideKeys end,
  414.          set = function(info, value)
  415.            selectedKey = value
  416.          end,
  417.          get = function(info)
  418.            return selectedKey
  419.          end,
  420.          order = 160,
  421.        },
  422.        separator1 = {
  423.          type = "header",
  424.          name = "",
  425.          order = 170,
  426.        },
  427.        suggestedCommands = {
  428.          type = "select",
  429.          style = "dropdown",
  430.          name = "Suggestions",
  431.          desc = "You can select one of these suggested actions and have the corresponding " ..
  432.                 "command inserted above.",
  433.          values = function(info) return suggestedCommands end,
  434.          hidden = function() return not selectedKey or not overrideKeys[selectedKey] end,
  435.          set = function(info, val)
  436.              db.profile.mouseOverrideBindings[overrideKeys[selectedKey]] = val
  437.              applyOverrideBindings()
  438.            end,
  439.          get = function(info)
  440.              return db.profile.mouseOverrideBindings[overrideKeys[selectedKey]]
  441.            end,
  442.          order = 180,
  443.        },
  444.        commandInput = {
  445.          name = "Command",
  446.          desc = "The command to perform; can be any name attribute value of a " ..
  447.                 "Bindings.xml-defined binding, or an action command string.",
  448.          type = "input",
  449.          width = "double",
  450.          hidden = function() return not selectedKey or not overrideKeys[selectedKey] end,
  451.          set = function(info, val)
  452.              if val == "" then val = nil end
  453.              db.profile.mouseOverrideBindings[overrideKeys[selectedKey]] = val
  454.              applyOverrideBindings()
  455.            end,
  456.          get = function(info)
  457.              return db.profile.mouseOverrideBindings[overrideKeys[selectedKey]]
  458.            end,
  459.          order = 190,
  460.        },
  461.        commandDescription = {
  462.          -- [url]http://en.wikipedia.org/wiki/Help:Link_color[/url]
  463.          name = "The command assigned to the key selected above. Can be any name attribute " ..
  464.                 "value of a Bindings.xml-defined binding, or an action command string. See " ..
  465.                 "|cFF3366BBhttp://wowpedia.org/API_SetBinding|r for more information.\n" ..
  466.                 "    You can select one of the suggested actions and have the corresponding " ..
  467.                 "command inserted above.",
  468.          type = "description",
  469.          hidden = function() return not selectedKey or not overrideKeys[selectedKey] end,
  470.          fontSize = "medium",
  471.          order = 200,
  472.        },
  473.        spacer1 = {
  474.          type = "description",
  475.          name = "",
  476.          hidden = function() return not selectedKey or not overrideKeys[selectedKey] end,
  477.          order = 210,
  478.        },
  479.        clearBindingButton = {
  480.          type = "execute",
  481.          name = "Delete",
  482.          desc = "Delete the selected override binding.",
  483.          hidden = function() return not selectedKey or not overrideKeys[selectedKey] end,
  484.          width = "half",
  485.          confirm = true,
  486.          confirmText = "This can't be undone. Continue?",
  487.          func = function()
  488.              _G.SetMouselookOverrideBinding(overrideKeys[selectedKey], nil)
  489.              db.profile.mouseOverrideBindings[overrideKeys[selectedKey]] = nil
  490.              -- This wont shift down the remaining integer keys: overrideKeys[selectedKey] = nil
  491.              _G.table.remove(overrideKeys, selectedKey)
  492.              selectedKey = 0
  493.            end,
  494.          order = 220,
  495.        },
  496.        deleteBindingDescription = {
  497.          type = "description",
  498.          name = "    Clear the selected override binding.",
  499.          hidden = function() return not selectedKey or not overrideKeys[selectedKey] end,
  500.          width = "double",
  501.          fontSize = "medium",
  502.          order = 230,
  503.        },
  504.      },
  505.    },
  506.    advanced = {
  507.      type = "group",
  508.      name = "Advanced",
  509.      order = 120,
  510.      args = {
  511.        header1 = {
  512.          type = "header",
  513.          name = "Lua chunk",
  514.          order = 0,
  515.        },
  516.        desc1 = {
  517.          type = "description",
  518.          name = "You can provide a chunk of Lua code that will " ..
  519.                 "be compiled and ran when loading the addon " ..
  520.                 "(and when you change the Lua chunk). " ..
  521.                 "It must define a function " ..
  522.                 "\'MouselookHandler:predFun\' which will control " ..
  523.                 "when mouselook is started and stopped and " ..
  524.                 "gets called with these arguments:\n" ..
  525.                 " - the current default mouselook state (boolean),\n" ..
  526.                 " - the state of the temporary inversion switch; " ..
  527.                 "true while the key assigned is being held down (boolean),\n" ..
  528.                 " - the clause text obtained from your macro string; " ..
  529.                 "i.e., the text after whichever set of conditions applied (string), " ..
  530.                 "if any, and otherwise nil.\n\n" ..
  531.                 "Additionally, if it was called in response to an event the name " ..
  532.                 "of the event (string) and the event's specific arguments will be passed " ..
  533.                 "(See |cFF3366BBhttp://wowprogramming.com/docs/events|r).\n" ..
  534.                 "    Mouselook will be enabled if true is returned and disabled otherwise.",
  535.          fontSize = "medium",
  536.          order = 1,
  537.        },
  538.        eventList = {
  539.          type = "input",
  540.          name = "Event list",
  541.          desc = "Your function will be updated every time one of these events fires. Separate with spaces.",
  542.          width = "full",
  543.          set = setEventList,
  544.          get = getEventList,
  545.          order = 2,
  546.        },
  547.        macroConditional = {
  548.          type = "input",
  549.          name = "Macro conditions",
  550.          desc = "Your function will be reevaluated whenever the macro conditions entered here change.",
  551.          width = "full",
  552.          set = setMacroText,
  553.          get = getMacroText,
  554.          order = 3,
  555.        },
  556.        header2 = {
  557.          type = "header",
  558.          name = "Reset advanced settings",
  559.          order = 4,
  560.        },
  561.        desc2 = {
  562.          type = "description",
  563.          name = "Reenter the default events, macro text and function.",
  564.          fontSize = "medium",
  565.          width = "double",
  566.          order = 5,
  567.        },
  568.        resetButton = {
  569.          type = "execute",
  570.          name = "Reset",
  571.          desc = "Reenter the default events, macro text and function.",
  572.          width = "half",
  573.          confirm = true,
  574.          confirmText = "Your customizations will be removed. Continue?",
  575.          func = function()
  576.                   setEventList(nil, databaseDefaults.profile.eventList)
  577.                   setMacroText(nil, databaseDefaults.profile.macroText)
  578.                   if validateCustomFunction(nil, databaseDefaults.profile.customFunction) == true then
  579.                     setCustomFunction(nil, databaseDefaults.profile.customFunction)
  580.                   end
  581.                 end,
  582.          order = 6,
  583.        },
  584.        advanced1 = {
  585.          type = "group",
  586.          name = "Lua chunk",
  587.          args = {
  588.            header1 = {
  589.              type = "header",
  590.              name = "Lua chunk",
  591.              order = 0,
  592.            },
  593.            customFunction = {
  594.              type = "input",
  595.              name = "",
  596.              multiline = 20,
  597.              width = "full",
  598.              validate = validateCustomFunction,
  599.              set = setCustomFunction,
  600.              get = getCustomFunction,
  601.              order = 1,
  602.            },
  603.            header2 = {
  604.              type = "header",
  605.              name = "Reload UI",
  606.              order = 2,
  607.            },
  608.            desc1 = {
  609.              type = "description",
  610.              name = "Useful to get rid of side effects introduced by previous Lua chunks " ..
  611.                     "(e.g. global variables or hooks from hooksecurefunc()). Otherwise unnecessary.",
  612.              fontSize = "medium",
  613.              width = "double",
  614.              order = 3,
  615.            },
  616.            reloadButton = {
  617.              type = "execute",
  618.              name = "Reload",
  619.              width = "half",
  620.              func = function()
  621.                       _G.ReloadUI()
  622.                     end,
  623.              order = 4,
  624.            },
  625.          },
  626.        },
  627.      },
  628.    },
  629.    binds = {
  630.      type = "group",
  631.      name = "Keybindings",
  632.      order = 130,
  633.      args = {
  634.        toggleHeader = {
  635.          type = "header",
  636.          name = _G["BINDING_NAME_TOGGLEMOUSELOOK"],
  637.          order = 0,
  638.        },
  639.        toggleDescription = {
  640.          type = "description",
  641.          name = "Toggles the normal mouselook state.",
  642.          width = "double",
  643.          fontSize = "medium",
  644.          order = 1,
  645.        },
  646.        toggle = {
  647.          type = "keybinding",
  648.          name = "",
  649.          desc = "Toggles the normal mouselook state.",
  650.          width = "half",
  651.          set = function(info, key)
  652.                  local oldKey = (_G.GetBindingKey("TOGGLEMOUSELOOK"))
  653.                  if oldKey then _G.SetBinding(oldKey) end
  654.                  _G.SetBinding(key, "TOGGLEMOUSELOOK")
  655.                  _G.SaveBindings(_G.GetCurrentBindingSet())
  656.                end,
  657.          get = function(info) return (_G.GetBindingKey("TOGGLEMOUSELOOK")) end,
  658.          order = 2,
  659.        },
  660.        invertHeader = {
  661.          type = "header",
  662.          name = _G["BINDING_NAME_INVERTMOUSELOOK"],
  663.          order = 3,
  664.        },
  665.        invertDescription = {
  666.          type = "description",
  667.          name = "Inverts mouselook while the key is being held.",
  668.          width = "double",
  669.          fontSize = "medium",
  670.          order = 4,
  671.        },
  672.        invert = {
  673.          type = "keybinding",
  674.          name = "",
  675.          desc = "Inverts mouselook while the key is being held.",
  676.          width = "half",
  677.          set = function(info, key)
  678.                  local oldKey = (_G.GetBindingKey("INVERTMOUSELOOK"))
  679.                  if oldKey then _G.SetBinding(oldKey) end
  680.                  _G.SetBinding(key, "INVERTMOUSELOOK")
  681.                  _G.SaveBindings(_G.GetCurrentBindingSet())
  682.                end,
  683.          get = function(info) return (_G.GetBindingKey("INVERTMOUSELOOK")) end,
  684.          order = 5,
  685.        },
  686.        lockHeader = {
  687.          type = "header",
  688.          name = _G["BINDING_NAME_LOCKMOUSELOOK"],
  689.          order = 6,
  690.        },
  691.        lockDescription = {
  692.          type = "description",
  693.          name = "Sets the normal mouselook state to enabled.",
  694.          width = "double",
  695.          fontSize = "medium",
  696.          order = 7,
  697.        },
  698.        lock = {
  699.          type = "keybinding",
  700.          name = "",
  701.          desc = "Sets the normal mouselook state to enabled.",
  702.          width = "half",
  703.          set = function(info, key)
  704.                  local oldKey = (_G.GetBindingKey("LOCKMOUSELOOK"))
  705.                  if oldKey then _G.SetBinding(oldKey) end
  706.                  _G.SetBinding(key, "LOCKMOUSELOOK")
  707.                  _G.SaveBindings(_G.GetCurrentBindingSet())
  708.                end,
  709.          get = function(info) return (_G.GetBindingKey("LOCKMOUSELOOK")) end,
  710.          order = 8,
  711.        },
  712.        unlockHeader = {
  713.          type = "header",
  714.          name = _G["BINDING_NAME_UNLOCKMOUSELOOK"],
  715.          order = 9,
  716.        },
  717.        unlockDescription = {
  718.          type = "description",
  719.          name = "Sets the normal mouselook state to disabled.",
  720.          width = "double",
  721.          fontSize = "medium",
  722.          order = 10,
  723.        },
  724.        unlock = {
  725.          type = "keybinding",
  726.          name = "",
  727.          desc = "Sets the normal mouselook state to disabled.",
  728.          width = "half",
  729.          set = function(info, key)
  730.                  local oldKey = (_G.GetBindingKey("UNLOCKMOUSELOOK"))
  731.                  if oldKey then _G.SetBinding(oldKey) end
  732.                  _G.SetBinding(key, "UNLOCKMOUSELOOK")
  733.                  _G.SaveBindings(_G.GetCurrentBindingSet())
  734.                end,
  735.          get = function(info) return (_G.GetBindingKey("UNLOCKMOUSELOOK")) end,
  736.          order = 11,
  737.        },
  738.      },
  739.    },
  740.  },
  741. }
  742.  
  743. ----------------------------------------------------------------------------------------------------
  744. -- </ in-game configuration UI code > --------------------------------------------------------------
  745. ----------------------------------------------------------------------------------------------------
  746.  
  747. databaseDefaults = {
  748.  ["global"] = {
  749.    ["version"] = nil,
  750.  },
  751.  ["profile"] = {
  752.    ["newUser"] = true,
  753.    ["useSpellTargetingOverride"] = true,
  754.    ["useDeferWorkaround"] = true,
  755.    ["useOverrideBindings"] = true,
  756.    ["mouseOverrideBindings"] = {
  757.        ["BUTTON1"] = "STRAFELEFT",
  758.        ["BUTTON2"] = "STRAFERIGHT",
  759.    },
  760.    macroText = "",
  761.    eventList = ""
  762.  },
  763. }
  764.  
  765. databaseDefaults.profile.customFunction = [[
  766. function MouselookHandler:predFun(enabled, inverted, clauseText, event, ...)
  767.  return (enabled and not inverted) or
  768.    (not enabled and inverted)
  769. end
  770. ]]
  771.  
  772. local function migrateLegacyGlobalPreferences()
  773.  -- None of the values of these keys in db.global are tables, so we don't need a deep copy
  774.  -- ([url]http://lua-users.org/wiki/CopyTable[/url]).
  775.  local legacyGlobalKeys = {
  776.    "useSpellTargetingOverride",
  777.    "useDeferWorkaround",
  778.    "useOverrideBindings",
  779.    "macroText",
  780.    "eventList",
  781.    "customFunction",
  782.  }
  783.  
  784.  local curProfile = db:GetCurrentProfile()
  785.  if curProfile == "Default" then
  786.    -- If they have any global settings which don't match the default, copy them.
  787.    for _, key in _G.pairs(legacyGlobalKeys) do
  788.      if db.global[key] and db.global[key] ~= databaseDefaults.profile[key] then
  789.        db.profile[key] = db.global[key]
  790.      end
  791.      db.global[key] = nil
  792.    end
  793.    db.global.newUser = nil
  794.  end
  795. end
  796.  
  797. -- Called by AceAddon on ADDON_LOADED?
  798. -- See: wowace.com/addons/ace3/pages/getting-started/#w-standard-methods
  799. function MouselookHandler:OnInitialize()
  800.  -- The ".toc" need say "## SavedVariables: MouselookHandlerDB".
  801.  self.db = LibStub("AceDB-3.0"):New("MouselookHandlerDB", databaseDefaults, true)
  802.  
  803.  local currentVersion = _G.GetAddOnMetadata(modName, "Version")
  804.  if not self.db.global.version then
  805.    migrateLegacyGlobalPreferences()
  806.  end
  807.  self.db.global.version = currentVersion
  808.  
  809.  if db.profile.newUser then
  810.    MouselookHandler:Print("This seems to be your first time using this AddOn. To get started " ..
  811.      "you should bring up the configuration UI (/mh) and assign keys to toggle mouselook.")
  812.  end
  813.  
  814.  self.db.RegisterCallback(self, "OnProfileChanged", "RefreshDB")
  815.  self.db.RegisterCallback(self, "OnProfileCopied", "RefreshDB")
  816.  self.db.RegisterCallback(self, "OnProfileReset", "RefreshDB")
  817.  self:RefreshDB()
  818.  
  819.  if validateCustomFunction(nil, db.profile.customFunction) == true then
  820.    setCustomFunction(nil, db.profile.customFunction)
  821.  end
  822.  
  823.  for k, _ in _G.pairs(db.profile.mouseOverrideBindings) do
  824.    if not (_G.type(k) == "string") then
  825.      db.profile.mouseOverrideBindings[k] = nil
  826.    else
  827.      _G.table.insert(overrideKeys, (k))
  828.    end
  829.  end
  830.  _G.table.sort(overrideKeys)
  831.  
  832.  options.args.profiles = AceDBOptions:GetOptionsTable(self.db)
  833.  options.args.profiles.order = 121
  834.  local function changeFontSize(optionsGroup)
  835.    --_G.assert(optionsGroup.type == "group")
  836.    --_G.assert(optionsGroup.args)
  837.    for k, v in _G.pairs(optionsGroup.args) do
  838.      if _G.type(v) == "table" then
  839.        if v.type and v.type == "description" then
  840.          optionsGroup.args[k].fontSize = "medium"
  841.        elseif v.type and v.type == "group" then
  842.          changeFontSize(v)
  843.        end
  844.      end
  845.    end
  846.  end
  847.  changeFontSize(options.args.profiles)
  848.  options.args.profiles.args.addedHeader = {
  849.    type = "header",
  850.    name = "Profiles",
  851.    order = 0,
  852.  },
  853.  
  854.  -- See wowace.com/addons/ace3/pages/getting-started/#w-registering-the-options.
  855.  AceConfig:RegisterOptionsTable(modName, options)
  856.  AceConfigRegistry:RegisterOptionsTable("MouselookHandler_Profiles", options.args.profiles)
  857.  AceConfigDialog:SetDefaultSize(modName, 800, 600)
  858.  
  859.  -- [url]http://www.wowace.com/addons/ace3/pages/api/ace-config-dialog-3-0/[/url]
  860.  local configFrame = AceConfigDialog:AddToBlizOptions("MouselookHandler", "MouselookHandler")
  861.  configFrame.default = function()
  862.    self.db:ResetProfile()
  863.  end
  864.  
  865.  --------------------------------------------------------------------------------------------------
  866.  stateHandler = _G.CreateFrame("Frame", modName .. "stateHandler", UIParent,
  867.    "SecureHandlerStateTemplate")
  868.  function stateHandler:onMouselookState(newstate)
  869.    _G["MouselookHandler"]["clauseText"] = newstate
  870.    _G["MouselookHandler"].update()
  871.  end
  872.  stateHandler:SetAttribute("_onstate-mouselookstate", [[
  873.    self:CallMethod("onMouselookState", newstate)
  874.  ]])
  875.  _G.RegisterStateDriver(stateHandler, "mouselookstate", db.profile.macroText)
  876.  ------------------------------------------------------------------------------
  877.  customEventFrame = _G.CreateFrame("Frame", modName .. "customEventFrame")
  878.  customEventFrame:SetScript("OnEvent", function(self, event, ...)
  879.    _G["MouselookHandler"].update(event, ...)
  880.  end)
  881.  for event in _G.string.gmatch(db.profile.eventList, "[^%s]+") do
  882.    customEventFrame:RegisterEvent(event)
  883.  end
  884.  --------------------------------------------------------------------------------------------------
  885.  
  886.  local function toggleOptionsUI()
  887.    if not _G.InCombatLockdown() then
  888.      -- Sorry pwoodworth, but I prefer a standalone options panel that can be moved and resized.
  889.      -- The options are still available from the Blizzard panel, though.
  890.      AceConfigDialog:Open("MouselookHandler")
  891.      -- Call twice to workaround a Blizzard bug (the options panel isn't opened at the requested
  892.      -- category the first time).
  893.      --_G.InterfaceOptionsFrame_OpenToCategory(configFrame)
  894.      --_G.InterfaceOptionsFrame_OpenToCategory(configFrame)
  895.      db.profile.newUser = false
  896.    end
  897.  end
  898.  self:RegisterChatCommand("mouselookhandler", toggleOptionsUI)
  899.  self:RegisterChatCommand("mh", toggleOptionsUI)
  900.  
  901.  update()
  902. end
  903.  
  904. function MouselookHandler:RefreshDB()
  905.    --MouselookHandler:Print("Refreshing DB Profile")
  906.    applyOverrideBindings()
  907. end
  908.  
  909. -- Called by AceAddon.
  910. function MouselookHandler:OnEnable()
  911.  -- Nothing here yet.
  912. end
  913.  
  914. -- Called by AceAddon.
  915. function MouselookHandler:OnDisable()
  916.  -- Nothing here yet.
  917. end
  918.  
  919. -- vim: tw=100 sts=-1 sw=2 et
  Reply With Quote