From 48d7d896293181ce3a1123c775280b82b2202c74 Mon Sep 17 00:00:00 2001 From: Raphael Hanneken Date: Tue, 22 Mar 2016 18:09:01 +0100 Subject: [PATCH] Meet SwiftLint requirements --- Icns Composer.xcodeproj/project.pbxproj | 17 ++ Icns Composer/AppDelegate.swift | 50 ++--- Icns Composer/DragDropImageView.swift | 178 ++++++++-------- Icns Composer/Iconset.swift | 183 +++++++++-------- Icns Composer/MainWindowController.swift | 251 +++++++++++------------ Icns Composer/NSImageExtensions.swift | 231 +++++++++++---------- 6 files changed, 469 insertions(+), 441 deletions(-) diff --git a/Icns Composer.xcodeproj/project.pbxproj b/Icns Composer.xcodeproj/project.pbxproj index 7232f7c..3802064 100644 --- a/Icns Composer.xcodeproj/project.pbxproj +++ b/Icns Composer.xcodeproj/project.pbxproj @@ -129,6 +129,7 @@ 20FA7A5A1B14E9D900E7B8E7 /* Frameworks */, 20FA7A5B1B14E9D900E7B8E7 /* Resources */, 8EA095AC1B583BFC00DA6A2E /* CopyFiles */, + 8E4CB2331CA196F4001D52C4 /* ShellScript */, ); buildRules = ( ); @@ -187,6 +188,22 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 8E4CB2331CA196F4001D52C4 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\n swiftlint autocorrect\n swiftlint\nelse\n echo \"Warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 20FA7A591B14E9D900E7B8E7 /* Sources */ = { isa = PBXSourcesBuildPhase; diff --git a/Icns Composer/AppDelegate.swift b/Icns Composer/AppDelegate.swift index b111e60..fc4f396 100644 --- a/Icns Composer/AppDelegate.swift +++ b/Icns Composer/AppDelegate.swift @@ -31,31 +31,31 @@ import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - /// Handle the window via MainWindowController. - var mainWindowController: MainWindowController? - - - func applicationDidFinishLaunching(aNotification: NSNotification) { - // Create a new WindowController instance. - let mainWindowController = MainWindowController() - - // Display the associated window on screen. - mainWindowController.showWindow(self) - - // Point the instance variable to the WindowController object. - self.mainWindowController = mainWindowController - } - - // Reopen mainWindow, when the user clicks on the dock icon. - func applicationShouldHandleReopen(sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { - if let mainWindowController = self.mainWindowController { - mainWindowController.showWindow(self) - } - return true - } + /// Handle the window via MainWindowController. + var mainWindowController: MainWindowController? + + + func applicationDidFinishLaunching(aNotification: NSNotification) { + // Create a new WindowController instance. + let mainWindowController = MainWindowController() - func applicationWillTerminate(aNotification: NSNotification) { - // Insert code here to tear down your application + // Display the associated window on screen. + mainWindowController.showWindow(self) + + // Point the instance variable to the WindowController object. + self.mainWindowController = mainWindowController + } + + // Reopen mainWindow, when the user clicks on the dock icon. + func applicationShouldHandleReopen(sender: NSApplication, + hasVisibleWindows flag: Bool) -> Bool { + if let mainWindowController = self.mainWindowController { + mainWindowController.showWindow(self) } -} + return true + } + func applicationWillTerminate(aNotification: NSNotification) { + // Insert code here to tear down your application + } +} diff --git a/Icns Composer/DragDropImageView.swift b/Icns Composer/DragDropImageView.swift index b035386..cb9586d 100644 --- a/Icns Composer/DragDropImageView.swift +++ b/Icns Composer/DragDropImageView.swift @@ -29,94 +29,98 @@ import Cocoa class DragDropImageView: NSImageView, NSDraggingSource { - - /// Holds the last mouse down event, to track the drag distance. - var mouseDownEvent: NSEvent? - - - - override init(frame frameRect: NSRect) { - super.init(frame: frameRect) - - // Assure editable is set to true, to enable drop capabilities. - self.editable = true - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - - // Assure editable is set to true, to enable drop capabilities. - self.editable = true - } - - override func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) - } - - - - // MARK: - NSDraggingSource - - // Since we only want to copy/delete the current image we register ourselfes - // for .Copy and .Delete operations. - func draggingSession(session: NSDraggingSession, sourceOperationMaskForDraggingContext context: NSDraggingContext) -> NSDragOperation { - return NSDragOperation.Copy.union(.Delete) - } - - // Clear the ImageView on delete operation; e.g. the image gets - // dropped on the trash can in the dock. - func draggingSession(session: NSDraggingSession, endedAtPoint screenPoint: NSPoint, operation: NSDragOperation) { - if operation == .Delete { - self.image = nil - } + + /// Holds the last mouse down event, to track the drag distance. + var mouseDownEvent: NSEvent? + + + + override init(frame frameRect: NSRect) { + super.init(frame: frameRect) + + // Assure editable is set to true, to enable drop capabilities. + self.editable = true + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + + // Assure editable is set to true, to enable drop capabilities. + self.editable = true + } + + override func drawRect(dirtyRect: NSRect) { + super.drawRect(dirtyRect) + } + + + + // MARK: - NSDraggingSource + + // Since we only want to copy/delete the current image we register ourselfes + // for .Copy and .Delete operations. + func draggingSession(session: NSDraggingSession, sourceOperationMaskForDraggingContext + context: NSDraggingContext) -> NSDragOperation { + return NSDragOperation.Copy.union(.Delete) + } + + // Clear the ImageView on delete operation; e.g. the image gets + // dropped on the trash can in the dock. + func draggingSession(session: NSDraggingSession, endedAtPoint screenPoint: NSPoint, + operation: NSDragOperation) { + if operation == .Delete { + self.image = nil } - - // Track mouse down events and safe the to the poperty. - override func mouseDown(theEvent: NSEvent) { - self.mouseDownEvent = theEvent + } + + // Track mouse down events and safe the to the poperty. + override func mouseDown(theEvent: NSEvent) { + self.mouseDownEvent = theEvent + } + + // Track mouse dragged events to handle dragging sessions. + override func mouseDragged(theEvent: NSEvent) { + // Calculate the drag distance... + let mouseDown = self.mouseDownEvent!.locationInWindow + let dragPoint = theEvent.locationInWindow + let dragDistance = hypot(mouseDown.x - dragPoint.x, mouseDown.y - dragPoint.y) + + // ...to cancel the dragging session in case of accidental drag. + if dragDistance < 3 { + return } - - // Track mouse dragged events to handle dragging sessions. - override func mouseDragged(theEvent: NSEvent) { - // Calculate the drag distance... - let mouseDown = self.mouseDownEvent!.locationInWindow - let dragPoint = theEvent.locationInWindow - let dragDistance = hypot(mouseDown.x - dragPoint.x, mouseDown.y - dragPoint.y) - - // ...to cancel the dragging session in case of accidental drag. - if dragDistance < 3 { - return - } - - // Unwrap the image property - if let image = self.image { - // Do some math to properly resize the given image. - let size = NSSize(width: log10(image.size.width) * 30, height: log10(image.size.height) * 30) - let img = image.copyWithSize(size)! - - // Create a new NSDraggingItem with the image as content. - let draggingItem = NSDraggingItem(pasteboardWriter: image) - // Calculate the mouseDown location from the window's coordinate system to the - // ImageView's coordinate system, to use it as origin for the dragging frame. - let draggingFrameOrigin = convertPoint(mouseDown, fromView: nil) - // Build the dragging frame and offset it by half the image size on each axis - // to center the mouse cursor within the dragging frame. - let draggingFrame = NSRect(origin: draggingFrameOrigin, size: img.size).offsetBy(dx: -img.size.width / 2, dy: -img.size.height / 2) - - // Assign the dragging frame to the draggingFrame property of our dragging item. - draggingItem.draggingFrame = draggingFrame - - // Provide the components of the dragging image. - draggingItem.imageComponentsProvider = { - let component = NSDraggingImageComponent(key: NSDraggingImageComponentIconKey) - - component.contents = image - component.frame = NSRect(origin: NSPoint(), size: draggingFrame.size) - return [component] - } - - // Begin actual dragging session. Woohow! - beginDraggingSessionWithItems([draggingItem], event: mouseDownEvent!, source: self) - } + + // Unwrap the image property + if let image = self.image { + // Do some math to properly resize the given image. + let size = NSSize(width: log10(image.size.width) * 30, + height: log10(image.size.height) * 30) + let img = image.copyWithSize(size)! + + // Create a new NSDraggingItem with the image as content. + let draggingItem = NSDraggingItem(pasteboardWriter: image) + // Calculate the mouseDown location from the window's coordinate system to the + // ImageView's coordinate system, to use it as origin for the dragging frame. + let draggingFrameOrigin = convertPoint(mouseDown, fromView: nil) + // Build the dragging frame and offset it by half the image size on each axis + // to center the mouse cursor within the dragging frame. + let draggingFrame = NSRect(origin: draggingFrameOrigin, size: img.size) + .offsetBy(dx: -img.size.width / 2, dy: -img.size.height / 2) + + // Assign the dragging frame to the draggingFrame property of our dragging item. + draggingItem.draggingFrame = draggingFrame + + // Provide the components of the dragging image. + draggingItem.imageComponentsProvider = { + let component = NSDraggingImageComponent(key: NSDraggingImageComponentIconKey) + + component.contents = image + component.frame = NSRect(origin: NSPoint(), size: draggingFrame.size) + return [component] + } + + // Begin actual dragging session. Woohow! + beginDraggingSessionWithItems([draggingItem], event: mouseDownEvent!, source: self) } + } } diff --git a/Icns Composer/Iconset.swift b/Icns Composer/Iconset.swift index 72b6da2..5b09534 100644 --- a/Icns Composer/Iconset.swift +++ b/Icns Composer/Iconset.swift @@ -30,101 +30,106 @@ import Cocoa enum IconsetError: ErrorType { - case MissingURL + case MissingURL } class Iconset { - - /// Holds the necessary images to create an iconset that conforms iconutil - var images: [String : NSImage] = [:] - - - - /// Adds an image to the images dictionary. - /// - /// - parameter img: Image object to add to the array - /// - parameter size: Size of the given image, e.g. 512x512@2x - func addImage(img: NSImage, ofSize size: String) { - images[size] = img + + /// Holds the necessary images to create an iconset that conforms iconutil + var images: [String : NSImage] = [:] + + + /// Adds an image to the images dictionary. + /// + /// - parameter img: Image object to add to the array + /// - parameter size: Size of the given image, e.g. 512x512@2x + func addImage(img: NSImage, ofSize size: String) { + images[size] = img + } + + /// Saves an icns file to the supplied url. + /// + /// - parameter url: URL to save the icns file to. + /// - throws: A MissingURL error, when the supplied url cant be unwrapped. + func saveIcnsToURL(url: NSURL?) throws { + // Unwrap the given url. + guard let url = url else { + throw IconsetError.MissingURL } - - /// Saves an *.icns file with images from images - /// - /// - parameter url: Path to the directory, where to save the icns file. - func saveIcnsToURL(url: NSURL?) throws { - // Unwrap the given url. - guard let url = url else { - throw IconsetError.MissingURL - } - - // Get the temporary directory for the current user and append the choosen iconset name + .iconset - let tmpURL = NSURL(fileURLWithPath: NSTemporaryDirectory() + url.lastPathComponent! + ".iconset", isDirectory: true) - - // Build the iconset. - try writeIconsetToURL(tmpURL) - - // Create the *.icns file. - try runIconUtilWithInput(tmpURL, andOutputURL: url) - - // Open the working directory. - NSWorkspace.sharedWorkspace().openURL(url.URLByDeletingLastPathComponent!) + + // Get the temporary directory for the current user and + // append the choosen iconset name + .iconset + let tmpURL = NSURL(fileURLWithPath: + NSTemporaryDirectory() + url.lastPathComponent! + ".iconset", isDirectory: true) + + // Build the iconset. + try writeIconsetToURL(tmpURL) + + // Create the *.icns file. + try runIconUtilWithInput(tmpURL, andOutputURL: url) + + // Open the working directory. + NSWorkspace.sharedWorkspace().openURL(url.URLByDeletingLastPathComponent!) + } + + + /// Saves the resized images as iconset to the supplied URL. + /// + /// - parameter url: Path the location where to save the iconset. + /// - throws: A MissingURL error, in case the supplied url cant be unwrapped. + func writeIconsetToURL(url: NSURL?) throws { + // Unwrap the given url. + guard let url = url else { + throw IconsetError.MissingURL } - - - /// Saves the resized images as *.iconset to the given URL. - /// - /// - parameter url: Path to the directory, where to save the iconset. - /// - /// - returns: True on success - func writeIconsetToURL(url: NSURL?) throws { - // Unwrap the given url. - guard let url = url else { - throw IconsetError.MissingURL - } - - // Create the iconset directory, if not already existent. - try NSFileManager.defaultManager().createDirectoryAtURL(url, withIntermediateDirectories: true, attributes: nil) - - // For each image in the dictionary... - for (size, image) in images { - // ...append the appropriate file name to the given url,... - let imgURL = url.URLByAppendingPathComponent("icon_\(size).png", isDirectory: false) - - // ...create a png representation and... - guard let png = image.PNGRepresentation() else { - continue - } - - // ...write the png file to the HD. - try png.writeToURL(imgURL, options: .DataWritingAtomic) - } + + // Create the iconset directory, if not already existent. + try NSFileManager.defaultManager().createDirectoryAtURL(url, + withIntermediateDirectories: true, + attributes: nil) + + // For each image in the dictionary... + for (size, image) in images { + // ...append the appropriate file name to the given url,... + let imgURL = url.URLByAppendingPathComponent("icon_\(size).png", isDirectory: false) + + // ...create a png representation and... + guard let png = image.PNGRepresentation() else { + continue + } + + // ...write the png file to the HD. + try png.writeToURL(imgURL, options: .DataWritingAtomic) } - - - /// Runs iconutil with the given url as input path. - /// - /// - parameter url: Path to a convertable iconset directory. - /// - parameter url: Path to the location, where to save the generated icns file. - func runIconUtilWithInput(input: NSURL?, andOutputURL output: NSURL?) throws { - // Unwrap the optional url. - guard let input = input, output = output else { - throw IconsetError.MissingURL - } - - // Create a new task. - let iconUtil = NSTask() - - // Append the .icns file extension to the output path. - let outputURL = output.URLByAppendingPathExtension("icns") - - // Configure the NSTask and fire it up. - iconUtil.launchPath = "/usr/bin/iconutil" - iconUtil.arguments = ["-c", "icns", "-o", outputURL.path!, input.path!] - iconUtil.launch() - iconUtil.waitUntilExit() - - // Delete the .iconset - try NSFileManager.defaultManager().removeItemAtURL(input) + } + + + /// Executes iconutil with the given url as input path. + /// + /// - parameter input: Path to a convertable iconset directory. + /// - parameter output: Path to the location, where to save the generated icns file. + /// + /// - throws: Throws a MissingURL error, in case one of the supplied urls cant be unwrapped. + func runIconUtilWithInput(input: NSURL?, andOutputURL output: NSURL?) throws { + // Unwrap the optional url. + guard let input = input, output = output else { + throw IconsetError.MissingURL } + + // Create a new task. + let iconUtil = NSTask() + + // Append the .icns file extension to the output path. + let outputURL = output.URLByAppendingPathExtension("icns") + + // Configure the NSTask and fire it up. + iconUtil.launchPath = "/usr/bin/iconutil" + iconUtil.arguments = ["-c", "icns", "-o", outputURL.path!, input.path!] + iconUtil.launch() + iconUtil.waitUntilExit() + + // Delete the .iconset + try NSFileManager.defaultManager().removeItemAtURL(input) + } } diff --git a/Icns Composer/MainWindowController.swift b/Icns Composer/MainWindowController.swift index 3481163..5a5fbd9 100644 --- a/Icns Composer/MainWindowController.swift +++ b/Icns Composer/MainWindowController.swift @@ -28,133 +28,132 @@ import Cocoa -class MainWindowController : NSWindowController, NSWindowDelegate { - - override var windowNibName : String? { - return "MainWindow" - } - - /// Holds the 1024x1024px image - @IBOutlet weak var image1024: NSImageView! - /// Holds the 512x512px image - @IBOutlet weak var image512: NSImageView! - /// Holds the 256x256px image - @IBOutlet weak var image256: NSImageView! - /// Holds the 64x64px image - @IBOutlet weak var image128: NSImageView! - /// Holds the 32x32px image - @IBOutlet weak var image64: NSImageView! - - /// Handles the icon creation process. - let icon = Iconset() - - - - // override windowDidLoad() to hide the window title. - override func windowDidLoad() { - super.windowDidLoad() - - // To display the unified toolbar, hide the window title. - window!.titleVisibility = .Hidden - } - - - - // MARK: - Actions - - - /// Gets called everytime the user clicks 'Export'. - /// Opens an NSSavePanel, to let the user choose, where to save the icns file. - /// - /// - parameter sender: An NSToolbarItem - @IBAction func export(sender: NSToolbarItem) { - // Create a new NSSavePanel instance... - let dialog = NSSavePanel() - - // ...and open it on top of the main window. - dialog.beginSheetModalForWindow(window!) { (result: Int) -> Void in - // Did the user choose a directory? - if result == NSFileHandlingPanelOKButton { - // Save the iconset to the HD. - do { - try self.icon.saveIcnsToURL(dialog.URL) - } catch { - guard let window = self.window else { - return - } - // Create an alert for the user. - let alert = NSAlert() - - alert.messageText = "This should not have happened!" - alert.informativeText = "The icns file could not be saved due to a critical error." - alert.beginSheetModalForWindow(window, completionHandler: nil) - - // Print the error on the console - print(error) - } - } - } - } - - - /// Gets called everytime a user dropps an image onto a connected NSImageView. - /// Resizes the dropped images to the appropriate size and adds them to the icon object. - /// - /// - parameter sender: An NSImageView - @IBAction func resize(sender: NSImageView) { - // Unwrap the given image object. - guard let img = sender.image else { +class MainWindowController: NSWindowController, NSWindowDelegate { + + override var windowNibName: String? { + return "MainWindow" + } + + /// Holds the 1024x1024px image + @IBOutlet weak var image1024: NSImageView! + /// Holds the 512x512px image + @IBOutlet weak var image512: NSImageView! + /// Holds the 256x256px image + @IBOutlet weak var image256: NSImageView! + /// Holds the 64x64px image + @IBOutlet weak var image128: NSImageView! + /// Holds the 32x32px image + @IBOutlet weak var image64: NSImageView! + + /// Handles the icon creation process. + let icon = Iconset() + + + + // override windowDidLoad() to hide the window title. + override func windowDidLoad() { + super.windowDidLoad() + // To display the unified toolbar, hide the window title. + window!.titleVisibility = .Hidden + } + + + + // MARK: - Actions + + + /// Gets called everytime the user clicks 'Export'. + /// Opens an NSSavePanel, to let the user choose, where to save the icns file. + /// + /// - parameter sender: An NSToolbarItem + @IBAction func export(sender: NSToolbarItem) { + // Create a new NSSavePanel instance... + let dialog = NSSavePanel() + + // ...and open it on top of the main window. + dialog.beginSheetModalForWindow(window!) { (result: Int) -> Void in + // Did the user choose a directory? + if result == NSFileHandlingPanelOKButton { + // Save the iconset to the HD. + do { + try self.icon.saveIcnsToURL(dialog.URL) + } catch { + guard let window = self.window else { return + } + // Create an alert for the user. + let alert = NSAlert() + + alert.messageText = "This should not have happened!" + alert.informativeText = "The icns file could not be saved due to a critical error." + alert.beginSheetModalForWindow(window, completionHandler: nil) + + // Print the error on the console + print(error) } - - let tag = sender.tag - let x1 = NSSize(width: tag / 2, height: tag / 2) - let x2 = NSSize(width: tag, height: tag) - - switch tag { - case 1024: - // Resize image to the appropriate size... - image1024.image = img.copyWithSize(x2) - - // ...and add it to the icon object. - icon.addImage(image1024.image!, ofSize: "512x512@2x") - icon.addImage(img.copyWithSize(x1)!, ofSize: "512x512") - - case 512: - // Resize image to the appropriate size... - image512.image = img.copyWithSize(x2) - - // ...and add it to the icon object. - icon.addImage(image512.image!, ofSize: "256x256@2x") - icon.addImage(img.copyWithSize(x1)!, ofSize: "256x256") - - case 256: - // Resize image to the appropriate size... - image256.image = img.copyWithSize(x2) - - // ...and add it to the icon object. - icon.addImage(image256.image!, ofSize: "128x128@2x") - icon.addImage(img.copyWithSize(x1)!, ofSize: "128x128") - - case 64: - // Resize image to the appropriate size... - image128.image = img.copyWithSize(x2) - - // ...and add it to the icon object. - icon.addImage(image128.image!, ofSize: "32x32@2x") - icon.addImage(img.copyWithSize(x1)!, ofSize: "32x32") - - case 32: - // Resize image to the appropriate size... - image64.image = img.copyWithSize(x2) - - // ...and add it to the icon object. - icon.addImage(image64.image!, ofSize: "16x16@2x") - icon.addImage(img.copyWithSize(x1)!, ofSize: "16x16") - - default: - // Nothing to do here. *flies away* - return - } + } + } + } + + + /// Gets called everytime a user dropps an image onto a connected NSImageView. + /// Resizes the dropped images to the appropriate size and adds them to the icon object. + /// + /// - parameter sender: An NSImageView + @IBAction func resize(sender: NSImageView) { + // Unwrap the given image object. + guard let img = sender.image else { + return + } + + let tag = sender.tag + let x1 = NSSize(width: tag / 2, height: tag / 2) + let x2 = NSSize(width: tag, height: tag) + + switch tag { + case 1024: + // Resize image to the appropriate size... + image1024.image = img.copyWithSize(x2) + + // ...and add it to the icon object. + icon.addImage(image1024.image!, ofSize: "512x512@2x") + icon.addImage(img.copyWithSize(x1)!, ofSize: "512x512") + + case 512: + // Resize image to the appropriate size... + image512.image = img.copyWithSize(x2) + + // ...and add it to the icon object. + icon.addImage(image512.image!, ofSize: "256x256@2x") + icon.addImage(img.copyWithSize(x1)!, ofSize: "256x256") + + case 256: + // Resize image to the appropriate size... + image256.image = img.copyWithSize(x2) + + // ...and add it to the icon object. + icon.addImage(image256.image!, ofSize: "128x128@2x") + icon.addImage(img.copyWithSize(x1)!, ofSize: "128x128") + + case 64: + // Resize image to the appropriate size... + image128.image = img.copyWithSize(x2) + + // ...and add it to the icon object. + icon.addImage(image128.image!, ofSize: "32x32@2x") + icon.addImage(img.copyWithSize(x1)!, ofSize: "32x32") + + case 32: + // Resize image to the appropriate size... + image64.image = img.copyWithSize(x2) + + // ...and add it to the icon object. + icon.addImage(image64.image!, ofSize: "16x16@2x") + icon.addImage(img.copyWithSize(x1)!, ofSize: "16x16") + + default: + // Nothing to do here. *flies away* + return } + } } diff --git a/Icns Composer/NSImageExtensions.swift b/Icns Composer/NSImageExtensions.swift index 02c185b..91e3f9f 100644 --- a/Icns Composer/NSImageExtensions.swift +++ b/Icns Composer/NSImageExtensions.swift @@ -29,124 +29,127 @@ import Cocoa extension NSImage { - - /// Returns the height of the current image. - var height: CGFloat { - return self.size.height + + /// Returns the height of the current image. + var height: CGFloat { + return self.size.height + } + + /// Returns the width of the current image. + var width: CGFloat { + return self.size.width + } + + /// Copies the current image and resizes it to the given size. + /// + /// - parameter size: The size of the new image. + /// + /// - returns: The resized copy of the given image. + func copyWithSize(size: NSSize) -> NSImage? { + // Create a new rect with given width and height + let frame = NSMakeRect(0, 0, size.width, size.height) + + // Get the best representation for the given size. + guard let rep = self.bestRepresentationForRect(frame, context: nil, hints: nil) else { + return nil } - - /// Returns the width of the current image. - var width: CGFloat { - return self.size.width + + // Create an empty image with the given size. + let img = NSImage(size: size) + + // Set the drawing context and make sure to remove the focus before returning. + img.lockFocus() + defer { img.unlockFocus() } + + // Draw the new image + if rep.drawInRect(frame) { + return img + } + + // Return nil in case something went wrong. + return nil + } + + /// Copies the current image and resizes it to the size of the given NSSize, while + /// maintaining the aspect ratio of the original image. + /// + /// - parameter size: The size of the new image. + /// + /// - returns: The resized copy of the given image. + func resizeWhileMaintainingAspectRatioToSize(size: NSSize) -> NSImage? { + let newSize: NSSize + + let widthRatio = size.width / self.width + let heightRatio = size.height / self.height + + if widthRatio > heightRatio { + newSize = NSSize(width: floor(self.width * widthRatio), + height: floor(self.height * widthRatio)) + } else { + newSize = NSSize(width: floor(self.width * heightRatio), + height: floor(self.height * heightRatio)) } - - /// Copies the current image and resizes it to the given size. - /// - /// - parameter size: The size of the new image. - /// - /// - returns: The resized copy of the given image. - func copyWithSize(size: NSSize) -> NSImage? { - // Create a new rect with given width and height - let frame = NSMakeRect(0, 0, size.width, size.height) - - // Get the best representation for the given size. - guard let rep = self.bestRepresentationForRect(frame, context: nil, hints: nil) else { - return nil - } - - // Create an empty image with the given size. - let img = NSImage(size: size) - - // Set the drawing context and make sure to remove the focus before returning. - img.lockFocus() - defer { img.unlockFocus() } - - // Draw the new image - if rep.drawInRect(frame) { - return img - } - - // Return nil in case something went wrong. - return nil + + return self.copyWithSize(newSize) + } + + /// Copies and crops an image to the given size. + /// + /// - parameter size: The size of the new image. + /// + /// - returns: The cropped copy of the given image. + func cropToSize(size: NSSize) -> NSImage? { + // Resize the current image, while preserving the aspect ratio. + guard let resized = self.resizeWhileMaintainingAspectRatioToSize(size) else { + return nil } - - /// Copies the current image and resizes it to the size of the given NSSize, while - /// maintaining the aspect ratio of the original image. - /// - /// - parameter size: The size of the new image. - /// - /// - returns: The resized copy of the given image. - func resizeWhileMaintainingAspectRatioToSize(size: NSSize) -> NSImage? { - let newSize: NSSize - - let widthRatio = size.width / self.width - let heightRatio = size.height / self.height - - if widthRatio > heightRatio { - newSize = NSSize(width: floor(self.width * widthRatio), height: floor(self.height * widthRatio)) - } else { - newSize = NSSize(width: floor(self.width * heightRatio), height: floor(self.height * heightRatio)) - } - - return self.copyWithSize(newSize) + // Get some points to center the cropping area. + let x = floor((resized.width - size.width) / 2) + let y = floor((resized.height - size.height) / 2) + + // Create the cropping frame. + let frame = NSMakeRect(x, y, size.width, size.height) + + // Get the best representation of the image for the given cropping frame. + guard let rep = resized.bestRepresentationForRect(frame, context: nil, hints: nil) else { + return nil } - - /// Copies and crops an image to the given size. - /// - /// - parameter size: The size of the new image. - /// - /// - returns: The cropped copy of the given image. - func cropToSize(size: NSSize) -> NSImage? { - // Resize the current image, while preserving the aspect ratio. - guard let resized = self.resizeWhileMaintainingAspectRatioToSize(size) else { - return nil - } - // Get some points to center the cropping area. - let x = floor((resized.width - size.width) / 2) - let y = floor((resized.height - size.height) / 2) - - // Create the cropping frame. - let frame = NSMakeRect(x, y, size.width, size.height) - - // Get the best representation of the image for the given cropping frame. - guard let rep = resized.bestRepresentationForRect(frame, context: nil, hints: nil) else { - return nil - } - - // Create a new image with the new size - let img = NSImage(size: size) - - img.lockFocus() - defer { img.unlockFocus() } - - if rep.drawInRect(NSMakeRect(0, 0, size.width, size.height), - fromRect: frame, - operation: NSCompositingOperation.CompositeCopy, - fraction: 1.0, - respectFlipped: false, - hints: [:]) { - // Return the cropped image. - return img - } - - // Return nil in case anything fails. - return nil + + // Create a new image with the new size + let img = NSImage(size: size) + + img.lockFocus() + defer { img.unlockFocus() } + + if rep.drawInRect(NSMakeRect(0, 0, size.width, size.height), + fromRect: frame, + operation: NSCompositingOperation.CompositeCopy, + fraction: 1.0, + respectFlipped: false, + hints: [:]) { + // Return the cropped image. + return img } - - /// Creates a PNGRepresentation of the current image. - /// - /// - returns: The PNG representation of the current image. - func PNGRepresentation() -> NSData? { - // Lock drawing focus on self and make sure the focus gets unlocked before returning. - self.lockFocus() - defer { self.unlockFocus() } - - // Get the bitmap representation of self. - guard let rep = NSBitmapImageRep(focusedViewRect: NSMakeRect(0, 0, self.width, self.height)) else { - return nil - } - - // Return NSPNGFileType representation of the bitmap object. - return rep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: [:]) + + // Return nil in case anything fails. + return nil + } + + /// Creates a PNGRepresentation of the current image. + /// + /// - returns: The PNG representation of the current image. + func PNGRepresentation() -> NSData? { + // Lock drawing focus on self and make sure the focus gets unlocked before returning. + self.lockFocus() + defer { self.unlockFocus() } + // Define a new rect + let imgRect = NSMakeRect(0, 0, self.width, self.height) + // Get the bitmap representation of self. + guard let rep = NSBitmapImageRep(focusedViewRect: imgRect) else { + return nil } + + // Return NSPNGFileType representation of the bitmap object. + return rep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: [:]) + } }