move contrasting color to Theme and cache computed var

This commit is contained in:
sh95014 2024-02-12 13:27:32 -08:00
parent f7fed6e94c
commit e94b09d157
2 changed files with 33 additions and 25 deletions

View file

@ -167,12 +167,14 @@ import SwiftUI
public var tintColor: Color {
didSet {
themeStorage.tintColor = tintColor
computeContrastingTintColor()
}
}
public var primaryBackgroundColor: Color {
didSet {
themeStorage.primaryBackgroundColor = primaryBackgroundColor
computeContrastingTintColor()
}
}
@ -185,6 +187,33 @@ import SwiftUI
public var labelColor: Color {
didSet {
themeStorage.labelColor = labelColor
computeContrastingTintColor()
}
}
public private(set) var contrastingTintColor: Color
// set contrastingTintColor to either labelColor or primaryBackgroundColor, whichever contrasts
// better against the tintColor
private func computeContrastingTintColor() {
@Environment(\.self) var environment
func luminance(_ color: Color.Resolved) -> Float {
return 0.299 * color.red + 0.587 * color.green + 0.114 * color.blue;
}
let resolvedTintColor = tintColor.resolve(in: environment)
let resolvedLabelColor = labelColor.resolve(in: environment)
let resolvedPrimaryBackgroundColor = primaryBackgroundColor.resolve(in: environment)
let tintLuminance = luminance(resolvedTintColor)
let labelLuminance = luminance(resolvedLabelColor)
let primaryBackgroundLuminance = luminance(resolvedPrimaryBackgroundColor)
if abs(tintLuminance - labelLuminance) > abs(tintLuminance - primaryBackgroundLuminance) {
contrastingTintColor = labelColor
} else {
contrastingTintColor = primaryBackgroundColor
}
}
@ -281,6 +310,7 @@ import SwiftUI
primaryBackgroundColor = themeStorage.primaryBackgroundColor
secondaryBackgroundColor = themeStorage.secondaryBackgroundColor
labelColor = themeStorage.labelColor
contrastingTintColor = .red // real work done in computeContrastingTintColor()
avatarPosition = themeStorage.avatarPosition
avatarShape = themeStorage.avatarShape
storedSet = themeStorage.storedSet
@ -293,6 +323,8 @@ import SwiftUI
chosenFontData = themeStorage.chosenFontData
statusActionSecondary = themeStorage.statusActionSecondary
selectedSet = storedSet
computeContrastingTintColor()
}
public static var allColorSet: [ColorSet] {

View file

@ -177,7 +177,6 @@ struct BlurOverLay: View {
@Environment(\.isInCaptureMode) private var isInCaptureMode: Bool
@Environment(UserPreferences.self) private var preferences
@Environment(\.isMediaCompact) private var isCompact: Bool
@Environment(\.self) var environment
@Namespace var buttonSpace
@ -213,7 +212,7 @@ struct BlurOverLay: View {
.matchedGeometryEffect(id: "eye", in: buttonSpace)
}
.lineLimit(1)
.foregroundColor(contrastingColor(against: theme.tintColor))
.foregroundColor(theme.contrastingTintColor)
} else {
Image(systemName: "eye.slash")
.transition(.opacity)
@ -246,29 +245,6 @@ struct BlurOverLay: View {
default: false
}
}
// return either labelColor or primaryBackgroundColor, whichever contrasts better against
// the specified background color
private func contrastingColor(against backgroundColor: Color) -> Color {
func luminance(_ color: Color.Resolved) -> Float {
return 0.299 * color.red + 0.587 * color.green + 0.114 * color.blue;
}
let resolvedBackgroundColor = backgroundColor.resolve(in: environment)
let resolvedLabelColor = theme.labelColor.resolve(in: environment)
let resolvedPrimaryBackgroundColor = theme.primaryBackgroundColor.resolve(in: environment)
let backgroundLuminance = luminance(resolvedBackgroundColor)
let labelLuminance = luminance(resolvedLabelColor)
let primaryBackgroundLuminance = luminance(resolvedPrimaryBackgroundColor)
if backgroundLuminance < 0.5 {
return (labelLuminance > primaryBackgroundLuminance) ? theme.labelColor : theme.primaryBackgroundColor
} else {
return (labelLuminance < primaryBackgroundLuminance) ? theme.labelColor : theme.primaryBackgroundColor
}
}
}
struct AltTextButton: View {