Skip to content

Commit

Permalink
Add Material to the HTML renderer (#418)
Browse files Browse the repository at this point in the history
  • Loading branch information
carson-katri committed Jul 7, 2021
1 parent 54146b8 commit 4a7748a
Show file tree
Hide file tree
Showing 13 changed files with 400 additions and 84 deletions.
34 changes: 30 additions & 4 deletions Sources/TokamakCore/Modifiers/StyleModifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,50 @@ public extension View {
) -> some View where V: View {
background(content(), alignment: alignment)
}
}

@frozen public struct _BackgroundShapeModifier<Style, Bounds>: ViewModifier, EnvironmentReader
where Style: ShapeStyle, Bounds: Shape
{
public var environment: EnvironmentValues!

public var style: Style
public var shape: Bounds
public var fillStyle: FillStyle

@inlinable
public init(style: Style, shape: Bounds, fillStyle: FillStyle) {
self.style = style
self.shape = shape
self.fillStyle = fillStyle
}

public func body(content: Content) -> some View {
content
.background(shape.fill(style, style: fillStyle))
}

public mutating func setContent(from values: EnvironmentValues) {
environment = values
}
}

public extension View {
@inlinable
func background<S, T>(
_ style: S,
in shape: T,
fillStyle: FillStyle = FillStyle()
) -> some View where S: ShapeStyle, T: Shape {
background {
shape.fill(style, style: fillStyle)
}
modifier(_BackgroundShapeModifier(style: style, shape: shape, fillStyle: fillStyle))
}

@inlinable
func background<S>(
in shape: S,
fillStyle: FillStyle = FillStyle()
) -> some View where S: Shape {
background(ForegroundStyle(), in: shape, fillStyle: fillStyle)
background(BackgroundStyle(), in: shape, fillStyle: fillStyle)
}
}

Expand Down
79 changes: 79 additions & 0 deletions Sources/TokamakCore/Shapes/ShapeStyles/BackgroundStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2020-2021 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/6/21.
//

public struct BackgroundStyle: ShapeStyle {
public init() {}

public func _apply(to shape: inout _ShapeStyle_Shape) {
if let backgroundStyle = shape.environment._backgroundStyle {
backgroundStyle._apply(to: &shape)
} else {
shape.result = .none
}
}

public static func _apply(to shape: inout _ShapeStyle_ShapeType) {}
}

extension EnvironmentValues {
private struct BackgroundStyleKey: EnvironmentKey {
static let defaultValue: AnyShapeStyle? = nil
}

public var _backgroundStyle: AnyShapeStyle? {
get {
self[BackgroundStyleKey.self]
}
set {
self[BackgroundStyleKey.self] = newValue
}
}
}

public extension View {
@inlinable
func background() -> some View {
modifier(_BackgroundStyleModifier(style: BackgroundStyle()))
}

@inlinable
func background<S>(_ style: S) -> some View where S: ShapeStyle {
modifier(_BackgroundStyleModifier(style: style))
}
}

@frozen public struct _BackgroundStyleModifier<Style>: ViewModifier, EnvironmentModifier,
EnvironmentReader
where Style: ShapeStyle
{
public var environment: EnvironmentValues!
public var style: Style

@inlinable
public init(style: Style) {
self.style = style
}

public typealias Body = Never
public mutating func setContent(from values: EnvironmentValues) {
environment = values
}

public func modifyEnvironment(_ values: inout EnvironmentValues) {
values._backgroundStyle = .init(styles: [style, style, style], environment: values)
}
}
53 changes: 53 additions & 0 deletions Sources/TokamakCore/Shapes/ShapeStyles/ForegroundStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,56 @@ public struct ForegroundStyle: ShapeStyle {

public static func _apply(to shape: inout _ShapeStyle_ShapeType) {}
}

extension EnvironmentValues {
private struct ForegroundStyleKey: EnvironmentKey {
static let defaultValue: AnyShapeStyle? = nil
}

public var _foregroundStyle: AnyShapeStyle? {
get {
self[ForegroundStyleKey.self]
}
set {
self[ForegroundStyleKey.self] = newValue
}
}
}

public extension View {
@inlinable
func foregroundStyle<S>(_ style: S) -> some View
where S: ShapeStyle
{
foregroundStyle(style, style, style)
}

@inlinable
func foregroundStyle<S1, S2>(_ primary: S1, _ secondary: S2) -> some View
where S1: ShapeStyle, S2: ShapeStyle
{
foregroundStyle(primary, secondary, secondary)
}

@inlinable
func foregroundStyle<S1, S2, S3>(_ primary: S1, _ secondary: S2,
_ tertiary: S3) -> some View
where S1: ShapeStyle, S2: ShapeStyle, S3: ShapeStyle
{
modifier(_ForegroundStyleModifier(styles: [primary, secondary, tertiary]))
}
}

