From 4405e3ffc1fd95613cb29204e5b087ad47486a72 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 16 Mar 2023 11:32:53 -0500 Subject: [PATCH] refactored colorconfiguration classes Signed-off-by: Matt Bruce --- VDS/Classes/ColorConfiguration.swift | 183 +++++++++++++++++---------- 1 file changed, 113 insertions(+), 70 deletions(-) diff --git a/VDS/Classes/ColorConfiguration.swift b/VDS/Classes/ColorConfiguration.swift index a1288aa2..952d6e66 100644 --- a/VDS/Classes/ColorConfiguration.swift +++ b/VDS/Classes/ColorConfiguration.swift @@ -10,76 +10,6 @@ import UIKit public typealias ObjectColorable = Colorable & Initable & ObjectWithable -public class ControlColorConfiguration: StateColorConfiguration, ObjectColorable { - public typealias ObjectType = UIControl & Surfaceable - - required public override init() {} - - public override func getColor(_ surface: Surface, forState state: UIControl.State) -> UIColor { - - // find the exact match - if let stateColor = stateColors.first(where: {$0.state == state }) { - return stateColor.surfaceConfig.getColor(surface) - - } else if state.contains(.disabled), let stateColor = stateColors.first(where: {$0.state == .disabled }) { - return stateColor.surfaceConfig.getColor(surface) - - } else if state.contains(.highlighted), let stateColor = stateColors.first(where: {$0.state == .highlighted }) { - return stateColor.surfaceConfig.getColor(surface) - - } else { - return .clear - - } - } - public func getColor(_ object: any ObjectType) -> UIColor { - return getColor(object.surface, forState: object.state) - } -} - -public class ViewColorConfiguration: StateColorConfiguration, ObjectColorable { - public typealias ObjectType = Disabling & Surfaceable - - required public override init() {} - - public func setSurfaceColors(_ lightColor: UIColor, _ darkColor: UIColor, forDisabled disabled: Bool) { - setSurfaceColors(lightColor, darkColor, forState: disabled) - } - - public func getColor(_ object: any ObjectType) -> UIColor { - return getColor(object.surface, forState: object.disabled) - } -} - -public class StateColorConfiguration { - - struct StateColor { - var state: StateType - var surfaceConfig: SurfaceColorConfiguration - } - - internal var stateColors: [StateColor] = [] - - public init() { } - - public func getColor(_ surface: Surface, forState state: StateType) -> UIColor { - if let stateColor = stateColors.first(where: {$0.state == state }) { - return stateColor.surfaceConfig.getColor(surface) - } else { - return .clear //default - } - } - - public func setSurfaceColors(_ lightColor: UIColor, _ darkColor: UIColor, forState state: StateType) { - stateColors.append(.init(state: state, surfaceConfig: .init(lightColor, darkColor))) - } - - public func reset() { - stateColors.removeAll() - } -} - - /// Meant to be used in a Object that implements the following interfaces for 2 possible color combinations /// - Surfaceable (var surface: Surface) /// @@ -112,3 +42,116 @@ open class SurfaceColorConfiguration: ObjectColorable { return getColor(object.surface) } } + + +/// Struct to Hold onto KeyType and SurfaceConfiguration +public struct KeyColorConfiguration { + 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] { 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() + } +} + + +public class ControlColorConfiguration: KeyColorConfigurable { + public typealias KeyType = UIControl.State + public typealias ObjectType = Surfaceable & UIControl + public var keyColors: [KeyColorConfiguration] = [] + + 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 }) { + return keyColor.surfaceConfig.getColor(surface) + + } else if state.contains(.disabled), let keyColor = keyColors.first(where: {$0.key == .disabled }) { + return keyColor.surfaceConfig.getColor(surface) + + } else if state.contains(.highlighted), let keyColor = keyColors.first(where: {$0.key == .highlighted }) { + return keyColor.surfaceConfig.getColor(surface) + + } else { + return .clear + } + } +} + +public class ViewColorConfiguration: KeyColorConfigurable { + public typealias KeyType = Bool + public typealias ObjectType = Surfaceable & Disabling + public var keyColors: [KeyColorConfiguration] = [] + + 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 : KeyColorConfigurable { + //Type of Class that at least implements Surfaceable + public typealias ObjectType = ObjectType + + /// property that will be used for reflection, the type of this property must implement Equatable + public var keyName: String + + /// Array of structs where the KeyValue is registered against a SurfaceColorConfiguration + public var keyColors: [KeyColorConfiguration] = [] + + public required init() { + self.keyName = "" + } + + //this must be used + public convenience init(keyName: String) { + self.init() + self.keyName = keyName + } + + public func getKeyValue(_ object: ObjectType) -> KeyType? { + guard !keyName.isEmpty else { fatalError("keyName must not be empty, make sure you initialize this class using init(keyName: String) method") } + + let mirror = Mirror(reflecting: object) + guard let result = mirror.children.first(where: {$0.label == keyName })?.value as? KeyType, !mirror.children.isEmpty else { return nil } + return result + } + + 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 + } + } +}