Skip to content

Commit 7e7f000

Browse files
committed
Refactored project, moved Window specific code into a NSWindow and update specific code to the UpdateModel
Fixed JPEG compression issue (always really low quality if lower than 10/10)
1 parent 3bb6262 commit 7e7f000

File tree

12 files changed

+472
-304
lines changed

12 files changed

+472
-304
lines changed

Retini.xcodeproj/project.pbxproj

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
038880BC1B305F6300F8807F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 038880BA1B305F6300F8807F /* MainMenu.xib */; };
1414
038880C81B305F6300F8807F /* RetiniTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 038880C71B305F6300F8807F /* RetiniTests.m */; };
1515
038880D31B305FDB00F8807F /* DragDropView.m in Sources */ = {isa = PBXBuildFile; fileRef = 038880D21B305FDB00F8807F /* DragDropView.m */; };
16+
039731AC1FA326F10040F92E /* MainWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 039731AB1FA326F10040F92E /* MainWindow.m */; };
17+
039731AF1FA327350040F92E /* UpdateModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 039731AE1FA327350040F92E /* UpdateModel.m */; };
1618
03C461981C2760CD00F1572A /* ResizeModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 03C461971C2760CD00F1572A /* ResizeModel.m */; };
1719
03CB44F21BC80603003C4879 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03CB44F11BC80603003C4879 /* QuartzCore.framework */; };
1820
03CB44F51BC8118E003C4879 /* pngout in Resources */ = {isa = PBXBuildFile; fileRef = 03CB44F41BC8118E003C4879 /* pngout */; };
@@ -44,6 +46,10 @@
4446
038880C71B305F6300F8807F /* RetiniTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RetiniTests.m; sourceTree = "<group>"; };
4547
038880D11B305FDB00F8807F /* DragDropView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragDropView.h; sourceTree = "<group>"; };
4648
038880D21B305FDB00F8807F /* DragDropView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DragDropView.m; sourceTree = "<group>"; };
49+
039731AA1FA326F10040F92E /* MainWindow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainWindow.h; sourceTree = "<group>"; };
50+
039731AB1FA326F10040F92E /* MainWindow.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainWindow.m; sourceTree = "<group>"; };
51+
039731AD1FA327350040F92E /* UpdateModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UpdateModel.h; sourceTree = "<group>"; };
52+
039731AE1FA327350040F92E /* UpdateModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UpdateModel.m; sourceTree = "<group>"; };
4753
03C461961C2760CD00F1572A /* ResizeModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResizeModel.h; sourceTree = "<group>"; };
4854
03C461971C2760CD00F1572A /* ResizeModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResizeModel.m; sourceTree = "<group>"; };
4955
03CB44F11BC80603003C4879 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
@@ -99,9 +105,10 @@
99105
children = (
100106
038880B31B305F6300F8807F /* AppDelegate.h */,
101107
038880B41B305F6300F8807F /* AppDelegate.m */,
102-
03C461951C27608F00F1572A /* Frameworks */,
108+
039731A91FA326AD0040F92E /* Windows */,
103109
03C461941C27608500F1572A /* Views */,
104110
03C461931C27607D00F1572A /* Models */,
111+
03C461951C27608F00F1572A /* Extensions */,
105112
03CB44F31BC8117F003C4879 /* 3rd party */,
106113
038880B81B305F6300F8807F /* Images.xcassets */,
107114
038880BA1B305F6300F8807F /* MainMenu.xib */,
@@ -136,11 +143,22 @@
136143
name = "Supporting Files";
137144
sourceTree = "<group>";
138145
};
146+
039731A91FA326AD0040F92E /* Windows */ = {
147+
isa = PBXGroup;
148+
children = (
149+
039731AA1FA326F10040F92E /* MainWindow.h */,
150+
039731AB1FA326F10040F92E /* MainWindow.m */,
151+
);
152+
name = Windows;
153+
sourceTree = "<group>";
154+
};
139155
03C461931C27607D00F1572A /* Models */ = {
140156
isa = PBXGroup;
141157
children = (
142158
03C461961C2760CD00F1572A /* ResizeModel.h */,
143159
03C461971C2760CD00F1572A /* ResizeModel.m */,
160+
039731AD1FA327350040F92E /* UpdateModel.h */,
161+
039731AE1FA327350040F92E /* UpdateModel.m */,
144162
);
145163
name = Models;
146164
sourceTree = "<group>";
@@ -154,13 +172,13 @@
154172
name = Views;
155173
sourceTree = "<group>";
156174
};
157-
03C461951C27608F00F1572A /* Frameworks */ = {
175+
03C461951C27608F00F1572A /* Extensions */ = {
158176
isa = PBXGroup;
159177
children = (
160178
03D63F7A1BB9804200CC8485 /* NSImage+Resize.h */,
161179
03D63F7B1BB9804200CC8485 /* NSImage+Resize.m */,
162180
);
163-
name = Frameworks;
181+
name = Extensions;
164182
sourceTree = "<group>";
165183
};
166184
03CB44F31BC8117F003C4879 /* 3rd party */ = {
@@ -326,8 +344,10 @@
326344
files = (
327345
038880B71B305F6300F8807F /* main.m in Sources */,
328346
038880B51B305F6300F8807F /* AppDelegate.m in Sources */,
347+
039731AC1FA326F10040F92E /* MainWindow.m in Sources */,
329348
038880D31B305FDB00F8807F /* DragDropView.m in Sources */,
330349
03D63F7C1BB9804200CC8485 /* NSImage+Resize.m in Sources */,
350+
039731AF1FA327350040F92E /* UpdateModel.m in Sources */,
331351
03C461981C2760CD00F1572A /* ResizeModel.m in Sources */,
332352
);
333353
runOnlyForDeploymentPostprocessing = 0;
Binary file not shown.

Retini.zip

189 KB
Binary file not shown.

Retini/AppDelegate.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88

99
#import <Cocoa/Cocoa.h>
1010
#import <Foundation/Foundation.h>
11-
#import "AFNetworking.h"
11+
#import "MainWindow.h"
1212

13-
@interface AppDelegate : NSObject <NSApplicationDelegate, NSAlertDelegate>
13+
@interface AppDelegate : NSObject <NSApplicationDelegate>
1414

15-
- (BOOL)processFile:(NSString *)file;
15+
@property (nonatomic, retain) IBOutlet MainWindow *window;
1616

1717
@end
1818

Retini/AppDelegate.m

Lines changed: 2 additions & 265 deletions
Original file line numberDiff line numberDiff line change
@@ -7,277 +7,14 @@
77
//
88

99
#import "AppDelegate.h"
10-
#import "DragDropView.h"
11-
#import <QuartzCore/QuartzCore.h>
12-
13-
@interface AppDelegate ()
14-
15-
// Jup, i know this all shoud be in neat UIWindows and stuff, i'm going to refractor the code soon.
16-
17-
@property (nonatomic, retain) IBOutlet NSLayoutConstraint *topDragConstraint;
18-
@property (nonatomic, retain) IBOutlet NSLayoutConstraint *bottomDragConstraint;
19-
@property (nonatomic, retain) IBOutlet NSWindow *window;
20-
@property (nonatomic, retain) IBOutlet DragDropView *dropView;
21-
22-
@property (nonatomic, retain) IBOutlet NSButton *settingsButton;
23-
@property (nonatomic, retain) IBOutlet NSTextField *jpegQualityField;
24-
@property (nonatomic, retain) IBOutlet NSStepper *jpegQualityStepper;
25-
@property (nonatomic, retain) IBOutlet NSButton *pngOutButton;
26-
27-
@property (nonatomic, retain) IBOutlet NSProgressIndicator *loader;
28-
29-
- (IBAction)checkForUpdates:(id)sender;
30-
- (IBAction)hitSettings:(id)sender;
31-
- (IBAction)stepperDidClick:(id)sender;
32-
- (IBAction)pngOutDidClick:(id)sender;
33-
34-
@end
3510

3611
@implementation AppDelegate
3712

38-
@synthesize jpegQualityField, jpegQualityStepper, settingsButton, pngOutButton;
39-
@synthesize loader;
13+
@synthesize window;
4014

4115
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
4216
{
43-
return [self processFile:filename];
44-
}
45-
46-
- (BOOL)processFile:(NSString *)file
47-
{
48-
[self.dropView checkFiles:@[file]];
49-
50-
return YES; // Return YES when file processed succesfull, else return NO.
51-
}
52-
53-
- (IBAction)hitSettings:(id)sender
54-
{
55-
if(self.bottomDragConstraint.animator.constant == 0){
56-
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
57-
[context setDuration:0.2];
58-
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
59-
self.topDragConstraint.animator.constant = -105;
60-
self.bottomDragConstraint.animator.constant = 105;
61-
62-
[settingsButton setTitle:@"Close"];
63-
} completionHandler:^{
64-
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
65-
[context setDuration:0.3];
66-
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
67-
self.topDragConstraint.animator.constant = -100;
68-
self.bottomDragConstraint.animator.constant = 100;
69-
} completionHandler:nil];
70-
}];
71-
} else{
72-
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
73-
[context setDuration:0.15];
74-
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
75-
self.topDragConstraint.animator.constant = 5;
76-
self.bottomDragConstraint.animator.constant = -5;
77-
78-
[settingsButton setTitle:@"Settings"];
79-
} completionHandler:^{
80-
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
81-
[context setDuration:0.2];
82-
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
83-
self.topDragConstraint.animator.constant = 0;
84-
self.bottomDragConstraint.animator.constant = 0;
85-
} completionHandler:nil];
86-
}];
87-
}
88-
}
89-
90-
- (IBAction)stepperDidClick:(id)sender
91-
{
92-
if([sender isKindOfClass:[NSStepper class]]){
93-
NSStepper *stepper = (NSStepper *)sender;
94-
95-
int stepperVal = MIN(MAX([stepper intValue], 1), 10);
96-
97-
[jpegQualityField setStringValue:[NSString stringWithFormat:@"%i/10", stepperVal]];
98-
99-
[[NSUserDefaults standardUserDefaults] setInteger:stepperVal forKey:@"jpegQuality"];
100-
[[NSUserDefaults standardUserDefaults] synchronize];
101-
}
102-
}
103-
104-
- (IBAction)pngOutDidClick:(id)sender
105-
{
106-
[[NSUserDefaults standardUserDefaults] setInteger:[(NSButton *)sender state] forKey:@"pngOut"];
107-
[[NSUserDefaults standardUserDefaults] synchronize];
108-
}
109-
110-
- (IBAction)checkForUpdates:(id)sender
111-
{
112-
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
113-
manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //to bad github gives the raw content as plain text
114-
manager.requestSerializer = [AFHTTPRequestSerializer serializer]; //otherwise this would have been AFPlistResponse / requestserializers
115-
116-
[manager GET:@"https://raw.githubusercontent.com/terwanerik/Retini/master/Retini/Info.plist"
117-
parameters:nil
118-
success:^(AFHTTPRequestOperation *operation, id responseObject) {
119-
[self checkPlist:responseObject andOrigin:sender];
120-
}
121-
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
122-
// just leave it be.
123-
}];
124-
}
125-
126-
- (void)checkPlist:(NSData *)plistData andOrigin:(id)sender
127-
{
128-
NSString *error;
129-
NSPropertyListFormat format;
130-
NSDictionary *plist = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
131-
132-
// remove dots to get big number. Versioning will never go beyond 10 so should work fine atm.
133-
int onlineVersion = [[[plist objectForKey:@"CFBundleShortVersionString"] stringByReplacingOccurrencesOfString:@"." withString:@""] intValue];
134-
int myVersion = [[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] stringByReplacingOccurrencesOfString:@"." withString:@""] intValue];
135-
136-
if(onlineVersion > myVersion){
137-
NSAlert *newVersionAlert = [[NSAlert alloc] init];
138-
[newVersionAlert setMessageText:@"A new version of Retini is found. Would you like to download the update?"];
139-
[newVersionAlert addButtonWithTitle:@"Update"];
140-
[newVersionAlert addButtonWithTitle:@"Cancel"];
141-
[newVersionAlert setDelegate:self];
142-
[newVersionAlert beginSheetModalForWindow:self.window
143-
modalDelegate:self
144-
didEndSelector:@selector(alertButtonClicked:returnCode:contextInfo:)
145-
contextInfo:nil];
146-
} else if(sender != nil){
147-
NSAlert *newVersionAlert = [[NSAlert alloc] init];
148-
[newVersionAlert setMessageText:@"No new version is found.. Check GitHub to be sure?"];
149-
[newVersionAlert addButtonWithTitle:@"GitHub? Letsgo!"];
150-
[newVersionAlert addButtonWithTitle:@"I'm good."];
151-
[newVersionAlert setDelegate:nil];
152-
[newVersionAlert beginSheetModalForWindow:self.window
153-
modalDelegate:self
154-
didEndSelector:@selector(alertButtonClicked:returnCode:contextInfo:)
155-
contextInfo:nil];
156-
}
157-
}
158-
159-
- (void)alertButtonClicked:(NSAlert *)alert
160-
returnCode:(int)returnCode
161-
contextInfo:(void *)contextInfo
162-
{
163-
if(returnCode == 1000){
164-
if(alert.delegate == self){
165-
//[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://github.com/terwanerik/Retini/raw/master/Retini.zip"]];
166-
167-
[self downloadNewZip];
168-
} else{
169-
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://github.com/terwanerik/Retini"]];
170-
}
171-
}
172-
}
173-
174-
- (void)downloadNewZip
175-
{
176-
[loader startAnimation:nil];
177-
178-
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
179-
manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //to bad github gives the raw content as plain text
180-
manager.requestSerializer = [AFHTTPRequestSerializer serializer]; //otherwise this would have been AFPlistResponse / requestserializers
181-
182-
[manager GET:@"https://github.com/terwanerik/Retini/raw/master/Retini.zip"
183-
parameters:nil
184-
success:^(AFHTTPRequestOperation *operation, id responseObject) {
185-
[self installZip:responseObject];
186-
}
187-
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
188-
NSAlert *newVersionAlert = [[NSAlert alloc] init];
189-
[newVersionAlert setMessageText:@"Couldn't download new version. Would you like to download it straight from GitHub?"];
190-
[newVersionAlert addButtonWithTitle:@"GitHub? Letsgo!"];
191-
[newVersionAlert addButtonWithTitle:@"I'm good."];
192-
[newVersionAlert setDelegate:nil];
193-
[newVersionAlert beginSheetModalForWindow:self.window
194-
modalDelegate:self
195-
didEndSelector:@selector(alertButtonClicked:returnCode:contextInfo:)
196-
contextInfo:nil];
197-
}];
198-
}
199-
200-
- (void)installZip:(NSData *)zip
201-
{
202-
NSString *filePath = [NSString stringWithFormat:@"%@/Retini.zip", NSTemporaryDirectory()];
203-
204-
if([[NSFileManager defaultManager] createFileAtPath:filePath
205-
contents:zip
206-
attributes:nil]){
207-
208-
NSTask *task = [[NSTask alloc] init];
209-
[task setLaunchPath:@"/usr/bin/unzip"];
210-
[task setCurrentDirectoryPath:NSTemporaryDirectory()];
211-
[task setArguments:@[@"-o", @"Retini.zip"]];
212-
[task launch];
213-
[task waitUntilExit];
214-
215-
[loader stopAnimation:nil];
216-
217-
NSError *error;
218-
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
219-
220-
if(!error){
221-
[[NSFileManager defaultManager] moveItemAtPath:[NSString stringWithFormat:@"%@/Retini.app", NSTemporaryDirectory()]
222-
toPath:@"/Applications/Retini_tmp.app"
223-
error:&error];
224-
225-
[self relaunchAfterDelay:1.0];
226-
}
227-
}
228-
}
229-
230-
- (void)relaunchAfterDelay:(float)seconds
231-
{
232-
NSTask *task = [[NSTask alloc] init];
233-
NSMutableArray *args = [NSMutableArray array];
234-
[args addObject:@"-c"];
235-
[args addObject:[NSString stringWithFormat:@"sleep %f; open \"%@\"", seconds, @"/Applications/Retini.app"]];
236-
[task setLaunchPath:@"/bin/sh"];
237-
[task setArguments:args];
238-
[task launch];
239-
240-
NSError *error;
241-
242-
if([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Retini.app"]){
243-
[[NSFileManager defaultManager] removeItemAtPath:@"/Applications/Retini.app" error:&error];
244-
}
245-
246-
if(!error){
247-
[[NSFileManager defaultManager] moveItemAtPath:@"/Applications/Retini_tmp.app"
248-
toPath:@"/Applications/Retini.app"
249-
error:&error];
250-
251-
[[NSApplication sharedApplication] terminate:nil];
252-
}
253-
}
254-
255-
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
256-
[self checkForUpdates:nil];
257-
258-
if([[NSUserDefaults standardUserDefaults] integerForKey:@"jpegQuality"]){
259-
[jpegQualityStepper setDoubleValue:[[NSUserDefaults standardUserDefaults] integerForKey:@"jpegQuality"]];
260-
}
261-
262-
if([[NSUserDefaults standardUserDefaults] integerForKey:@"pngOut"]){
263-
[pngOutButton setState:[[NSUserDefaults standardUserDefaults] integerForKey:@"pngOut"]];
264-
}
265-
266-
int stepperVal = MIN(MAX([jpegQualityStepper intValue], 1), 10);
267-
268-
[jpegQualityStepper setAlphaValue:0.7];
269-
[jpegQualityField setStringValue:[NSString stringWithFormat:@"%i/10", stepperVal]];
270-
271-
[settingsButton setTarget:self];
272-
[settingsButton setAction:@selector(hitSettings:)];
273-
274-
NSColor *color = [NSColor colorWithWhite:1.0 alpha:0.8];
275-
NSMutableAttributedString *colorTitle = [[NSMutableAttributedString alloc] initWithAttributedString:[pngOutButton attributedTitle]];
276-
NSRange titleRange = NSMakeRange(0, [colorTitle length]);
277-
[colorTitle addAttribute:NSForegroundColorAttributeName value:color range:titleRange];
278-
[pngOutButton setAttributedTitle:colorTitle];
279-
280-
[self.window setBackgroundColor:[NSColor colorWithWhite:0.08 alpha:1.0]];
17+
return [window processFile:filename];
28118
}
28219

28320
- (void)applicationWillTerminate:(NSNotification *)aNotification {

0 commit comments

Comments
 (0)