@frozen public struct _ForegroundStyleModifier: ViewModifier, EnvironmentModifier {
public var styles: [ShapeStyle]

@inlinable
public init(styles: [ShapeStyle]) {
self.styles = styles
}

public typealias Body = Never
public func modifyEnvironment(_ values: inout EnvironmentValues) {
values._foregroundStyle = .init(styles: styles, environment: values)
}
}
57 changes: 57 additions & 0 deletions Sources/TokamakCore/Shapes/ShapeStyles/Material.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2020-2021 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/6/21.
//

public struct Material {
private let style: _MaterialStyle

private init(_ style: _MaterialStyle) {
self.style = style
}

public static let regular = Self(.regular)
public static let thick = Self(.thick)
public static let thin = Self(.thin)
public static let ultraThin = Self(.ultraThin)
public static let ultraThick = Self(.ultraThick)
}

public enum _MaterialStyle {
case regular
case thick
case thin
case ultraThin
case ultraThick
}

extension Material: ShapeStyle {
public func _apply(to shape: inout _ShapeStyle_Shape) {
shape.result = .resolved(
.foregroundMaterial(
_ColorProxy(Color._withScheme {
$0 == .light ? Color.white : Color.black
}).resolve(in: shape.environment),
style
)
)
}

public static func _apply(to shape: inout _ShapeStyle_ShapeType) {}
}

public extension Material {
static let bar = Self.regular
}
58 changes: 3 additions & 55 deletions Sources/TokamakCore/Shapes/ShapeStyles/ShapeStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ public struct _ShapeStyle_ShapeType {}
public indirect enum _ResolvedStyle {
case color(AnyColorBox.ResolvedValue)
// case paint(AnyResolvedPaint) // I think is used for Image as a ShapeStyle (SwiftUI.ImagePaint).
// TODO: Material
// case foregroundMaterial(AnyColorBox.ResolvedValue, MaterialStyle)
case foregroundMaterial(AnyColorBox.ResolvedValue, _MaterialStyle)
// case backgroundMaterial(AnyColorBox.ResolvedValue)
case array([_ResolvedStyle])
case opacity(Float, _ResolvedStyle)
Expand All @@ -138,6 +137,8 @@ public indirect enum _ResolvedStyle {
switch self {
case let .color(resolved):
return Color(_ConcreteColorBox(resolved))
case let .foregroundMaterial(resolved, _):
return Color(_ConcreteColorBox(resolved))
case let .array(children):
return children[level].color(at: level)
case let .opacity(opacity, resolved):
Expand All @@ -146,56 +147,3 @@ public indirect enum _ResolvedStyle {
}
}
}

extension EnvironmentValues {
private struct ForegroundStyleKey: EnvironmentKey {
static let defaultValue: AnyShapeStyle? = nil
}

public var _foregroundStyle: AnyShapeStyle? {
get {
self[ForegroundStyleKey.self]
}
set {
self[ForegroundStyleKey.self] = newValue
}
}
}

public extension View {
@inlinable
func foregroundStyle<S>(_ style: S) -> some View
where S: ShapeStyle
{
foregroundStyle(style, style, style)
}

@inlinable
func foregroundStyle<S1, S2>(_ primary: S1, _ secondary: S2) -> some View
where S1: ShapeStyle, S2: ShapeStyle
{
foregroundStyle(primary, secondary, secondary)
}

@inlinable
func foregroundStyle<S1, S2, S3>(_ primary: S1, _ secondary: S2,
_ tertiary: S3) -> some View
where S1: ShapeStyle, S2: ShapeStyle, S3: ShapeStyle
{
modifier(_ForegroundStyleModifier(styles: [primary, secondary, tertiary]))
}
}

@frozen public struct _ForegroundStyleModifier: ViewModifier, EnvironmentModifier {
public var styles: [ShapeStyle]

@inlinable
public init(styles: [ShapeStyle]) {
self.styles = styles
}

public typealias Body = Never
public func modifyEnvironment(_ values: inout EnvironmentValues) {
values._foregroundStyle = .init(styles: styles, environment: values)
}
}
3 changes: 3 additions & 0 deletions Sources/TokamakDOM/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public typealias Rectangle = TokamakCore.Rectangle
public typealias RoundedRectangle = TokamakCore.RoundedRectangle
public typealias ContainerRelativeShape = TokamakCore.ContainerRelativeShape

public typealias ForegroundStyle = TokamakCore.ForegroundStyle
public typealias Material = TokamakCore.Material

// MARK: Primitive values

public typealias Color = TokamakCore.Color
Expand Down
Loading

0 comments on commit 4a7748a

Please sign in to comment.