961 lines · 41.3 KB · Swift
RawDownload
import AppKitimport CodexBarCore enum IconRenderer {    private static let creditsCap: Double = 1000    private static let baseSize = NSSize(width: 18, height: 18)    // Render to an 18×18 pt template (36×36 px at 2×) to match the system menu bar size.    private static let outputSize = NSSize(width: 18, height: 18)    private static let outputScale: CGFloat = 2    private static let canvasPx = Int(outputSize.width * outputScale)     private struct PixelGrid: Sendable {        let scale: CGFloat         func pt(_ px: Int) -> CGFloat {            CGFloat(px) / self.scale        }         func rect(x: Int, y: Int, w: Int, h: Int) -> CGRect {            CGRect(x: self.pt(x), y: self.pt(y), width: self.pt(w), height: self.pt(h))        }         func snapDelta(_ value: CGFloat) -> CGFloat {            (value * self.scale).rounded() / self.scale        }    }     private static let grid = PixelGrid(scale: outputScale)     private struct IconCacheKey: Hashable {        let primary: Int        let weekly: Int        let credits: Int        let stale: Bool        let style: Int        let indicator: Int    }     private final class IconCacheStore: @unchecked Sendable {        private var cache: [IconCacheKey: NSImage] = [:]        private var order: [IconCacheKey] = []        private let lock = NSLock()         func cachedIcon(for key: IconCacheKey) -> NSImage? {            self.lock.lock()            defer { self.lock.unlock() }            guard let image = self.cache[key] else { return nil }            if let idx = self.order.firstIndex(of: key) {                self.order.remove(at: idx)                self.order.append(key)            }            return image        }         func storeIcon(_ image: NSImage, for key: IconCacheKey, limit: Int) {            self.lock.lock()            defer { self.lock.unlock() }            self.cache[key] = image            self.order.removeAll { $0 == key }            self.order.append(key)            while self.order.count > limit {                let oldest = self.order.removeFirst()                self.cache.removeValue(forKey: oldest)            }        }    }     private static let iconCacheStore = IconCacheStore()    private static let iconCacheLimit = 64    private static let morphBucketCount = 200    private static let morphCache = MorphCache(limit: 512)     private final class MorphCache: @unchecked Sendable {        private let cache = NSCache<NSNumber, NSImage>()         init(limit: Int) {            self.cache.countLimit = limit        }         func image(for key: NSNumber) -> NSImage? {            self.cache.object(forKey: key)        }         func set(_ image: NSImage, for key: NSNumber) {            self.cache.setObject(image, forKey: key)        }    }     private struct RectPx: Hashable, Sendable {        let x: Int        let y: Int        let w: Int        let h: Int         var midXPx: Int { self.x + self.w / 2 }        var midYPx: Int { self.y + self.h / 2 }         func rect() -> CGRect {            Self.grid.rect(x: self.x, y: self.y, w: self.w, h: self.h)        }         private static let grid = IconRenderer.grid    }     // swiftlint:disable function_body_length    static func makeIcon(        primaryRemaining: Double?,        weeklyRemaining: Double?,        creditsRemaining: Double?,        stale: Bool,        style: IconStyle,        blink: CGFloat = 0,        wiggle: CGFloat = 0,        tilt: CGFloat = 0,        statusIndicator: ProviderStatusIndicator = .none) -> NSImage    {        let shouldCache = blink <= 0.0001 && wiggle <= 0.0001 && tilt <= 0.0001        let render = {            self.renderImage {                // Keep monochrome template icons; Claude uses subtle shape cues only.                let baseFill = NSColor.labelColor                let trackFillAlpha: CGFloat = stale ? 0.18 : 0.28                let trackStrokeAlpha: CGFloat = stale ? 0.28 : 0.44                let fillColor = baseFill.withAlphaComponent(stale ? 0.55 : 1.0)                 let barWidthPx = 30 // 15 pt at 2×, uses the slot better without touching edges.                let barXPx = (Self.canvasPx - barWidthPx) / 2                 func drawBar(                    rectPx: RectPx,                    remaining: Double?,                    alpha: CGFloat = 1.0,                    addNotches: Bool = false,                    addFace: Bool = false,                    addGeminiTwist: Bool = false,                    addAntigravityTwist: Bool = false,                    addFactoryTwist: Bool = false,                    blink: CGFloat = 0)                {                    let rect = rectPx.rect()                    // Claude reads better as a blockier critter; Codex stays as a capsule.                    let cornerRadiusPx = addNotches ? 0 : rectPx.h / 2                    let radius = Self.grid.pt(cornerRadiusPx)                     let trackPath = NSBezierPath(roundedRect: rect, xRadius: radius, yRadius: radius)                    baseFill.withAlphaComponent(trackFillAlpha * alpha).setFill()                    trackPath.fill()                     // Crisp outline: stroke an inset path so the stroke stays within pixel bounds.                    let strokeWidthPx = 2 // 1 pt == 2 px at 2×                    let insetPx = strokeWidthPx / 2                    let strokeRect = Self.grid.rect(                        x: rectPx.x + insetPx,                        y: rectPx.y + insetPx,                        w: max(0, rectPx.w - insetPx * 2),                        h: max(0, rectPx.h - insetPx * 2))                    let strokePath = NSBezierPath(                        roundedRect: strokeRect,                        xRadius: Self.grid.pt(max(0, cornerRadiusPx - insetPx)),                        yRadius: Self.grid.pt(max(0, cornerRadiusPx - insetPx)))                    strokePath.lineWidth = CGFloat(strokeWidthPx) / Self.outputScale                    baseFill.withAlphaComponent(trackStrokeAlpha * alpha).setStroke()                    strokePath.stroke()                     // Fill: clip to the capsule and paint a left-to-right rect so the progress edge is straight.                    if let remaining {                        let clamped = max(0, min(remaining / 100, 1))                        let fillWidthPx = max(0, min(rectPx.w, Int((CGFloat(rectPx.w) * CGFloat(clamped)).rounded())))                        if fillWidthPx > 0 {                            NSGraphicsContext.current?.cgContext.saveGState()                            trackPath.addClip()                            fillColor.withAlphaComponent(alpha).setFill()                            NSBezierPath(                                rect: Self.grid.rect(                                    x: rectPx.x,                                    y: rectPx.y,                                    w: fillWidthPx,                                    h: rectPx.h)).fill()                            NSGraphicsContext.current?.cgContext.restoreGState()                        }                    }                     // Codex face: eye cutouts plus faint eyelids to give the prompt some personality.                    if addFace {                        let ctx = NSGraphicsContext.current?.cgContext                        let eyeSizePx = 4                        let eyeOffsetPx = 7                        let eyeCenterYPx = rectPx.y + rectPx.h / 2                        let centerXPx = rectPx.midXPx                         ctx?.saveGState()                        ctx?.setShouldAntialias(false)                        ctx?.clear(Self.grid.rect(                            x: centerXPx - eyeOffsetPx - eyeSizePx / 2,                            y: eyeCenterYPx - eyeSizePx / 2,                            w: eyeSizePx,                            h: eyeSizePx))                        ctx?.clear(Self.grid.rect(                            x: centerXPx + eyeOffsetPx - eyeSizePx / 2,                            y: eyeCenterYPx - eyeSizePx / 2,                            w: eyeSizePx,                            h: eyeSizePx))                        ctx?.restoreGState()                         // Blink: refill eyes from the top down using the bar fill color.                        if blink > 0.001 {                            let clamped = max(0, min(blink, 1))                            let blinkHeightPx = Int((CGFloat(eyeSizePx) * clamped).rounded())                            fillColor.withAlphaComponent(alpha).setFill()                            let blinkRectLeft = Self.grid.rect(                                x: centerXPx - eyeOffsetPx - eyeSizePx / 2,                                y: eyeCenterYPx + eyeSizePx / 2 - blinkHeightPx,                                w: eyeSizePx,                                h: blinkHeightPx)                            let blinkRectRight = Self.grid.rect(                                x: centerXPx + eyeOffsetPx - eyeSizePx / 2,                                y: eyeCenterYPx + eyeSizePx / 2 - blinkHeightPx,                                w: eyeSizePx,                                h: blinkHeightPx)                            NSBezierPath(rect: blinkRectLeft).fill()                            NSBezierPath(rect: blinkRectRight).fill()                        }                         // Hat: a tiny cap hovering above the eyes to give the face more character.                        let hatWidthPx = 18                        let hatHeightPx = 4                        let hatRect = Self.grid.rect(                            x: centerXPx - hatWidthPx / 2,                            y: rectPx.y + rectPx.h - hatHeightPx,                            w: hatWidthPx,                            h: hatHeightPx)                        ctx?.saveGState()                        if abs(tilt) > 0.0001 {                            // Tilt only the hat; keep eyes pixel-crisp and axis-aligned.                            let faceCenter = CGPoint(x: Self.grid.pt(centerXPx), y: Self.grid.pt(eyeCenterYPx))                            ctx?.translateBy(x: faceCenter.x, y: faceCenter.y)                            ctx?.rotate(by: tilt)                            ctx?.translateBy(x: -faceCenter.x, y: -faceCenter.y - abs(tilt) * 1.2)                        }                        fillColor.withAlphaComponent(alpha).setFill()                        NSBezierPath(rect: hatRect).fill()                        ctx?.restoreGState()                    }                     // Claude twist: blocky crab-style critter (arms + legs + vertical eyes).                    if addNotches {                        let ctx = NSGraphicsContext.current?.cgContext                        let wiggleOffset = Self.grid.snapDelta(wiggle * 0.6)                        let wigglePx = Int((wiggleOffset * Self.outputScale).rounded())                         fillColor.withAlphaComponent(alpha).setFill()                         // Arms/claws: mid-height side protrusions.                        // Keep within the 18×18pt canvas: barX is 3px, so 3px arms reach the edge without clipping.                        let armWidthPx = 3                        let armHeightPx = max(0, rectPx.h - 6)                        let armYPx = rectPx.y + 3 + wigglePx / 6                        let leftArm = Self.grid.rect(                            x: rectPx.x - armWidthPx,                            y: armYPx,                            w: armWidthPx,                            h: armHeightPx)                        let rightArm = Self.grid.rect(                            x: rectPx.x + rectPx.w,                            y: armYPx,                            w: armWidthPx,                            h: armHeightPx)                        NSBezierPath(rect: leftArm).fill()                        NSBezierPath(rect: rightArm).fill()                         // Legs: 4 little pixels underneath, like a tiny crab.                        let legCount = 4                        let legWidthPx = 2                        let legHeightPx = 3                        let legYPx = rectPx.y - legHeightPx + wigglePx / 6                        let stepPx = max(1, rectPx.w / (legCount + 1))                        for idx in 0..<legCount {                            let cx = rectPx.x + stepPx * (idx + 1)                            let leg = Self.grid.rect(                                x: cx - legWidthPx / 2,                                y: legYPx,                                w: legWidthPx,                                h: legHeightPx)                            NSBezierPath(rect: leg).fill()                        }                         // Eyes: tall vertical cutouts near the top.                        let eyeWidthPx = 2                        let eyeHeightPx = 5                        let eyeOffsetPx = 6                        let eyeYPx = rectPx.y + rectPx.h - eyeHeightPx - 2 + wigglePx / 8                        ctx?.saveGState()                        ctx?.setShouldAntialias(false)                        ctx?.clear(Self.grid.rect(                            x: rectPx.midXPx - eyeOffsetPx - eyeWidthPx / 2,                            y: eyeYPx,                            w: eyeWidthPx,                            h: eyeHeightPx))                        ctx?.clear(Self.grid.rect(                            x: rectPx.midXPx + eyeOffsetPx - eyeWidthPx / 2,                            y: eyeYPx,                            w: eyeWidthPx,                            h: eyeHeightPx))                        ctx?.restoreGState()                         // Blink: fill the eyes from the top down (blocky).                        if blink > 0.001 {                            let clamped = max(0, min(blink, 1))                            let blinkHeightPx = Int((CGFloat(eyeHeightPx) * clamped).rounded())                            fillColor.withAlphaComponent(alpha).setFill()                            let leftBlink = Self.grid.rect(                                x: rectPx.midXPx - eyeOffsetPx - eyeWidthPx / 2,                                y: eyeYPx + eyeHeightPx - blinkHeightPx,                                w: eyeWidthPx,                                h: blinkHeightPx)                            let rightBlink = Self.grid.rect(                                x: rectPx.midXPx + eyeOffsetPx - eyeWidthPx / 2,                                y: eyeYPx + eyeHeightPx - blinkHeightPx,                                w: eyeWidthPx,                                h: blinkHeightPx)                            NSBezierPath(rect: leftBlink).fill()                            NSBezierPath(rect: rightBlink).fill()                        }                    }                     // Gemini twist: sparkle-inspired design with prominent 4-pointed stars as eyes                    // and decorative points extending from the bar.                    if addGeminiTwist {                        let ctx = NSGraphicsContext.current?.cgContext                        let centerXPx = rectPx.midXPx                        let eyeCenterYPx = rectPx.y + rectPx.h / 2                         ctx?.saveGState()                        ctx?.setShouldAntialias(true)                         // 4-pointed star cutouts (Gemini sparkle eyes) - BIGGER                        let starSizePx = 8                        let eyeOffsetPx = 8                        let sr = Self.grid.pt(starSizePx / 2)                        let innerR = sr * 0.25                         func drawStarCutout(cx: CGFloat, cy: CGFloat) {                            let path = NSBezierPath()                            for i in 0..<8 {                                let angle = CGFloat(i) * .pi / 4 - .pi / 2                                let radius = (i % 2 == 0) ? sr : innerR                                let px = cx + cos(angle) * radius                                let py = cy + sin(angle) * radius                                if i == 0 {                                    path.move(to: NSPoint(x: px, y: py))                                } else {                                    path.line(to: NSPoint(x: px, y: py))                                }                            }                            path.close()                            path.fill()                        }                         let ldCx = Self.grid.pt(centerXPx - eyeOffsetPx)                        let rdCx = Self.grid.pt(centerXPx + eyeOffsetPx)                        let yCy = Self.grid.pt(eyeCenterYPx)                         // Clear star shapes for eyes                        ctx?.setBlendMode(.clear)                        drawStarCutout(cx: ldCx, cy: yCy)                        drawStarCutout(cx: rdCx, cy: yCy)                        ctx?.setBlendMode(.normal)                         // Decorative sparkle points extending from bar (sized to stay within 36px canvas)                        fillColor.withAlphaComponent(alpha).setFill()                        let pointHeightPx = 4                        let pointWidthPx = 4                         // Top center point (like a crown/sparkle)                        let topPointPath = NSBezierPath()                        let topCx = Self.grid.pt(centerXPx)                        let topBaseY = Self.grid.pt(rectPx.y + rectPx.h)                        let topPeakY = Self.grid.pt(rectPx.y + rectPx.h + pointHeightPx)                        let halfW = Self.grid.pt(pointWidthPx / 2)                        topPointPath.move(to: NSPoint(x: topCx - halfW, y: topBaseY))                        topPointPath.line(to: NSPoint(x: topCx, y: topPeakY))                        topPointPath.line(to: NSPoint(x: topCx + halfW, y: topBaseY))                        topPointPath.close()                        topPointPath.fill()                         // Bottom center point                        let bottomPointPath = NSBezierPath()                        let bottomBaseY = Self.grid.pt(rectPx.y)                        let bottomPeakY = Self.grid.pt(rectPx.y - pointHeightPx)                        bottomPointPath.move(to: NSPoint(x: topCx - halfW, y: bottomBaseY))                        bottomPointPath.line(to: NSPoint(x: topCx, y: bottomPeakY))                        bottomPointPath.line(to: NSPoint(x: topCx + halfW, y: bottomBaseY))                        bottomPointPath.close()                        bottomPointPath.fill()                         // Side points (max 3px to stay within canvas edge)                        let sidePointH = 3                        let sidePointW = 3                        let sideHalfW = Self.grid.pt(sidePointW / 2)                        let barMidY = Self.grid.pt(eyeCenterYPx)                         // Left side point                        let leftSidePath = NSBezierPath()                        let leftBaseX = Self.grid.pt(rectPx.x)                        let leftPeakX = Self.grid.pt(rectPx.x - sidePointH)                        leftSidePath.move(to: NSPoint(x: leftBaseX, y: barMidY - sideHalfW))                        leftSidePath.line(to: NSPoint(x: leftPeakX, y: barMidY))                        leftSidePath.line(to: NSPoint(x: leftBaseX, y: barMidY + sideHalfW))                        leftSidePath.close()                        leftSidePath.fill()                         // Right side point                        let rightSidePath = NSBezierPath()                        let rightBaseX = Self.grid.pt(rectPx.x + rectPx.w)                        let rightPeakX = Self.grid.pt(rectPx.x + rectPx.w + sidePointH)                        rightSidePath.move(to: NSPoint(x: rightBaseX, y: barMidY - sideHalfW))                        rightSidePath.line(to: NSPoint(x: rightPeakX, y: barMidY))                        rightSidePath.line(to: NSPoint(x: rightBaseX, y: barMidY + sideHalfW))                        rightSidePath.close()                        rightSidePath.fill()                         ctx?.restoreGState()                         // Blink: fill star eyes                        if blink > 0.001 {                            let clamped = max(0, min(blink, 1))                            fillColor.withAlphaComponent(alpha).setFill()                            let blinkR = sr * clamped                            let blinkInnerR = blinkR * 0.25                             func drawBlinkStar(cx: CGFloat, cy: CGFloat) {                                let path = NSBezierPath()                                for i in 0..<8 {                                    let angle = CGFloat(i) * .pi / 4 - .pi / 2                                    let radius = (i % 2 == 0) ? blinkR : blinkInnerR                                    let px = cx + cos(angle) * radius                                    let py = cy + sin(angle) * radius                                    if i == 0 {                                        path.move(to: NSPoint(x: px, y: py))                                    } else {                                        path.line(to: NSPoint(x: px, y: py))                                    }                                }                                path.close()                                path.fill()                            }                             drawBlinkStar(cx: ldCx, cy: yCy)                            drawBlinkStar(cx: rdCx, cy: yCy)                        }                    }                     if addAntigravityTwist {                        let dotSizePx = 3                        let dotOffsetXPx = rectPx.x + rectPx.w + 2                        let dotOffsetYPx = rectPx.y + rectPx.h - 2                        fillColor.withAlphaComponent(alpha).setFill()                        let dotRect = Self.grid.rect(                            x: dotOffsetXPx - dotSizePx / 2,                            y: dotOffsetYPx - dotSizePx / 2,                            w: dotSizePx,                            h: dotSizePx)                        NSBezierPath(ovalIn: dotRect).fill()                    }                     // Factory twist: 8-pointed asterisk/gear-like eyes with cog teeth accents                    if addFactoryTwist {                        let ctx = NSGraphicsContext.current?.cgContext                        let centerXPx = rectPx.midXPx                        let eyeCenterYPx = rectPx.y + rectPx.h / 2                         ctx?.saveGState()                        ctx?.setShouldAntialias(true)                         // 8-pointed asterisk cutouts (Factory gear-like eyes)                        let starSizePx = 7                        let eyeOffsetPx = 8                        let sr = Self.grid.pt(starSizePx / 2)                        let innerR = sr * 0.3                         func drawAsteriskCutout(cx: CGFloat, cy: CGFloat) {                            let path = NSBezierPath()                            // 8 points for the asterisk                            for i in 0..<16 {                                let angle = CGFloat(i) * .pi / 8 - .pi / 2                                let radius = (i % 2 == 0) ? sr : innerR                                let px = cx + cos(angle) * radius                                let py = cy + sin(angle) * radius                                if i == 0 {                                    path.move(to: NSPoint(x: px, y: py))                                } else {                                    path.line(to: NSPoint(x: px, y: py))                                }                            }                            path.close()                            path.fill()                        }                         let ldCx = Self.grid.pt(centerXPx - eyeOffsetPx)                        let rdCx = Self.grid.pt(centerXPx + eyeOffsetPx)

Lines 1–500 of 961.