• match empty circle and filled circles in diameter. • use chat tint color for checkmark background in `selected` state.
132 lines
4.0 KiB
Swift
132 lines
4.0 KiB
Swift
//
|
|
// Copyright 2021 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
public import SignalServiceKit
|
|
import UIKit
|
|
|
|
// MARK: -
|
|
|
|
/// ColorOrGradientSetting is used for persistence and comparison.
|
|
/// ColorOrGradientValue is used for rendering.
|
|
public enum ColorOrGradientValue: CustomStringConvertible {
|
|
case transparent
|
|
case blur(blurEffect: UIVisualEffect)
|
|
case solidColor(color: UIColor)
|
|
/// If angleRadians = 0, gradientColor1 is N.
|
|
/// If angleRadians = PI / 2, gradientColor1 is E.
|
|
/// etc.
|
|
case gradient(
|
|
gradientColor1: UIColor,
|
|
gradientColor2: UIColor,
|
|
angleRadians: CGFloat,
|
|
)
|
|
|
|
public var description: String {
|
|
switch self {
|
|
case .transparent:
|
|
return "[transparent]"
|
|
case .blur:
|
|
return "[blur]"
|
|
case .solidColor(let color):
|
|
return "[solidColor: \(color.asOWSColor)]"
|
|
case .gradient(let gradientColor1, let gradientColor2, let angleRadians):
|
|
return "[gradient gradientColor1: \(gradientColor1.asOWSColor), gradientColor2: \(gradientColor2.asOWSColor), angleRadians: \(angleRadians)]"
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public enum ColorOrGradientThemeMode: Int {
|
|
case auto
|
|
case alwaysLight
|
|
case alwaysDark
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public extension ColorOrGradientSetting {
|
|
var asValue: ColorOrGradientValue {
|
|
asValue(themeMode: .auto)
|
|
}
|
|
|
|
func asValue(themeMode: ColorOrGradientThemeMode) -> ColorOrGradientValue {
|
|
let shouldUseDarkColors: Bool = {
|
|
switch themeMode {
|
|
case .auto:
|
|
return Theme.isDarkThemeEnabled
|
|
case .alwaysDark:
|
|
return true
|
|
case .alwaysLight:
|
|
return false
|
|
}
|
|
}()
|
|
|
|
switch self {
|
|
case .solidColor(let solidColor):
|
|
return .solidColor(color: solidColor.asUIColor)
|
|
case .themedColor(let lightThemeColor, let darkThemeColor):
|
|
let color = shouldUseDarkColors ? darkThemeColor : lightThemeColor
|
|
return .solidColor(color: color.asUIColor)
|
|
case .gradient(let gradientColor1, let gradientColor2, let angleRadians):
|
|
return .gradient(
|
|
gradientColor1: gradientColor1.asUIColor,
|
|
gradientColor2: gradientColor2.asUIColor,
|
|
angleRadians: angleRadians,
|
|
)
|
|
case .themedGradient(
|
|
let lightGradientColor1,
|
|
let lightGradientColor2,
|
|
let darkGradientColor1,
|
|
let darkGradientColor2,
|
|
let angleRadians,
|
|
):
|
|
let gradientColor1 = shouldUseDarkColors ? darkGradientColor1 : lightGradientColor1
|
|
let gradientColor2 = shouldUseDarkColors ? darkGradientColor2 : lightGradientColor2
|
|
return .gradient(
|
|
gradientColor1: gradientColor1.asUIColor,
|
|
gradientColor2: gradientColor2.asUIColor,
|
|
angleRadians: angleRadians,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public extension UIColor {
|
|
var asOWSColor: OWSColor {
|
|
let (red, green, blue, _) = self.components() ?? (0, 0, 0, 0)
|
|
return OWSColor(red: red.clamp01(), green: green.clamp01(), blue: blue.clamp01())
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public extension ColorOrGradientValue {
|
|
|
|
func asChatUIElementTintColor() -> UIColor {
|
|
let bubbleColor: UIColor = {
|
|
switch self {
|
|
case .transparent, .blur:
|
|
return .Signal.accent
|
|
|
|
case .solidColor(let color):
|
|
return color
|
|
|
|
case .gradient(let gradientColor1, let gradientColor2, _):
|
|
return gradientColor1.midPoint(with: gradientColor2)
|
|
}
|
|
}()
|
|
let lightThemeFinalColor = bubbleColor.blendedWithOverlay(.white, opacity: 0.16)
|
|
let darkThemeFinalColor = bubbleColor.blendedWithOverlay(.black, opacity: 0.1)
|
|
return UIColor(
|
|
light: lightThemeFinalColor,
|
|
dark: darkThemeFinalColor,
|
|
)
|
|
}
|
|
}
|