Skip to content
Open
11 changes: 11 additions & 0 deletions changelog/snippets/graphics.7105.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
- (#7105) Improve scoreboard legibility and internal text functions for mods/devs

#### UI

Improve scoreboard legibility with better alignment, tooltips, dropshadows, and text cropping.

#### Modding/development

added SetTruncationText() to assign custom trailing characters like "..." when text is cropped

split SetText() into **SetText()** and its implicitly called **SetDisplayText()**. This allows for fancier text implementations like custom truncation.
4 changes: 4 additions & 0 deletions loc/US/strings_db.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5951,6 +5951,10 @@ tooltipui0734="No Vote"
tooltipui0735="Vote no to your team recalling from battle as a defeat."
tooltipui0736="[Hide/Show] Mass Fabricator Panel"
tooltipui0737="[Hide/Show] Voting Panel"
tooltipui0738="Game Speed"
tooltipui0739="[your requested speed] / [actual game speed]"
tooltipui0740="Game Quality"
tooltipui0741="Estimated game quality"

-- External Factory and Auto-Deploy tooltips
tooltipui0750 = "Mobile Factory"
Expand Down
75 changes: 75 additions & 0 deletions lua/maui/text.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,38 @@ Text = ClassUI(moho.text_methods, Control) {
self._color.OnDirty = function(var)
self:SetNewColor(var())
end
self._truncationText = ""
self._fullText = nil


--- Direct Engine SetText() that changes what text is displayed
---@type function
---@param str string | number
self.SetDisplayText = self.SetText


--- FAF extensible SetText() that uses SetDisplayText() but can retain it's original text for fancy text display setups like truncation
---@param text string | number
self.SetText = function (self, text)
self.SetDisplayText(self,text)
self._fullText = text
if self._truncationText ~= nil and self._truncationText ~= "" then
if self._initialized then
self:_applyTruncation()
end
end
end

--- Direct Engine GetText() for getting the current displayed value
---@type function
---@return string
self.GetDisplayText = self.GetText

--- FAF extensible GetText() that retrieves raw original text that isn't modified for display
---@return string
self.GetText = function (self)
return self._fullText
end
end,

OnInit = function(self)
Expand All @@ -41,15 +73,58 @@ Text = ClassUI(moho.text_methods, Control) {
self:SetClipToWidth(false)
end,

--- Sets custom truncation trailing characters like "..." or "-". Set to "" to disable.
---@param text string | number
SetTruncationText = function (self, text)
self._truncationText = tostring(text)
if self._fullText ~= nil and self._initialized then
self:_applyTruncation()
end
end,

SetClipToWidth = function(self, clipToWidth)
if clipToWidth then
self.Width:Set(function() return self.Right() - self.Left() end)

self.Width.OnDirty = function()
if self._truncationText ~= nil and self._truncationText ~= "" then
self:_applyTruncation()
end
end
else
self.Width:Set(function() return math.floor(self.TextAdvance()) end)
self.Width.OnDirty = nil
end
self:SetNewClipToWidth(clipToWidth)
end,

--- Internal function to fit the truncation string inside the max width
_applyTruncation = function(self)
local maxWidth = self.Width()
if maxWidth <= 0 then
return
end

-- ellipsis is the trailing '...' on truncated text
local ellipsis = self._truncationText
local str = self._fullText
if str == nil then return end
-- restore full text if it now fits
if self:GetStringAdvance(str) <= maxWidth then
self.SetDisplayText(self, str)
return
end
Comment thread
coderabbitai[bot] marked this conversation as resolved.

--iterate until string + ellipsis fit
local i = STR_Utf8Len(str)
while i > 0 and self:GetStringAdvance(str .. ellipsis) > maxWidth do
str = STR_Utf8SubString(str, 1, i - 1)
i = i - 1
end

self.SetDisplayText(self, str .. ellipsis)
end,

-- lazy var support
SetFont = function(self, family, pointsize)
if self._font then
Expand Down
4 changes: 4 additions & 0 deletions lua/ui/game/layouts/score_mini.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ function SetLayout()
controls.timeIcon:SetTexture(UIUtil.UIFile('/game/unit_view_icons/time.dds'))
LayoutHelpers.RightOf(controls.time, controls.timeIcon)

LayoutHelpers.RightOf(controls.gameSpeed, controls.time, 4)

LayoutHelpers.AtLeftTopIn(controls.gameQuality, controls.bgTop, 138, 6)

LayoutHelpers.AtRightTopIn(controls.unitIcon, controls.bgTop, 10, 6)
controls.unitIcon:SetTexture(UIUtil.UIFile('/dialogs/score-overlay/tank_bmp.dds'))
LayoutHelpers.LeftOf(controls.units, controls.unitIcon)
Expand Down
65 changes: 55 additions & 10 deletions lua/ui/game/score.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,15 @@ function updatePlayerName(line)
end

if sessionInfo.Options.Divisions then
line.name:SetText(playerClan .. playerName .. playerDivision)
line.division:SetText(playerDivision)
else
line.name:SetText(playerClan .. playerName .. playerRating)
line.division:SetText(playerRating)
end

line.name:SetTruncationText("...")
line.name:SetText(playerClan .. playerName)
line.name:SetDropShadow(true)
LayoutHelpers.AnchorToLeft(line.name, line.division)
end

function armyGroupHeight()
Expand Down Expand Up @@ -118,14 +123,20 @@ function CreateScoreUI(parent)

LayoutHelpers.SetWidth(controls.bgTop, 320)

controls.time = UIUtil.CreateText(controls.bgTop, '0', 12, UIUtil.bodyFont)
controls.time = UIUtil.CreateText(controls.bgTop, '0', 12, UIUtil.bodyFont, true)
controls.time:SetColor('ff00dbff')
controls.timeIcon = Bitmap(controls.bgTop)
Tooltip.AddControlTooltip(controls.timeIcon, 'score_time')
Tooltip.AddControlTooltip(controls.time, 'score_time')
controls.gameSpeed = UIUtil.CreateText(controls.bgTop, '', 12, UIUtil.bodyFont, true)
controls.gameSpeed:SetColor('ffbadaff')
Tooltip.AddControlTooltip(controls.gameSpeed, 'score_game_speed')
controls.gameQuality = UIUtil.CreateText(controls.bgTop, '', 12, UIUtil.bodyFont, true)
controls.gameQuality:SetColor('ff00dbff')
Tooltip.AddControlTooltip(controls.gameQuality, 'score_game_quality')
controls.unitIcon = Bitmap(controls.bgTop)
Tooltip.AddControlTooltip(controls.unitIcon, 'score_units')
controls.units = UIUtil.CreateText(controls.bgTop, '0', 12, UIUtil.bodyFont)
controls.units = UIUtil.CreateText(controls.bgTop, '0', 12, UIUtil.bodyFont, true)
controls.units:SetColor('ffff9900')
Tooltip.AddControlTooltip(controls.units, 'score_units')

Expand Down Expand Up @@ -302,6 +313,12 @@ function SetupPlayerLines()
LayoutHelpers.AtVerticalCenterIn(group.name, group)
group.name:SetColor('ffffffff')

group.division = UIUtil.CreateText(group, '', 12, UIUtil.bodyFont, true)
group.division:DisableHitTest()
LayoutHelpers.AtRightIn(group.division, group, 135)
LayoutHelpers.AtVerticalCenterIn(group.division, group)
group.division:SetColor('ffffffff')

group.score = UIUtil.CreateText(group, '', 12, UIUtil.bodyFont)
group.score:DisableHitTest()
LayoutHelpers.AtRightIn(group.score, group, sw * 2 + 16)
Expand Down Expand Up @@ -372,6 +389,18 @@ function SetupPlayerLines()
Tooltip.AddControlTooltip(group.units, {text = '', body = bodyText}, 1)
end

-- hover to see full name (incase they are cut off)
group.nameHover = Bitmap(group)
group.nameHover:SetSolidColor('00000000') -- fully transparent
LayoutHelpers.AnchorToLeft(group.nameHover, group.division)
LayoutHelpers.AtLeftIn(group.nameHover, group, 12)
group.nameHover.Height:Set(group.name.Height)
LayoutHelpers.AtVerticalCenterIn(group.nameHover, group)
Tooltip.AddAutoUpdatedControlTooltip(group.nameHover,
function() return group.name:GetText() or "" end,
function() return "" end,
0.5)

group.Height:Set(group.faction.Height)
group.Width:Set(controls.armyGroup.Width)
group.armyID = armyIndex
Expand Down Expand Up @@ -416,6 +445,7 @@ function SetupPlayerLines()
observerLine:Hide()
observerLine.OnHide = blockOnHide
observerLine.name.Top:Set(observerLine.Top)
observerLine.name:SetDropShadow(true)
LayoutHelpers.SetHeight(observerLine, 15)

if SessionIsReplay() then
Expand Down Expand Up @@ -476,7 +506,7 @@ function SetupPlayerLines()
end

-- ui for share conditions
group.ShareConditions = UIUtil.CreateText(group, data.ShareConditionsTitle, 10, UIUtil.bodyFont)
group.ShareConditions = UIUtil.CreateText(group, data.ShareConditionsTitle, 10, UIUtil.bodyFont, true)
Tooltip.AddForcedControlTooltipManual(group.ShareConditions, data.ShareConditionsTitle, data.ShareConditionsDescription)
LayoutHelpers.AtLeftIn(group.ShareConditions, group)
LayoutHelpers.AtVerticalCenterIn(group.ShareConditions, group)
Expand All @@ -485,15 +515,15 @@ function SetupPlayerLines()
previous = AddDash()

-- ui for map size
group.Size = UIUtil.CreateText(group, data.SizeText, 10, UIUtil.bodyFont)
group.Size = UIUtil.CreateText(group, data.SizeText, 10, UIUtil.bodyFont, true)
LayoutHelpers.RightOf(group.Size, previous)
LayoutHelpers.AtVerticalCenterIn(group.Size, group)
group.Size:SetColor('ffffffff')
previous = group.Size
previous = AddDash()

-- ui for map name
group.MapName = UIUtil.CreateText(group, data.MapTitle, 10, UIUtil.bodyFont)
group.MapName = UIUtil.CreateText(group, data.MapTitle, 10, UIUtil.bodyFont, true)
Tooltip.AddForcedControlTooltipManual(group.MapName, data.MapTitle, data.MapDescription)
LayoutHelpers.RightOf(group.MapName, previous)
LayoutHelpers.AtVerticalCenterIn(group.MapName, group)
Expand Down Expand Up @@ -618,11 +648,17 @@ local prevPlayableWidth = sessionInfo.PlayableAreaWidth
local prevPlayableHeight = sessionInfo.PlayableAreaHeight

function _OnBeat()
local s = string.format("%s (%+d / %+d)", GetGameTime(), gameSpeed, GetSimRate())
local t = string.format("%s", GetGameTime())
controls.time:SetText(t)

local s = string.format("(%+d / %+d)",gameSpeed, GetSimRate())
controls.gameSpeed:SetText(s)

if sessionInfo.Options.Quality then
s = string.format("%s Q:%.2f%%", s, sessionInfo.Options.Quality)
local q = string.format("Q:%.2f%%", sessionInfo.Options.Quality)
controls.gameQuality:SetText(q)
end
Comment thread
coderabbitai[bot] marked this conversation as resolved.
controls.time:SetText(s)


if sessionInfo.Options.NoRushOption and sessionInfo.Options.NoRushOption ~= 'Off' then
local norush = tonumber(sessionInfo.Options.NoRushOption) * 60
Expand Down Expand Up @@ -717,26 +753,35 @@ function _OnBeat()
if line.armyID == prevArmy then
if line.OOG then
line.name:SetColor('ffa0a0a0')
line.division:SetColor('ffa0a0a0')
line.score:SetColor('ffa0a0a0')
else
line.name:SetColor('ffffffff')
line.division:SetColor('ffffffff')
line.score:SetColor('ffffffff')
end
line.name:SetFont(UIUtil.bodyFont, 12)
line.division:SetFont(UIUtil.bodyFont, 12)
line.score:SetFont(UIUtil.bodyFont, 12)
elseif line.armyID == curFA then
line.name:SetColor('ffff7f00')
line.division:SetColor('ffff7f00')
line.score:SetColor('ffff7f00')

line.name:SetFont('Arial Bold', 12)
line.division:SetFont('Arial Bold', 12)
line.score:SetFont('Arial Bold', 12)
end
end
if curFA < 1 then
observerLine.name:SetColor('ffff7f00')
observerLine.division:SetColor('ffff7f00')
observerLine.name:SetFont('Arial Bold', 12)
elseif prevArmy < 1 then
observerLine.name:SetColor('ffffffff')
observerLine.division:SetColor('ffffffff')
observerLine.name:SetFont(UIUtil.bodyFont, 12)
observerLine.division:SetFont(UIUtil.bodyFont, 12)
end
if observerLine:IsHidden() and ((curFA < 1) or (sessionInfo.Options.CheatsEnabled == 'true')) then
table.insert(controls.armyLines, table.getsize(controls.armyLines), observerLine)
Expand Down
8 changes: 8 additions & 0 deletions lua/ui/help/tooltips.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1808,6 +1808,14 @@ Tooltips = {
title = "<LOC tooltipui0473>Game Time",
description = "",
},
score_game_speed ={
title = "<LOC tooltipui0738>Game Speed",
description = "<LOC tooltipui0739>[your requested speed] / [actual game speed]",
},
score_game_quality = {
title = "<LOC tooltipui0740>Game Quality",
description = "<LOC tooltipui0741>Estimated game quality",
},
score_units = {
title = "<LOC tooltipui0474>Unit Count",
description = "<LOC tooltipui0507>Current and maximum unit counts",
Expand Down