WoWInterface SVN MultiScreenSupport

[/] [trunk/] [MultiScreenSupport.lua] - Rev 17

Go to most recent revision | Compare with Previous | Blame | View Log

MultiScreenSupport = LibStub("AceAddon-3.0"):NewAddon("MultiScreenSupport", "AceEvent-3.0")
local AceConfig = LibStub("AceConfig-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
--local L = LibStub("AceLocale-3.0"):GetLocale("MultiScreenSupport")

function MultiScreenSupport:OnInitialize()
        MultiScreenSupport:RegisterEvent("PLAYER_LOGIN")
end

function MultiScreenSupport:addParentAnchor(frameName)
        if _G[frameName] then
                MultiScreenSupport:setParentAnchor(_G[frameName])
                _G['multiscreensupportsave']['standart'][frameName] = true
        end
end

function MultiScreenSupport:setParentAnchor(frame)
        local hookFunction = function(frame)
                local point, relativeTo, relativePoint, xOfs, yOfs = frame:GetPoint()
                if relativeTo == nil or relativeTo:GetName() == UIParent:GetName() then
                        if not InCombatLockdown() then
                                frame:ClearAllPoints()
                                frame:SetPoint(point, MultiScreenSupportParent, relativePoint, xOfs, yOfs)
                        end
                end
        end
        local point, relativeTo, relativePoint, xOfs, yOfs = frame:GetPoint()
        if relativeTo == nil or relativeTo:GetName() == UIParent:GetName() then
                if frame:GetName() == "OrderHallTalentFrame" then--NEEDED since 7.2.5 probably because of chromie
                        frame:HookScript("OnShow", function(self)
                                frame:HookScript("OnUpdate", hookFunction)
                        end)
                else
                        frame:HookScript("OnUpdate", hookFunction)
                end
        end
end

function MultiScreenSupport:setSpecificParentAnchor(frame)
        if frame ~= nil then
                local point, relativeTo, relativePoint, xOfs, yOfs = frame:GetPoint()
                frame:ClearAllPoints()
                frame:SetPoint(point, MultiScreenSupportParent, relativePoint, xOfs, yOfs)
        end
end

function MultiScreenSupport:tableMerge(first_table, second_table)
        for k,v in pairs(second_table) do first_table[k] = v end
        return first_table
end

function MultiScreenSupport:initSettings()
        local MSSVersion = GetAddOnMetadata("MultiScreenSupport", "Version");

        if type(_G['multiscreensupportsave']) ~= "table" or not(_G['multiscreensupportsave']['MSSVersion']) or _G['multiscreensupportsave']['MSSVersion'] < '2.0' then
                _G['multiscreensupportsave'] = {
                        standart = {
                                ["PVEFrame"] = true,
                                ["CharacterFrame"] = true,
                                ["PlayerTalentFrame"] = true,
                                ["SpellBookFrame"] = true,
                                ["AchievementFrame"] = true,
                                ["FriendsFrame"] = true,
                                ["TradeSkillFrame"] = true,
                                ["GuildFrame"] = true,
                                ["CollectionsJournal"] = true,
                                ["MerchantFrame"] = true,
                                ["GossipFrame"] = true,
                                ["MailFrame"] = true,
                                --["EventTraceFrame"] = true, MOVABLE
                                ["GarrisonCapacitiveDisplayFrame"] = true,
                                ["GarrisonRecruiterFrame"] = true,
                                ["AuctionFrame"] = true,
                                ["BlackMarketFrame"] = true,
                                ["QuestFrame"] = true,
                                ["MacroFrame"] = true,
                                ["TimeManagerFrame"] = true,
                                ["CalendarFrame"] = true,
                                ["GarrisonLandingPage"] = true,
                                ["EncounterJournal"] = true,
                                ["LookingForGuildFrame"] = true,
                                ["TransmogrifyFrame"] = true,
                                ["ItemUpgradeFrame"] = true,
                                ["ArchaeologyFrame"] = true,
                                ["VoidStorageFrame"] = true,
                                ["BarberShopFrame"] = true,
                                ["ItemSocketingFrame"] = true,
                                ["InspectFrame"] = true,
                                ["GuildBankFrame"] = true,
                                ["QuestLogPopupDetailFrame"] = true,
                                ["ClassTrainerFrame"] = true,
                                ["BuffFrame"] = true,
                                ["BankFrame"] = true,
                                ["TradeFrame"] = true,
                                ["ContainerFrame1"] = true,
                                ["ContainerFrame2"] = true,
                                ["ContainerFrame3"] = true,
                                ["ContainerFrame4"] = true,
                                ["ContainerFrame5"] = true,
                                ["ContainerFrame6"] = true,
                                ["ContainerFrame7"] = true,
                                ["ContainerFrame8"] = true,
                                ["ContainerFrame9"] = true,
                                ["ContainerFrame10"] = true,
                                ["ContainerFrame11"] = true,
                                ["ContainerFrame12"] = true,
                                ["ContainerFrame13"] = true,
                                ["ArtifactFrame"] = true,
                                ["ItemTextFrame"] = true,
                                ["WardrobeFrame"] = true,
                                ["WorldMapFrame"] = true,
                        },
                        specific = {
                                --["WorldMapScreenAnchor"] = true,
                                ["MinimapCluster"] = true,
                        }
                }
        end
        if not(_G['multiscreensupportsave']['MSSVersion']) or _G['multiscreensupportsave']['MSSVersion'] < '2.2' then
                _G['multiscreensupportsave']['standart']["DressUpFrame"] = true
        end
        if not(_G['multiscreensupportsave']['MSSVersion']) or _G['multiscreensupportsave']['MSSVersion'] < '4.2' then
                _G['multiscreensupportsave']['standart']["ScrappingMachineFrame"] = true
                _G['multiscreensupportsave']['standart']["AzeriteEmpoweredItemUI"] = true
                _G['multiscreensupportsave']['standart']["ObliterumForgeFrame"] = true
                _G['multiscreensupportsave']['standart']["ArtifactRelicForgeFrame"] = true
                _G['multiscreensupportsave']['standart']["CommunitiesFrame"] = true
                _G['multiscreensupportsave']['standart']["AzeriteRespecFrame"] = true
        end

        _G['multiscreensupportsave']["MSSVersion"] = MSSVersion
end

function MultiScreenSupport:PLAYER_LOGIN()
        local allActiveFramesOrder = {}
        local allFramesOrder = {}
        local j, eyefinity
        local Resolution = ({GetScreenResolutions()})[GetCurrentResolution()]
        if Resolution == nil then
                print("MultiScreenSupport: The resolution for the PixelPerfect option can not be found properly. You should try to change your client to fullscreen and then back to windowed.")
                return false
        end
        local ScreenWidth, ScreenHeight = DecodeResolution(Resolution)

        --Pixel Perfect scale
        local scale = 768/ScreenHeight
        if (scale < 0.64) then
                scale = 0.64
        end
        
        currentScale = GetCVar("uiScale")
        if tostring(scale) ~= currentScale then
                print ('Moving scale from ' .. currentScale .. ' to ' .. scale .. '.')
                SetCVar("uiScale", scale)
        end

        if (ScreenWidth > 3840) or (UIParent:GetWidth() + 1 > ScreenWidth) then
                local width = ScreenWidth
                local height = ScreenHeight

                -- because some user enable bezel compensation, we need to find the real width of a single monitor.
                -- I don't know how it really work, but i'm assuming they add pixel to width to compensate the bezel. :P

                -- HQ resolution
                if width >= 9840 then width = 3280 end                                          -- WQSXGA
                if width >= 7680 and width < 9840 then width = 2560 end                     -- WQXGA
                if width >= 5760 and width < 7680 then width = 1920 end                         -- WUXGA & HDTV
                if width >= 5040 and width < 5760 then width = 1680 end                         -- WSXGA+

                -- adding height condition here to be sure it work with bezel compensation because WSXGA+ and UXGA/HD+ got approx same width
                if width >= 4800 and width < 5760 and height == 900 then width = 1600 end   -- UXGA & HD+

                -- low resolution screen
                if width >= 4320 and width < 4800 then width = 1440 end                         -- WSXGA
                if width >= 4080 and width < 4320 then width = 1360 end                         -- WXGA
                if width >= 3840 and width < 4080 then width = 1224 end                         -- SXGA & SXGA (UVGA) & WXGA & HDTV

                -- register a constant, we will need it later for launch.lua
                eyefinity = width
        end

        if not eyefinity then
                print('ERROR WITH THE DETECTION OF SURROUND GAMING / EYEFINITY, MultiSreenSupport WILL NOT WORK');
                return
        end

        MultiScreenSupport:initSettings()
        
        if ScreenHeight > 1200 then
                local h = UIParent:GetHeight();
                local ratio = ScreenHeight / h;
                local w = eyefinity / ratio;

                eyefinity = w;
                ScreenHeight = h;
        end
        
        local width = eyefinity
        local height = ScreenHeight

        local MultiScreenSupportParent = CreateFrame('Frame', 'MultiScreenSupportParent', UIParent)
        MultiScreenSupportParent:SetFrameLevel(UIParent:GetFrameLevel())
        MultiScreenSupportParent:SetPoint('CENTER', UIParent, 'CENTER')
        MultiScreenSupportParent:SetSize(width, height)
        --MultiScreenSupportParent:SetBackdrop({bgFile = "Interface/Tooltips/UI-Tooltip-Background", 
        --                                        edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
        --                                        tile = true, tileSize = 16, edgeSize = 1,
        --                                        insets = { left = 1, right = 1, top = 1, bottom = 1 }})

        local setting = {}
        local specificSetting = {}

        _G['MultiScreenSupportChildren'] = {}

        local childs = { UIParent:GetChildren() }
        local i = 2
        for _, child in ipairs(childs) do
                if not child:IsForbidden() then
                        local childname = child:GetName()
                        if childname ~= 'MultiScreenSupportParent' then
                                if childname ~= nil then
                                        local point, relativeTo, relativePoint, xOfs, yOfs = child:GetPoint()
                                        if relativeTo == nil or relativeTo:GetName() == UIParent:GetName() then
                                                setting[childname] = {
                                                        order = i,
                                                        name = childname,
                                                        desc = childname,
                                                        type = "toggle",
                                                        set = function(_,val)
                                                                if val then
                                                                        MultiScreenSupport:setParentAnchor(child)
                                                                else
                                                                        print('Reload UI is needed to reset a frame ankor')
                                                                end
                                                                _G['multiscreensupportsave']['standart'][childname] = val
                                                        end,
                                                        get = function(_)
                                                                if _G['multiscreensupportsave']['standart'][childname] == nil then
                                                                        _G['multiscreensupportsave']['standart'][childname] = false
                                                                end
                                                                return _G['multiscreensupportsave']['standart'][childname]
                                                        end
                                                }
                                                _G['MultiScreenSupportChildren'][childname] = true
                                                if _G['multiscreensupportsave']['standart'][childname] then
                                                        table.insert(allActiveFramesOrder, childname)
                                                else
                                                        table.insert(allFramesOrder, childname)
                                                end
                                                i = i+1
                                        end
                                end
                        end
                end
        end

        table.sort(allActiveFramesOrder)
        table.sort(allFramesOrder)
        j=2
        table.foreach(allActiveFramesOrder, function(_,v)
                setting[v].order = j
                j=j+1
        end)
        if j > 2 then
                setting['enabled'] = {
                        order = 1,
                        name = "Enabled",
                        type = "header"
                }
                j=j+1
                setting['available'] = {
                        order = j,
                        name = "Available",
                        type = "header"
                }
                j=j+1
        end
        table.foreach(allFramesOrder, function(_,v)
                setting[v].order = j
                j=j+1
        end)

        local standartconfig = {
                name = "MultiScreenSupport Standard options",
                handler = MultiScreenSupport,
                type = "group",
                args = setting
        }


        local childs = { WorldMapScreenAnchor }
        i = 2
        for _, child in ipairs(childs) do
                if not child:IsForbidden() then
                        local childname = child:GetName()
                        specificSetting[childname] = {
                                order = i,
                                name = childname,
                                desc = childname,
                                type = "toggle",
                                set = function(_,val)
                                        if val then
                                                MultiScreenSupport:setSpecificParentAnchor(child)
                                        else
                                                print('Reload UI is needed to reset a frame ankor')
                                        end
                                        _G['multiscreensupportsave']['specific'][childname] = val
                                end,
                                get = function(_)
                                        if _G['multiscreensupportsave']['specific'][childname] == nil then
                                                _G['multiscreensupportsave']['specific'][childname] = false
                                        end
                                        return _G['multiscreensupportsave']['specific'][childname]
                                end
                        }
                        i = i+1
                end
        end

        local specificconfig = {
                name = "MultiScreenSupport Specific options",
                handler = MultiScreenSupport,
                type = "group",
                args = specificSetting
        }

        AceConfig:RegisterOptionsTable("MultiScreenSupport_standart", standartconfig)
        AceConfig:RegisterOptionsTable("MultiScreenSupport_specific", specificconfig)

        local SetDefaultOpttion = AceConfigDialog:AddToBlizOptions("MultiScreenSupport_standart","MultiScreenSupport ".._G['multiscreensupportsave']["MSSVersion"])
        SetDefaultOpttion.default = function() _G['multiscreensupportsave'] = { standart = {}, specific = {} } end

        SetDefaultOpttion = AceConfigDialog:AddToBlizOptions("MultiScreenSupport_specific","Specific frames","MultiScreenSupport ".._G['multiscreensupportsave']["MSSVersion"])
        SetDefaultOpttion.default = function() _G['multiscreensupportsave'] = { standart = {}, specific = {} } end

        table.foreach(_G['multiscreensupportsave']['standart'], function(k,v)
                if v and _G[k] then
                        MultiScreenSupport:setParentAnchor(_G[k])
                end
        end)

        table.foreach(_G['multiscreensupportsave']['specific'], function(k,v)
                if v then
                        --print(k)
                        MultiScreenSupport:setSpecificParentAnchor(_G[k])
                end
        end)

        --to add specific addon frame like blizzard one.
        MultiScreenSupport:RegisterEvent("ADDON_LOADED")
end

function MultiScreenSupport:ADDON_LOADED(_, addon)
        local allActiveFramesOrder = {}
        local allFramesOrder = {}
        local setting = {}
        local childs = { UIParent:GetChildren() }
        local i = 2
        for _, child in ipairs(childs) do
                if not child:IsForbidden() then
                        local childname = child:GetName()
                        if childname ~= 'MultiScreenSupportParent' and childname ~= nil and _G['MultiScreenSupportChildren'][childname] == nil then
                                local point, relativeTo, relativePoint, xOfs, yOfs = child:GetPoint()
                                if relativeTo == nil or relativeTo:GetName() == UIParent:GetName() then
                                        setting[childname] = {
                                                order = i,
                                                name = childname,
                                                desc = childname,
                                                type = "toggle",
                                                set = function(_,val)
                                                        if val then
                                                                MultiScreenSupport:setParentAnchor(child)
                                                        else
                                                                print('Reload UI is needed to reset a frame ankor')
                                                        end
                                                        _G['multiscreensupportsave']['standart'][childname] = val
                                                end,
                                                get = function(_)
                                                        if _G['multiscreensupportsave']['standart'][childname] == nil then
                                                                _G['multiscreensupportsave']['standart'][childname] = false
                                                        end
                                                        return _G['multiscreensupportsave']['standart'][childname]
                                                end
                                        }
                                        _G['MultiScreenSupportChildren'][childname] = true
                                        if _G['multiscreensupportsave']['standart'][childname] then
                                                table.insert(allActiveFramesOrder, childname)
                                        else
                                                table.insert(allFramesOrder, childname)
                                        end
                                        i = i+1
                                end
                        end
                end
        end

        table.sort(allActiveFramesOrder)
        table.sort(allFramesOrder)
        local j=2
        table.foreach(allActiveFramesOrder, function(_,v)
                setting[v].order = j
                j=j+1
        end)
        if j > 2 then
                setting['enabled'] = {
                        order = 1,
                        name = "Enabled",
                        type = "header"
                }
                j=j+1
                setting['available'] = {
                        order = j,
                        name = "Available",
                        type = "header"
                }
                j=j+1
        end
        table.foreach(allFramesOrder, function(_,v)
                setting[v].order = j
                j=j+1
        end)

        local addonconfig = {
                name = "MultiScreenSupport Specific options",
                handler = MultiScreenSupport,
                type = "group",
                args = setting
        }

        if j > 2 then
                AceConfig:RegisterOptionsTable("MultiScreenSupport_"..addon, addonconfig)

                local SetDefaultOpttion = AceConfigDialog:AddToBlizOptions("MultiScreenSupport_"..addon, addon, "MultiScreenSupport ".._G['multiscreensupportsave']["MSSVersion"])
                SetDefaultOpttion.default = function() _G['multiscreensupportsave'] = { standart = {}, specific = {} } end

                table.foreach(_G['multiscreensupportsave']['standart'], function(k,v)
                        if v and _G[k] then
                                MultiScreenSupport:setParentAnchor(_G[k])
                        end
                end)
        end
        --print(addon..' LOADED')
end




SLASH_MULTISCREENSUPPORT1 = "/MultiScreenSupport"
SLASH_MULTISCREENSUPPORT2 = "/MSS"
SlashCmdList["MULTISCREENSUPPORT"] = function(msg)
        if msg then
                local command2 = msg--string.lower(msg);
                local command, rest2 = command2:match("^(%S*)%s*(.-)$")
                if command == 'add' and rest2 and _G[rest2] then
                        print('add '..rest2)
                        MultiScreenSupport:addParentAnchor(_G[rest2])
                end
                if command == 'remove' and rest2 and _G['multiscreensupportsave']['standart'][rest2] then
                        _G['multiscreensupportsave']['standart'][rest2] = false
                end
                if command == 'frame' then
                        local arg = GetMouseFocus()
                        if rest2  ~= "" then
                                arg = _G[rest2]
                        end
                        if arg ~= nil and arg:GetName() ~= nil then
                                local point, relativeTo, relativePoint, xOfs, yOfs = arg:GetPoint()
                                ChatFrame1:AddMessage("|cffCC0000~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
                                ChatFrame1:AddMessage("Name: |cffFFD100"..arg:GetName())
                                if arg:GetParent() and arg:GetParent():GetName() then
                                        ChatFrame1:AddMessage("Parent: |cffFFD100"..arg:GetParent():GetName())
                                end

                                ChatFrame1:AddMessage("Width: |cffFFD100"..format("%.2f",arg:GetWidth()))
                                ChatFrame1:AddMessage("Height: |cffFFD100"..format("%.2f",arg:GetHeight()))
                                ChatFrame1:AddMessage("Strata: |cffFFD100"..arg:GetFrameStrata())
                                ChatFrame1:AddMessage("Level: |cffFFD100"..arg:GetFrameLevel())

                                if xOfs then
                                        ChatFrame1:AddMessage("X: |cffFFD100"..format("%.2f",xOfs))
                                end
                                if yOfs then
                                        ChatFrame1:AddMessage("Y: |cffFFD100"..format("%.2f",yOfs))
                                end
                                if relativeTo and relativeTo:GetName() then
                                        ChatFrame1:AddMessage("Point: |cffFFD100"..point.."|r anchored to "..relativeTo:GetName().."'s |cffFFD100"..relativePoint)
                                end
                                ChatFrame1:AddMessage("|cffCC0000~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
                        elseif arg ~= nil then
                                local point, relativeTo, relativePoint, xOfs, yOfs = arg:GetPoint()
                                ChatFrame1:AddMessage("|cffCC0000~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
                                if arg:GetParent() and arg:GetParent():GetName() then
                                        ChatFrame1:AddMessage("Parent: |cffFFD100"..arg:GetParent():GetName())
                                end

                                ChatFrame1:AddMessage("Width: |cffFFD100"..format("%.2f",arg:GetWidth()))
                                ChatFrame1:AddMessage("Height: |cffFFD100"..format("%.2f",arg:GetHeight()))
                                ChatFrame1:AddMessage("Strata: |cffFFD100"..arg:GetFrameStrata())
                                ChatFrame1:AddMessage("Level: |cffFFD100"..arg:GetFrameLevel())

                                if xOfs then
                                        ChatFrame1:AddMessage("X: |cffFFD100"..format("%.2f",xOfs))
                                end
                                if yOfs then
                                        ChatFrame1:AddMessage("Y: |cffFFD100"..format("%.2f",yOfs))
                                end
                                if relativeTo and relativeTo:GetName() then
                                        ChatFrame1:AddMessage("Point: |cffFFD100"..point.."|r anchored to "..relativeTo:GetName().."'s |cffFFD100"..relativePoint)
                                end
                                ChatFrame1:AddMessage("|cffCC0000~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
                        elseif arg == nil then
                                ChatFrame1:AddMessage("Invalid frame name")
                        else
                                ChatFrame1:AddMessage("Could not find frame info")
                        end
                end
        else
                print('error')
        end
end

Go to most recent revision | Compare with Previous | Blame