Rename Image to ImageView, add Image props (#55)
This allows adding props for components that accept images, for example `Switch` is now able to implement `onImage` and `offImage` props. * Add separate (empty for now) Image prop * Implement Image, add Switch {on,off}Image props
This commit is contained in:
parent
570c2677d6
commit
a570352abc
|
@ -18,9 +18,9 @@ struct ImageExample: PureLeafComponent {
|
|||
axis: .vertical,
|
||||
distribution: .fillEqually
|
||||
), [
|
||||
Image.node(.init(
|
||||
ImageView.node(.init(
|
||||
Style(contentMode: .scaleAspectFit),
|
||||
name: "tokamak"
|
||||
image: Image(name: "tokamak")
|
||||
)),
|
||||
])
|
||||
}
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
//
|
||||
// Image.swift
|
||||
// Tokamak
|
||||
//
|
||||
// Created by Matvii Hodovaniuk on 2/17/19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct Image: HostComponent {
|
||||
public typealias Children = [AnyNode]
|
||||
|
||||
public struct Props: Equatable, StyleProps {
|
||||
public enum RenderingMode {
|
||||
case automatic
|
||||
case alwaysOriginal
|
||||
case alwaysTemplate
|
||||
}
|
||||
|
||||
public enum Source: Equatable {
|
||||
case name(String)
|
||||
case data(Data)
|
||||
}
|
||||
|
||||
// when changed initializes new image with `UIImage(named:)`
|
||||
// or `UIImage(data:)`
|
||||
public let source: Source
|
||||
|
||||
// when changed creates new image with `withRenderingMode`
|
||||
public let renderingMode: RenderingMode
|
||||
|
||||
// when changed initializes new image with given scale
|
||||
public let scale: Double
|
||||
|
||||
// mirrors `flipsForRightToLeftLayoutDirection`
|
||||
public let flipsForRTL: Bool
|
||||
|
||||
public let style: Style?
|
||||
|
||||
public init(
|
||||
_ style: Style? = nil,
|
||||
flipsForRTL: Bool = false,
|
||||
name: String,
|
||||
renderingMode: RenderingMode = .automatic,
|
||||
scale: Double = 1.0
|
||||
) {
|
||||
source = .name(name)
|
||||
self.renderingMode = renderingMode
|
||||
self.scale = scale
|
||||
self.flipsForRTL = flipsForRTL
|
||||
self.style = style
|
||||
}
|
||||
|
||||
public init(
|
||||
_ style: Style? = nil,
|
||||
data: Data,
|
||||
flipsForRTL: Bool = false,
|
||||
renderingMode: RenderingMode = .automatic,
|
||||
scale: Double = 1.0
|
||||
) {
|
||||
source = .data(data)
|
||||
self.renderingMode = renderingMode
|
||||
self.scale = scale
|
||||
self.flipsForRTL = flipsForRTL
|
||||
self.style = style
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// ImageView.swift
|
||||
// Tokamak
|
||||
//
|
||||
// Created by Matvii Hodovaniuk on 2/17/19.
|
||||
//
|
||||
|
||||
public struct ImageView: HostComponent {
|
||||
public typealias Children = [AnyNode]
|
||||
|
||||
public struct Props: Equatable, StyleProps {
|
||||
public let image: Image
|
||||
public let style: Style?
|
||||
|
||||
public init(
|
||||
_ style: Style? = nil,
|
||||
image: Image
|
||||
) {
|
||||
self.image = image
|
||||
self.style = style
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,12 +14,16 @@ public struct Switch: HostComponent {
|
|||
public let valueHandler: Handler<Bool>?
|
||||
public let isEnabled: Bool
|
||||
public let isAnimated: Bool
|
||||
public let onImage: Image?
|
||||
public let offImage: Image?
|
||||
|
||||
public init(
|
||||
_ style: Style? = nil,
|
||||
handlers: EventHandlers = [:],
|
||||
isAnimated: Bool = true,
|
||||
isEnabled: Bool = true,
|
||||
offImage: Image? = nil,
|
||||
onImage: Image? = nil,
|
||||
value: Bool,
|
||||
valueHandler: Handler<Bool>? = nil
|
||||
) {
|
||||
|
@ -29,6 +33,8 @@ public struct Switch: HostComponent {
|
|||
self.valueHandler = valueHandler
|
||||
self.isEnabled = isEnabled
|
||||
self.isAnimated = isAnimated
|
||||
self.offImage = offImage
|
||||
self.onImage = onImage
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// Image.swift
|
||||
// Tokamak
|
||||
//
|
||||
// Created by Max Desiatov on 26/02/2019.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct Image: Equatable {
|
||||
public enum RenderingMode {
|
||||
case automatic
|
||||
case alwaysOriginal
|
||||
case alwaysTemplate
|
||||
}
|
||||
|
||||
public enum Source: Equatable {
|
||||
case name(String)
|
||||
case data(Data)
|
||||
}
|
||||
|
||||
/// when changed initializes new image with given data or name
|
||||
public let source: Source
|
||||
|
||||
/// when changed creates new image with `withRenderingMode`
|
||||
public let renderingMode: RenderingMode
|
||||
|
||||
/// equivalent to `flipsForRightToLeftLayoutDirection` in UIKit
|
||||
public let flipsForRTL: Bool
|
||||
|
||||
// when changed initializes new image with given scale
|
||||
public let scale: Double
|
||||
|
||||
public init(
|
||||
flipsForRTL: Bool = false,
|
||||
name: String,
|
||||
renderingMode: RenderingMode = .automatic,
|
||||
scale: Double = 1.0
|
||||
) {
|
||||
source = .name(name)
|
||||
self.renderingMode = renderingMode
|
||||
self.scale = scale
|
||||
self.flipsForRTL = flipsForRTL
|
||||
}
|
||||
|
||||
public init(
|
||||
data: Data,
|
||||
flipsForRTL: Bool = false,
|
||||
renderingMode: RenderingMode = .automatic,
|
||||
scale: Double = 1.0
|
||||
) {
|
||||
source = .data(data)
|
||||
self.renderingMode = renderingMode
|
||||
self.scale = scale
|
||||
self.flipsForRTL = flipsForRTL
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ final class TokamakImage: UIImageView, Default {
|
|||
}
|
||||
|
||||
extension UIImage.RenderingMode {
|
||||
public init(_ rawValue: Image.Props.RenderingMode) {
|
||||
public init(_ rawValue: Image.RenderingMode) {
|
||||
switch rawValue {
|
||||
case .automatic:
|
||||
self = .automatic
|
||||
|
@ -27,27 +27,14 @@ extension UIImage.RenderingMode {
|
|||
}
|
||||
}
|
||||
|
||||
extension Image: UIViewComponent {
|
||||
extension ImageView: UIViewComponent {
|
||||
public typealias RefTarget = UIImageView
|
||||
|
||||
static func update(
|
||||
view box: ViewBox<TokamakImage>,
|
||||
_ props: Image.Props,
|
||||
_ props: ImageView.Props,
|
||||
_ children: [AnyNode]
|
||||
) {
|
||||
var image: UIImage?
|
||||
|
||||
switch props.source {
|
||||
case let .name(name):
|
||||
image = UIImage(named: name)
|
||||
case let .data(data):
|
||||
image = UIImage(data: data, scale: CGFloat(props.scale))
|
||||
}
|
||||
|
||||
if props.flipsForRTL {
|
||||
image = image?.imageFlippedForRightToLeftLayoutDirection()
|
||||
}
|
||||
|
||||
box.view.image = image?.withRenderingMode(.init(props.renderingMode))
|
||||
box.view.image = UIImage.from(image: props.image)
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ extension Label: UIViewComponent {
|
|||
view.textAlignment = NSTextAlignment(props.alignment)
|
||||
view.numberOfLines = props.numberOfLines
|
||||
view.lineBreakMode = NSLineBreakMode(props.lineBreakMode)
|
||||
props.textColor.flatMap { view.textColor = UIColor($0) }
|
||||
view.textColor = props.textColor.flatMap { UIColor($0) }
|
||||
view.text = children
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ extension Switch: UIValueComponent {
|
|||
static func update(valueBox: ValueControlBox<TokamakSwitch>,
|
||||
_ props: Switch.Props,
|
||||
_ children: Null) {
|
||||
valueBox.view.isAnimated = props.isAnimated
|
||||
let view = valueBox.view
|
||||
view.isAnimated = props.isAnimated
|
||||
view.onImage = props.onImage.flatMap { UIImage.from(image: $0) }
|
||||
view.offImage = props.onImage.flatMap { UIImage.from(image: $0) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// Image.swift
|
||||
// Tokamak
|
||||
//
|
||||
// Created by Max Desiatov on 26/02/2019.
|
||||
//
|
||||
|
||||
import Tokamak
|
||||
import UIKit
|
||||
|
||||
extension UIImage {
|
||||
static func from(image: Image) -> UIImage? {
|
||||
var result: UIImage?
|
||||
|
||||
switch image.source {
|
||||
case let .name(name):
|
||||
result = UIImage(named: name)
|
||||
case let .data(data):
|
||||
result = UIImage(data: data, scale: CGFloat(image.scale))
|
||||
}
|
||||
|
||||
if image.flipsForRTL {
|
||||
result = result?.imageFlippedForRightToLeftLayoutDirection()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
|
@ -25,8 +25,10 @@
|
|||
A6AB60B5221C70340063F88A /* ContentMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6AB60B4221C70340063F88A /* ContentMode.swift */; };
|
||||
A6D188EC221F1CA300C3947C /* Accessibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6D188EB221F1CA300C3947C /* Accessibility.swift */; };
|
||||
A6D188EE2220221B00C3947C /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6D188ED2220221B00C3947C /* TextField.swift */; };
|
||||
D1B4F8DB221AFB0E00C53C42 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4F8D9221AFB0800C53C42 /* Image.swift */; };
|
||||
D1B4F8DD221AFB2B00C53C42 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4F8DC221AFB2B00C53C42 /* Image.swift */; };
|
||||
D1B4F8DB221AFB0E00C53C42 /* ImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4F8D9221AFB0800C53C42 /* ImageView.swift */; };
|
||||
D1B4F8DD221AFB2B00C53C42 /* ImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4F8DC221AFB2B00C53C42 /* ImageView.swift */; };
|
||||
D1CFC81D222546F500B03222 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CFC81C222546F500B03222 /* Image.swift */; };
|
||||
D1CFC8202225622D00B03222 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CFC81E222561AD00B03222 /* Image.swift */; };
|
||||
OBJ_153 /* AnyEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_66 /* AnyEquatable.swift */; };
|
||||
OBJ_154 /* AnyNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_67 /* AnyNode.swift */; };
|
||||
OBJ_155 /* Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_68 /* Components.swift */; };
|
||||
|
@ -190,8 +192,10 @@
|
|||
A6D188EB221F1CA300C3947C /* Accessibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Accessibility.swift; sourceTree = "<group>"; };
|
||||
A6D188ED2220221B00C3947C /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
||||
A6D188EF2220222F00C3947C /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
||||
D1B4F8D9221AFB0800C53C42 /* Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
||||
D1B4F8DC221AFB2B00C53C42 /* Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
||||
D1B4F8D9221AFB0800C53C42 /* ImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageView.swift; sourceTree = "<group>"; };
|
||||
D1B4F8DC221AFB2B00C53C42 /* ImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageView.swift; sourceTree = "<group>"; };
|
||||
D1CFC81C222546F500B03222 /* Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
||||
D1CFC81E222561AD00B03222 /* Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
||||
OBJ_10 /* ContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerViewController.swift; sourceTree = "<group>"; };
|
||||
OBJ_100 /* FirstBaseline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstBaseline.swift; sourceTree = "<group>"; };
|
||||
OBJ_101 /* Height.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Height.swift; sourceTree = "<group>"; };
|
||||
|
@ -418,9 +422,9 @@
|
|||
OBJ_17 /* Host */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D1B4F8D9221AFB0800C53C42 /* Image.swift */,
|
||||
OBJ_18 /* Button.swift */,
|
||||
OBJ_19 /* DatePicker.swift */,
|
||||
D1B4F8D9221AFB0800C53C42 /* ImageView.swift */,
|
||||
OBJ_20 /* Label.swift */,
|
||||
OBJ_21 /* ListView.swift */,
|
||||
OBJ_22 /* ModalPresenter.swift */,
|
||||
|
@ -443,6 +447,7 @@
|
|||
OBJ_32 /* Color.swift */,
|
||||
OBJ_33 /* Constraint */,
|
||||
OBJ_52 /* Event.swift */,
|
||||
D1CFC81E222561AD00B03222 /* Image.swift */,
|
||||
OBJ_53 /* LineBreakMode.swift */,
|
||||
OBJ_54 /* Rectangle.swift */,
|
||||
A6AB60B4221C70340063F88A /* ContentMode.swift */,
|
||||
|
@ -555,11 +560,11 @@
|
|||
OBJ_70 /* Host */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D1B4F8DC221AFB2B00C53C42 /* Image.swift */,
|
||||
OBJ_71 /* Alert.swift */,
|
||||
OBJ_72 /* Animated.swift */,
|
||||
OBJ_73 /* Button.swift */,
|
||||
OBJ_74 /* DatePicker.swift */,
|
||||
D1B4F8DC221AFB2B00C53C42 /* ImageView.swift */,
|
||||
OBJ_75 /* Label.swift */,
|
||||
OBJ_76 /* ListView.swift */,
|
||||
OBJ_77 /* NavigationController.swift */,
|
||||
|
@ -568,8 +573,8 @@
|
|||
OBJ_80 /* StackView.swift */,
|
||||
OBJ_81 /* Stepper.swift */,
|
||||
OBJ_82 /* Switch.swift */,
|
||||
OBJ_83 /* View.swift */,
|
||||
A6D188ED2220221B00C3947C /* TextField.swift */,
|
||||
OBJ_83 /* View.swift */,
|
||||
);
|
||||
path = Host;
|
||||
sourceTree = "<group>";
|
||||
|
@ -619,6 +624,7 @@
|
|||
OBJ_93 /* Constraint */,
|
||||
OBJ_110 /* Event.swift */,
|
||||
OBJ_111 /* Insets.swift */,
|
||||
D1CFC81C222546F500B03222 /* Image.swift */,
|
||||
OBJ_112 /* LineBreakMode.swift */,
|
||||
OBJ_113 /* Rectangle.swift */,
|
||||
OBJ_114 /* Second.swift */,
|
||||
|
@ -781,6 +787,7 @@
|
|||
OBJ_159 /* DatePicker.swift in Sources */,
|
||||
OBJ_160 /* Label.swift in Sources */,
|
||||
OBJ_161 /* ListView.swift in Sources */,
|
||||
D1CFC81D222546F500B03222 /* Image.swift in Sources */,
|
||||
OBJ_162 /* NavigationController.swift in Sources */,
|
||||
OBJ_163 /* SegmentedControl.swift in Sources */,
|
||||
OBJ_164 /* Slider.swift in Sources */,
|
||||
|
@ -798,7 +805,7 @@
|
|||
OBJ_176 /* Bottom.swift in Sources */,
|
||||
A6D188EE2220221B00C3947C /* TextField.swift in Sources */,
|
||||
OBJ_177 /* Center.swift in Sources */,
|
||||
D1B4F8DD221AFB2B00C53C42 /* Image.swift in Sources */,
|
||||
D1B4F8DD221AFB2B00C53C42 /* ImageView.swift in Sources */,
|
||||
A6D188EC221F1CA300C3947C /* Accessibility.swift in Sources */,
|
||||
OBJ_178 /* CenterX.swift in Sources */,
|
||||
OBJ_179 /* CenterY.swift in Sources */,
|
||||
|
@ -896,8 +903,9 @@
|
|||
OBJ_276 /* CenterX.swift in Sources */,
|
||||
OBJ_277 /* CenterY.swift in Sources */,
|
||||
OBJ_278 /* Constrainable.swift in Sources */,
|
||||
D1B4F8DB221AFB0E00C53C42 /* Image.swift in Sources */,
|
||||
D1B4F8DB221AFB0E00C53C42 /* ImageView.swift in Sources */,
|
||||
OBJ_279 /* Constraint.swift in Sources */,
|
||||
D1CFC8202225622D00B03222 /* Image.swift in Sources */,
|
||||
OBJ_280 /* FirstBaseline.swift in Sources */,
|
||||
OBJ_281 /* Height.swift in Sources */,
|
||||
OBJ_282 /* LastBaseline.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue