You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
10 KiB

local _,rematch = ...
local L = rematch.localization
local C = rematch.constants
local settings = rematch.settings
rematch.layout = {}
local allLayouts = {} -- contains all registered layouts, indexed by their layoutName ("1-pets", "2-teams-target", etc.)
local knownPanels = {} -- lookup table of all encountered panels; keyed by panel's frame reference
local defaultLayouts = {} -- indexed by mode, the first layout registered is the default layout for the mode
--[[
definitions.lua has more information on layout definitions
For referencing a layout, there's four constants that should always be used as a reference:
C.CURRENT -- the current layout regardless of standalone vs journal or minimized state
C.STANDALONE -- the last standalone layout used (can be minimized or maximized)
C.MAXIMIZED -- the last maximized standalone layout used (never minimized)
C.JOURNAL -- the last journal layout used (never minimized)
The following return information about one of the four layouts above:
rematch.layout:GetLayout(C.CURRENT) -- returns the name of the layout used for one of the four layouts above (*)
rematch.layout:GetLayout(layoutName) -- returns the layoutName if valid and adjusts it to suit the current mode if not
rematch.layout:GetDefinition(C.CURRENT) -- returns the full layout definition in table form
rematch.layout:GetMode(C.CURRENT) -- returns the mode (0=minimized, 1=single panel, 2=dual panel, 3=triple panel)
rematch.layout:GetView(C.CURRENT) -- returns the view ("pets", "teams", "queue", "options")
(*) GetLayout(layoutName) can also be used to validate the layoutName and return an adjusted name if it's not valid
The following can be used to alter the layout:
rematch.layout:ChangeMode(mode) -- changes the mode of the current layout to the given mode and calls a Configure
rematch.layout:ChangeView(view) -- changes the view of the current layout to the given view and calls a Configure
]]
-- on login, set up layout definitions
rematch.events:Register(rematch.layout,"PLAYER_LOGIN",function(self)
-- register the layouts defined in definitions.lua
for _,layout in ipairs(rematch.layout.definitions) do
rematch.layout:Register(layout)
end
-- done with definitions, safe to delete
rematch.layout.definitions = nil
end)
-- registers a layout in allLayouts and returns the layout's name
function rematch.layout:Register(layout)
-- asserting the layout is defined properly
assert(type(layout)=="table","Layout format: {mode=[number], view=[string], panels=[table]}")
assert(layout.mode and layout.mode>=0 and layout.mode<=3,"A layout mode must be 0-3.")
assert(type(layout.view)=="string","A layout must have a named view, like 'pets'.")
assert(type(layout.width)=="number" and type(layout.height)=="number","A layout must have a width and height.")
assert(type(layout.panels)=="table" and #layout.panels>0,"A layout must have at least one panel defined.")
-- build a name for the layout, this will be used as a reference for this layout
local layoutName = layout.mode.."-"..layout.view..(layout.subview and "-"..layout.subview or "")
-- some more assertions that panels are defined properly
for _,info in ipairs(layout.panels) do
for i=1,11 do
assert(info[i] and true,"Layout panel format: {parentKey, anchorPoint1, relativeTo1, relativePoint1, xoff1, yoff1, anchorPoint2, relativeTo2, relativePoint2, xoff2, yoff2}")
end
assert(info[1] and rematch.frame[info[1]],"Layout panel nil parentKey in "..layoutName)
assert(info[3] and rematch.frame[info[3]],"Layout panel nil relativeTo1 in "..layoutName)
assert(info[8] and rematch.frame[info[8]],"Layout panel nil relativeTo2 in "..layoutName)
end
-- add the layout to allLayouts (making a copy instead of referencing original)
allLayouts[layoutName] = CopyTable(layout)
allLayouts[layoutName].layoutName = layoutName
-- create a lookup table for panels used in this layout
allLayouts[layoutName].panelsUsed = {}
-- add its panels to knownPanels
for _,info in ipairs(layout.panels) do
knownPanels[rematch.frame[info[1]]] = true
allLayouts[layoutName].panelsUsed[rematch.frame[info[1]]] = true
end
-- register the layout to its tab (if any)
rematch.panelTabs:Register(layoutName)
-- if this is first time seeing this mode, set this layout as the default (in case moving to a mode where
-- a view doesnt exist, such as moving from 2-pets to 3-pets (doesn't exist) will move to 3-teams
if not defaultLayouts[layout.mode] then
defaultLayouts[layout.mode] = layoutName
end
return layoutName
end
-- returns the name of the CURRENT, STANDALONE, MAXIMIZED or JOURNAL layout; or validates the name of the given
-- layout. if the layout doesn't exist for the layout's mode, it will return the default layout that does exist
-- (for example going from 1-pets to 3-pets for the journal will switch to 3-teams since 3-pets doesn't exist.)
function rematch.layout:GetLayout(layout)
local layoutName = layout -- can be one of the CURRENT/STANDALONE/JOURNAL constants or a layout name
if not layout or layout==C.CURRENT then
layoutName = settings.CurrentLayout
elseif layout==C.STANDALONE then
layoutName = settings.StandaloneLayout
elseif layout==C.MAXIMIZED then
layoutName = settings.MaximizedLayout
elseif layout==C.JOURNAL then
layoutName = settings.JournalLayout
-- if in journal mode and somehow ended up with a non-3 layout, revert back
if not layoutName or (layoutName and layoutName:sub(1,1)~="3") then
layoutName = C.DEFAULT_JOURNAL_LAYOUT
end
else
layoutName = layout
end
-- verifies the layout exists before returning it
if type(layoutName)=="string" then
if allLayouts[layoutName] then -- if given layout was a named layout that exists, return same layout name
return layoutName
else -- layout name doesn't exist, see if it has a mode to grab the mode's default layout
local mode = tonumber(layoutName:sub(1,1))
if mode then
return defaultLayouts[mode]
end
end
end
-- if reached here, no layout or an invalid layout was given
assert(false,"Layout "..(layoutName or "nil").." doesn't exist.")
end
-- returns the definition for the CURRENT, STANDALONE, MAXIMIZED, JOURNAL or named layout
function rematch.layout:GetDefinition(layout)
return allLayouts[rematch.layout:GetLayout(layout)]
end
-- returns the mode for the CURRENT, STANDALONE, MAXIMIZED, JOURNAL or named layout
function rematch.layout:GetMode(layout)
return rematch.layout:GetDefinition(layout).mode
end
-- returns the view for the CURRENT, STANDALONE, MAXIMIZED, JOURNAL or named layout
function rematch.layout:GetView(layout)
return rematch.layout:GetDefinition(layout).view
end
-- returns the subview for the CURRENT, STANDALONE, MAXIMIZED, JOURNAL or named layout
function rematch.layout:GetSubview(layout)
return rematch.layout:GetDefinition(layout).subview
end
-- changes the current mode to a different mode with the same view (changes view if view doesn't exist in the mode)
-- returns true if already in the mode or successfully changed into it
function rematch.layout:ChangeMode(mode)
local def = rematch.layout:GetDefinition(C.CURRENT)
-- if already in the intended mode, just leave
if def.mode==mode then
return true
end
-- if view and mode exists then apply
if def.view and mode then
rematch.frame:Configure(rematch.layout:GetLayout(mode.."-"..def.view))
end
end
-- changes the current layout to a different view of the same mode
function rematch.layout:ChangeView(view)
local def = rematch.layout:GetDefinition(C.CURRENT)
-- if already in intended view, just leave
if def.view==view then
return
end
-- if mode and view exist then apply
if def.mode and view then
rematch.frame:Configure(rematch.layout:GetLayout(def.mode.."-"..view))
end
end
-- intended to turn a subview on and off of the current layout; subview is nil to turn it off
function rematch.layout:ChangeSubview(subview)
local def = rematch.layout:GetDefinition(C.CURRENT)
if def.subview==subview then
return
end
if not subview then
rematch.frame:Configure(rematch.layout:GetLayout(def.mode.."-"..def.view))
else
rematch.frame:Configure(rematch.layout:GetLayout(def.mode.."-"..def.view.."-"..subview))
end
end
-- hides all panels that don't belong to the given definition
function rematch.layout:HidePanels(def)
for panel in pairs(knownPanels) do
if not def.panelsUsed[panel] then
panel:Hide()
end
end
end
-- a more forceful version of ChangeView, it summons the Rematch window (in preferred mode if not already up) and
-- goes to the given view, one of: "pets", "teams", "targets", "queue" or "options".
-- for any new panels created, this would use the ___Panel name. eg otherPanel would be OpenView("other")
function rematch.layout:SummonView(view)
-- summon window if it's not already visible
if not rematch.frame:IsVisible() then
if settings.LastOpenJournal then
ToggleCollectionsJournal(COLLECTIONS_JOURNAL_TAB_INDEX_PETS)
else
rematch.frame:Toggle()
end
end
-- append Panel to the view to tell if it's already visible (eg petsPanel)
local panel = view.."Panel"
-- only go to the view if the panel isn't visible
if rematch[panel] and not rematch[panel]:IsVisible() then
if rematch.layout:GetMode()==0 then -- in minimized mode, switch to a maximized mode with the view
local mode = rematch.layout:GetMode(C.MAXIMIZED)
rematch.frame:Configure(mode.."-"..view)
else -- not minimized, simpler switch to the view
rematch.layout:ChangeView(view)
end
end
end