-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Some fixes #246
base: master
Are you sure you want to change the base?
Some fixes #246
Changes from 6 commits
da45553
538f20a
56eba94
5a6cb14
55f3c45
91fd767
d651920
5cfaa99
c002e91
7359256
d739506
277ade9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
0C7AF650186B4E890064EE7B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C7AF64F186B4E890064EE7B /* QuartzCore.framework */; }; | ||
32BDEBC3173A46A900513A7C /* eye_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 32BDEBC2173A46A900513A7C /* eye_icon.png */; }; | ||
32D86505173A4555009C724B /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 32D86503173A4555009C724B /* [email protected] */; }; | ||
636C388F1ABCB1B7004DECCF /* ATZScreenshotsStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 636C388E1ABCB1B7004DECCF /* ATZScreenshotsStorage.m */; }; | ||
64C28A5518136FF30025C0B1 /* toolbar_colors.png in Resources */ = {isa = PBXBuildFile; fileRef = 64C28A4918136FF30025C0B1 /* toolbar_colors.png */; }; | ||
64C28A5618136FF30025C0B1 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 64C28A4A18136FF30025C0B1 /* [email protected] */; }; | ||
64C28A5918136FF30025C0B1 /* toolbar_plugins.png in Resources */ = {isa = PBXBuildFile; fileRef = 64C28A4D18136FF30025C0B1 /* toolbar_plugins.png */; }; | ||
|
@@ -83,6 +84,8 @@ | |
0C7AF64F186B4E890064EE7B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; | ||
32BDEBC2173A46A900513A7C /* eye_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = eye_icon.png; sourceTree = "<group>"; }; | ||
32D86503173A4555009C724B /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; }; | ||
636C388D1ABCB1B7004DECCF /* ATZScreenshotsStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATZScreenshotsStorage.h; sourceTree = "<group>"; }; | ||
636C388E1ABCB1B7004DECCF /* ATZScreenshotsStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATZScreenshotsStorage.m; sourceTree = "<group>"; }; | ||
6449530218CE826C009494BD /* ATZVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATZVersion.h; sourceTree = "<group>"; }; | ||
64C28A4918136FF30025C0B1 /* toolbar_colors.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = toolbar_colors.png; sourceTree = "<group>"; }; | ||
64C28A4A18136FF30025C0B1 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; }; | ||
|
@@ -353,6 +356,8 @@ | |
8917DA171726B63B00F0B2D2 /* ATZShell.m */, | ||
89B4F2BC172FF5AC001FD2E3 /* ATZPBXProjParser.h */, | ||
89B4F2BD172FF5AC001FD2E3 /* ATZPBXProjParser.m */, | ||
636C388D1ABCB1B7004DECCF /* ATZScreenshotsStorage.h */, | ||
636C388E1ABCB1B7004DECCF /* ATZScreenshotsStorage.m */, | ||
); | ||
path = Helpers; | ||
sourceTree = "<group>"; | ||
|
@@ -509,6 +514,7 @@ | |
8917D9F31726B4EE00F0B2D2 /* ATZColorScheme.m in Sources */, | ||
8917D9F41726B4EE00F0B2D2 /* ATZFileTemplate.m in Sources */, | ||
8917D9F51726B4EE00F0B2D2 /* ATZPackage.m in Sources */, | ||
636C388F1ABCB1B7004DECCF /* ATZScreenshotsStorage.m in Sources */, | ||
8917D9F61726B4EE00F0B2D2 /* ATZPlugin.m in Sources */, | ||
8ADC22341A2AD5B800DB7BCA /* ATZPreviewImageButton.m in Sources */, | ||
8917D9F71726B4EE00F0B2D2 /* ATZProjectTemplate.m in Sources */, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ | |
#import "ATZColorScheme.h" | ||
#import "ATZDownloader.h" | ||
#import "NSColor+Alcatraz.h" | ||
#import "ATZScreenshotsStorage.h" | ||
|
||
@interface ATZPackageTableViewDelegate () | ||
|
||
|
@@ -85,23 +86,12 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn | |
[view.descriptionField setStringValue:package.summary]; | ||
[view.linkButton setImage:[self tableView:tableView websiteImageForTableColumn:tableColumn row:row]]; | ||
[view.linkButton setTitle:[self tableView:tableView displayWebsiteForTableColumn:tableColumn row:row]]; | ||
[view.typeImageView setImage:[self tableView:tableView packageTypeImageForTableColumn:tableColumn row:row]]; | ||
[view.installButton setTitle:([package isInstalled] ? @"REMOVE" : @"INSTALL")]; | ||
BOOL hasImage = package.screenshotPath != nil; | ||
[view.previewButton setFullSize:hasImage]; | ||
[view.previewButton setHidden:!hasImage]; | ||
if (package.screenshotPath) { | ||
[view.previewButton setImage:[[self class] cachedImageForPackage:package]]; | ||
if (!view.previewButton.image) { | ||
__block NSButton* imageButton = view.previewButton; | ||
[[self class] fetchAndCacheImageForPackage:package progress:NULL completion:^(NSImage *image) { | ||
imageButton.image = image; | ||
[tableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndex:row]]; | ||
}]; | ||
} | ||
} else { | ||
[view.previewButton setImage:nil]; | ||
} | ||
view.screenshotPath = package.screenshotPath; | ||
view.screenshotImageView.image = [ATZScreenshotsStorage cachedImageForPackage:package]; | ||
ATZFillableButton* installButton = (ATZFillableButton*)view.installButton; | ||
[installButton setButtonBorderStyle:ATZFillableButtonTypeInstall]; | ||
[installButton setFillRatio:([package isInstalled] ? 100 : 0) animated:NO]; | ||
|
@@ -156,73 +146,23 @@ - (NSImage *)tableView:(NSTableView*)tableView websiteImageForTableColumn:(NSTab | |
return [[Alcatraz sharedPlugin].bundle imageForResource:websiteImageName]; | ||
} | ||
|
||
- (NSImage *)tableView:(NSTableView*)tableView packageTypeImageForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { | ||
NSString* typeImageName = nil; | ||
ATZPackage* package = [self tableView:tableView objectValueForTableColumn:tableColumn row:row]; | ||
if ([package isKindOfClass:[ATZPlugin class]]) { | ||
typeImageName = @"740-gear"; | ||
} else if ([package isKindOfClass:[ATZTemplate class]]) { | ||
typeImageName = @"808-documents"; | ||
} else if ([package isKindOfClass:[ATZColorScheme class]]) { | ||
typeImageName = @"837-palette"; | ||
} else { | ||
return nil; | ||
} | ||
if ([package isInstalled]) | ||
typeImageName = [NSString stringWithFormat:@"%@-selected", typeImageName]; | ||
|
||
return [self selectionTemplateImageNamed:typeImageName]; | ||
- (void)loadImagesForVisibleRowsInTableView:(NSTableView *)tableView { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refactor here appreciated (try to have max 3 levels of indentation) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh...actually I deleted these lines, as they were unused 😮 |
||
NSRange range = [tableView rowsInRect:tableView.visibleRect]; | ||
for (NSInteger row = range.location; row < range.location + range.length; ++row) { | ||
ATZPackageListTableCellView *view = [tableView viewAtColumn:0 row:row makeIfNecessary:NO]; | ||
ATZPackage *package = self.filteredPackages[row]; | ||
|
||
if (package.screenshotPath && !view.screenshotImageView.image) { | ||
NSImageView __weak *imageView = view.screenshotImageView; | ||
[ATZScreenshotsStorage fetchAndCacheImageForPackage:package progress:NULL completion:^(ATZPackage *pkg, NSImage *image) { | ||
if ([view.titleField.stringValue isEqualToString:pkg.name]) { | ||
imageView.image = image; | ||
[tableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndex:row]]; | ||
} | ||
}]; | ||
} | ||
} | ||
} | ||
|
||
- (NSImage *)selectionTemplateImageNamed:(NSString *)imageName { | ||
NSImage *template = [[Alcatraz sharedPlugin].bundle imageForResource:imageName]; | ||
NSSize size = [template size]; | ||
|
||
NSImage *copiedImage = [template copy]; | ||
[copiedImage setTemplate:NO]; | ||
[copiedImage lockFocus]; | ||
[[NSColor selectedItemColor] set]; | ||
NSRectFillUsingOperation(NSMakeRect(0, 0, size.width, size.height), NSCompositeSourceAtop); | ||
[copiedImage unlockFocus]; | ||
|
||
return copiedImage; | ||
} | ||
|
||
#pragma mark - Image Previews | ||
|
||
+ (NSCache *)imageCache { | ||
static NSCache* cache = nil; | ||
static dispatch_once_t onceToken; | ||
dispatch_once(&onceToken, ^{ | ||
cache = [[NSCache alloc] init]; | ||
}); | ||
return cache; | ||
} | ||
|
||
+ (NSImage *)cachedImageForPackage:(ATZPackage*)package { | ||
return [[self imageCache] objectForKey:package.name]; | ||
} | ||
|
||
+ (void)cacheImage:(NSImage *)image forPackage:(ATZPackage *)package { | ||
[[self imageCache] setObject:image forKey:package.name]; | ||
} | ||
|
||
+ (void)fetchAndCacheImageForPackage:(ATZPackage*)package progress:(void(^)(CGFloat))progress completion:(void(^)(NSImage *))completion { | ||
ATZDownloader *downloader = [ATZDownloader new]; | ||
[downloader downloadFileFromPath:package.screenshotPath | ||
progress:progress | ||
completion:^(NSData *responseData, NSError *error) { | ||
if (error) | ||
return; | ||
|
||
NSImage *image = [[NSImage alloc] initWithData:responseData]; | ||
if (!image) | ||
return; | ||
|
||
[self cacheImage:image forPackage:package]; | ||
if (completion) | ||
completion(image); | ||
}]; | ||
} | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
// PluginWindowController.m | ||
// | ||
// | ||
// Copyright (c) 2014 Marin Usalj | supermar.in | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
|
@@ -8,10 +8,10 @@ | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
|
@@ -51,10 +51,16 @@ typedef NS_ENUM(NSInteger, ATZFilterSegment) { | |
@interface ATZPluginWindowController () | ||
@property (nonatomic, assign) NSView *hoverButtonsContainer; | ||
@property (nonatomic, strong) ATZPackageTableViewDelegate* tableViewDelegate; | ||
@property (nonatomic, strong) NSTimer *loadImagesTimer; | ||
|
||
@end | ||
|
||
@implementation ATZPluginWindowController | ||
|
||
- (void)dealloc { | ||
[[NSNotificationCenter defaultCenter] removeObserver:self]; | ||
} | ||
|
||
- (id)init { | ||
@throw [NSException exceptionWithName:@"There's a better initializer" reason:@"Use -initWithNibName:inBundle:" userInfo:nil]; | ||
} | ||
|
@@ -73,8 +79,17 @@ - (id)initWithBundle:(NSBundle *)bundle { | |
- (void)windowDidLoad { | ||
[super windowDidLoad]; | ||
[self addVersionToWindow]; | ||
if ([self.window respondsToSelector:@selector(setTitleVisibility:)]) | ||
|
||
typeof(self) __weak wSelf = self; | ||
[[NSNotificationCenter defaultCenter] addObserverForName:NSScrollViewDidLiveScrollNotification object:self.tableView.enclosingScrollView queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { | ||
[wSelf.loadImagesTimer invalidate]; | ||
wSelf.loadImagesTimer = [NSTimer timerWithTimeInterval:0.2 target:wSelf selector:@selector(loadImagesInVisibleRows) userInfo:nil repeats:NO]; | ||
[[NSRunLoop mainRunLoop] addTimer:self.loadImagesTimer forMode:NSRunLoopCommonModes]; | ||
}]; | ||
|
||
if ([self.window respondsToSelector:@selector(setTitleVisibility:)]) { | ||
self.window.titleVisibility = NSWindowTitleHidden; | ||
} | ||
} | ||
|
||
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification { | ||
|
@@ -89,7 +104,7 @@ - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentN | |
|
||
- (IBAction)installPressed:(ATZFillableButton *)button { | ||
ATZPackage *package = [self.tableViewDelegate tableView:self.tableView objectValueForTableColumn:0 row:[self.tableView rowForView:button]]; | ||
|
||
if (package.isInstalled) | ||
[self removePackage:package andUpdateControl:button]; | ||
else | ||
|
@@ -174,7 +189,6 @@ - (void)reloadTableView { | |
self.tableView.dataSource = self.tableViewDelegate; | ||
[self.tableViewDelegate configureTableView:self.tableView]; | ||
[self updatePredicate]; | ||
[self.tableView reloadData]; | ||
} | ||
|
||
#pragma mark - Private | ||
|
@@ -209,7 +223,7 @@ - (void)installPackage:(ATZPackage *)package andUpdateControl:(ATZFillableButton | |
|
||
- (void)postNotificationForInstalledPackage:(ATZPackage *)package { | ||
if (![NSUserNotificationCenter class] || !package.isInstalled) return; | ||
|
||
NSUserNotification *notification = [NSUserNotification new]; | ||
notification.title = [NSString stringWithFormat:@"%@ installed", package.type]; | ||
NSString *restartText = package.requiresRestart ? @" Please restart Xcode to use it." : @""; | ||
|
@@ -237,6 +251,11 @@ - (void)updatePredicate { | |
|
||
[self.tableViewDelegate filterUsingPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:predicates]]; | ||
[self.tableView reloadData]; | ||
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | ||
// wait next run loop, otherwise there are no rows yet | ||
[self loadImagesInVisibleRows]; | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this an indication that something somewhere else is going wrong? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The cells will be visible only in the next runloop, so this is a solution I know. If you can recommend something better - I'd appreciate that :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why load the table and then fetch images instead of loading the images when the cell is loaded? There's a bit more delay before all the images have been cached. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because I don't load images when cell loaded, only after slight delay when scroll ends. So if I scroll quickly through list, I wont get all them in loading queue. |
||
} | ||
|
||
- (void)updatePackages { | ||
|
@@ -250,7 +269,7 @@ - (void)openWebsite:(NSString *)address { | |
} | ||
|
||
- (void)displayScreenshotWithPath:(NSString *)screenshotPath withTitle:(NSString *)title { | ||
|
||
[self.previewPanel.animator setAlphaValue:0.f]; | ||
self.previewPanel.title = title; | ||
[self retrieveImageViewForScreenshot:screenshotPath | ||
|
@@ -276,22 +295,26 @@ - (void)displayImage:(NSImage *)image withTitle:(NSString*)title { | |
} | ||
|
||
- (void)retrieveImageViewForScreenshot:(NSString *)screenshotPath progress:(void (^)(CGFloat))downloadProgress completion:(void (^)(NSImage *))completion { | ||
|
||
ATZDownloader *downloader = [ATZDownloader new]; | ||
[downloader downloadFileFromPath:screenshotPath | ||
progress:^(CGFloat progress) { | ||
downloadProgress(progress); | ||
} | ||
completion:^(NSData *responseData, NSError *error) { | ||
|
||
NSImage *image = [[NSImage alloc] initWithData:responseData]; | ||
completion(image); | ||
}]; | ||
|
||
} | ||
|
||
- (void)addVersionToWindow { | ||
self.versionTextField.stringValue = @(ATZ_VERSION); | ||
} | ||
|
||
- (void)loadImagesInVisibleRows { | ||
[self.tableViewDelegate loadImagesForVisibleRowsInTableView:self.tableView]; | ||
} | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// | ||
// ATZScreenshotsStorage.h | ||
// Alcatraz | ||
// | ||
// Created by Alex Antonyuk on 3/20/15. | ||
// Copyright (c) 2015 supermar.in. All rights reserved. | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
|
||
@class ATZPackage; | ||
|
||
typedef void(^ATZImagesStorageCompletion)(ATZPackage *pkg, NSImage *image); | ||
|
||
@interface ATZScreenshotsStorage : NSObject | ||
|
||
+ (NSImage *)cachedImageForPackage:(ATZPackage*)package; | ||
+ (void)cacheImage:(NSImage *)image forPackage:(ATZPackage *)package; | ||
+ (void)fetchAndCacheImageForPackage:(ATZPackage*)package progress:(void(^)(CGFloat))progress completion:(ATZImagesStorageCompletion)completion; | ||
|
||
@end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely should keep indentation consistent with the project; soft tabs, 4 spaces per tab.