diff --git a/Sources/TokamakCore/Modifiers/Effects/GeometryEffect.swift b/Sources/TokamakCore/Modifiers/Effects/GeometryEffect.swift new file mode 100644 index 00000000..f37893ed --- /dev/null +++ b/Sources/TokamakCore/Modifiers/Effects/GeometryEffect.swift @@ -0,0 +1,53 @@ +// Copyright 2020 Tokamak contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Created by Carson Katri on 7/3/20. +// + +// FIXME: Make `Animatable` +public protocol GeometryEffect: ViewModifier { + func effectValue(size: CGSize) -> ProjectionTransform +} + +public struct ProjectionTransform: Equatable { + public var m11: CGFloat = 1, m12: CGFloat = 0, m13: CGFloat = 0 + public var m21: CGFloat = 0, m22: CGFloat = 1, m23: CGFloat = 0 + public var m31: CGFloat = 0, m32: CGFloat = 0, m33: CGFloat = 1 + public init() {} + public init(_ m: CGAffineTransform) { + m11 = m.a + m12 = m.b + m21 = m.c + m22 = m.d + m31 = m.tx + m32 = m.ty + } + + public var isIdentity: Bool { + self == ProjectionTransform() + } + + public var isAffine: Bool { + m13 == 0 && m23 == 0 && m33 == 1 + } + + public mutating func invert() -> Bool { + self = inverted() + return true + } + + public func inverted() -> ProjectionTransform { + .init(CGAffineTransform(a: m11, b: m12, c: m21, d: m22, tx: m31, ty: m32).inverted()) + } +} diff --git a/Sources/TokamakCore/Modifiers/Effects/RotationEffect.swift b/Sources/TokamakCore/Modifiers/Effects/RotationEffect.swift new file mode 100644 index 00000000..0aeab014 --- /dev/null +++ b/Sources/TokamakCore/Modifiers/Effects/RotationEffect.swift @@ -0,0 +1,40 @@ +// Copyright 2020 Tokamak contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Created by Carson Katri on 7/3/20. +// + +public struct _RotationEffect: GeometryEffect { + public var angle: Angle + public var anchor: UnitPoint + + public init(angle: Angle, anchor: UnitPoint = .center) { + self.angle = angle + self.anchor = anchor + } + + public func effectValue(size: CGSize) -> ProjectionTransform { + .init(CGAffineTransform.identity.rotated(by: angle.radians)) + } + + public func body(content: Content) -> some View { + content + } +} + +extension View { + public func rotationEffect(_ angle: Angle, anchor: UnitPoint = .center) -> some View { + modifier(_RotationEffect(angle: angle, anchor: anchor)) + } +} diff --git a/Sources/TokamakCore/Modifiers/ModifiedContent.swift b/Sources/TokamakCore/Modifiers/ModifiedContent.swift index 2bdcfce7..eb79fa9f 100644 --- a/Sources/TokamakCore/Modifiers/ModifiedContent.swift +++ b/Sources/TokamakCore/Modifiers/ModifiedContent.swift @@ -24,10 +24,14 @@ public struct ModifiedContent { } } -extension ModifiedContent: View where Content: View, Modifier: ViewModifier { +extension ModifiedContent: View, ParentView where Content: View, Modifier: ViewModifier { public var body: Body { neverBody("ModifiedContent") } + + public var children: [AnyView] { + [AnyView(content)] + } } extension ModifiedContent: ViewModifier where Content: ViewModifier, Modifier: ViewModifier { diff --git a/Sources/TokamakCore/Styles/ListStyle.swift b/Sources/TokamakCore/Styles/ListStyle.swift new file mode 100644 index 00000000..1ba02bec --- /dev/null +++ b/Sources/TokamakCore/Styles/ListStyle.swift @@ -0,0 +1,88 @@ +// Copyright 2020 Tokamak contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Created by Carson Katri on 7/5/20. +// + +public protocol ListStyle {} +/// A protocol implemented on the renderer to create platform-specific list styles. +public protocol ListStyleDeferredToRenderer { + func listBody(_ content: ListBody) -> AnyView where ListBody: View + func listRow(_ row: Row) -> AnyView where Row: View + func sectionHeader
(_ header: Header) -> AnyView where Header: View + func sectionBody(_ section: SectionBody) -> AnyView where SectionBody: View + func sectionFooter