Scale more gracefully based on text size

This commit is contained in:
Matt Wagner 2021-07-03 15:46:06 -07:00
parent 0cb888f021
commit f0427893f5
3 changed files with 97 additions and 74 deletions

View File

@ -153,7 +153,7 @@ function lotj.galaxyMap.recordPlanet(planetData)
lotj.galaxyMap.drawSystems() lotj.galaxyMap.drawSystems()
end end
local systemPointSize = 14 local systemPointSize = math.ceil(getFontSize()*1.1)
local function stylePoint(point, gov, currentSystem) local function stylePoint(point, gov, currentSystem)
local backgroundColor = lotj.galaxyMap.data.govToColor[gov] or "#AAAAAA" local backgroundColor = lotj.galaxyMap.data.govToColor[gov] or "#AAAAAA"
local borderStyle = "" local borderStyle = ""
@ -237,7 +237,7 @@ function lotj.galaxyMap.drawSystems()
local label = lotj.galaxyMap.systemLabels[system.name] local label = lotj.galaxyMap.systemLabels[system.name]
if label == nil then if label == nil then
label = Geyser.Label:new({ label = Geyser.Label:new({
height = 16, width = 100, height = math.ceil(getFontSize()*1.33), width = 100,
fillBg = 0, fillBg = 0,
}, container()) }, container())
@ -245,7 +245,7 @@ function lotj.galaxyMap.drawSystems()
else else
label:show() label:show()
end end
label:echo(systemDisplayName(system), "white", "12c") label:echo(systemDisplayName(system), "white", (getFontSize()-1).."c")
local sysX = math.floor(xOffset + (system.x-minX)*pxPerCoord - systemPointSize/2 + 0.5) local sysX = math.floor(xOffset + (system.x-minX)*pxPerCoord - systemPointSize/2 + 0.5)
local sysY = math.floor(yOffset + (maxY-system.y)*pxPerCoord - systemPointSize/2 + 0.5) local sysY = math.floor(yOffset + (maxY-system.y)*pxPerCoord - systemPointSize/2 + 0.5)

View File

