| | |
| | | struct AppGridCollectionView: NSViewRepresentable { |
| | | let groups: [TagGroup] |
| | | let tagColors: [String: Int] |
| | | let tagCustomColors: [String: TagCustomColor] |
| | | let displayMode: String |
| | | let iconSize: CGFloat |
| | | let showNames: Bool |
| | |
| | | context.coordinator.update( |
| | | groups: groups, |
| | | tagColors: tagColors, |
| | | tagCustomColors: tagCustomColors, |
| | | displayMode: displayMode, |
| | | iconSize: iconSize, |
| | | showNames: showNames, |
| | |
| | | final class Coordinator: NSObject, NSCollectionViewDataSource, NSCollectionViewDelegate { |
| | | var groups: [TagGroup] = [] |
| | | var tagColors: [String: Int] = [:] |
| | | var tagCustomColors: [String: TagCustomColor] = [:] |
| | | var displayMode = AppDefaults.displayMode |
| | | var iconSize: CGFloat = AppDefaults.iconSize |
| | | var showNames = true |
| | |
| | | func update( |
| | | groups: [TagGroup], |
| | | tagColors: [String: Int], |
| | | tagCustomColors: [String: TagCustomColor], |
| | | displayMode: String, |
| | | iconSize: CGFloat, |
| | | showNames: Bool, |
| | |
| | | ) { |
| | | self.groups = groups |
| | | self.tagColors = tagColors |
| | | self.tagCustomColors = tagCustomColors |
| | | self.displayMode = displayMode |
| | | self.iconSize = iconSize |
| | | self.showNames = showNames |
| | |
| | | |
| | | let nextSignature = Self.signature( |
| | | tagColors: tagColors, |
| | | tagCustomColors: tagCustomColors, |
| | | displayMode: displayMode, |
| | | iconSize: iconSize, |
| | | showNames: showNames, |
| | |
| | | |
| | | private static func signature( |
| | | tagColors: [String: Int], |
| | | tagCustomColors: [String: TagCustomColor], |
| | | displayMode: String, |
| | | iconSize: CGFloat, |
| | | showNames: Bool, |
| | |
| | | .sorted { $0.key < $1.key } |
| | | .map { "\($0.key)=\($0.value)" } |
| | | .joined(separator: ",") |
| | | let customColorPart = tagCustomColors |
| | | .sorted { $0.key < $1.key } |
| | | .map { "\($0.key)=\($0.value.signature)" } |
| | | .joined(separator: ",") |
| | | return [ |
| | | displayMode, |
| | | "\(Int(iconSize.rounded()))", |
| | |
| | | showUncommonAppBubbles ? "uncommon" : "allbubbles", |
| | | "bottom=\(Int(bottomContentPadding.rounded()))", |
| | | colorPart, |
| | | customColorPart, |
| | | "rev=\(contentRevision)" |
| | | ].joined(separator: "|") |
| | | } |
| | | |
| | | func tagColor(for groupName: String) -> NSColor { |
| | | TagColor.nsColor( |
| | | for: tagColors[groupName] ?? 0, |
| | | customColor: tagCustomColors[groupName] |
| | | ) |
| | | } |
| | | |
| | | private static func clampedUsageTipIndex(_ index: Int, tips: [AppGridUsageTip]) -> Int { |
| | |
| | | override func draw(_ dirtyRect: NSRect) { |
| | | guard let coordinator, let group else { return } |
| | | let displayStyle = coordinator.displayStyle |
| | | let tagColor = TagColor.nsColor(for: coordinator.tagColors[group.name] ?? 0) |
| | | let tagColor = coordinator.tagColor(for: group.name) |
| | | let isNavigationHighlighted = coordinator.highlightedGroupName == group.name |
| | | let isColorlessActive = coordinator.isColorlessContainerMode |
| | | && (isHovered || isNavigationHighlighted) |
| | |
| | | let shouldShadow = coordinator.displayStyle.usesCardSurface |
| | | && ((coordinator.isColoredContainerMode && (isHovered || isNavigationHighlighted)) || isColorlessActive) |
| | | if coordinator.appGridTheme.usesDarkGlass && coordinator.displayStyle.usesCardSurface { |
| | | let tagColor = TagColor.nsColor(for: coordinator.tagColors[group?.name ?? ""] ?? 0) |
| | | let tagColor = coordinator.tagColor(for: group?.name ?? "") |
| | | let active = isHovered || isNavigationHighlighted |
| | | layer?.shadowColor = active |
| | | ? tagColor.withAlphaComponent(0.82).cgColor |