Files
MatchLiveTv/native/ios/MatchLiveTv/Streaming/Overlay/CompactScoreboardElement.swift
T
eminuxandCursor c3ef8e91a6 Rende usabili calendario, overlay ospite e stato diretta del cartellone.
Il calendario non deve più scorrere in orizzontale, il logo a destra non copre il nome e una diretta YouTube o in collegamento compare come In diretta.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 09:55:08 +02:00

115 lines
6.2 KiB
Swift

import UIKit
struct CompactScoreboardElement: OverlayElement {
func draw(in context: CGContext, state: OverlayState, layout: OverlayLayout) {
guard let compact = state.compactScoreboard else { return }
let kind = state.overlayKind
guard kind == .basket || kind == .timed || kind == .racket || kind == .volley else { return }
let scale = CGFloat(layout.canvasHeight) / 720
let pad = max(8, Int((10 * scale).rounded()))
let barW = max(3, Int((4 * scale).rounded()))
let logoSize = max(20, Int((28 * scale).rounded()))
let gap = max(4, Int((6 * scale).rounded()))
let totalW = max(320, Int((CGFloat(layout.canvasWidth) * 0.62).rounded()))
let mainH = max(56, Int((CGFloat(layout.canvasHeight) * 0.09).rounded()))
let metaH = max(16, Int((CGFloat(layout.canvasHeight) * 0.028).rounded()))
let totalH = mainH + metaH + pad
let left = CGFloat(layout.marginPx)
let top = CGFloat(layout.marginPx)
let rect = CGRect(x: left, y: top, width: CGFloat(totalW), height: CGFloat(totalH))
context.setFillColor(UIColor(white: 0.047, alpha: 0.82).cgColor)
context.addPath(UIBezierPath(roundedRect: rect, cornerRadius: 10 * scale).cgPath)
context.fillPath()
let centerX = rect.midX
let rowCenterY = top + CGFloat(pad) + CGFloat(mainH) * 0.58
let sideMaxW = CGFloat(totalW) * 0.34
let scoreZoneHalf = CGFloat(totalW) * 0.11
let labelSize = max(13, CGFloat(mainH) * 0.28)
let scoreSize = max(24, CGFloat(mainH) * 0.46)
let labelFont = UIFont.boldSystemFont(ofSize: labelSize)
let scoreFont = UIFont.boldSystemFont(ofSize: scoreSize)
drawTeamSide(context: context, compact: compact, isHome: true, rectLeft: rect.minX + CGFloat(pad), rectRight: centerX - scoreZoneHalf, centerY: rowCenterY, barW: barW, logoSize: logoSize, gap: gap, maxWidth: sideMaxW, labelFont: labelFont)
drawTeamSide(context: context, compact: compact, isHome: false, rectLeft: centerX + scoreZoneHalf, rectRight: rect.maxX - CGFloat(pad), centerY: rowCenterY, barW: barW, logoSize: logoSize, gap: gap, maxWidth: sideMaxW, labelFont: labelFont)
let scoreText = "\(compact.homeScore) - \(compact.awayScore)"
let scoreAttrs: [NSAttributedString.Key: Any] = [.font: scoreFont, .foregroundColor: UIColor.white]
let scoreNSString = scoreText as NSString
let scoreTextSize = scoreNSString.size(withAttributes: scoreAttrs)
scoreNSString.draw(at: CGPoint(x: centerX - scoreTextSize.width / 2, y: rowCenterY + scoreSize * 0.32 - scoreTextSize.height), withAttributes: scoreAttrs)
if let period = compact.periodLabel?.trimmingCharacters(in: .whitespacesAndNewlines), !period.isEmpty {
let metaSize = max(11, CGFloat(metaH) * 0.72)
let metaFont = UIFont.systemFont(ofSize: metaSize)
let metaAttrs: [NSAttributedString.Key: Any] = [.font: metaFont, .foregroundColor: UIColor(white: 0.67, alpha: 1)]
let metaNSString = period as NSString
let metaSize2 = metaNSString.size(withAttributes: metaAttrs)
metaNSString.draw(at: CGPoint(x: centerX - metaSize2.width / 2, y: rect.maxY - CGFloat(pad) * 0.45 - metaSize2.height), withAttributes: metaAttrs)
}
}
private func drawTeamSide(
context: CGContext,
compact: CompactScoreboardState,
isHome: Bool,
rectLeft: CGFloat,
rectRight: CGFloat,
centerY: CGFloat,
barW: Int,
logoSize: Int,
gap: Int,
maxWidth: CGFloat,
labelFont: UIFont
) {
let accent = isHome ? compact.homeAccentColor : compact.awayAccentColor
let logoUrl = isHome ? compact.homeLogoUrl : compact.awayLogoUrl
let logo = OverlayLogoCache.get(logoUrl)
let rawName = (isHome ? compact.homeTeamName : compact.awayTeamName)
.trimmingCharacters(in: .whitespacesAndNewlines)
let attrs: [NSAttributedString.Key: Any] = [.font: labelFont, .foregroundColor: UIColor.white]
let textY = centerY + labelFont.pointSize * 0.35 - labelFont.lineHeight
let barHalfH = CGFloat(logoSize) * 0.45
if isHome {
var x = rectLeft
context.setFillColor(accent.cgColor)
context.fill(CGRect(x: x, y: centerY - barHalfH, width: CGFloat(barW), height: CGFloat(logoSize) * 0.9))
x += CGFloat(barW + gap)
if let logo, let cg = logo.cgImage {
context.draw(cg, in: CGRect(x: x, y: centerY - CGFloat(logoSize) / 2, width: CGFloat(logoSize), height: CGFloat(logoSize)))
x += CGFloat(logoSize + gap)
}
let name = ellipsize(rawName, font: labelFont, maxWidth: min(rectRight - x, maxWidth))
(name as NSString).draw(at: CGPoint(x: x, y: textY), withAttributes: attrs)
} else {
// Specchio del lato casa: barra, logo, poi nome a sinistra del logo.
var x = rectRight
context.setFillColor(accent.cgColor)
context.fill(CGRect(x: x - CGFloat(barW), y: centerY - barHalfH, width: CGFloat(barW), height: CGFloat(logoSize) * 0.9))
x -= CGFloat(barW + gap)
if let logo, let cg = logo.cgImage {
x -= CGFloat(logoSize)
context.draw(cg, in: CGRect(x: x, y: centerY - CGFloat(logoSize) / 2, width: CGFloat(logoSize), height: CGFloat(logoSize)))
x -= CGFloat(gap)
}
let name = ellipsize(rawName, font: labelFont, maxWidth: min(x - rectLeft, maxWidth))
let nameSize = (name as NSString).size(withAttributes: attrs)
(name as NSString).draw(at: CGPoint(x: x - nameSize.width, y: textY), withAttributes: attrs)
}
}
private func ellipsize(_ text: String, font: UIFont, maxWidth: CGFloat) -> String {
let safeMax = max(48, maxWidth)
let attrs: [NSAttributedString.Key: Any] = [.font: font]
if (text as NSString).size(withAttributes: attrs).width <= safeMax { return text }
var result = text
while result.count > 1 && (result as NSString).size(withAttributes: attrs).width > safeMax {
result = String(result.dropLast())
}
return result + "…"
}
}