Sort out FocusedImage and why it works
- ID
75a3b5f- date
2023-06-09 23:12:36+00:00- author
Alex Chan <alex@alexwlchan.net>- parent
d569d3c- message
Sort out FocusedImage and why it works- changed files
Changed files
BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj (32032) → BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj (31876)
diff --git a/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj b/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj
index 62d8c9c..81d626c 100644
--- a/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj
+++ b/BlinkReviewer/BlinkReviewer.xcodeproj/project.pbxproj
@@ -13,7 +13,7 @@
945F17B42A33D726004FC479 /* ReviewStateIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945F17B32A33D726004FC479 /* ReviewStateIcon.swift */; };
945F17B62A33D7AA004FC479 /* ReviewStateBorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945F17B52A33D7AA004FC479 /* ReviewStateBorder.swift */; };
945F17B82A33DAC7004FC479 /* ReviewStateSaturation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945F17B72A33DAC7004FC479 /* ReviewStateSaturation.swift */; };
- 94A0835E2A33E49E00238964 /* BigImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94A0835D2A33E49E00238964 /* BigImage.swift */; };
+ 94A0835E2A33E49E00238964 /* FocusedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94A0835D2A33E49E00238964 /* FocusedImage.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 */; };
@@ -59,7 +59,7 @@
945F17B32A33D726004FC479 /* ReviewStateIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewStateIcon.swift; sourceTree = "<group>"; };
945F17B52A33D7AA004FC479 /* ReviewStateBorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewStateBorder.swift; sourceTree = "<group>"; };
945F17B72A33DAC7004FC479 /* ReviewStateSaturation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewStateSaturation.swift; sourceTree = "<group>"; };
- 94A0835D2A33E49E00238964 /* BigImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BigImage.swift; sourceTree = "<group>"; };
+ 94A0835D2A33E49E00238964 /* FocusedImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusedImage.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>"; };
@@ -132,19 +132,12 @@
path = Thumbnails;
sourceTree = "<group>";
};
- 94A083592A33E46D00238964 /* New Group1 */ = {
+ 94A0835F2A33E7E900238964 /* FocusedImage */ = {
isa = PBXGroup;
children = (
+ 94A0835D2A33E49E00238964 /* FocusedImage.swift */,
);
- path = "New Group1";
- sourceTree = "<group>";
- };
- 94A0835C2A33E49400238964 /* BigImage */ = {
- isa = PBXGroup;
- children = (
- 94A0835D2A33E49E00238964 /* BigImage.swift */,
- );
- path = BigImage;
+ path = FocusedImage;
sourceTree = "<group>";
};
94D2C8B72A320E6600BEE15B /* Model */ = {
@@ -217,8 +210,7 @@
94D7511A2A31A7A6005859E7 /* Views */ = {
isa = PBXGroup;
children = (
- 94A0835C2A33E49400238964 /* BigImage */,
- 94A083592A33E46D00238964 /* New Group1 */,
+ 94A0835F2A33E7E900238964 /* FocusedImage */,
945F17AE2A33D15D004FC479 /* Thumbnails */,
940331742A336BEB00200C5D /* Helpers */,
94D7511B2A31A7B1005859E7 /* ThumbnailImage.swift */,
@@ -386,7 +378,7 @@
94D750F02A31A796005859E7 /* BlinkReviewerApp.swift in Sources */,
940331732A336B5100200C5D /* DeferredRendering.swift in Sources */,
94D751202A31B53E005859E7 /* AlbumInfo.swift in Sources */,
- 94A0835E2A33E49E00238964 /* BigImage.swift in Sources */,
+ 94A0835E2A33E49E00238964 /* FocusedImage.swift in Sources */,
94D751302A31DC4A005859E7 /* ThumbnailList.swift in Sources */,
945F17B82A33DAC7004FC479 /* ReviewStateSaturation.swift in Sources */,
94D751222A31BD8E005859E7 /* PhotoReviewer.swift in Sources */,
BlinkReviewer/BlinkReviewer/Views/BigImage/BigImage.swift (646) → BlinkReviewer/BlinkReviewer/Views/BigImage/BigImage.swift (0)
diff --git a/BlinkReviewer/BlinkReviewer/Views/BigImage/BigImage.swift b/BlinkReviewer/BlinkReviewer/Views/BigImage/BigImage.swift
deleted file mode 100644
index 0d3b20e..0000000
--- a/BlinkReviewer/BlinkReviewer/Views/BigImage/BigImage.swift
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// BigImage.swift
-// BlinkReviewer
-//
-// Created by Alex Chan on 09/06/2023.
-//
-
-import SwiftUI
-import Photos
-
-struct BigImage: View {
- @State var asset: PHAsset
- @ObservedObject var assetImage: PHAssetImage
-
- init(_ asset: PHAsset) {
- print("creating an instance of BigImage!")
- self.asset = asset
- self.assetImage = PHAssetImage(
- asset,
- size: PHImageManagerMaximumSize,
- deliveryMode: .highQualityFormat
- )
- }
-
- var body: some View {
- Image(nsImage: assetImage.image)
- .resizable()
- .aspectRatio(contentMode: .fit)
- }
-}
BlinkReviewer/BlinkReviewer/Views/FocusedImage/FocusedImage.swift (0) → BlinkReviewer/BlinkReviewer/Views/FocusedImage/FocusedImage.swift (825)
diff --git a/BlinkReviewer/BlinkReviewer/Views/FocusedImage/FocusedImage.swift b/BlinkReviewer/BlinkReviewer/Views/FocusedImage/FocusedImage.swift
new file mode 100644
index 0000000..05ff4a3
--- /dev/null
+++ b/BlinkReviewer/BlinkReviewer/Views/FocusedImage/FocusedImage.swift
@@ -0,0 +1,22 @@
+import SwiftUI
+import Photos
+
+/// Render the big image that gets shown in the main view.
+///
+/// It's important to avoid a "flash" of empty space when switching between
+/// images, so this View is only created once and then the parent modifies
+/// the `asset` referred to by `assetImage`. This means the image that was
+/// previously being rendered sticks around until the new image loads in.
+///
+/// If this view was being passed the focused image directly, it'd be
+/// recreated every time the focus changed, and there'd be a temporary flash
+/// of empty space until an image could be loaded in.
+struct FocusedImage: View {
+ @ObservedObject var assetImage: PHAssetImage
+
+ var body: some View {
+ Image(nsImage: assetImage.image)
+ .resizable()
+ .aspectRatio(contentMode: .fit)
+ }
+}
BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift (8844) → BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift (9584)
diff --git a/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift b/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift
index 9472eb4..8a0d609 100644
--- a/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift
+++ b/BlinkReviewer/BlinkReviewer/Views/PhotoReviewer.swift
@@ -30,6 +30,10 @@ struct PhotoReviewer: View {
@State var showStatistics: Bool = false
@State var showDebug: Bool = true
+ // This contains the big image that is currently in focus. See the comments
+ // on FocusedImage for why this state is defined outside that view.
+ @ObservedObject var focusedAssetImage = PHAssetImage(nil, size: PHImageManagerMaximumSize, deliveryMode: .highQualityFormat)
+
var body: some View {
if photosLibrary.isPhotoLibraryAuthorized {
ZStack {
@@ -40,17 +44,26 @@ struct PhotoReviewer: View {
}
.frame(height: 90)
- BigImage(focusedAsset)
+ FocusedImage(assetImage: focusedAssetImage)
Spacer()
}
}
.onAppear {
+
+
NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in
handleKeyEventNew(event)
return event
}
}
+ // These two lines update the big image that fills most of the window.
+ // See the comments on FocusedImage for more explanation of why this is
+ // managed this way.
+ .onAppear { focusedAssetImage.asset = focusedAsset }
+ .onChange(of: focusedAsset) { newFocusedAsset in
+ focusedAssetImage.asset = newFocusedAsset
+ }
//
// VStack {
// let binding = Binding {