Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ShapeStyle support #108

Merged
merged 4 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Docs/Version.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
RELEASE_2021 - iOS 15.5 - macOS 12.7.1

RELEASE_2023 - iOS 17.4 - macOS 14.4.1

<!--RELEASE_2024 - iOS 18.0 Beta 1 - macOS 15.0 Beta 1-->
10 changes: 10 additions & 0 deletions Sources/OpenSwiftUI/Data/Other/BitVector64.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// BitVector64.swift
// OpenSwiftUI
//
// Audited for RELEASE_2021
// Status: WIP

struct BitVector64: OptionSet {
var rawValue: UInt64
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// ContentResponder.swift
// OpenSwiftUI
//
// Audited for RELEASE_2021
// Status: WIP

import Foundation
internal import COpenSwiftUI

protocol ContentResponder {
func contains(points: [CGPoint], size: CGSize) -> BitVector64
func contentPath(size: CGSize) -> Path
func contentPath(size: CGSize, kind: ContentShapeKinds) -> Path
}

extension ContentResponder {
func contains(points: [CGPoint], size: CGSize) -> BitVector64 {
guard !points.isEmpty else { return BitVector64() }
#if OPENSWIFTUI_RELEASE_2024
// TODO: mapBool
#else
fatalError("TODO")
#endif

Check warning on line 24 in Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentResponder.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentResponder.swift#L18-L24

Added lines #L18 - L24 were not covered by tests
}

func contentPath(size: CGSize) -> Path {
Path(CGRect(origin: .zero, size: size))

Check warning on line 28 in Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentResponder.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentResponder.swift#L27-L28

Added lines #L27 - L28 were not covered by tests
}

func contentPath(size: CGSize, kind: ContentShapeKinds) -> Path {
if kind == .interaction {
return contentPath(size: size)
} else {
let semantics = Semantics.v3
let shouldReturnEmptyPath = if let forced = Semantics.forced {
forced >= semantics
} else {
dyld_program_sdk_at_least(.init(semantics: semantics))

Check warning on line 39 in Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentResponder.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentResponder.swift#L31-L39

Added lines #L31 - L39 were not covered by tests
}
if shouldReturnEmptyPath {
return Path()
} else {
return contentPath(size: size)

Check warning on line 44 in Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentResponder.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentResponder.swift#L41-L44

Added lines #L41 - L44 were not covered by tests
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//
// ContentShapeKinds.swift
// OpenSwiftUI
//
// Audited for RELEASE_2023
// Status: Complete

import Foundation

/// A kind for the content shape of a view.
///
/// The kind is used by the system to influence various effects, hit-testing,
/// and more.
public struct ContentShapeKinds: OptionSet, Sendable {

/// The corresponding value of the raw type.
///
/// A new instance initialized with `rawValue` will be equivalent to this
/// instance. For example:
///
/// enum PaperSize: String {
/// case A4, A5, Letter, Legal
/// }
///
/// let selectedSize = PaperSize.Letter
/// print(selectedSize.rawValue)
/// // Prints "Letter"
///
/// print(selectedSize == PaperSize(rawValue: selectedSize.rawValue)!)
/// // Prints "true"
public var rawValue: Int

/// Creates a content shape kind.
public init(rawValue: Int) {
self.rawValue = rawValue

Check warning on line 35 in Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentShapeKinds.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/EventHandling/InputEvent/HitTesting/ContentShapeKinds.swift#L34-L35

Added lines #L34 - L35 were not covered by tests
}

/// The kind for hit-testing and accessibility.
///
/// Setting a content shape with this kind causes the view to hit-test
/// using the specified shape.
public static let interaction: ContentShapeKinds = ContentShapeKinds(rawValue: 1 << 0)

/// The kind for drag and drop previews.
///
/// When using this kind, only the preview shape is affected. To control the
/// shape used to hit-test and start the drag preview, use the `interaction`
/// kind.
@available(watchOS, unavailable)
@available(tvOS, unavailable)
public static let dragPreview: ContentShapeKinds = ContentShapeKinds(rawValue: 1 << 1)

/// The kind for context menu previews.
///
/// When using this kind, only the preview shape will be affected. To
/// control the shape used to hit-test and start the context menu
/// presentation, use the `.interaction` kind.
@available(tvOS 17.0, *)
@available(macOS, unavailable)
@available(watchOS, unavailable)
public static let contextMenuPreview: ContentShapeKinds = ContentShapeKinds(rawValue: 1 << 2)

/// The kind for hover effects.
///
/// When using this kind, only the preview shape is affected. To control
/// the shape used to hit-test and start the effect, use the `interaction`
/// kind.
///
/// This kind does not affect the `onHover` modifier.
@available(macOS, unavailable)
@available(watchOS, unavailable)
@available(tvOS, unavailable)
public static let hoverEffect: ContentShapeKinds = ContentShapeKinds(rawValue: 1 << 3)

#if OPENSWIFTUI_SUPPORT_2023_API
/// The kind for accessibility visuals and sorting.
///
/// Setting a content shape with this kind causes the accessibility frame
/// and path of the view's underlying accessibility element to match the
/// shape without adjusting the hit-testing shape, updating the visual focus
/// ring that assistive apps, such as VoiceOver, draw, as well as how the
/// element is sorted. Updating the accessibility shape is only required if
/// the shape or size used to hit-test significantly diverges from the visual
/// shape of the view.
///
/// To control the shape for accessibility and hit-testing, use the `interaction` kind.
public static let accessibility: ContentShapeKinds = ContentShapeKinds(rawValue: 1 << 4)
#endif
}
2 changes: 2 additions & 0 deletions Sources/OpenSwiftUI/View/Graphic/Color/Color.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// TODO
public struct Color {}
38 changes: 0 additions & 38 deletions Sources/OpenSwiftUI/View/Shape/ShapeStyle.swift

This file was deleted.

73 changes: 73 additions & 0 deletions Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// AnyShapeStyle.swift
// OpenSwiftUI
//
// Audited for RELEASE_2021
// Status: Complete
// ID: ABC85937500395B09974756E9F651929

import Foundation
internal import OpenGraphShims

/// A type-erased ShapeStyle value.
@frozen
public struct AnyShapeStyle: ShapeStyle {
@usableFromInline
@frozen
package struct Storage: Equatable {
package var box: AnyShapeStyleBox

@usableFromInline
package static func == (lhs: Storage, rhs: Storage) -> Bool {
if lhs.box === rhs.box {
return true
} else {
return lhs.box.isEqual(to: rhs.box)

Check warning on line 25 in Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift#L21-L25

Added lines #L21 - L25 were not covered by tests
}
}
}

package var storage: Storage

/// Create an instance from `style`.
public init<S>(_ style: S) where S: ShapeStyle {
storage = .init(box: ShapeStyleBox(style))

Check warning on line 34 in Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift#L33-L34

Added lines #L33 - L34 were not covered by tests
}

public func _apply(to shape: inout _ShapeStyle_Shape) {
storage.box.apply(to: &shape)

Check warning on line 38 in Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift#L37-L38

Added lines #L37 - L38 were not covered by tests
}

public static func _apply(to type: inout _ShapeStyle_ShapeType) {
type.result = .none

Check warning on line 42 in Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift#L41-L42

Added lines #L41 - L42 were not covered by tests
}

#if OPENSWIFTUI_SUPPORT_2023_API
public typealias Resolved = Never
#endif
}

/// Abstract base class for type-erased ShapeStyle storage.
@usableFromInline
package class AnyShapeStyleBox {
package func apply(to shape: inout _ShapeStyle_Shape) {}
package func isEqual(to other: AnyShapeStyleBox) -> Bool { false }

Check warning on line 54 in Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift#L53-L54

Added lines #L53 - L54 were not covered by tests
}

// ID: ABC85937500395B09974756E9F651929
private final class ShapeStyleBox<S>: AnyShapeStyleBox where S: ShapeStyle {
let base: S

init(_ base: S) {
self.base = base

Check warning on line 62 in Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift#L61-L62

Added lines #L61 - L62 were not covered by tests
}

override func apply(to shape: inout _ShapeStyle_Shape) {
base._apply(to: &shape)

Check warning on line 66 in Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift#L65-L66

Added lines #L65 - L66 were not covered by tests
}

override func isEqual(to other: AnyShapeStyleBox) -> Bool {
let otherBox = other as? Self
return otherBox.map { compareValues(base, $0.base) } ?? false

Check warning on line 71 in Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/View/Shape/ShapeStyle/AnyShapeStyle.swift#L69-L71

Added lines #L69 - L71 were not covered by tests
}
}
Loading
Loading