@ -46,7 +46,7 @@ end
local function styleGaugeText(gauge, fontSize) local function styleGaugeText(gauge, fontSize)
gauge.text:setStyleSheet([[ gauge.text:setStyleSheet([[
padding-right: 10px; padding-right: ]]..(getFontSize()-2)..[[px;
]]) ]])
gauge:setAlignment("r") gauge:setAlignment("r")
gauge:setFontSize(fontSize) gauge:setFontSize(fontSize)
@ -88,7 +88,7 @@ function lotj.infoPanel.createBasicStats(container)
}, container) }, container)
healthGauge.front:setStyleSheet(gaugeFrontStyle("#f04141", "#ef2929", "#cc0000", "#a40000", "#cc0000")) healthGauge.front:setStyleSheet(gaugeFrontStyle("#f04141", "#ef2929", "#cc0000", "#a40000", "#cc0000"))
healthGauge.back:setStyleSheet(gaugeBackStyle("#3f1111", "#3f0707", "#330000", "#220000", "#330000")) healthGauge.back:setStyleSheet(gaugeBackStyle("#3f1111", "#3f0707", "#330000", "#220000", "#330000"))
styleGaugeText(healthGauge, 12) styleGaugeText(healthGauge, getFontSize()-1)
wireGaugeUpdate(healthGauge, "Char.Vitals.hp", "Char.Vitals.maxHp", "hp", "gmcp.Char.Vitals") wireGaugeUpdate(healthGauge, "Char.Vitals.hp", "Char.Vitals.maxHp", "hp", "gmcp.Char.Vitals")
local wimpyBar = Geyser.Label:new({ local wimpyBar = Geyser.Label:new({
@ -100,6 +100,8 @@ function lotj.infoPanel.createBasicStats(container)
]]) ]])
lotj.setup.registerEventHandler("gmcp.Char.Vitals", function() lotj.setup.registerEventHandler("gmcp.Char.Vitals", function()
if not gmcp.Char or not gmcp.Char.Vitals then return end
local health = gmcp.Char.Vitals.hp local health = gmcp.Char.Vitals.hp
local healthMax = gmcp.Char.Vitals.maxHp local healthMax = gmcp.Char.Vitals.maxHp
local wimpy = gmcp.Char.Vitals.wimpy local wimpy = gmcp.Char.Vitals.wimpy
@ -120,7 +122,7 @@ function lotj.infoPanel.createBasicStats(container)
}, container) }, container)
movementGauge.front:setStyleSheet(gaugeFrontStyle("#41f041", "#29ef29", "#00cc00", "#00a400", "#00cc00")) movementGauge.front:setStyleSheet(gaugeFrontStyle("#41f041", "#29ef29", "#00cc00", "#00a400", "#00cc00"))
movementGauge.back:setStyleSheet(gaugeBackStyle("#113f11", "#073f07", "#003300", "#002200", "#003300")) movementGauge.back:setStyleSheet(gaugeBackStyle("#113f11", "#073f07", "#003300", "#002200", "#003300"))
styleGaugeText(movementGauge, 12) styleGaugeText(movementGauge, getFontSize()-1)
wireGaugeUpdate(movementGauge, "Char.Vitals.move", "Char.Vitals.maxMove", "mv", "gmcp.Char.Vitals") wireGaugeUpdate(movementGauge, "Char.Vitals.move", "Char.Vitals.maxMove", "mv", "gmcp.Char.Vitals")
-- Mana gauge (will be hidden later if we do not have mana) -- Mana gauge (will be hidden later if we do not have mana)
@ -130,32 +132,43 @@ function lotj.infoPanel.createBasicStats(container)
}, container) }, container)
manaGauge.front:setStyleSheet(gaugeFrontStyle("#4141f0", "#2929ef", "#0000cc", "#0000a4", "#0000cc")) manaGauge.front:setStyleSheet(gaugeFrontStyle("#4141f0", "#2929ef", "#0000cc", "#0000a4", "#0000cc"))
manaGauge.back:setStyleSheet(gaugeBackStyle("#11113f", "#07073f", "#000033", "#000022", "#000011")) manaGauge.back:setStyleSheet(gaugeBackStyle("#11113f", "#07073f", "#000033", "#000022", "#000011"))
styleGaugeText(manaGauge, 12) styleGaugeText(manaGauge, getFontSize()-1)
wireGaugeUpdate(manaGauge, "Char.Vitals.mana", "Char.Vitals.maxMana", "mn", "gmcp.Char.Vitals") wireGaugeUpdate(manaGauge, "Char.Vitals.mana", "Char.Vitals.maxMana", "mn", "gmcp.Char.Vitals")
lotj.setup.registerEventHandler("gmcp.Char.Vitals", function() lotj.setup.registerEventHandler("gmcp.Char.Vitals", function()
local totalSpace = lotj.layout.lowerInfoPanelHeight
local manaMax = gmcp.Char.Vitals.maxMana or 0 local manaMax = gmcp.Char.Vitals.maxMana or 0
if manaMax > 0 then if manaMax > 0 then
healthGauge:move(nil, 4) local gaugeSpacing = math.floor(totalSpace/20)
healthGauge:resize(nil, 16) local gaugeHeight = math.ceil(lotj.layout.lowerInfoPanelHeight/5 * 1.33)
healthGauge:setFontSize("12") local allGaugesHeight = gaugeHeight*3+gaugeSpacing*2
local gaugesStart = math.floor((totalSpace - allGaugesHeight)/2)
healthGauge:move(nil, gaugesStart)
healthGauge:resize(nil, gaugeHeight)
healthGauge:setFontSize(getFontSize()-1)
movementGauge:move(nil, 23) movementGauge:move(nil, gaugesStart+gaugeHeight+gaugeSpacing)
movementGauge:resize(nil, 16) movementGauge:resize(nil, gaugeHeight)
movementGauge:setFontSize("12") movementGauge:setFontSize(getFontSize()-1)
manaGauge:show() manaGauge:show()
manaGauge:move(nil, 42) manaGauge:move(nil, gaugesStart+gaugeHeight*2+gaugeSpacing*2)
manaGauge:resize(nil, 16) manaGauge:resize(nil, gaugeHeight)
manaGauge:setFontSize("12") manaGauge:setFontSize(getFontSize()-1)
else else
healthGauge:move(nil, 6) local gaugeSpacing = math.floor(totalSpace/15)
healthGauge:resize(nil, 22) local gaugeHeight = math.ceil(lotj.layout.lowerInfoPanelHeight/5 * 1.66)
healthGauge:setFontSize("13") local allGaugesHeight = gaugeHeight*2+gaugeSpacing
local gaugesStart = math.floor((totalSpace - allGaugesHeight)/2)
healthGauge:move(nil, gaugesStart)
healthGauge:resize(nil, gaugeHeight)
healthGauge:setFontSize(getFontSize())
movementGauge:move(nil, 32) movementGauge:move(nil, gaugesStart+gaugeHeight+gaugeSpacing)
movementGauge:resize(nil, 22) movementGauge:resize(nil, gaugeHeight)
movementGauge:setFontSize("13") movementGauge:setFontSize(getFontSize())
manaGauge:hide() manaGauge:hide()
end end
@ -166,14 +179,14 @@ end
function lotj.infoPanel.createOpponentStats(container) function lotj.infoPanel.createOpponentStats(container)
-- Opponent health gauge -- Opponent health gauge
local opponentGauge = Geyser.Gauge:new({ local opponentGauge = Geyser.Gauge:new({
x="5%", y=6, x="5%", y="10%",
width="90%", height=48, width="90%", height="80%",
}, container) }, container)
opponentGauge.front:setStyleSheet(gaugeFrontStyle("#bd7833", "#bd6e20", "#994c00", "#703800", "#994c00")) opponentGauge.front:setStyleSheet(gaugeFrontStyle("#bd7833", "#bd6e20", "#994c00", "#703800", "#994c00"))
opponentGauge.back:setStyleSheet(gaugeBackStyle("#442511", "#441d08", "#331100", "#200900", "#331100")) opponentGauge.back:setStyleSheet(gaugeBackStyle("#442511", "#441d08", "#331100", "#200900", "#331100"))
opponentGauge.text:setStyleSheet("padding: 10px;") opponentGauge.text:setStyleSheet("padding: 10px;")
opponentGauge:setAlignment("c") opponentGauge:setAlignment("c")
opponentGauge:setFontSize("12") opponentGauge:setFontSize(getFontSize()-1)
local function update() local function update()
if not gmcp.Char.Enemy.name then if not gmcp.Char.Enemy.name then
@ -195,38 +208,33 @@ end
function lotj.infoPanel.createChatInfo(container) function lotj.infoPanel.createChatInfo(container)
-- Commnet channel/code -- Commnet channel/code
local commnetLabel = Geyser.Label:new({
x="3%", y=6,
width="20%", height=24,
}, container)
commnetLabel:echo("Comm:", nil, "rb13")
local commnetInfo = Geyser.Label:new({ local commnetInfo = Geyser.Label:new({
x = "25%", y = 6, x="3%", y="10%",
width = "75%", height = 24 width="94%", height="40%",
}, container) }, container)
local function updateCommnet() local function updateCommnet()
local commChannel = gmcp.Char.Chat.commChannel local commChannel = gmcp.Char.Chat.commChannel
local commEncrypt = gmcp.Char.Chat.commEncrypt local commEncrypt = gmcp.Char.Chat.commEncrypt
if not commChannel then if not commChannel then
commnetInfo:echo("None", nil, "l13") commnetInfo:echo("<b>Comm:</b> None", nil, "l"..getFontSize())
elseif commEncrypt then elseif commEncrypt then
commnetInfo:echo(commChannel.." (E "..commEncrypt..")", nil, "l13") commnetInfo:echo("<b>Comm:</b> "..commChannel.." (E "..commEncrypt..")", nil, "l"..getFontSize())
else else
commnetInfo:echo(commChannel, nil, "l13") commnetInfo:echo("<b>Comm:</b> "..commChannel, nil, "l"..getFontSize())
end end
end end
lotj.setup.registerEventHandler("gmcp.Char.Chat", updateCommnet) lotj.setup.registerEventHandler("gmcp.Char.Chat", updateCommnet)
-- OOC meter -- OOC meter
local oocLabel = Geyser.Label:new({ local oocLabel = Geyser.Label:new({
x="3%", y=32, x="3%", y="53%",
width="20%", height=24, width="27%", height="40%",
}, container) }, container)
oocLabel:echo("OOC:", nil, "rb13") oocLabel:echo("OOC:", nil, "rb"..getFontSize())
local oocGauge = Geyser.Gauge:new({ local oocGauge = Geyser.Gauge:new({
x="25%", y=32, x="33%", y="53%",
width="40%", height=20, width="40%", height="33%",
}, container) }, container)
oocGauge.front:setStyleSheet(gaugeFrontStyle("#31d0d0", "#22cfcf", "#00b2b2", "#009494", "#00b2b2")) oocGauge.front:setStyleSheet(gaugeFrontStyle("#31d0d0", "#22cfcf", "#00b2b2", "#009494", "#00b2b2"))
oocGauge.back:setStyleSheet(gaugeBackStyle("#113f3f", "#073f3f", "#003333", "#002222", "#001111")) oocGauge.back:setStyleSheet(gaugeBackStyle("#113f3f", "#073f3f", "#003333", "#002222", "#001111"))
@ -240,48 +248,54 @@ end
function lotj.infoPanel.createSpaceStats(container) function lotj.infoPanel.createSpaceStats(container)
local totalSpace = lotj.layout.lowerInfoPanelHeight
local gaugeSpacing = math.floor(totalSpace/15)
local gaugeHeight = math.ceil(lotj.layout.lowerInfoPanelHeight/5 * 1.33)
local allGaugesHeight = gaugeHeight*3+gaugeSpacing
local gaugesStart = math.floor((totalSpace - allGaugesHeight)/2)
local energyGauge = Geyser.Gauge:new({ local energyGauge = Geyser.Gauge:new({
x="3%", y=4, x="3%", y=gaugesStart,
width="30%", height=16, width="30%", height=gaugeHeight,
}, container) }, container)
energyGauge.front:setStyleSheet(gaugeFrontStyle("#7a7a7a", "#777777", "#656565", "#505050", "#656565")) energyGauge.front:setStyleSheet(gaugeFrontStyle("#7a7a7a", "#777777", "#656565", "#505050", "#656565"))
energyGauge.back:setStyleSheet(gaugeBackStyle("#383838", "#303030", "#222222", "#151515", "#222222")) energyGauge.back:setStyleSheet(gaugeBackStyle("#383838", "#303030", "#222222", "#151515", "#222222"))
styleGaugeText(energyGauge, 12) styleGaugeText(energyGauge, getFontSize()-1)
wireGaugeUpdate(energyGauge, "Ship.Info.energy", "Ship.Info.maxEnergy", "en", "gmcp.Ship.Info") wireGaugeUpdate(energyGauge, "Ship.Info.energy", "Ship.Info.maxEnergy", "en", "gmcp.Ship.Info")
local hullGauge = Geyser.Gauge:new({ local hullGauge = Geyser.Gauge:new({
x="3%", y=23, x="3%", y=gaugesStart+gaugeHeight+gaugeSpacing,
width="30%", height=16, width="30%", height=gaugeHeight,
}, container) }, container)
hullGauge.front:setStyleSheet(gaugeFrontStyle("#bd7833", "#bd6e20", "#994c00", "#703800", "#994c00")) hullGauge.front:setStyleSheet(gaugeFrontStyle("#bd7833", "#bd6e20", "#994c00", "#703800", "#994c00"))
hullGauge.back:setStyleSheet(gaugeBackStyle("#442511", "#441d08", "#331100", "#200900", "#331100")) hullGauge.back:setStyleSheet(gaugeBackStyle("#442511", "#441d08", "#331100", "#200900", "#331100"))
styleGaugeText(hullGauge, 12) styleGaugeText(hullGauge, getFontSize()-1)
wireGaugeUpdate(hullGauge, "Ship.Info.hull", "Ship.Info.maxHull", "hl", "gmcp.Ship.Info") wireGaugeUpdate(hullGauge, "Ship.Info.hull", "Ship.Info.maxHull", "hl", "gmcp.Ship.Info")
local shieldGauge = Geyser.Gauge:new({ local shieldGauge = Geyser.Gauge:new({
x="3%", y=42, x="3%", y=gaugesStart+gaugeHeight*2+gaugeSpacing*2,
width="30%", height=16, width="30%", height=gaugeHeight,
}, container) }, container)
shieldGauge.front:setStyleSheet(gaugeFrontStyle("#31d0d0", "#22cfcf", "#00b2b2", "#009494", "#00b2b2")) shieldGauge.front:setStyleSheet(gaugeFrontStyle("#31d0d0", "#22cfcf", "#00b2b2", "#009494", "#00b2b2"))
shieldGauge.back:setStyleSheet(gaugeBackStyle("#113f3f", "#073f3f", "#003333", "#002222", "#001111")) shieldGauge.back:setStyleSheet(gaugeBackStyle("#113f3f", "#073f3f", "#003333", "#002222", "#001111"))
styleGaugeText(shieldGauge, 12) styleGaugeText(shieldGauge, getFontSize()-1)
wireGaugeUpdate(shieldGauge, "Ship.Info.shield", "Ship.Info.maxShield", "sh", "gmcp.Ship.Info") wireGaugeUpdate(shieldGauge, "Ship.Info.shield", "Ship.Info.maxShield", "sh", "gmcp.Ship.Info")
-- Piloting indicator -- Piloting indicator
local pilotLabel = Geyser.Label:new({ local pilotLabel = Geyser.Label:new({
x="35%", y=6, x="35%", y="10%",
width="13%", height=24 width="13%", height="40%"
}, container) }, container)
pilotLabel:echo("Pilot:", nil, "lb12") pilotLabel:echo("Pilot: ", nil, "rb"..getFontSize())
local pilotBoxCont = Geyser.Label:new({ local pilotBoxCont = Geyser.Label:new({
x="48%", y=10, x="48%", y="16%",
width="8%", height=16 width="8%", height=gaugeHeight
}, container) }, container)
local pilotBox = Geyser.Label:new({ local pilotBox = Geyser.Label:new({
x=2, y=0, x=2, y=0,
width=16, height=16 width=gaugeHeight, height=gaugeHeight
}, pilotBoxCont) }, pilotBoxCont)
lotj.setup.registerEventHandler("gmcp.Ship.Info", function() lotj.setup.registerEventHandler("gmcp.Ship.Info", function()
@ -294,47 +308,47 @@ function lotj.infoPanel.createSpaceStats(container)
local speedGauge = Geyser.Label:new({ local speedGauge = Geyser.Label:new({
x="56%", y=6, x="56%", y="10%",
width="19%", height=24, width="19%", height="40%",
}, container) }, container)
local function updateSpeed() local function updateSpeed()
if not gmcp.Ship or not gmcp.Ship.Info or not gmcp.Ship.Info.maxSpeed then if not gmcp.Ship or not gmcp.Ship.Info or not gmcp.Ship.Info.maxSpeed then
speedGauge:echo("<b>Sp:</b> N/A", nil, "l12") speedGauge:echo("<b>Sp:</b> N/A", nil, "l"..getFontSize())
else else
local speed = gmcp.Ship.Info.speed or 0 local speed = gmcp.Ship.Info.speed or 0
local maxSpeed = gmcp.Ship.Info.maxSpeed or 0 local maxSpeed = gmcp.Ship.Info.maxSpeed or 0
speedGauge:echo("<b>Sp:</b> "..speed.."<b>/</b>"..maxSpeed, nil, "l12") speedGauge:echo("<b>Sp:</b> "..speed.."<b>/</b>"..maxSpeed, nil, "l"..getFontSize())
end end
end end
lotj.setup.registerEventHandler("gmcp.Ship.Info", updateSpeed) lotj.setup.registerEventHandler("gmcp.Ship.Info", updateSpeed)
local coordsInfo = Geyser.Label:new({ local coordsInfo = Geyser.Label:new({
x="35%", y=32, x="35%", y="53%",
width="40%", height=24, width="60%", height="40%",
}, container) }, container)
local function updateCoords() local function updateCoords()
if not gmcp.Ship or not gmcp.Ship.Info or not gmcp.Ship.Info.posX then if not gmcp.Ship or not gmcp.Ship.Info or not gmcp.Ship.Info.posX then
coordsInfo:echo("<b>Coords:</b> N/A", nil, "l12") coordsInfo:echo("<b>Coords:</b> N/A", nil, "l"..getFontSize())
else else
local shipX = gmcp.Ship.Info.posX or 0 local shipX = gmcp.Ship.Info.posX or 0
local shipY = gmcp.Ship.Info.posY or 0 local shipY = gmcp.Ship.Info.posY or 0
local shipZ = gmcp.Ship.Info.posZ or 0 local shipZ = gmcp.Ship.Info.posZ or 0
coordsInfo:echo("<b>Coords:</b> "..shipX.." "..shipY.." "..shipZ, nil, "l12") coordsInfo:echo("<b>Coords:</b> "..shipX.." "..shipY.." "..shipZ, nil, "l"..getFontSize())
end end
end end
lotj.setup.registerEventHandler("gmcp.Ship.Info", updateCoords) lotj.setup.registerEventHandler("gmcp.Ship.Info", updateCoords)
lotj.infoPanel.spaceTickCounter = Geyser.Label:new({ lotj.infoPanel.spaceTickCounter = Geyser.Label:new({
x="77%", y=6, x="77%", y="10%",
width="20%", height=24, width="15%", height="40%",
}, container) }, container)
lotj.infoPanel.chaffIndicator = Geyser.Label:new({ lotj.infoPanel.chaffIndicator = Geyser.Label:new({
x="77%", y=32, x="77%", y="53%",
width="20%", height=24, width="15%", height="40%",
}, container) }, container)
lotj.infoPanel.chaffIndicator:echo("[Chaff]", "yellow", "c13b") lotj.infoPanel.chaffIndicator:echo("[Chaff]", "yellow", "c13b")
lotj.infoPanel.chaffIndicator:hide() lotj.infoPanel.chaffIndicator:hide()

View File

@ -24,13 +24,14 @@ local function createTabbedPanel(tabData, container, tabList)
tabData.tabs = {} tabData.tabs = {}
tabData.contents = {} tabData.contents = {}
local tabContainerHeight = getFontSize()*2+4
local tabContainer = Geyser.HBox:new({ local tabContainer = Geyser.HBox:new({
x = "2%", y = 0, x = "2%", y = 0,
width = "96%", height = 30, width = "96%", height = tabContainerHeight,
}, container) }, container)
local contentsContainer = Geyser.Label:new({ local contentsContainer = Geyser.Label:new({
x = 0, y = 30, x = 0, y = tabContainerHeight,
width = "100%", width = "100%",
}, container) }, container)
@ -39,13 +40,20 @@ local function createTabbedPanel(tabData, container, tabList)
lotj.layout.resizeTabContents(container, tabContainer, contentsContainer) lotj.layout.resizeTabContents(container, tabContainer, contentsContainer)
end) end)
local totalSpace = 0
for _, tabInfo in ipairs(tabList) do
totalSpace = totalSpace + #tabInfo.label + 4 -- Account for 2 characters on either side as padding
end
for _, tabInfo in ipairs(tabList) do for _, tabInfo in ipairs(tabList) do
local keyword = tabInfo.keyword local keyword = tabInfo.keyword
local label = tabInfo.label local label = tabInfo.label
tabData.tabs[keyword] = Geyser.Label:new({}, tabContainer) tabData.tabs[keyword] = Geyser.Label:new({
h_stretch_factor = (#tabInfo.label + 4) / totalSpace,
}, tabContainer)
tabData.tabs[keyword]:setClickCallback("lotj.layout.selectTab", tabData, keyword) tabData.tabs[keyword]:setClickCallback("lotj.layout.selectTab", tabData, keyword)
tabData.tabs[keyword]:setFontSize(12) tabData.tabs[keyword]:setFontSize(getFontSize())
tabData.tabs[keyword]:echo("<center>"..label) tabData.tabs[keyword]:echo("<center>"..label)
tabData.contents[keyword] = Geyser.Label:new({ tabData.contents[keyword] = Geyser.Label:new({
@ -136,12 +144,13 @@ function lotj.layout.setup()
-- Lower info panel, for prompt hp/move gauges and other basic status -- Lower info panel, for prompt hp/move gauges and other basic status
lotj.layout.lowerInfoPanelHeight = getFontSize()*5
lotj.layout.lowerInfoPanel = Geyser.HBox:new({ lotj.layout.lowerInfoPanel = Geyser.HBox:new({
x = 0, y = -60, x = 0, y = -lotj.layout.lowerInfoPanelHeight,
width = (100-rightPanelWidthPct).."%", width = (100-rightPanelWidthPct).."%",
height = 60, height = lotj.layout.lowerInfoPanelHeight,
}) })
setBorderBottom(60) setBorderBottom(lotj.layout.lowerInfoPanelHeight)
end end
function lotj.layout.teardown() function lotj.layout.teardown()