170 lines
5.7 KiB
Swift
170 lines
5.7 KiB
Swift
//
|
|
// ModelColorConfiguration.swift
|
|
// VDS
|
|
//
|
|
// Created by Matt Bruce on 8/4/22.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
public typealias ObjectColorable = Colorable & Initable & ObjectWithable
|
|
|
|
/// Meant to be used in a Object that implements the following interfaces for 2 possible color combinations
|
|
/// - Surfaceable (var surface: Surface)
|
|
///
|
|
/// let model = TestModel()
|
|
/// model.surface = .light
|
|
///
|
|
/// let config = SurfaceColorConfiguration()
|
|
/// config.lightColor = .black
|
|
/// config.darkColor = .white
|
|
///
|
|
/// let textColor = config.getColor(model) //returns .black
|
|
|
|
open class SurfaceColorConfiguration: ObjectColorable {
|
|
public typealias ObjectType = Surfaceable
|
|
public var lightColor: UIColor = .clear
|
|
public var darkColor: UIColor = .clear
|
|
|
|
required public init(){}
|
|
|
|
public init(_ lightColor: UIColor, _ darkColor: UIColor) {
|
|
self.lightColor = lightColor
|
|
self.darkColor = darkColor
|
|
}
|
|
|
|
public func getColor(_ surface: Surface) -> UIColor {
|
|
return surface == .light ? lightColor : darkColor
|
|
}
|
|
|
|
public func getColor(_ object: any ObjectType) -> UIColor {
|
|
return getColor(object.surface)
|
|
}
|
|
}
|
|
|
|
|
|
/// Struct to Hold onto KeyType and SurfaceConfiguration
|
|
public struct KeyColorConfiguration<KeyType: Equatable> {
|
|
var key: KeyType
|
|
var surfaceConfig: SurfaceColorConfiguration
|
|
}
|
|
|
|
// Protocol to Hold onto the relationship of KeyType and SurfaceConfiguration
|
|
public protocol KeyColorConfigurable: ObjectColorable {
|
|
associatedtype KeyType: Equatable
|
|
var keyColors: [KeyColorConfiguration<KeyType>] { get set }
|
|
}
|
|
|
|
extension KeyColorConfigurable {
|
|
public func setSurfaceColors(_ lightColor: UIColor, _ darkColor: UIColor, forKey key: KeyType) {
|
|
keyColors.append(.init(key: key, surfaceConfig: .init(lightColor, darkColor)))
|
|
}
|
|
|
|
public func reset() {
|
|
keyColors.removeAll()
|
|
}
|
|
}
|
|
|
|
extension KeyColorConfigurable where ObjectType: Surfaceable {
|
|
public func getColor(for object: ObjectType, with key: KeyType) -> UIColor {
|
|
if let keyColor = keyColors.first(where: {$0.key == key }) {
|
|
return keyColor.surfaceConfig.getColor(object)
|
|
} else {
|
|
return .clear //default
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public class ControlColorConfiguration: KeyColorConfigurable {
|
|
public typealias KeyType = UIControl.State
|
|
public typealias ObjectType = Surfaceable & UIControl
|
|
public var keyColors: [KeyColorConfiguration<KeyType>] = []
|
|
private var lastKeyColor: KeyColorConfiguration<KeyType>?
|
|
public required init() { }
|
|
|
|
public func setSurfaceColors(_ lightColor: UIColor, _ darkColor: UIColor, forState state: KeyType) {
|
|
setSurfaceColors(lightColor, darkColor, forKey: state)
|
|
}
|
|
|
|
public func getColor(_ object: any ObjectType) -> UIColor {
|
|
let state = object.state
|
|
let surface = object.surface
|
|
|
|
// find the exact match
|
|
if let keyColor = keyColors.first(where: {$0.key == state }) {
|
|
lastKeyColor = keyColor
|
|
return keyColor.surfaceConfig.getColor(surface)
|
|
|
|
} else if state.contains(.disabled), let keyColor = keyColors.first(where: {$0.key == .disabled }) {
|
|
lastKeyColor = keyColor
|
|
return keyColor.surfaceConfig.getColor(surface)
|
|
|
|
} else if state.contains(.highlighted), let keyColor = keyColors.first(where: {$0.key == .highlighted }) {
|
|
lastKeyColor = keyColor
|
|
return keyColor.surfaceConfig.getColor(surface)
|
|
|
|
} else {
|
|
if let lastKeyColor {
|
|
return lastKeyColor.surfaceConfig.getColor(surface)
|
|
} else {
|
|
return .clear
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ViewColorConfiguration: KeyColorConfigurable {
|
|
public typealias KeyType = Bool
|
|
public typealias ObjectType = Surfaceable & Disabling
|
|
public var keyColors: [KeyColorConfiguration<KeyType>] = []
|
|
|
|
public required init() { }
|
|
|
|
public func setSurfaceColors(_ lightColor: UIColor, _ darkColor: UIColor, forDisabled disabled: KeyType) {
|
|
setSurfaceColors(lightColor, darkColor, forKey: disabled)
|
|
}
|
|
|
|
public func getColor(_ object: ObjectType) -> UIColor {
|
|
if let keyColor = keyColors.first(where: {$0.key == object.disabled }) {
|
|
return keyColor.surfaceConfig.getColor(object)
|
|
} else {
|
|
return .clear //default
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Generic Class that allows reflection for a object's specific property (equatable) to be defined as the lookup for a SurfaceConfiguration
|
|
public class KeyedColorConfiguration<ObjectType: Surfaceable, KeyType: Equatable> : KeyColorConfigurable {
|
|
//Type of Class that at least implements Surfaceable
|
|
public typealias ObjectType = ObjectType
|
|
|
|
//where the value exist for the object
|
|
public var keyPath: KeyPath<ObjectType, KeyType>?
|
|
|
|
/// Array of structs where the KeyValue is registered against a SurfaceColorConfiguration
|
|
public var keyColors: [KeyColorConfiguration<KeyType>] = []
|
|
|
|
public required init() {}
|
|
|
|
//this must be used
|
|
public required convenience init(keyPath: KeyPath<ObjectType, KeyType>) {
|
|
self.init()
|
|
self.keyPath = keyPath
|
|
}
|
|
|
|
public func getKeyValue(_ object: ObjectType) -> KeyType? {
|
|
guard let keyPath else { fatalError("keyPath must not be empty, make sure you initialize this class using init(keyPath: \\Object.property) method") }
|
|
return object[keyPath: keyPath]
|
|
}
|
|
|
|
public func getColor(_ object: ObjectType) -> UIColor {
|
|
if let key = getKeyValue(object), let keyColor = keyColors.first(where: {$0.key == key }) {
|
|
return keyColor.surfaceConfig.getColor(object)
|
|
} else {
|
|
return .clear //default
|
|
}
|
|
}
|
|
}
|