Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e2c6d74
Introduce GIImageDiffView files
Stengo Feb 20, 2021
d18411b
Attach GIImageDiffView to GIDiffContentData
Stengo Feb 20, 2021
0dde98c
Show a GIImageDiffCellView for image diffs
Stengo Feb 20, 2021
7b534c7
Allow GIImageDiffView to request a height
Stengo Feb 20, 2021
904c156
Inject GIImageDiffView into GIImageDiffCellView
Stengo Feb 20, 2021
116af15
Inject the repository into each GIImageDiffView
Stengo Feb 20, 2021
dbf7187
Pass along the GCDiffDelta to GIImageDiffView
Stengo Feb 20, 2021
0e0520a
Add an image view for the current (new) image
Stengo Feb 20, 2021
a6f936d
Update the frame of the current image view
Stengo Feb 20, 2021
0ca502e
Update the current image when the delta is set
Stengo Feb 20, 2021
c889fde
Avoid unnecessary image updates
Stengo Feb 20, 2021
f987cdd
Show the proper new file for all cases
Stengo Feb 20, 2021
f248c00
Add the second comparison image view
Stengo Feb 20, 2021
c415aac
Position the old image view alongside the new one
Stengo Feb 20, 2021
fd0af86
Display the correct old comparison image
Stengo Feb 20, 2021
555c2ea
Add a method to calculate the combined image size
Stengo Feb 20, 2021
ddffca5
Add a method to calculate the comparison frame
Stengo Feb 20, 2021
044b396
Move old and new image into the shared area
Stengo Feb 20, 2021
a65c640
Make the image diff view ask for the proper height
Stengo Feb 20, 2021
e898f99
Add percentage to keep track of shown fractions
Stengo Feb 20, 2021
9b15865
Reset the percentage when delta is updated
Stengo Feb 20, 2021
8bc7b5e
Partially hide the images according to percentage
Stengo Feb 20, 2021
b0861e5
Update the percentage according to mouse input
Stengo Feb 20, 2021
8a82223
Avoid implicit layer animation
Stengo Feb 20, 2021
854d2fd
Show the entire new image if there is no old one
Stengo Feb 20, 2021
2c35978
Add a transparency background layer
Stengo Feb 21, 2021
23c0a87
Update colors on every draw call
Stengo Feb 21, 2021
9c50cf4
Add indicator borders
Stengo Feb 21, 2021
ac7d2d7
Add a divider line
Stengo Feb 21, 2021
c4f52a4
Infer file type based on UTI
Stengo Jun 5, 2021
991f889
Limit maximum size of images in memory
Stengo Jun 5, 2021
bae1fc2
Restrict image diffing to NSImage compatible types
Stengo Jun 7, 2021
febb995
Separate image loading and cell size calculation
Stengo Sep 26, 2021
f29bc23
Show the entire deleted image
Stengo Oct 7, 2021
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
28 changes: 16 additions & 12 deletions GitUpKit/Components/Base.lproj/GIDiffContentsViewController.xib
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
Expand All @@ -17,18 +17,18 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<view id="Mge-gB-T5T" userLabel="Main View" customClass="GIView">
<rect key="frame" x="0.0" y="0.0" width="700" height="500"/>
<rect key="frame" x="0.0" y="0.0" width="700" height="704"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="100" horizontalPageScroll="10" verticalLineScroll="100" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="OCe-0p-vJs" customClass="GIDiffContentScrollView">
<rect key="frame" x="0.0" y="0.0" width="700" height="500"/>
<rect key="frame" x="0.0" y="0.0" width="700" height="704"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" id="KvI-YZ-5JJ">
<rect key="frame" x="0.0" y="0.0" width="700" height="500"/>
<rect key="frame" x="0.0" y="0.0" width="700" height="704"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" tableStyle="plain" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="100" rowSizeStyle="automatic" viewBased="YES" id="vcn-19-sDY" customClass="GIContentsTableView">
<rect key="frame" x="0.0" y="0.0" width="700" height="500"/>
<rect key="frame" x="0.0" y="0.0" width="700" height="704"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
Expand Down Expand Up @@ -97,8 +97,12 @@
<rect key="frame" x="0.0" y="34" width="700" height="100"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</tableCellView>
<tableCellView identifier="image" id="Az3-mF-xSz" customClass="GIImageDiffCellView">
<rect key="frame" x="0.0" y="134" width="700" height="100"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</tableCellView>
<tableCellView identifier="empty" id="JmW-sf-koG" customClass="GIEmptyDiffCellView">
<rect key="frame" x="0.0" y="134" width="700" height="50"/>
<rect key="frame" x="0.0" y="234" width="700" height="50"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vEH-U7-166">
Expand All @@ -113,7 +117,7 @@
</subviews>
</tableCellView>
<tableCellView identifier="binary" id="OJg-Sv-XTo" customClass="GIBinaryDiffCellView">
<rect key="frame" x="0.0" y="184" width="700" height="100"/>
<rect key="frame" x="0.0" y="284" width="700" height="100"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jMk-52-KEf">
Expand All @@ -127,7 +131,7 @@
</connections>
</tableCellView>
<tableCellView identifier="conflict" id="hYN-9E-rxQ" customClass="GIConflictDiffCellView">
<rect key="frame" x="0.0" y="284" width="700" height="60"/>
<rect key="frame" x="0.0" y="384" width="700" height="60"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="IHV-Ry-isd">
Expand Down Expand Up @@ -187,7 +191,7 @@
</connections>
</tableCellView>
<tableCellView identifier="submodule" id="cNk-N6-wN7" customClass="GISubmoduleDiffCellView">
<rect key="frame" x="0.0" y="344" width="700" height="50"/>
<rect key="frame" x="0.0" y="444" width="700" height="50"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eWx-eZ-o0j">
Expand Down Expand Up @@ -269,7 +273,7 @@
</scroller>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="esO-al-uQm">
<rect key="frame" x="0.0" y="252" width="700" height="18"/>
<rect key="frame" x="0.0" y="359" width="700" height="18"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="center" title="&lt;EMPTY&gt;" id="vil-2I-MOS">
<font key="font" metaFont="system" size="14"/>
Expand All @@ -278,7 +282,7 @@
</textFieldCell>
</textField>
</subviews>
<point key="canvasLocation" x="232" y="536"/>
<point key="canvasLocation" x="232" y="638"/>
</view>
</objects>
<resources>
Expand Down
43 changes: 38 additions & 5 deletions GitUpKit/Components/GIDiffContentsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ @interface GIDiffContentData : NSObject
@property(nonatomic, strong) GCDiffDelta* delta;
@property(nonatomic, strong) GCIndexConflict* conflict;
@property(nonatomic, strong) GIDiffView* diffView;
@property(nonatomic, strong) GIImageDiffView* imageDiffView;
@property(nonatomic, getter=isEmpty) BOOL empty;
@end

