diff --git a/Dev/Brightroom.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Dev/Brightroom.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3546f2f7..cd673f15 100644 --- a/Dev/Brightroom.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Dev/Brightroom.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/VergeGroup/Normalization", "state" : { - "revision" : "6e7cb1ddeda4d0f1d2fbf8ca6d25ecd8ed6ba917", - "version" : "1.1.0" + "revision" : "360cc940e9c9f5c14db229ea9757c1b18a541fff", + "version" : "2.0.1" } }, { @@ -59,8 +59,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/VergeGroup/swift-concurrency-task-manager", "state" : { - "revision" : "3fcfb05f115a3b5bc24f0dfe0d35137f3e398f0b", - "version" : "1.3.1" + "revision" : "87605b623fa1a02c657534251ae238a56bc0d15c", + "version" : "3.0.0" } }, { @@ -68,17 +68,26 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/VergeGroup/swift-macro-state-struct", "state" : { - "revision" : "88e3937abd26b76bafe9027938538966457f156f", - "version" : "1.0.0" + "revision" : "f19ad3018ad718f9af725cbbc66a9d87f78d4780", + "version" : "3.0.1" } }, { "identity" : "swift-syntax", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-syntax.git", + "location" : "https://github.com/swiftlang/swift-syntax.git", + "state" : { + "revision" : "4799286537280063c85a32f09884cfbca301b1a1", + "version" : "602.0.0" + } + }, + { + "identity" : "swift-typed-identifier", + "kind" : "remoteSourceControl", + "location" : "https://github.com/VergeGroup/swift-typed-identifier", "state" : { - "revision" : "0687f71944021d616d34d922343dcef086855920", - "version" : "600.0.1" + "revision" : "ea7afa2ce943c6bf3ef87d385c8a6e9f67fea4f3", + "version" : "2.0.4" } }, { @@ -117,22 +126,13 @@ "version" : "1.0.0" } }, - { - "identity" : "typedidentifier", - "kind" : "remoteSourceControl", - "location" : "https://github.com/VergeGroup/TypedIdentifier", - "state" : { - "revision" : "284340409ba47858a1b3c353dcef9c21303953db", - "version" : "2.0.3" - } - }, { "identity" : "verge", "kind" : "remoteSourceControl", "location" : "https://github.com/VergeGroup/Verge.git", "state" : { - "revision" : "b2e5d4b162797119ae0bf2e7609fc74faca00418", - "version" : "14.0.0-beta.2" + "revision" : "084a448dc2dac9bbaa79a70e100a1364d8afbd95", + "version" : "14.1.2" } } ], diff --git a/Dev/Sources/SwiftUIDemo/DemoCropView.swift b/Dev/Sources/SwiftUIDemo/DemoCropView.swift index e1a5216a..8efbdceb 100644 --- a/Dev/Sources/SwiftUIDemo/DemoCropView.swift +++ b/Dev/Sources/SwiftUIDemo/DemoCropView.swift @@ -11,25 +11,26 @@ import BrightroomUI import BrightroomUIPhotosCrop import SwiftUI import UIKit +import Verge struct DemoCropView: View { - @StateObject var editingStack: EditingStack + @ReadingObject var editingStackState: EditingStack.State @State var resultImage: ResultImage? init( editingStack: @escaping () -> EditingStack ) { - self._editingStack = .init(wrappedValue: editingStack()) + self._editingStackState = .init(editingStack) } var body: some View { ZStack { VStack { - PhotosCropRotating(editingStack: { editingStack }) + PhotosCropRotating(editingStack: { $editingStackState.driver }) // Button("Done") { -// let image = try! editingStack.makeRenderer().render().cgImage +// let image = try! $editingStackState.driver.makeRenderer().render().cgImage // self.resultImage = .init(cgImage: image) // } } @@ -38,7 +39,7 @@ struct DemoCropView: View { HStack { Spacer() Button("Done") { - let image = try! editingStack.makeRenderer().render().cgImage + let image = try! $editingStackState.driver.makeRenderer().render().cgImage self.resultImage = .init(cgImage: image) } .buttonStyle(.borderedProminent) @@ -55,13 +56,13 @@ struct DemoCropView: View { } // .safeAreaInset(edge: .top, content: { // Button("Done") { -// let image = try! editingStack.makeRenderer().render().cgImage +// let image = try! $editingStackState.driver.makeRenderer().render().cgImage // self.resultImage = .init(cgImage: image) // } // }) .onAppear { - editingStack.start() + $editingStackState.driver.start() } .sheet(item: $resultImage) { RenderedResultView(result: $0) diff --git a/Dev/Sources/SwiftUIDemo/DemoCropView2.swift b/Dev/Sources/SwiftUIDemo/DemoCropView2.swift index 44c00210..d377c60a 100644 --- a/Dev/Sources/SwiftUIDemo/DemoCropView2.swift +++ b/Dev/Sources/SwiftUIDemo/DemoCropView2.swift @@ -12,10 +12,11 @@ import BrightroomUIPhotosCrop import SwiftUI import UIKit import SwiftUISupport +import Verge struct DemoCropView2: View { - @StateObject var editingStack: EditingStack + @ReadingObject var editingStackState: EditingStack.State @State var resultImage: ResultImage? @State var angle: EditingCrop.AdjustmentAngle = .zero @State var baselineAngle: EditingCrop.AdjustmentAngle = .zero @@ -24,7 +25,7 @@ struct DemoCropView2: View { init( editingStack: @escaping () -> EditingStack ) { - self._editingStack = .init(wrappedValue: editingStack()) + self._editingStackState = .init(editingStack) } var body: some View { @@ -35,7 +36,7 @@ struct DemoCropView2: View { Spacer() SwiftUICropView( - editingStack: editingStack, + editingStack: $editingStackState.driver, isGuideInteractionEnabled: false, areAnimationsEnabled: false, contentInset: .init(top: 20, left: 20, bottom: 20, right: 20), @@ -70,8 +71,8 @@ struct DemoCropView2: View { .frame(height: 300) .clipped() .background(Color.gray) - - ViewHost(instantiated: ImagePreviewView(editingStack: editingStack)) + + ViewHost(instantiated: ImagePreviewView(editingStack: $editingStackState.driver)) .background(Color.black) .cornerRadius(24, style: .continuous) .padding(.init(top: 20, leading: 20, bottom: 20, trailing: 20)) @@ -96,7 +97,7 @@ struct DemoCropView2: View { HStack { Spacer() Button("Done") { - let image = try! editingStack.makeRenderer().render().cgImage + let image = try! $editingStackState.driver.makeRenderer().render().cgImage self.resultImage = .init(cgImage: image) } .buttonStyle(.borderedProminent) @@ -112,7 +113,7 @@ struct DemoCropView2: View { } .onAppear { - editingStack.start() + $editingStackState.driver.start() } .sheet(item: $resultImage) { RenderedResultView(result: $0) diff --git a/Dev/Sources/SwiftUIDemo/DemoFilterView.swift b/Dev/Sources/SwiftUIDemo/DemoFilterView.swift index cbf7bf04..5e5f0a6b 100644 --- a/Dev/Sources/SwiftUIDemo/DemoFilterView.swift +++ b/Dev/Sources/SwiftUIDemo/DemoFilterView.swift @@ -4,6 +4,7 @@ import BrightroomUI import SwiftUI import SwiftUISupport import UIKit +import Verge struct DemoFilterView: View { @@ -93,7 +94,7 @@ struct DemoFilterView: View { let grayscaleFilter: GrayscaleFilter = .init() let motionBlurFilter: MotionBlurFilter = .init() - @StateObject var editingStack: EditingStack + @ReadingObject var editingStackState: EditingStack.State @State var invertToggle: Bool = false @State var grayscaleToggle: Bool = false @State var motionBlurToggle: Bool = false @@ -103,15 +104,15 @@ struct DemoFilterView: View { init( editingStack: @escaping () -> EditingStack ) { - self._editingStack = .init(wrappedValue: editingStack()) + self._editingStackState = .init(editingStack) } var body: some View { VStack { - ViewHost(instantiated: ImagePreviewView(editingStack: editingStack)) + ViewHost(instantiated: ImagePreviewView(editingStack: $editingStackState.driver)) - SwiftUICropView(editingStack: editingStack, contentInset: .zero) + SwiftUICropView(editingStack: $editingStackState.driver, contentInset: .zero) .clipped() VStack { @@ -120,7 +121,7 @@ struct DemoFilterView: View { Toggle("MotionBlur", isOn: $motionBlurToggle) } .onChange(of: [invertToggle, grayscaleToggle, motionBlurToggle], perform: { _ in - editingStack.set(filters: { + $editingStackState.driver.set(filters: { $0.additionalFilters = [ grayscaleToggle ? grayscaleFilter.asAny() : nil, invertToggle ? invertFilter.asAny() : nil, @@ -131,7 +132,7 @@ struct DemoFilterView: View { .padding() Button("Done") { - try! editingStack.makeRenderer().render { result in + try! $editingStackState.driver.makeRenderer().render { result in switch result { case let .success(rendered): self.resultImage = .init(cgImage: rendered.cgImage) @@ -143,7 +144,7 @@ struct DemoFilterView: View { } .onAppear { - editingStack.start() + $editingStackState.driver.start() } .sheet(item: $resultImage) { RenderedResultView(result: $0) diff --git a/Dev/Sources/SwiftUIDemo/IsolatedEditingView.swift b/Dev/Sources/SwiftUIDemo/IsolatedEditingView.swift index a0da9e49..bdf228e6 100644 --- a/Dev/Sources/SwiftUIDemo/IsolatedEditingView.swift +++ b/Dev/Sources/SwiftUIDemo/IsolatedEditingView.swift @@ -1,17 +1,22 @@ import BrightroomEngine import BrightroomUI import SwiftUI +import Verge struct IsolatedEditinView: View { - @StateObject var editingStack = Mocks.makeEditingStack(image: Mocks.imageHorizontal()) + @ReadingObject var editingStackState: EditingStack.State @State private var fullScreenView: FullscreenIdentifiableView? + init() { + self._editingStackState = .init { Mocks.makeEditingStack(image: Mocks.imageHorizontal()) } + } + var body: some View { Form.init { Button("Crop") { fullScreenView = .init { SwiftUIPhotosCropView( - editingStack: editingStack, + editingStack: $editingStackState.driver, onDone: {}, onCancel: {} ) @@ -20,11 +25,11 @@ struct IsolatedEditinView: View { } Button("Custom Crop") { - fullScreenView = .init { DemoCropView(editingStack: {editingStack}) } + fullScreenView = .init { DemoCropView(editingStack: { $editingStackState.driver }) } } Button("Blur Mask") { - fullScreenView = .init { MaskingViewWrapper(editingStack: editingStack) } + fullScreenView = .init { MaskingViewWrapper(editingStack: $editingStackState.driver) } } } .navigationTitle("Isolated-Editing") diff --git a/Package.resolved b/Package.resolved index ad79ef1a..1f6a7ae3 100644 --- a/Package.resolved +++ b/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/VergeGroup/Normalization", "state" : { - "revision" : "6e7cb1ddeda4d0f1d2fbf8ca6d25ecd8ed6ba917", - "version" : "1.1.0" + "revision" : "360cc940e9c9f5c14db229ea9757c1b18a541fff", + "version" : "2.0.1" } }, { @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/FluidGroup/PrecisionLevelSlider", "state" : { - "revision" : "3e460c1cea5ec916f7185948bc0a4e093e20f7a5", - "version" : "2.1.0" + "revision" : "d16becc518758b6f984ff07f8e8c6a0fa9245492", + "version" : "2.2.0" } }, { @@ -23,8 +23,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/ReactiveX/RxSwift.git", "state" : { - "revision" : "7e01c05f25c025143073eaa3be3532f9375c614b", - "version" : "6.1.0" + "revision" : "5734ad2b6d7d4c0656df3d09ca4ce54fa3c09913", + "version" : "6.10.1" } }, { @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-atomics.git", "state" : { - "revision" : "cd142fd2f64be2100422d658e7411e39489da985", - "version" : "1.2.0" + "revision" : "b601256eab081c0f92f059e12818ac1d4f178ff7", + "version" : "1.3.0" } }, { @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections", "state" : { - "revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb", - "version" : "1.1.0" + "revision" : "7b847a3b7008b2dc2f47ca3110d8c782fb2e5c7e", + "version" : "1.3.0" } }, { @@ -50,8 +50,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/VergeGroup/swift-concurrency-task-manager", "state" : { - "revision" : "9f686139a7d08ecca12d64a7a9bdf81cb1a1c986", - "version" : "1.2.0" + "revision" : "87605b623fa1a02c657534251ae238a56bc0d15c", + "version" : "3.0.0" } }, { @@ -59,8 +59,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/VergeGroup/swift-macro-state-struct", "state" : { - "revision" : "e13aa7350af0407d74552198a438cd1cb4b74c7d", - "version" : "2.2.0" + "revision" : "f19ad3018ad718f9af725cbbc66a9d87f78d4780", + "version" : "3.0.1" } }, { @@ -68,8 +68,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/swiftlang/swift-syntax.git", "state" : { - "revision" : "0687f71944021d616d34d922343dcef086855920", - "version" : "600.0.1" + "revision" : "4799286537280063c85a32f09884cfbca301b1a1", + "version" : "602.0.0" + } + }, + { + "identity" : "swift-typed-identifier", + "kind" : "remoteSourceControl", + "location" : "https://github.com/VergeGroup/swift-typed-identifier.git", + "state" : { + "revision" : "ea7afa2ce943c6bf3ef87d385c8a6e9f67fea4f3", + "version" : "2.0.4" } }, { @@ -77,8 +86,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/FluidGroup/swiftui-Hosting", "state" : { - "revision" : "7e8eaca72eae910d6d3b6272c263c6c3a10b755c", - "version" : "1.2.0" + "revision" : "f0f309cbb9a7e055bc57e931a3506ebb26bf0134", + "version" : "2.6.0" } }, { @@ -99,22 +108,13 @@ "version" : "1.0.0" } }, - { - "identity" : "typedidentifier", - "kind" : "remoteSourceControl", - "location" : "https://github.com/VergeGroup/TypedIdentifier", - "state" : { - "revision" : "284340409ba47858a1b3c353dcef9c21303953db", - "version" : "2.0.3" - } - }, { "identity" : "verge", "kind" : "remoteSourceControl", - "location" : "https://github.com/VergeGroup/Verge.git", + "location" : "https://github.com/VergeGroup/Verge", "state" : { - "revision" : "331d2ae4493c7aae0e5333c0d93d6173cced9325", - "version" : "14.0.0-beta.7" + "revision" : "084a448dc2dac9bbaa79a70e100a1364d8afbd95", + "version" : "14.1.2" } } ], diff --git a/Sources/BrightroomEngine/Core/EditingStack.swift b/Sources/BrightroomEngine/Core/EditingStack.swift index 71f99385..1beee6e0 100644 --- a/Sources/BrightroomEngine/Core/EditingStack.swift +++ b/Sources/BrightroomEngine/Core/EditingStack.swift @@ -66,6 +66,7 @@ open class EditingStack: Hashable, StoreDriverType { /** A representation of state in EditingStack */ + @Tracking public struct State: Equatable { public struct Loading: Equatable {} @@ -190,7 +191,7 @@ open class EditingStack: Hashable, StoreDriverType { } - public fileprivate(set) var hasStartedEditing = false + public fileprivate(set) var hasStartedEditing: Bool = false /** A Boolean value that indicates whether the image is currently loading for editing. */ diff --git a/Sources/BrightroomUIPhotosCrop/PhotosCropRotating/PhotosCropRotating.swift b/Sources/BrightroomUIPhotosCrop/PhotosCropRotating/PhotosCropRotating.swift index ab341102..89b7c17a 100644 --- a/Sources/BrightroomUIPhotosCrop/PhotosCropRotating/PhotosCropRotating.swift +++ b/Sources/BrightroomUIPhotosCrop/PhotosCropRotating/PhotosCropRotating.swift @@ -51,7 +51,7 @@ public struct PhotosCropRotating: View { } } - @StateObject var editingStack: EditingStack + @ReadingObject var editingStackState: EditingStack.State @State private var rotation: EditingCrop.Rotation? @State private var adjustmentAngle: EditingCrop.AdjustmentAngle? @@ -67,11 +67,11 @@ public struct PhotosCropRotating: View { public init( editingStack: @escaping () -> EditingStack ) { - self._editingStack = .init(wrappedValue: editingStack()) + self._editingStackState = .init(editingStack) } private var isLoading: Bool { - editingStack.state.isLoading + editingStackState.isLoading } public var body: some View { @@ -110,7 +110,7 @@ public struct PhotosCropRotating: View { Spacer() - if editingStack.state.loadedState?.hasUncommitedChanges ?? false { + if editingStackState.loadedState?.hasUncommitedChanges ?? false { Button { reset() } label: { @@ -143,7 +143,7 @@ public struct PhotosCropRotating: View { .zIndex(1) SwiftUICropView( - editingStack: editingStack, + editingStack: $editingStackState.driver, isAutoApplyEditingStackEnabled: true, stateHandler: { state in @@ -187,7 +187,7 @@ public struct PhotosCropRotating: View { } } .onAppear { - editingStack.start() + $editingStackState.driver.start() } } @@ -280,7 +280,7 @@ public struct PhotosCropRotating: View { let isDirectionButtonDisabled: Bool = { - guard let _ = editingStack.state.loadedState else { + guard let _ = editingStackState.loadedState else { return true } @@ -366,7 +366,7 @@ public struct PhotosCropRotating: View { Group { - let sourceDirection = editingStack.state.loadedState.map({ Direction(.init($0.imageSize)) }) + let sourceDirection = editingStackState.loadedState.map({ Direction(.init($0.imageSize)) }) let direction = croppingAspectRatio.map({ Direction($0) }) ?? sourceDirection switch sourceDirection { @@ -379,9 +379,9 @@ public struct PhotosCropRotating: View { case .vertical: AspectRationButton( title: Text("ORIGINAL"), - isSelected: croppingAspectRatio == editingStack.state.loadedState.map { .init($0.imageSize) } + isSelected: croppingAspectRatio == editingStackState.loadedState.map { .init($0.imageSize) } ) { - guard let imageSize = editingStack.state.loadedState?.imageSize else { + guard let imageSize = editingStackState.loadedState?.imageSize else { return } croppingAspectRatio = PixelAspectRatio.init(imageSize) @@ -389,9 +389,9 @@ public struct PhotosCropRotating: View { case .horizontal: AspectRationButton( title: Text("ORIGINAL"), - isSelected: croppingAspectRatio == editingStack.state.loadedState.map { .init($0.imageSize).swapped() } + isSelected: croppingAspectRatio == editingStackState.loadedState.map { .init($0.imageSize).swapped() } ) { - guard let imageSize = editingStack.state.loadedState?.imageSize else { + guard let imageSize = editingStackState.loadedState?.imageSize else { return } croppingAspectRatio = PixelAspectRatio.init(imageSize).swapped() @@ -404,9 +404,9 @@ public struct PhotosCropRotating: View { case .vertical: AspectRationButton( title: Text("ORIGINAL"), - isSelected: croppingAspectRatio == editingStack.state.loadedState.map { .init($0.imageSize).swapped() } + isSelected: croppingAspectRatio == editingStackState.loadedState.map { .init($0.imageSize).swapped() } ) { - guard let imageSize = editingStack.state.loadedState?.imageSize else { + guard let imageSize = editingStackState.loadedState?.imageSize else { return } croppingAspectRatio = PixelAspectRatio.init(imageSize).swapped() @@ -414,9 +414,9 @@ public struct PhotosCropRotating: View { case .horizontal: AspectRationButton( title: Text("ORIGINAL"), - isSelected: croppingAspectRatio == editingStack.state.loadedState.map { .init($0.imageSize) } + isSelected: croppingAspectRatio == editingStackState.loadedState.map { .init($0.imageSize) } ) { - guard let imageSize = editingStack.state.loadedState?.imageSize else { + guard let imageSize = editingStackState.loadedState?.imageSize else { return } croppingAspectRatio = PixelAspectRatio.init(imageSize) diff --git a/submodules/muukii/Reveal-SDK b/submodules/muukii/Reveal-SDK index 76b02972..039bf6b6 160000 --- a/submodules/muukii/Reveal-SDK +++ b/submodules/muukii/Reveal-SDK @@ -1 +1 @@ -Subproject commit 76b02972c18f14c717751f10bbc2d6b07dab85c7 +Subproject commit 039bf6b6f75ef67b5a8678b8caaa1b01e6708745