vds_ios/VDS/Classes/ColorConfiguration.swift
Matt Bruce 11416b5343 override getColor for state
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2022-12-08 17:56:49 -06:00

321 lines
10 KiB
Swift

//
// ModelColorConfiguration.swift
// VDS
//
// Created by Matt Bruce on 8/4/22.
//
import Foundation
import UIKit
public typealias ObjectColorable = Colorable & Initable & ObjectWithable
public class ControlColorConfiguration: StateColorConfiguration<UIControl.State>, 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<Bool>, 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<StateType: Equatable> {
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)
///
/// 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)
}
}
///-------------------------------------------------------------------
///MARK -- DisabledSurfaceColorable
///-------------------------------------------------------------------
public protocol DisabledSurfaceColorable: ObjectColorable {
var disabled: SurfaceColorConfiguration { get set }
var enabled: SurfaceColorConfiguration { get set }
}
extension DisabledSurfaceColorable {
public func getDisabledColor<M: Surfaceable & Disabling> (_ object: M) -> UIColor {
object.disabled ? disabled.getColor(object) : enabled.getColor(object)
}
}
/// Meant to be used in a Object that implements the following interfaces for 4 possible color combinations
/// - Disabling (var disabled: Bool)
/// - Surfaceable (var surface: Surface)
///
/// let model = TestModel()
/// model.surface = .dark
/// model.disabled = false
///
/// let config = DisabledSurfaceColorConfiguration()
///
/// //disabled == false
/// config.enabled.lightColor = .black
/// config.enabled.darkColor = .white
///
/// //disabled == true
/// config.disabled.lightColor = .gray
/// config.disabled.darkColor = .lightGray
///
/// let textColor = config.getColor(model) //returns .white
///
///
open class DisabledSurfaceColorConfiguration: DisabledSurfaceColorable {
public typealias ObjectType = Surfaceable & Disabling
public var disabled = SurfaceColorConfiguration()
public var enabled = SurfaceColorConfiguration()
required public init(){}
public func getColor(_ object: any ObjectType) -> UIColor {
getDisabledColor(object)
}
}
///-------------------------------------------------------------------
///MARK -- BinaryColorable
///-------------------------------------------------------------------
public protocol BinaryColorable{
var useTrueColor: Bool { get }
}
extension BinaryColorable where Self: Control {
public var useTrueColor: Bool { return isSelected }
}
///-------------------------------------------------------------------
///MARK -- BinarySurfaceColorable
///-------------------------------------------------------------------
public protocol BinarySurfaceColorable: ObjectColorable {
var forTrue: SurfaceColorConfiguration { get set }
var forFalse: SurfaceColorConfiguration { get set }
}
extension BinarySurfaceColorable {
public func getBinaryColor<M: Surfaceable & BinaryColorable>(_ object: M) -> UIColor {
object.useTrueColor ? forTrue.getColor(object) : forFalse.getColor(object)
}
}
/// Meant to be used in a Object that implements the following interfaces for 4 possible color combinations
/// - BinaryColorable (var userTrueColor: Bool)
/// - Surfaceable (var surface: Surface)
///
/// let model = TestModel()
/// model.surface = .dark
/// model.on = true //this is read in the extension var userTrueColor
/// let config = BinarySurfaceColorConfiguration()
///
/// //True from BinaryColorable.userTrueColor
/// config.forTrue.lightColor = .black
/// config.forTrue.darkColor = .white
///
/// //False from BinaryColorable.userTrueColor
/// config.forFalse.lightColor = .red
/// config.forFalse.darkColor = .red
///
/// let textColor = config.getColor(model) //returns .white
///
///
final public class BinarySurfaceColorConfiguration: BinarySurfaceColorable {
public typealias ObjectType = Surfaceable & BinaryColorable
public var forTrue = SurfaceColorConfiguration()
public var forFalse = SurfaceColorConfiguration()
required public init(){}
public func getColor(_ object: any ObjectType) -> UIColor {
getBinaryColor(object)
}
}
///-------------------------------------------------------------------
///MARK -- BinaryDisabledSurfaceColorable
///-------------------------------------------------------------------
public protocol BinaryDisabledSurfaceColorable: ObjectColorable {
var forTrue: DisabledSurfaceColorConfiguration { get set }
var forFalse: DisabledSurfaceColorConfiguration { get set }
}
extension BinaryDisabledSurfaceColorable {
public func getBinaryColor<M: Disabling & Surfaceable & BinaryColorable>(_ object: M) -> UIColor {
object.useTrueColor ? forTrue.getColor(object) : forFalse.getColor(object)
}
}
/// Meant to be used in a Object that implements the following interfaces for 8 possible color combinations
/// - BinaryColorable (var userTrueColor: Bool)
/// - Disabling (var disabled: Bool)
/// - Surfaceable (var surface: Surface)
///
/// let model = TestModel()
/// model.on = false
/// model.disabled = false
/// model.surface = .light
/// let config = BinaryDisabledSurfaceColorConfiguration()
///
/// //True
/// config.forTrue.enabled.lightColor = .black
/// config.forTrue.enabled.darkColor = .white
/// config.forTrue.disabled.lightColor = .darkGray
/// config.forTrue.disabled.darkColor = .lightGray
///
/// //False
/// config.forFalse.enabled.lightColor = .red
/// config.forFalse.enabled.darkColor = .red
/// config.forFalse.disabled.lightColor =.darkGray
/// config.forFalse.disabled.darkColor = .lightGray
///
/// let textColor = config.getColor(model)
///
///
final public class BinaryDisabledSurfaceColorConfiguration: BinaryDisabledSurfaceColorable {
public typealias ObjectType = Disabling & Surfaceable & BinaryColorable
public var forTrue = DisabledSurfaceColorConfiguration()
public var forFalse = DisabledSurfaceColorConfiguration()
required public init(){}
public func getColor(_ object: any ObjectType) -> UIColor {
getBinaryColor(object)
}
}
public class ControlStateColorConfiguration: ObjectColorable {
public typealias ObjectType = UIControl & Surfaceable
public var disabled = SurfaceColorConfiguration()
public var normal = SurfaceColorConfiguration()
public var highlighted: SurfaceColorConfiguration?
public var selected: SurfaceColorConfiguration?
public var error: SurfaceColorConfiguration?
required public init(){}
public func setColorable(_ config: SurfaceColorConfiguration, for state: UIControl.State) {
switch state {
case .disabled:
disabled = config
case .highlighted:
highlighted = config
case .selected:
selected = config
case .error:
error = config
default:
normal = config
}
}
public func getColor(_ object: any ObjectType) -> UIColor {
if object.state == .disabled {
return disabled.getColor(object)
} else if let highlighted, object.state == .highlighted {
return highlighted.getColor(object)
} else if let selected, object.state == .selected {
return selected.getColor(object)
} else if let error, object.state == .error {
return error.getColor(object)
} else {
return normal.getColor(object)
}
}
}