Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// IgnoredByLayoutEffectUITests.swift
// OpenSwiftUIUITests

import Testing
import SnapshotTesting

@MainActor
@Suite(.snapshots(record: .never, diffTool: diffTool))
struct IgnoredByLayoutEffectUITests {
@Test(.disabled("Animation is not implmemented yet"))
func offsetIgnoredByLayout() {
struct ContentView: View {
var body: some View {
WobbleColorView()
}
}

struct WobbleEffect: GeometryEffect {
var amount: CGFloat = 10
var shakesPerUnit = 3
var animatableData: CGFloat

nonisolated func effectValue(size: CGSize) -> ProjectionTransform {
let translation = amount * sin(animatableData * .pi * CGFloat(shakesPerUnit))
return ProjectionTransform(CGAffineTransform(translationX: translation, y: 0))
}
}

struct WobbleColorView: View {
@State private var wobble = false

var body: some View {
Color.red.frame(width: 200, height: 200)
.modifier(_OffsetEffect(offset: CGSize(width: 0, height: 100)).ignoredByLayout())
}
}
openSwiftUIAssertSnapshot(of: ContentView())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// OffsetEffectUITests.swift
// OpenSwiftUIUITests

import Testing
import SnapshotTesting

@MainActor
@Suite(.snapshots(record: .never, diffTool: diffTool))
struct OffsetEffectUITests {
@Test
func offsetWithFrame() {
struct ContentView: View {
var body: some View {
Color.blue
.offset(x: 20, y: 15)
.frame(width: 80, height: 60)
.background(Color.red)
.overlay(Color.green.offset(x: 40, y: 30))
}
}
openSwiftUIAssertSnapshot(of: ContentView())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// IgnoredByLayoutEffect.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: Complete

public import Foundation

/// A geometry effect type that prevents another geometry effect
/// affecting coordinate space conversions during layout, i.e. the
/// transform introduced by the other effect is only used when
/// rendering, not when converting locations from one view to another.
/// This is often used to disable layout changes during transitions.
@available(OpenSwiftUI_v1_0, *)
@frozen
public struct _IgnoredByLayoutEffect<Base>: GeometryEffect where Base: GeometryEffect {
public var base: Base

public static var _affectsLayout: Bool { false }

@inlinable
public init(_ base: Base) {
self.base = base
}

public func effectValue(size: CGSize) -> ProjectionTransform {
base.effectValue(size: size)
}

public var animatableData: Base.AnimatableData {
get { base.animatableData }
set { base.animatableData = newValue }
}
}

@available(*, unavailable)
extension _IgnoredByLayoutEffect: Sendable {}

@available(OpenSwiftUI_v1_0, *)
extension _IgnoredByLayoutEffect: Equatable where Base: Equatable {}

@available(OpenSwiftUI_v1_0, *)
extension GeometryEffect {
/// Returns an effect that produces the same geometry transform as this
/// effect, but only applies the transform while rendering its view.
///
/// Use this method to disable layout changes during transitions. The view
/// ignores the transform returned by this method while the view is
/// performing its layout calculations.
@inlinable
public func ignoredByLayout() -> _IgnoredByLayoutEffect<Self> {
return _IgnoredByLayoutEffect(self)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// ID: 1B17C64D9E901A0054B49B69A4A2439D (SwiftUICore)

public import Foundation
package import OpenGraphShims

// MARK: - EnvironmentValues + Display [6.4.41]

Expand Down Expand Up @@ -43,6 +44,12 @@ extension CachedEnvironment.ID {
package static let pixelLength: CachedEnvironment.ID = .init()
}

extension _ViewInputs {
package var pixelLength: Attribute<CGFloat> {
mapEnvironment(id: .pixelLength) { $0.pixelLength }
}
}

private struct DisplayGamutKey: EnvironmentKey {
static var defaultValue: DisplayGamut { .sRGB }
}
Expand Down
34 changes: 31 additions & 3 deletions Sources/OpenSwiftUICore/Render/DisplayList/DisplayList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
// Status: WIP
// ID: F37E3733E490AA5E3BDC045E3D34D9F8 (SwiftUICore)

package import CoreGraphicsShims
package import Foundation
package import OpenGraphShims

// MARK: - _DisplayList_Identity

Expand Down Expand Up @@ -98,7 +100,11 @@ package struct DisplayList: Equatable {
// TODO
items.append(contentsOf: other.items)
// _openSwiftUIUnimplementedFailure()
}
}

package var isEmpty: Bool {
items.isEmpty
}
}

@available(*, unavailable)
Expand Down Expand Up @@ -204,9 +210,7 @@ extension DisplayList {
}

package enum Transform {
#if canImport(Darwin)
case affine(CGAffineTransform)
#endif
case projection(ProjectionTransform)
// case rotation(_RotationEffect.Data)
// case rotation3D(_Rotation3DEffect.Data)
Expand Down Expand Up @@ -428,6 +432,30 @@ extension DisplayList {
}
}

extension PreferencesInputs {
@inline(__always)
package var requiresDisplayList: Bool {
get {
contains(DisplayList.Key.self)
}
set {
if newValue {
add(DisplayList.Key.self)
} else {
remove(DisplayList.Key.self)
}
}
}
}

extension PreferencesOutputs {
@inline(__always)
package var displayList: Attribute<DisplayList>? {
get { self[DisplayList.Key.self] }
set { self[DisplayList.Key.self] = newValue }
}
}

// MARK: - DisplayList.Item + Extension

extension DisplayList.Item {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,24 @@ extension _DisplayList_StableIdentityMap: ProtobufMessage {
}
}

// TODO: Blocked by _ViewInputs
//extension _ViewInputs {
// package mutating func configureStableIDs(root: _DisplayList_StableIdentityRoot) {
// package func pushIdentity(_ identity: _DisplayList_Identity)
// package func makeStableIdentity() -> _DisplayList_StableIdentity
//}
extension _ViewInputs {
package mutating func configureStableIDs(root: _DisplayList_StableIdentityRoot) {
_openSwiftUIUnimplementedFailure()
}

package func pushIdentity(_ identity: _DisplayList_Identity) {

guard base.needsStableDisplayListIDs else {
return
}
self[_DisplayList_StableIdentityScope.self].attribute!.value.pushIdentity(identity)
}

package func makeStableIdentity() -> _DisplayList_StableIdentity {
// Log.internalError("expected stable IDs to be supported")
_openSwiftUIUnimplementedFailure()
}
}

extension _GraphInputs {
private func pushScope<ID>(id: ID) where ID: StronglyHashable {
Expand All @@ -110,7 +122,7 @@ extension _GraphInputs {
}

package mutating func pushStableID<ID>(_ id: ID) where ID: Hashable {
guard options.contains(.needsStableDisplayListIDs) else {
guard needsStableDisplayListIDs else {
return
}
if let stronglyHashable = id as? StronglyHashable {
Expand All @@ -121,35 +133,31 @@ extension _GraphInputs {
}

package mutating func pushStableIndex(_ index: Int) {
guard options.contains(.needsStableDisplayListIDs) else {
guard needsStableDisplayListIDs else {
return
}
pushScope(id: index)
}

package mutating func pushStableType(_ type: any Any.Type) {
#if OPENSWIFTUI_SUPPORT_2024_API
guard options.contains(.needsStableDisplayListIDs) else {
guard needsStableDisplayListIDs else {
return
}
pushScope(id: makeStableTypeData(type))
#endif
}

package var stableIDScope: WeakAttribute<DisplayList.StableIdentityScope>? {
guard !options.contains(.needsStableDisplayListIDs) else {
guard !needsStableDisplayListIDs else { // Question
return nil
}
let result = self[_DisplayList_StableIdentityScope.self]
return result.attribute == nil ? nil : result
}
}

#if OPENSWIFTUI_SUPPORT_2024_API
package func makeStableTypeData(_ type: any Any.Type) -> StrongHash {
unsafeBitCast(Metadata(type).signature, to: StrongHash.self)
}
#endif

package func makeStableIDData<ID>(from id: ID) -> StrongHash? {
guard let encodable = id as? Encodable else {
Expand Down
Loading