Skip to main content

get the new hstack working with thumbnails

ID
d7a568b
date
2023-06-09 21:32:29+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
0b26311
message
get the new hstack working with thumbnails
changed files
4 files, 119 additions, 47 deletions

Changed files

BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj (28688) → BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj (29350)

diff --git a/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj b/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj
index 7d7b55e..363ac31 100644
--- a/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj
+++ b/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj
@@ -8,6 +8,7 @@
 
 /* Begin PBXBuildFile section */
 		940331732A336B5100200C5D /* DeferredRendering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 940331722A336B5100200C5D /* DeferredRendering.swift */; };
+		945F17B02A33D167004FC479 /* NewThumbnailImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945F17AF2A33D167004FC479 /* NewThumbnailImage.swift */; };
 		94C5FFF22A33ADD4004ADDF5 /* PHFetchResultCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C5FFF12A33ADD4004ADDF5 /* PHFetchResultCollection.swift */; };
 		94C5FFF62A33B698004ADDF5 /* PHAssetHStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C5FFF52A33B698004ADDF5 /* PHAssetHStack.swift */; };
 		94D2C8B92A320E6F00BEE15B /* ReviewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94D2C8B82A320E6F00BEE15B /* ReviewState.swift */; };
@@ -48,6 +49,7 @@
 
 /* Begin PBXFileReference section */
 		940331722A336B5100200C5D /* DeferredRendering.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeferredRendering.swift; sourceTree = "<group>"; };
+		945F17AF2A33D167004FC479 /* NewThumbnailImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewThumbnailImage.swift; sourceTree = "<group>"; };
 		94C5FFF12A33ADD4004ADDF5 /* PHFetchResultCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PHFetchResultCollection.swift; sourceTree = "<group>"; };
 		94C5FFF52A33B698004ADDF5 /* PHAssetHStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PHAssetHStack.swift; sourceTree = "<group>"; };
 		94D2C8B82A320E6F00BEE15B /* ReviewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewState.swift; sourceTree = "<group>"; };
@@ -108,6 +110,14 @@
 			path = Helpers;
 			sourceTree = "<group>";
 		};
+		945F17AE2A33D15D004FC479 /* Thumbnails */ = {
+			isa = PBXGroup;
+			children = (
+				945F17AF2A33D167004FC479 /* NewThumbnailImage.swift */,
+			);
+			path = Thumbnails;
+			sourceTree = "<group>";
+		};
 		94D2C8B72A320E6600BEE15B /* Model */ = {
 			isa = PBXGroup;
 			children = (
@@ -178,6 +188,7 @@
 		94D7511A2A31A7A6005859E7 /* Views */ = {
 			isa = PBXGroup;
 			children = (
+				945F17AE2A33D15D004FC479 /* Thumbnails */,
 				940331742A336BEB00200C5D /* Helpers */,
 				94D7511B2A31A7B1005859E7 /* ThumbnailImage.swift */,
 				94D7511D2A31B243005859E7 /* FullSizeImage.swift */,
@@ -333,6 +344,7 @@
 				94D7511C2A31A7B1005859E7 /* ThumbnailImage.swift in Sources */,
 				94D7512B2A31D6AC005859E7 /* AssetHelpers.swift in Sources */,
 				94D2C8BD2A32796500BEE15B /* AlbumHelpers.swift in Sources */,
+				945F17B02A33D167004FC479 /* NewThumbnailImage.swift in Sources */,
 				94D2C8BF2A3299BD00BEE15B /* PhotosLibrary.swift in Sources */,
 				94C5FFF62A33B698004ADDF5 /* PHAssetHStack.swift in Sources */,
 				94D7511E2A31B243005859E7 /* FullSizeImage.swift in Sources */,

BlinkReviewer/BlinkReviewer/Views/PHAssetImage.swift (4533) → BlinkReviewer/BlinkReviewer/Views/PHAssetImage.swift (4581)

diff --git a/BlinkReviewer/BlinkReviewer/Views/PHAssetImage.swift b/BlinkReviewer/BlinkReviewer/Views/PHAssetImage.swift
index 1bff24e..8163d28 100644
--- a/BlinkReviewer/BlinkReviewer/Views/PHAssetImage.swift
+++ b/BlinkReviewer/BlinkReviewer/Views/PHAssetImage.swift
@@ -103,6 +103,7 @@ class PHAssetImage: NSObject, ObservableObject {
                         }
                         
                         if let imageResult = result {
+                            print("got image!")
                             self.image = imageResult
                             
                             if !self.isDegraded {

BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift (6900) → BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift (8684)

diff --git a/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift b/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift
index 69bbd10..26f7acb 100644
--- a/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift
+++ b/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift
@@ -12,6 +12,18 @@ struct PhotoReviewer: View {
     @EnvironmentObject var photosLibrary: PhotosLibrary
     @ObservedObject var fullSizeImage: PHAssetImage = PHAssetImage(nil, size: PHImageManagerMaximumSize, deliveryMode: .highQualityFormat)
     
+    // Which asset is currently in focus?
+    //
+    // i.e. scrolled to in the thumbnail pane, showing a big preview.
+    //
+    // This is 0-indexed and counts from the right -- that is, the rightmost item
+    // is the 0th.
+    @State var focusedAssetIndex: Int = 0
+    
+    var focusedAsset: PHAsset {
+        photosLibrary.assets2.object(at: focusedAssetIndex)
+    }
+    
     @State var selectedAssetIndex: Int = -1
     
     @State var showStatistics: Bool = false
@@ -21,55 +33,79 @@ struct PhotoReviewer: View {
         if photosLibrary.isPhotoLibraryAuthorized {
             ZStack {
                 VStack {
-                    let binding = Binding {
-                        selectedAssetIndex == -1 ? photosLibrary.assets2.count - 1 : selectedAssetIndex
-                    } set: {
-                        self.selectedAssetIndex = $0
-                    }
-                    
-                    ThumbnailList(selectedAssetIndex: binding)
-                        .environmentObject(photosLibrary)
-                        .background(.gray.opacity(0.3))
-                    
-                    FullSizeImage(image: fullSizeImage)
-                        .background(.black)
-                }
-                .background(.black)
-                .onAppear {
-                    selectedAssetIndex = photosLibrary.assets2.count - 1
-                    
-                    fullSizeImage.asset = photosLibrary.assets2.object(at: photosLibrary.assets2.count - 1 - selectedAssetIndex)
-                    
-                    NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in
-                        handleKeyEvent(event)
-                        return event
-                    }
-                }.onChange(of: selectedAssetIndex, perform: { newIndex in
-                    fullSizeImage.asset = photosLibrary.assets2.object(at: photosLibrary.assets2.count - 1 - newIndex)
-                })
-                
-                HStack {
-                    Spacer()
-                    
-                    VStack {
-                        Spacer()
-                        
-                        if showStatistics {
-                            Statistics().environmentObject(photosLibrary)
-                        }
-                        
-                        if showDebug {
-                            Text("\(fullSizeImage.asset?.localIdentifier ?? "(none)")")
-                                .font(.title)
-                                .padding(10)
-                                .foregroundColor(.white)
-                                .background(.black.opacity(0.7))
-                                .cornerRadius(7.0)
-                                .shadow(radius: 2.0)
+                    PHAssetHStack(photosLibrary.assets2) { asset, index in
+                        VStack {
+                            
+                            NewThumbnailImage(asset)
+//                                .resizable()
+                                .saturation(photosLibrary.state(for: asset) == .Rejected ? 0.0 : 1.0)
+                                // Note: it's taken several attempts to get this working correctly;
+                                // it behaves differently in the running app to the SwiftUI preview.
+                                //
+                                // Expected properties:
+                                //
+                                //    - Thumbnails are square
+                                //    - Thumbnails are expanded to fill the square, but they prefer
+                                //      to crop rather than stretch the image
+                                //
+                                .scaledToFill()
+                                .frame(width: 70.0, height: 70.0, alignment: .center)
+                                .border(.green)
+//                            Text("\(index) / \(asset.localIdentifier)")
                         }
                     }
-                    .padding()
-                }.padding()
+                }
+//                
+//                VStack {
+//                    let binding = Binding {
+//                        selectedAssetIndex == -1 ? photosLibrary.assets2.count - 1 : selectedAssetIndex
+//                    } set: {
+//                        self.selectedAssetIndex = $0
+//                    }
+//                    
+//                    ThumbnailList(selectedAssetIndex: binding)
+//                        .environmentObject(photosLibrary)
+//                        .background(.gray.opacity(0.3))
+//                    
+//                    FullSizeImage(image: fullSizeImage)
+//                        .background(.black)
+//                }
+//                .background(.black)
+//                .onAppear {
+//                    selectedAssetIndex = photosLibrary.assets2.count - 1
+//                    
+//                    fullSizeImage.asset = photosLibrary.assets2.object(at: photosLibrary.assets2.count - 1 - selectedAssetIndex)
+//                    
+//                    NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in
+//                        handleKeyEvent(event)
+//                        return event
+//                    }
+//                }.onChange(of: selectedAssetIndex, perform: { newIndex in
+//                    fullSizeImage.asset = photosLibrary.assets2.object(at: photosLibrary.assets2.count - 1 - newIndex)
+//                })
+//                
+//                HStack {
+//                    Spacer()
+//                    
+//                    VStack {
+//                        Spacer()
+//                        
+//                        if showStatistics {
+//                            Statistics().environmentObject(photosLibrary)
+//                        }
+//                        
+//                        if showDebug {
+//                            Text("\(fullSizeImage.asset?.localIdentifier ?? "(none)")")
+//                                .font(.title)
+//                                .padding(10)
+//                                .foregroundColor(.white)
+//                                .background(.black.opacity(0.7))
+//                                .cornerRadius(7.0)
+//                                .shadow(radius: 2.0)
+//                        }
+//                    }
+//                    .padding()
+//                }.padding()
             }
         } else {
             Text("Waiting for Photos Library authorization…")

BlinkReviewer/BlinkReviewer/Views/Thumbnails/NewThumbnailImage.swift (0) → BlinkReviewer/BlinkReviewer/Views/Thumbnails/NewThumbnailImage.swift (492)

diff --git a/BlinkReviewer/BlinkReviewer/Views/Thumbnails/NewThumbnailImage.swift b/BlinkReviewer/BlinkReviewer/Views/Thumbnails/NewThumbnailImage.swift
new file mode 100644
index 0000000..a2b74a2
--- /dev/null
+++ b/BlinkReviewer/BlinkReviewer/Views/Thumbnails/NewThumbnailImage.swift
@@ -0,0 +1,23 @@
+//
+//  NewThumbnailImage.swift
+//  BlinkReviewer
+//
+//  Created by Alex Chan on 09/06/2023.
+//
+
+import SwiftUI
+import Photos
+
+struct NewThumbnailImage: View {
+    var asset: PHAsset
+    @ObservedObject var assetImage: PHAssetImage
+    
+    init(_ asset: PHAsset) {
+        self.asset = asset
+        self.assetImage = PHAssetImage(asset, size: CGSize(width: 70.0, height: 70.0), deliveryMode: .fastFormat)
+    }
+    
+    var body: some View {
+        Image(nsImage: assetImage.image)
+    }
+}