/trunk
MultiScreenSupport = LibStub("AceAddon-3.0"):NewAddon("MultiScreenSupport", "AceEvent-3.0") |
local AceConfigDialog = LibStub("AceConfigDialog-3.0") |
local AceConfig = LibStub("AceConfig-3.0") |
local AceConfigDialog = LibStub("AceConfigDialog-3.0") |
--local L = LibStub("AceLocale-3.0"):GetLocale("MultiScreenSupport") |
local FrameNumber = 0 |
MultiScreenSupport:RegisterEvent("PLAYER_LOGIN") |
end |
function MultiScreenSupport:IsNamePlate(obj) |
local Object = obj |
local Name = Object:GetName() |
if (Name and Name:match("NamePlate")) then |
return true |
else |
return false |
end |
end |
function MultiScreenSupport:OnShowPlate() |
if InCombatLockdown() then |
--table.insert(frameUpdateList, self) |
-- return -- TODO: watch this carefully |
else |
frameUpdateList = {} |
self.Bar:SetSize(self.Bar:GetWidth()/_G['multiscreensupportsave']['screen'], self.Bar:GetHeight()/_G['multiscreensupportsave']['screen']) |
end |
end |
function MultiScreenSupport:PlateTreatement(obj) |
local Plate = obj |
Plate.IsMultiScreenSupport = true |
Plate.Bar, Plate.Frame = Plate:GetChildren() |
if _G['multiscreensupportsave']['nameplatesbg'] ~= -1 then |
Plate.Bar:SetBackdrop( |
{ |
bgFile = "Interface/Tooltips/UI-Tooltip-Background", |
edgeFile = "", |
tile = true, tileSize = 1, edgeSize = 0, |
insets = { left = 0, right = 0, top = 0, bottom = 0 } |
} |
); |
Plate.Bar:SetBackdropColor(0,0,0,.2); |
end |
if _G['multiscreensupportsave']['nameplates'] ~= -1 then |
Plate:HookScript("OnShow", self.OnShowPlate) |
if InCombatLockdown() then |
--table.insert(frameUpdateList, Plate) |
-- return -- TODO: watch this carefully |
else |
frameUpdateList = {} |
--NP.db.healthBar.width, NP.db.healthBar.height |
Plate.Bar:SetSize(Plate.Bar:GetWidth()/_G['multiscreensupportsave']['screen'], Plate.Bar:GetHeight()/_G['multiscreensupportsave']['screen']) |
end |
end |
end |
function MultiScreenSupport:OnUpdate() |
local CurrentFrameNumber = WorldFrame:GetNumChildren() |
if (FrameNumber == CurrentFrameNumber) then |
return |
end |
for _, Object in pairs({WorldFrame:GetChildren()}) do |
local IsPlate = MultiScreenSupport.IsNamePlate(MultiScreenSupport, Object) |
if (not Object.IsMultiScreenSupport and IsPlate) then |
MultiScreenSupport:PlateTreatement(Object) |
end |
end |
FrameNumber = CurrentFrameNumber |
end |
function MultiScreenSupport:addParentAnchor(frameName) |
if _G[frameName] then |
MultiScreenSupport:setParentAnchor(_G[frameName]) |
end |
function MultiScreenSupport:initSettings() |
--[[MacroFrame_LoadUI() |
TalentFrame_LoadUI() |
GuildFrame_LoadUI() |
Garrison_LoadUI() |
GuildBankFrame_LoadUI() |
AuctionFrame_LoadUI() |
CollectionsJournal_LoadUI() |
BlackMarket_LoadUI() |
Calendar_LoadUI() |
EncounterJournal_LoadUI() |
LookingForGuildFrame_LoadUI() |
ItemAlteration_LoadUI() |
ItemUpgrade_LoadUI() |
ArchaeologyFrame_LoadUI() |
VoidStorage_LoadUI() |
BarberShopFrame_LoadUI() |
ItemSocketingFrame_LoadUI() |
TradeSkillFrame_LoadUI() |
InspectFrame_LoadUI() |
ClassTrainerFrame_LoadUI()]] |
--BattlefieldMinimap_LoadUI() --CAN'T be move correctly anyway |
local MSSVersion = GetAddOnMetadata("MultiScreenSupport", "Version"); |
if type(_G['multiscreensupportsave']) ~= "table" or not(_G['multiscreensupportsave']['MSSVersion']) or _G['multiscreensupportsave']['MSSVersion'] < '2.0' then |
["GuildBankFrame"] = true, |
["QuestLogPopupDetailFrame"] = true, |
["ClassTrainerFrame"] = true, |
["BuffFrame"] = true, |
["BankFrame"] = 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, |
}, |
specific = { |
["WorldMapScreenAnchor"] = true, |
local allActiveFramesOrder = {} |
local allFramesOrder = {} |
local j |
local Resolution = GetCVar("gxResolution") |
local Resolution = GetCVar("gxWindowedResolution") |
local ScreenHeight = tonumber(string.match(Resolution, "%d+x(%d+)")) |
local ScreenWidth = tonumber(string.match(Resolution, "(%d+)x+%d")) |
--Pixel Perfect scale |
SetCVar("uiScale", 768/ScreenHeight) |
if (ScreenWidth > 3840) or (UIParent:GetWidth() + 1 > ScreenWidth) then |
local width = ScreenWidth |
local height = ScreenHeight |
local width = eyefinity |
local height = ScreenHeight |
--TEST |
--width = 1280 |
--height = 720 |
MultiScreenSupport:initSettings() |
MultiScreenSupportParent = CreateFrame('Frame', 'MultiScreenSupportParent', UIParent) |
args = specificSetting |
} |
local config = { |
name = "MultiScreenSupport", |
handler = MultiScreenSupport, |
type = "group", |
args = { |
Description = { |
order = 0, |
name = "Nameplates hacking try to resize nameplates to match correct size. It only works out of combat. To help targeting the right nameplate when in combat a additional background is displayed to show you the current click-able area. This option does not work well with default nameplates.", |
fontSize = "medium", |
type = "description" |
}, |
NamePlates = {--NamePlates |
order = 2, |
name = "Enable Nameplates hacking", |
--desc = "Enable Nameplates hacking", |
type = "toggle", |
set = function(info,val) |
if not val then |
_G['multiscreensupportsave']['nameplates'] = -1 |
print("To disable nameplates hacking you should reload your UI") |
else |
_G['multiscreensupportsave']['nameplates'] = val |
end |
end, |
get = function(info) |
if not _G['multiscreensupportsave']['nameplates'] then |
_G['multiscreensupportsave']['nameplates'] = true |
end |
if _G['multiscreensupportsave']['nameplates'] == -1 then |
return false |
end |
return _G['multiscreensupportsave']['nameplates'] |
end |
}, |
Screens = {--Number of screens |
order = 3, |
name = "Number of screen", |
--desc = "Number of screen", |
type = "range", |
min = 2, |
max = 9, |
step = 1, |
bigStep = 1, |
set = function(info,val) |
_G['multiscreensupportsave']['screen'] = val |
end, |
get = function(info) |
if not _G['multiscreensupportsave']['screen'] then |
_G['multiscreensupportsave']['screen'] = 3 |
end |
return _G['multiscreensupportsave']['screen'] |
end, |
isPercent = false |
}, |
NamePlatesBG = {--NamePlates |
order = 4, |
name = "Enable Nameplates background", |
--desc = "Enable Nameplates background", |
type = "toggle", |
set = function(info,val) |
_G['multiscreensupportsave']['nameplatesbg'] = val |
if not val then |
_G['multiscreensupportsave']['nameplatesbg'] = -1 |
print("To disable nameplates background you should reload your UI") |
else |
_G['multiscreensupportsave']['nameplatesbg'] = val |
end |
end, |
get = function(info) |
if not _G['multiscreensupportsave']['nameplatesbg'] then |
_G['multiscreensupportsave']['nameplatesbg'] = true |
end |
if _G['multiscreensupportsave']['nameplatesbg'] == -1 then |
return false |
end |
return _G['multiscreensupportsave']['nameplatesbg'] |
end |
}, |
} |
} |
AceConfig:RegisterOptionsTable("MultiScreenSupport", config) |
AceConfig:RegisterOptionsTable("MultiScreenSupport_standart", standartconfig) |
AceConfig:RegisterOptionsTable("MultiScreenSupport_specific", specificconfig) |
local SetDefaultOpttion = AceConfigDialog:AddToBlizOptions("MultiScreenSupport","MultiScreenSupport ".._G['multiscreensupportsave']["MSSVersion"]) |
local SetDefaultOpttion = AceConfigDialog:AddToBlizOptions("MultiScreenSupport_standart","MultiScreenSupport ".._G['multiscreensupportsave']["MSSVersion"]) |
SetDefaultOpttion.default = function() _G['multiscreensupportsave'] = { standart = {}, specific = {} } end |
SetDefaultOpttion = AceConfigDialog:AddToBlizOptions("MultiScreenSupport_standart","MultiScreenSupport standard frame","MultiScreenSupport ".._G['multiscreensupportsave']["MSSVersion"]) |
SetDefaultOpttion = AceConfigDialog:AddToBlizOptions("MultiScreenSupport_specific","Specific frames","MultiScreenSupport ".._G['multiscreensupportsave']["MSSVersion"]) |
SetDefaultOpttion.default = function() _G['multiscreensupportsave'] = { standart = {}, specific = {} } end |
SetDefaultOpttion = AceConfigDialog:AddToBlizOptions("MultiScreenSupport_specific","MultiScreenSupport specific frame","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]) |
--to add specific addon frame like blizzard one. |
MultiScreenSupport:RegisterEvent("ADDON_LOADED") |
--NAMEPLATES Hacking |
if not _G['multiscreensupportsave']['screen'] then |
_G['multiscreensupportsave']['screen'] = 3 |
end |
if _G['multiscreensupportsave']['nameplatesbg'] ~= -1 or _G['multiscreensupportsave']['nameplates'] ~= -1 then |
local Plates = CreateFrame("Frame", nil, WorldFrame) |
Plates:SetScript("OnUpdate",function () MultiScreenSupport:OnUpdate() end) |
end |
end |
function MultiScreenSupport:ADDON_LOADED(event, addon) |
--[[local addons = { |
['Blizzard_MacroUI'] = true, |
} |
if addons[addon] then |
print(addon) |
end]] |
local allActiveFramesOrder = {} |
local allFramesOrder = {} |
local setting = {} |
-- end |
-- @class file |
-- @name AceAddon-3.0.lua |
-- @release $Id: AceAddon-3.0.lua 980 2010-10-27 14:20:11Z nevcairiel $ |
-- @release $Id: AceAddon-3.0.lua 1084 2013-04-27 20:14:11Z nevcairiel $ |
local MAJOR, MINOR = "AceAddon-3.0", 10 |
local MAJOR, MINOR = "AceAddon-3.0", 12 |
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR) |
if not AceAddon then return end -- No Upgrade needed. |
-- used in the addon metatable |
local function addontostring( self ) return self.name end |
-- Check if the addon is queued for initialization |
local function queuedForInitialization(addon) |
for i = 1, #AceAddon.initializequeue do |
if AceAddon.initializequeue[i] == addon then |
return true |
end |
end |
return false |
end |
--- Create a new AceAddon-3.0 addon. |
-- Any libraries you specified will be embeded, and the addon will be scheduled for |
-- its OnInitialize and OnEnable callbacks. |
-- MyModule:Enable() |
function Enable(self) |
self:SetEnabledState(true) |
return AceAddon:EnableAddon(self) |
-- nevcairiel 2013-04-27: don't enable an addon/module if its queued for init still |
-- it'll be enabled after the init process |
if not queuedForInitialization(self) then |
return AceAddon:EnableAddon(self) |
end |
end |
--- Disables the Addon, if possible, return true or false depending on success. |
-- Event Handling |
local function onEvent(this, event, arg1) |
if event == "ADDON_LOADED" or event == "PLAYER_LOGIN" then |
-- 2011-08-17 nevcairiel - ignore the load event of Blizzard_DebugTools, so a potential startup error isn't swallowed up |
if (event == "ADDON_LOADED" and arg1 ~= "Blizzard_DebugTools") or event == "PLAYER_LOGIN" then |
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration |
while(#AceAddon.initializequeue > 0) do |
local addon = tremove(AceAddon.initializequeue, 1) |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="CallbackHandler-1.0.lua"/> |
</Ui> |
--[[ $Id: CallbackHandler-1.0.lua 1131 2015-06-04 07:29:24Z nevcairiel $ ]] |
local MAJOR, MINOR = "CallbackHandler-1.0", 6 |
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR) |
if not CallbackHandler then return end -- No upgrade needed |
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end} |
-- Lua APIs |
local tconcat = table.concat |
local assert, error, loadstring = assert, error, loadstring |
local setmetatable, rawset, rawget = setmetatable, rawset, rawget |
local next, select, pairs, type, tostring = next, select, pairs, type, tostring |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: geterrorhandler |
local xpcall = xpcall |
local function errorhandler(err) |
return geterrorhandler()(err) |
end |
local function CreateDispatcher(argCount) |
local code = [[ |
local next, xpcall, eh = ... |
local method, ARGS |
local function call() method(ARGS) end |
local function dispatch(handlers, ...) |
local index |
index, method = next(handlers) |
if not method then return end |
local OLD_ARGS = ARGS |
ARGS = ... |
repeat |
xpcall(call, eh) |
index, method = next(handlers, index) |
until not method |
ARGS = OLD_ARGS |
end |
return dispatch |
]] |
local ARGS, OLD_ARGS = {}, {} |
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end |
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", ")) |
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler) |
end |
local Dispatchers = setmetatable({}, {__index=function(self, argCount) |
local dispatcher = CreateDispatcher(argCount) |
rawset(self, argCount, dispatcher) |
return dispatcher |
end}) |
-------------------------------------------------------------------------- |
-- CallbackHandler:New |
-- |
-- target - target object to embed public APIs in |
-- RegisterName - name of the callback registration API, default "RegisterCallback" |
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback" |
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API. |
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName) |
RegisterName = RegisterName or "RegisterCallback" |
UnregisterName = UnregisterName or "UnregisterCallback" |
if UnregisterAllName==nil then -- false is used to indicate "don't want this method" |
UnregisterAllName = "UnregisterAllCallbacks" |
end |
-- we declare all objects and exported APIs inside this closure to quickly gain access |
-- to e.g. function names, the "target" parameter, etc |
-- Create the registry object |
local events = setmetatable({}, meta) |
local registry = { recurse=0, events=events } |
-- registry:Fire() - fires the given event/message into the registry |
function registry:Fire(eventname, ...) |
if not rawget(events, eventname) or not next(events[eventname]) then return end |
local oldrecurse = registry.recurse |
registry.recurse = oldrecurse + 1 |
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...) |
registry.recurse = oldrecurse |
if registry.insertQueue and oldrecurse==0 then |
-- Something in one of our callbacks wanted to register more callbacks; they got queued |
for eventname,callbacks in pairs(registry.insertQueue) do |
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten. |
for self,func in pairs(callbacks) do |
events[eventname][self] = func |
-- fire OnUsed callback? |
if first and registry.OnUsed then |
registry.OnUsed(registry, target, eventname) |
first = nil |
end |
end |
end |
registry.insertQueue = nil |
end |
end |
-- Registration of a callback, handles: |
-- self["method"], leads to self["method"](self, ...) |
-- self with function ref, leads to functionref(...) |
-- "addonId" (instead of self) with function ref, leads to functionref(...) |
-- all with an optional arg, which, if present, gets passed as first argument (after self if present) |
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]]) |
if type(eventname) ~= "string" then |
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2) |
end |
method = method or eventname |
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten. |
if type(method) ~= "string" and type(method) ~= "function" then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2) |
end |
local regfunc |
if type(method) == "string" then |
-- self["method"] calling style |
if type(self) ~= "table" then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2) |
elseif self==target then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2) |
elseif type(self[method]) ~= "function" then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2) |
end |
if select("#",...)>=1 then -- this is not the same as testing for arg==nil! |
local arg=select(1,...) |
regfunc = function(...) self[method](self,arg,...) end |
else |
regfunc = function(...) self[method](self,...) end |
end |
else |
-- function ref with self=object or self="addonId" or self=thread |
if type(self)~="table" and type(self)~="string" and type(self)~="thread" then |
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2) |
end |
if select("#",...)>=1 then -- this is not the same as testing for arg==nil! |
local arg=select(1,...) |
regfunc = function(...) method(arg,...) end |
else |
regfunc = method |
end |
end |
if events[eventname][self] or registry.recurse<1 then |
-- if registry.recurse<1 then |
-- we're overwriting an existing entry, or not currently recursing. just set it. |
events[eventname][self] = regfunc |
-- fire OnUsed callback? |
if registry.OnUsed and first then |
registry.OnUsed(registry, target, eventname) |
end |
else |
-- we're currently processing a callback in this registry, so delay the registration of this new entry! |
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency |
registry.insertQueue = registry.insertQueue or setmetatable({},meta) |
registry.insertQueue[eventname][self] = regfunc |
end |
end |
-- Unregister a callback |
target[UnregisterName] = function(self, eventname) |
if not self or self==target then |
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2) |
end |
if type(eventname) ~= "string" then |
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2) |
end |
if rawget(events, eventname) and events[eventname][self] then |
events[eventname][self] = nil |
-- Fire OnUnused callback? |
if registry.OnUnused and not next(events[eventname]) then |
registry.OnUnused(registry, target, eventname) |
end |
end |
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then |
registry.insertQueue[eventname][self] = nil |
end |
end |
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds |
if UnregisterAllName then |
target[UnregisterAllName] = function(...) |
if select("#",...)<1 then |
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2) |
end |
if select("#",...)==1 and ...==target then |
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2) |
end |
for i=1,select("#",...) do |
local self = select(i,...) |
if registry.insertQueue then |
for eventname, callbacks in pairs(registry.insertQueue) do |
if callbacks[self] then |
callbacks[self] = nil |
end |
end |
end |
for eventname, callbacks in pairs(events) do |
if callbacks[self] then |
callbacks[self] = nil |
-- Fire OnUnused callback? |
if registry.OnUnused and not next(callbacks) then |
registry.OnUnused(registry, target, eventname) |
end |
end |
end |
end |
end |
end |
return registry |
end |
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it |
-- try to upgrade old implicit embeds since the system is selfcontained and |
-- relies on closures to work. |
..\FrameXML\UI.xsd"> |
<Script file="Libs\LibStub\LibStub.lua"/> |
<Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml"/> |
<Include file="Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/> |
<Include file="Libs\AceGUI-3.0\AceGUI-3.0.xml"/> |
<Include file="Libs\AceConfig-3.0\AceConfig-3.0.xml"/> |
<Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml"/> |