Files
shotscreen/ShotScreen/Sources/ThemeManager.swift
Nick Roodenrijs 0dabed11d2 🎉 ShotScreen v1.0 - Initial Release
🚀 First official release of ShotScreen with complete feature set:

 Core Features:
- Advanced screenshot capture system
- Multi-monitor support
- Professional UI/UX design
- Automated update system with Sparkle
- Apple notarized & code signed

🛠 Technical Excellence:
- Native Swift macOS application
- Professional build & deployment pipeline
- Comprehensive error handling
- Memory optimized performance

📦 Distribution Ready:
- Professional DMG packaging
- Apple notarization complete
- No security warnings for users
- Ready for public distribution

This is the foundation release that establishes ShotScreen as a premium screenshot tool for macOS.
2025-06-28 16:15:15 +02:00

176 lines
6.0 KiB
Swift

import AppKit
import SwiftUI
// MARK: - Centralized Theme Manager
class ThemeManager {
static let shared = ThemeManager()
private init() {}
// MARK: - System-Aware Colors (automatic light/dark adaptation)
/// Background colors for containers (GLASS EFFECT zoals stash)
var containerBackground: NSColor {
// NIEUW: Glass effect achtergrond zoals stash window
// Gebruik transparante achtergrond zodat visual effect view erdoor kan
return NSColor.clear
}
/// Glass effect background for visual effect views
var glassEffectMaterial: NSVisualEffectView.Material {
return .hudWindow // Exact hetzelfde als stash window
}
/// Glass effect blending mode
var glassEffectBlending: NSVisualEffectView.BlendingMode {
return .behindWindow // Exact hetzelfde als stash window
}
/// Glass effect alpha
var glassEffectAlpha: CGFloat {
return 0.95 // Exact hetzelfde als stash window
}
/// Background colors for secondary containers
var secondaryContainerBackground: NSColor {
if NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua {
return NSColor(white: 0.42, alpha: 0.90) // Dark mode: iets lichter
} else {
return NSColor(white: 0.98, alpha: 0.90) // Light mode: bijna wit
}
}
/// Button and icon colors (adaptive)
var buttonTintColor: NSColor {
if NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua {
return NSColor(white: 0.95, alpha: 1.0) // Dark mode: wit
} else {
return NSColor(white: 0.25, alpha: 1.0) // Light mode: donkergrijs
}
}
/// Text colors (adaptive)
var primaryTextColor: NSColor {
if NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua {
return NSColor.white // Dark mode: wit
} else {
return NSColor.black // Light mode: zwart
}
}
var secondaryTextColor: NSColor {
if NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua {
return NSColor(white: 0.7, alpha: 1.0) // Dark mode: grijs
} else {
return NSColor(white: 0.4, alpha: 1.0) // Light mode: donkergrijs
}
}
/// Filename label text color (adaptive with opacity)
var filenameLabelTextColor: NSColor {
if NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua {
return NSColor(white: 0.7, alpha: 1.0) // Dark mode: lichtgrijs
} else {
return NSColor(white: 0.1, alpha: 1.0) // Light mode: veel donkerder voor betere zichtbaarheid
}
}
/// Grid cell icon background (adaptive)
var gridCellIconBackground: NSColor {
if NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua {
return NSColor.white.withAlphaComponent(0.25) // Dark mode
} else {
return NSColor.black.withAlphaComponent(0.25) // Light mode
}
}
/// Grid cell text color with hover effect
func gridCellTextColor(isHovered: Bool) -> NSColor {
if NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua {
return isHovered ? NSColor.white : NSColor.white.withAlphaComponent(0.1)
} else {
return isHovered ? NSColor.black : NSColor.black.withAlphaComponent(0.1)
}
}
// MARK: - Shadow Configuration (adaptive)
var shadowColor: NSColor {
if NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua {
return NSColor.black // Dark mode: black shadows
} else {
return NSColor.black.withAlphaComponent(0.3) // Light mode: lighter shadows
}
}
var shadowOpacity: Float {
if NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua {
return 0.50 // Dark mode: stronger shadows
} else {
return 0.25 // Light mode: subtle shadows
}
}
// MARK: - Utility Methods
/// Check if currently in dark mode
var isDarkMode: Bool {
return NSApp.effectiveAppearance.name == NSAppearance.Name.darkAqua
}
/// Debug function to print current theme info
func printCurrentTheme() {
let mode = isDarkMode ? "DARK" : "LIGHT"
print("🎨 THEME DEBUG: Current mode = \(mode)")
print("🎨 THEME DEBUG: Container background = GLASS EFFECT (\(glassEffectMaterial.rawValue))")
print("🎨 THEME DEBUG: Glass effect alpha = \(glassEffectAlpha)")
print("🎨 THEME DEBUG: Button tint = \(buttonTintColor)")
print("🎨 THEME DEBUG: Primary text = \(primaryTextColor)")
print("🎨 THEME DEBUG: Shadow opacity = \(shadowOpacity)")
}
/// Get hover color for buttons
var buttonHoverColor: NSColor {
if isDarkMode {
return NSColor.white
} else {
return NSColor.black
}
}
/// Get original button color (for hover restoration)
var buttonOriginalColor: NSColor {
return buttonTintColor
}
// MARK: - Notification for Theme Changes
func observeThemeChanges(callback: @escaping () -> Void) {
// Observer voor system appearance changes
DistributedNotificationCenter.default.addObserver(
forName: NSNotification.Name("AppleInterfaceThemeChangedNotification"),
object: nil,
queue: .main
) { _ in
print("🎨 THEME: System theme changed - notifying observers")
callback()
}
}
}
// MARK: - SwiftUI Color Extensions
extension Color {
static var adaptiveContainerBackground: Color {
Color(ThemeManager.shared.containerBackground)
}
static var adaptiveSecondaryBackground: Color {
Color(ThemeManager.shared.secondaryContainerBackground)
}
static var adaptivePrimaryText: Color {
Color(ThemeManager.shared.primaryTextColor)
}
static var adaptiveSecondaryText: Color {
Color(ThemeManager.shared.secondaryTextColor)
}
}