Expand All @@ -54,6 +55,10 @@ @interface GITextDiffCellView : NSTableCellView
@property(nonatomic, weak) GIDiffView* diffView;
@end

@interface GIImageDiffCellView : NSTableCellView
@property(nonatomic, weak) GIImageDiffView* imageDiffView;
@end

@interface GIBinaryDiffCellView : NSTableCellView
@end

Expand Down Expand Up @@ -144,6 +149,9 @@ @implementation GIEmptyDiffCellView
@implementation GITextDiffCellView
@end

@implementation GIImageDiffCellView
@end

@implementation GIBinaryDiffCellView
@end

Expand Down Expand Up @@ -332,7 +340,17 @@ - (void)_reloadDeltas {
GCDiffPatch* patch = [self.repository makePatchForDiffDelta:delta isBinary:&isBinary error:&error];
if (patch) {
XLOG_DEBUG_CHECK(!isBinary || patch.empty);
if (patch.empty) {

CFStringRef fileExtension = CFBridgingRetain(delta.canonicalPath.pathExtension);
CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
BOOL isImage = [NSImage.imageTypes containsObject:(__bridge NSString * _Nonnull)(fileUTI)];
CFRelease(fileUTI);
CFRelease(fileExtension);
if (isImage) {
GIImageDiffView* imageDiffView = [[GIImageDiffView alloc] initWithRepository:self.repository];
imageDiffView.delta = delta;
data.imageDiffView = imageDiffView;
} else if (patch.empty) {
data.empty = !isBinary;
} else {
GIDiffView* diffView = [[[self _diffViewClassForChange:delta.change] alloc] initWithFrame:NSZeroRect];
Expand Down Expand Up @@ -438,10 +456,14 @@ - (void)tableView:(NSTableView*)tableView didRemoveRowView:(NSTableRowView*)rowV
row -= 1;
}
if (row % 2) {
GITextDiffCellView* view = [rowView viewAtColumn:0];
if ([view isKindOfClass:[GITextDiffCellView class]]) {
[view.diffView removeFromSuperview];
view.diffView = nil;
GITextDiffCellView* textDiffView = [rowView viewAtColumn:0];
GIImageDiffCellView* imageDiffView = [rowView viewAtColumn:0];
if ([textDiffView isKindOfClass:[GITextDiffCellView class]]) {
[textDiffView.diffView removeFromSuperview];
textDiffView.diffView = nil;
} else if ([imageDiffView isKindOfClass:[GIImageDiffCellView class]]) {
[imageDiffView.imageDiffView removeFromSuperview];
imageDiffView.imageDiffView = nil;
}
}
}
Expand Down Expand Up @@ -485,6 +507,15 @@ - (NSView*)tableView:(NSTableView*)tableView viewForTableColumn:(NSTableColumn*)
[view addSubview:data.diffView];
view.diffView = data.diffView;
return view;
} else if (data.imageDiffView) {
GIImageDiffCellView* view = [_tableView makeViewWithIdentifier:@"image" owner:self];
XLOG_DEBUG_CHECK(view.imageDiffView == nil);
XLOG_DEBUG_CHECK(data.imageDiffView.superview == nil);
data.imageDiffView.frame = view.bounds;
data.imageDiffView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[view addSubview:data.imageDiffView];
view.imageDiffView = data.imageDiffView;
return view;
} else if (data.empty) {
GIEmptyDiffCellView* view = [_tableView makeViewWithIdentifier:@"empty" owner:self];
return view;
Expand Down Expand Up @@ -626,6 +657,8 @@ - (CGFloat)tableView:(NSTableView*)tableView heightOfRow:(NSInteger)row {
GCDiffDelta* delta = data.delta;
if (data.diffView) {
return [data.diffView updateLayoutForWidth:[_tableView.tableColumns[0] width]];
} else if (data.imageDiffView) {
return [data.imageDiffView desiredHeightForWidth:[_tableView.tableColumns[0] width]];
} else if (data.empty) {
return _emptyViewHeight;
} else if (data.conflict) {
Expand Down
8 changes: 8 additions & 0 deletions GitUpKit/GitUpKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
1DADC0E225A25D63008C2C35 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DBBEE64C256B094000F96DAF /* libz.tbd */; };
1DF371CD22F5262300EF7BD9 /* GCLiveRepository+Utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DF371CB22F5262300EF7BD9 /* GCLiveRepository+Utilities.h */; };
1DF371CE22F5262300EF7BD9 /* GCLiveRepository+Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF371CC22F5262300EF7BD9 /* GCLiveRepository+Utilities.m */; };
6D8E3F0B25D90E1300AAFC17 /* GIImageDiffView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D8E3F0A25D90E1300AAFC17 /* GIImageDiffView.m */; };
6D8E3F1025D90E3400AAFC17 /* GIImageDiffView.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D8E3F0F25D90E3400AAFC17 /* GIImageDiffView.h */; settings = {ATTRIBUTES = (Public, ); }; };
743BF1841B871C0200E1CA49 /* GCOrderedSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 74EDB5D01B84D4C400F00E79 /* GCOrderedSet.h */; settings = {ATTRIBUTES = (Public, ); }; };
749335CA1B9B7FF200225513 /* GCOrderedSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 74EDB5D11B84D4C400F00E79 /* GCOrderedSet.m */; };
749786941B85AAB10065BD55 /* GCOrderedSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 74EDB5D11B84D4C400F00E79 /* GCOrderedSet.m */; };
Expand Down Expand Up @@ -418,6 +420,8 @@
0AC8525823A122C400479160 /* GILaunchServicesLocator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GILaunchServicesLocator.m; sourceTree = "<group>"; };
1DF371CB22F5262300EF7BD9 /* GCLiveRepository+Utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GCLiveRepository+Utilities.h"; sourceTree = "<group>"; };
1DF371CC22F5262300EF7BD9 /* GCLiveRepository+Utilities.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "GCLiveRepository+Utilities.m"; sourceTree = "<group>"; };
6D8E3F0A25D90E1300AAFC17 /* GIImageDiffView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GIImageDiffView.m; sourceTree = "<group>"; };
6D8E3F0F25D90E3400AAFC17 /* GIImageDiffView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GIImageDiffView.h; sourceTree = "<group>"; };
74EDB5D01B84D4C400F00E79 /* GCOrderedSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCOrderedSet.h; sourceTree = "<group>"; };
74EDB5D11B84D4C400F00E79 /* GCOrderedSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCOrderedSet.m; sourceTree = "<group>"; };
74EDB5D51B84E06500F00E79 /* GCOrderedSet-Tests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GCOrderedSet-Tests.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1001,6 +1005,8 @@
DBDFBC0B22B610F1003EEC6C /* Interface.xcassets */,
E2D4DEAD1A4D592000B6AF66 /* GIBranch.h */,
E2D4DEAE1A4D592000B6AF66 /* GIBranch.m */,
6D8E3F0A25D90E1300AAFC17 /* GIImageDiffView.m */,
6D8E3F0F25D90E3400AAFC17 /* GIImageDiffView.h */,
E23186031B139CB900A93CCF /* GIConstants.h */,
E2891AB41AE1684A00E58C77 /* GIDiffView.h */,
E2891AB51AE1684A00E58C77 /* GIDiffView.m */,
Expand Down Expand Up @@ -1159,6 +1165,7 @@
E267E2391B84DC3900BAB377 /* GISnapshotListViewController.h in Headers */,
1DF371CD22F5262300EF7BD9 /* GCLiveRepository+Utilities.h in Headers */,
E267E23A1B84DC3900BAB377 /* GIUnifiedReflogViewController.h in Headers */,
6D8E3F1025D90E3400AAFC17 /* GIImageDiffView.h in Headers */,
E267E24D1B84DC7D00BAB377 /* GIAdvancedCommitViewController.h in Headers */,
E267E24E1B84DC7D00BAB377 /* GICommitRewriterViewController.h in Headers */,
E267E24F1B84DC7D00BAB377 /* GICommitSplitterViewController.h in Headers */,
Expand Down Expand Up @@ -1475,6 +1482,7 @@
E267E2291B84DBF800BAB377 /* GIAppKit.m in Sources */,
E267E22A1B84DBF800BAB377 /* GIColorView.m in Sources */,
E267E22B1B84DBF800BAB377 /* GILinkButton.m in Sources */,
6D8E3F0B25D90E1300AAFC17 /* GIImageDiffView.m in Sources */,
DBDFBC1122B61135003EEC6C /* NSBundle+GitUpKit.m in Sources */,
E267E22C1B84DBF800BAB377 /* GIModalView.m in Sources */,
E267E22D1B84DBF800BAB377 /* GIViewController.m in Sources */,
Expand Down
8 changes: 8 additions & 0 deletions GitUpKit/Interface/GIImageDiffView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#import <AppKit/AppKit.h>

@interface GIImageDiffView : NSView
@property(nonatomic, strong) GCDiffDelta* delta;

- (id)initWithRepository:(GCLiveRepository*)repository;
- (CGFloat)desiredHeightForWidth:(CGFloat)width;
@end
Loading