tv-anarchy/Sources/TVAnarchyCore/Display/WinampSkinSprites.swift
Natalie 4a2ceb9781 feat(offline): inline star-to-keep and trash-to-cull on cache rows
Surface the existing pin (keep-from-cull) and per-file delete actions as
visible inline buttons on each offline cache row instead of context-menu-only:
a star toggles protection from auto-cull (and restore-if-missing), a trash
culls that file early. Aligns wording/icons to the star metaphor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 00:12:41 -04:00

72 lines
No EOL
3.6 KiB
Swift

import Foundation
/// Bitmap crop within a Winamp skin sheet (Webamp-compatible coordinates).
public struct WinampSpriteRect: Sendable, Equatable {
public let x: Int
public let y: Int
public let width: Int
public let height: Int
public init(x: Int, y: Int, width: Int, height: Int) {
self.x = x
self.y = y
self.width = width
self.height = height
}
}
/// Named sprites per `.BMP` sheet subset used by TVAnarchy Player chrome.
public enum WinampSkinSprites {
public static let sheets: [String: [String: WinampSpriteRect]] = [
"CBUTTONS": [
"MAIN_PREVIOUS_BUTTON": WinampSpriteRect(x: 0, y: 0, width: 23, height: 18),
"MAIN_PREVIOUS_BUTTON_ACTIVE": WinampSpriteRect(x: 0, y: 18, width: 23, height: 18),
"MAIN_PLAY_BUTTON": WinampSpriteRect(x: 23, y: 0, width: 23, height: 18),
"MAIN_PLAY_BUTTON_ACTIVE": WinampSpriteRect(x: 23, y: 18, width: 23, height: 18),
"MAIN_PAUSE_BUTTON": WinampSpriteRect(x: 46, y: 0, width: 23, height: 18),
"MAIN_PAUSE_BUTTON_ACTIVE": WinampSpriteRect(x: 46, y: 18, width: 23, height: 18),
"MAIN_STOP_BUTTON": WinampSpriteRect(x: 69, y: 0, width: 23, height: 18),
"MAIN_STOP_BUTTON_ACTIVE": WinampSpriteRect(x: 69, y: 18, width: 23, height: 18),
"MAIN_NEXT_BUTTON": WinampSpriteRect(x: 92, y: 0, width: 23, height: 18),
"MAIN_NEXT_BUTTON_ACTIVE": WinampSpriteRect(x: 92, y: 18, width: 22, height: 18),
],
"POSBAR": [
"MAIN_POSITION_SLIDER_BACKGROUND": WinampSpriteRect(x: 0, y: 0, width: 248, height: 10),
"MAIN_POSITION_SLIDER_THUMB": WinampSpriteRect(x: 248, y: 0, width: 29, height: 10),
"MAIN_POSITION_SLIDER_THUMB_ACTIVE": WinampSpriteRect(x: 248, y: 10, width: 29, height: 10),
],
"VOLUME": [
"MAIN_VOLUME_BACKGROUND": WinampSpriteRect(x: 0, y: 0, width: 68, height: 13),
"MAIN_VOLUME_THUMB": WinampSpriteRect(x: 15, y: 422, width: 14, height: 11),
"MAIN_VOLUME_THUMB_ACTIVE": WinampSpriteRect(x: 0, y: 422, width: 14, height: 11),
],
"MAIN": [
"MAIN_WINDOW_BACKGROUND": WinampSpriteRect(x: 0, y: 0, width: 275, height: 116),
],
"TITLEBAR": [
"MAIN_TITLE_BAR": WinampSpriteRect(x: 27, y: 15, width: 275, height: 14),
"MAIN_TITLE_BAR_SELECTED": WinampSpriteRect(x: 27, y: 0, width: 275, height: 14),
],
"NUMBERS": [
"DIGIT_0": WinampSpriteRect(x: 0, y: 0, width: 9, height: 13),
"DIGIT_1": WinampSpriteRect(x: 9, y: 0, width: 9, height: 13),
"DIGIT_2": WinampSpriteRect(x: 18, y: 0, width: 9, height: 13),
"DIGIT_3": WinampSpriteRect(x: 27, y: 0, width: 9, height: 13),
"DIGIT_4": WinampSpriteRect(x: 36, y: 0, width: 9, height: 13),
"DIGIT_5": WinampSpriteRect(x: 45, y: 0, width: 9, height: 13),
"DIGIT_6": WinampSpriteRect(x: 54, y: 0, width: 9, height: 13),
"DIGIT_7": WinampSpriteRect(x: 63, y: 0, width: 9, height: 13),
"DIGIT_8": WinampSpriteRect(x: 72, y: 0, width: 9, height: 13),
"DIGIT_9": WinampSpriteRect(x: 81, y: 0, width: 9, height: 13),
],
"PLAYPAUS": [
"MAIN_PLAYING_INDICATOR": WinampSpriteRect(x: 0, y: 0, width: 9, height: 9),
"MAIN_PAUSED_INDICATOR": WinampSpriteRect(x: 9, y: 0, width: 9, height: 9),
"MAIN_STOPPED_INDICATOR": WinampSpriteRect(x: 18, y: 0, width: 9, height: 9),
],
]
public static func rect(sheet: String, name: String) -> WinampSpriteRect? {
sheets[sheet.uppercased()]?[name]
}
}