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>
115 lines
6.2 KiB
Swift
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 + "…"
|
|
}
|
|
}
|