Full Code of yuhua-chen/LayerX for AI

master b96bfd477e2c cached
13 files
56.4 KB
15.0k tokens
1 requests
Download .txt
Repository: yuhua-chen/LayerX
Branch: master
Commit: b96bfd477e2c
Files: 13
Total size: 56.4 KB

Directory structure:
gitextract_ov5xqwub/

├── .gitignore
├── LayerX/
│   ├── AppDelegate.swift
│   ├── Assets.xcassets/
│   │   ├── AppIcon.appiconset/
│   │   │   └── Contents.json
│   │   ├── Contents.json
│   │   └── lock.imageset/
│   │       └── Contents.json
│   ├── Base.lproj/
│   │   └── Main.storyboard
│   ├── Info.plist
│   ├── MCDragAndDropImageView.swift
│   ├── MCWindow.swift
│   └── ViewController.swift
├── LayerX.xcodeproj/
│   ├── project.pbxproj
│   └── project.xcworkspace/
│       └── contents.xcworkspacedata
└── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Created by https://www.gitignore.io/api/xcode,osx

### Xcode ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
build/
DerivedData

## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata

## Other
*.xccheckout
*.moved-aside
*.xcuserstate


### OSX ###
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk



================================================
FILE: LayerX/AppDelegate.swift
================================================
//
//  AppDelegate.swift
//  LayerX
//
//  Created by Michael Chen on 2015/10/26.
//  Copyright © 2015年 Michael Chen. All rights reserved.
//

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

	private let defaultSize = NSMakeSize(480, 320)
	private let resizeStep: CGFloat = 0.1

	var allSpaces = false
	var locked = false
	var onTop = false

	weak var window: MCWIndow!
	weak var viewController: ViewController!
	var isLockIconHiddenWhileLocked = false {
		didSet { viewController.lockIconImageView.isHidden = window.isMovable || isLockIconHiddenWhileLocked }
	}
	var isSizeHidden = false {
		didSet { viewController.sizeTextField.isHidden = isSizeHidden }
	}

	func applicationDidFinishLaunching(_ aNotification: Notification) {
		if let window = NSApp.windows.first as? MCWIndow {
			window.fitsWithSize(defaultSize)
			window.collectionBehavior = [.managed, .moveToActiveSpace]
			self.window = window
		}
	}
}

fileprivate enum ArrowTag: Int {
	case up = 20
	case left = 21
	case right = 22
	case down = 23
}

// MARK: - Hotkeys

extension AppDelegate {

	private var originalSize: NSSize {
		viewController.imageView.image?.size ?? defaultSize
	}

	private func resizeAspectFit(calculator: (_ original: CGFloat, _ current: CGFloat) -> CGFloat) {
		let originalSize = self.originalSize
		let width = calculator(originalSize.width, window.frame.size.width)
		let height = width / originalSize.width * originalSize.height

		if width > 0 {
			window.resizeTo(NSSize(width: width, height: height), animated: true)
		}
	}

	@IBAction func actualSize(_ sender: AnyObject?) {
		window.resizeTo(originalSize, animated: true)
	}

	@IBAction func makeLarger(_ sender: AnyObject) {
		resizeAspectFit { $0 * ($1 / $0 + resizeStep) }
	}

	@IBAction func makeSmaller(_ sender: AnyObject) {
		resizeAspectFit { $0 * ($1 / $0 - resizeStep) }
	}

	@IBAction func makeLargerOnePixel(_ sender: AnyObject) {
		resizeAspectFit { $1 + 1 }
	}

	@IBAction func makeSmallerOnePixel(_ sender: AnyObject) {
		resizeAspectFit { $1 - 1 }
	}

	@IBAction func increaseTransparency(_ sender: AnyObject) {
		var alpha = viewController.imageView.alphaValue
		alpha -= 0.1
		viewController.imageView.alphaValue = max(alpha, 0.05)
	}

	@IBAction func reduceTransparency(_ sender: AnyObject) {
		var alpha = viewController.imageView.alphaValue
		alpha += 0.1
		viewController.imageView.alphaValue = min(alpha, 1.0)
	}
	
	func getPasteboardImage() -> NSImage? {
		let pasteboard = NSPasteboard.general;
		if let file = pasteboard.data(forType: NSPasteboard.PasteboardType.fileURL),
		   let str = String(data: file, encoding: .utf8),
		   let url = URL(string: str)
		{
			return NSImage(contentsOf: url)
		}

		if let tiff = pasteboard.data(forType: NSPasteboard.PasteboardType.tiff) {
			return NSImage(data: tiff)
		}

		if let png = pasteboard.data(forType: NSPasteboard.PasteboardType.png) {
			return NSImage(data: png)
		}

		return nil
	}
	
	@IBAction func paste(_ sender: AnyObject) {
		guard let image = getPasteboardImage() else { return }
		let rep = image.representations[0]
		viewController.imageView.image = image
		let size = NSMakeSize(CGFloat(rep.pixelsWide), CGFloat(rep.pixelsHigh))
		window.resizeTo(size, animated: true)
		viewController.sizeTextField.isHidden = false
		viewController.placeholderTextField.isHidden = true

	}
	
	@IBAction func toggleLockWindow(_ sender: AnyObject) {
		let menuItem = sender as! NSMenuItem
		locked = !locked
		onTop = locked
		if locked {
			menuItem.title  = "Unlock"
			window.isMovable = false
			window.ignoresMouseEvents = true
			window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.maximumWindow)))
		} else {
			menuItem.title  = "Lock"
			window.isMovable = true
			window.ignoresMouseEvents = false
			window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.normalWindow)))
		}

		viewController.lockIconImageView.isHidden = window.isMovable || isLockIconHiddenWhileLocked
	}
	
	@IBAction func toggleOnTop(_ sender: AnyObject) {
		let menuItem = sender as! NSMenuItem
		onTop = !onTop
		if onTop {
			menuItem.title = "Don't keep on top"
			window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.maximumWindow)))
		} else if !locked {
			menuItem.title = "Keep on top"
			window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.normalWindow)))
		}
	}
	
	@IBAction func toggleLockIconVisibility(_ sender: AnyObject) {
		let menuItem = sender as! NSMenuItem
		menuItem.state = menuItem.state == .on ? .off : .on
		isLockIconHiddenWhileLocked = menuItem.state == .on
	}

	@IBAction func toggleSizeVisibility(_ sender: AnyObject) {
		let menuItem = sender as! NSMenuItem
		menuItem.state = menuItem.state == .on ? .off : .on
		isSizeHidden = menuItem.state == .on
	}

	@IBAction func moveAround(_ sender: AnyObject) {
		let menuItem = sender as! NSMenuItem

		guard let arrow = ArrowTag(rawValue: menuItem.tag) else {
			return
		}

		switch arrow {
		case .up:
			window.moveBy(CGPoint(x: 0, y: 1))
		case .left:
			window.moveBy(CGPoint(x: -1, y: 0))
		case .right:
			window.moveBy(CGPoint(x: 1, y: 0))
		case .down:
			window.moveBy(CGPoint(x: 0, y: -1))
		}
	}

	@IBAction func toggleAllSpaces(_ sender: AnyObject) {
		let menuItem = sender as! NSMenuItem
		allSpaces = !allSpaces
		if allSpaces {
			menuItem.title = "Keep on this space"
			window.collectionBehavior = [.canJoinAllSpaces]
		} else {
			menuItem.title = "Keep on all spaces"
			window.collectionBehavior = [.managed, .moveToActiveSpace]
		}
	}

	func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
		return viewController.imageView.image != nil
	}
}

// MARK: - Helper

func appDelegate() -> AppDelegate {
	return NSApp.delegate as! AppDelegate
}


================================================
FILE: LayerX/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
  "images" : [
    {
      "size" : "16x16",
      "idiom" : "mac",
      "filename" : "appIcon-16.png",
      "scale" : "1x"
    },
    {
      "size" : "16x16",
      "idiom" : "mac",
      "filename" : "appIcon-32.png",
      "scale" : "2x"
    },
    {
      "size" : "32x32",
      "idiom" : "mac",
      "filename" : "appIcon-34.png",
      "scale" : "1x"
    },
    {
      "size" : "32x32",
      "idiom" : "mac",
      "filename" : "appIcon-64.png",
      "scale" : "2x"
    },
    {
      "size" : "128x128",
      "idiom" : "mac",
      "filename" : "appIcon-128.png",
      "scale" : "1x"
    },
    {
      "size" : "128x128",
      "idiom" : "mac",
      "filename" : "appIcon-257.png",
      "scale" : "2x"
    },
    {
      "size" : "256x256",
      "idiom" : "mac",
      "filename" : "appIcon-256.png",
      "scale" : "1x"
    },
    {
      "size" : "256x256",
      "idiom" : "mac",
      "filename" : "appIcon.png",
      "scale" : "2x"
    },
    {
      "size" : "512x512",
      "idiom" : "mac",
      "filename" : "appIcon-1.png",
      "scale" : "1x"
    },
    {
      "size" : "512x512",
      "idiom" : "mac",
      "filename" : "appIcon-2.png",
      "scale" : "2x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: LayerX/Assets.xcassets/Contents.json
================================================
{
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: LayerX/Assets.xcassets/lock.imageset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "Lock-16.png",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "filename" : "lock-32.png",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "filename" : "lock.png",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: LayerX/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
        <capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
    </dependencies>
    <scenes>
        <!--Application-->
        <scene sceneID="JPo-4y-FX3">
            <objects>
                <application id="hnw-xV-0zn" sceneMemberID="viewController">
                    <menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
                        <items>
                            <menuItem title="LayerX" id="1Xt-HY-uBw">
                                <modifierMask key="keyEquivalentModifierMask"/>
                                <menu key="submenu" title="LayerX" systemMenu="apple" id="uQy-DD-JDr">
                                    <items>
                                        <menuItem title="About LayerX" id="5kV-Vb-QxS">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
                                        <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
                                        <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
                                        <menuItem title="Services" id="NMo-om-nkz">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
                                        </menuItem>
                                        <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
                                        <menuItem title="Hide LayerX" keyEquivalent="h" id="Olw-nP-bQN">
                                            <connections>
                                                <action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
                                            <connections>
                                                <action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Show All" id="Kd2-mp-pUS">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
                                        <menuItem title="Quit LayerX" keyEquivalent="q" id="4sb-4s-VLi">
                                            <connections>
                                                <action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
                                            </connections>
                                        </menuItem>
                                    </items>
                                </menu>
                            </menuItem>
                            <menuItem title="File" id="dMs-cI-mzQ">
                                <modifierMask key="keyEquivalentModifierMask"/>
                                <menu key="submenu" title="File" id="bib-Uj-vzu">
                                    <items>
                                        <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
                                            <connections>
                                                <action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
                                            <connections>
                                                <action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Open Recent" id="tXI-mr-wws">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
                                                <items>
                                                    <menuItem title="Clear Menu" id="vNY-rz-j42">
                                                        <modifierMask key="keyEquivalentModifierMask"/>
                                                        <connections>
                                                            <action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
                                                        </connections>
                                                    </menuItem>
                                                </items>
                                            </menu>
                                        </menuItem>
                                        <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
                                        <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
                                            <connections>
                                                <action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
                                            <connections>
                                                <action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
                                            <connections>
                                                <action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Revert to Saved" id="KaW-ft-85H">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
                                        <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
                                            <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
                                            <connections>
                                                <action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
                                            <connections>
                                                <action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
                                            </connections>
                                        </menuItem>
                                    </items>
                                </menu>
                            </menuItem>
                            <menuItem title="Edit" id="dAm-Da-fWl">
                                <modifierMask key="keyEquivalentModifierMask"/>
                                <menu key="submenu" title="Edit" id="aeY-sH-oUd">
                                    <items>
                                        <menuItem title="Paste" keyEquivalent="v" id="Wup-uR-bUt">
                                            <connections>
                                                <action selector="paste:" target="Voe-Tx-rLC" id="mh3-X2-sMC"/>
                                            </connections>
                                        </menuItem>
                                    </items>
                                </menu>
                            </menuItem>
                            <menuItem title="View" id="H8h-7b-M4v">
                                <modifierMask key="keyEquivalentModifierMask"/>
                                <menu key="submenu" title="View" id="HyV-fh-RgO">
                                    <items>
                                        <menuItem title="Actual Size" keyEquivalent="0" id="snW-S8-Cw5">
                                            <connections>
                                                <action selector="actualSize:" target="Voe-Tx-rLC" id="Rr0-Sv-VSe"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Scale Up 10%" keyEquivalent="+" id="Ed8-Vk-OS6">
                                            <connections>
                                                <action selector="makeLarger:" target="Voe-Tx-rLC" id="ldh-JS-1g5"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Scale Down 10%" keyEquivalent="-" id="trE-Hj-Y6i">
                                            <connections>
                                                <action selector="makeSmaller:" target="Voe-Tx-rLC" id="gWX-vc-gSr"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Scale Up 1px" keyEquivalent="=" id="QFF-N1-xBx">
                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
                                            <connections>
                                                <action selector="makeLargerOnePixel:" target="Voe-Tx-rLC" id="a6e-El-RWw"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Scale Down 1px" keyEquivalent="-" id="mKa-lu-KYo">
                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
                                            <connections>
                                                <action selector="makeSmallerOnePixel:" target="Voe-Tx-rLC" id="lBc-iQ-i2i"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem isSeparatorItem="YES" id="S7H-4j-wWG"/>
                                        <menuItem title="Move up 1px" tag="20" keyEquivalent="" id="xt1-zP-8lE">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="moveAround:" target="Voe-Tx-rLC" id="qks-64-WYp"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Move left 1px" tag="21" keyEquivalent="" id="Ud7-FA-vtA">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="moveAround:" target="Voe-Tx-rLC" id="RxY-3b-ZPJ"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Move right 1px" tag="22" keyEquivalent="" id="SC9-Za-3te">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="moveAround:" target="Voe-Tx-rLC" id="7UQ-dw-xVi"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Move down 1px" tag="23" keyEquivalent="" id="T88-KV-33B">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="moveAround:" target="Voe-Tx-rLC" id="gZw-Fh-AIF"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem isSeparatorItem="YES" id="Uol-cd-eOj"/>
                                        <menuItem title="Increase Transparency" keyEquivalent="j" id="PLz-nj-Geg">
                                            <connections>
                                                <action selector="increaseTransparency:" target="Voe-Tx-rLC" id="O9E-CS-NRG"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Reduce Transparency" keyEquivalent="k" id="P7g-e7-fyw">
                                            <connections>
                                                <action selector="reduceTransparency:" target="Voe-Tx-rLC" id="6jy-Px-MpF"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem isSeparatorItem="YES" id="4H8-5J-P5x"/>
                                        <menuItem title="Hide Lock Icon" id="MeZ-fZ-1OL">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="toggleLockIconVisibility:" target="Voe-Tx-rLC" id="RCB-nJ-o0E"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Hide Size" id="JXi-GL-qzz">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="toggleSizeVisibility:" target="Voe-Tx-rLC" id="e8c-Wd-zRh"/>
                                            </connections>
                                        </menuItem>
                                    </items>
                                </menu>
                            </menuItem>
                            <menuItem title="Window" id="aUF-d1-5bR">
                                <modifierMask key="keyEquivalentModifierMask"/>
                                <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
                                    <items>
                                        <menuItem title="Lock" keyEquivalent="l" id="OY7-WF-poV">
                                            <connections>
                                                <action selector="toggleLockWindow:" target="Voe-Tx-rLC" id="Mfc-bV-lDx"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Keep on top" keyEquivalent="t" id="WZF-Ql-Ptb">
                                            <connections>
                                                <action selector="toggleOnTop:" target="Voe-Tx-rLC" id="1mS-lL-oZG"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem title="Keep on all spaces" keyEquivalent="a" id="pZ0-jf-Hps">
                                            <connections>
                                                <action selector="toggleAllSpaces:" target="Voe-Tx-rLC" id="N0L-4A-TpV"/>
                                            </connections>
                                        </menuItem>
                                        <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
                                        <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
                                            <modifierMask key="keyEquivalentModifierMask"/>
                                            <connections>
                                                <action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
                                            </connections>
                                        </menuItem>
                                    </items>
                                </menu>
                            </menuItem>
                            <menuItem title="Help" id="wpr-3q-Mcd">
                                <modifierMask key="keyEquivalentModifierMask"/>
                                <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
                                    <items>
                                        <menuItem title="LayerX Help" keyEquivalent="?" id="FKE-Sm-Kum">
                                            <connections>
                                                <action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
                                            </connections>
                                        </menuItem>
                                    </items>
                                </menu>
                            </menuItem>
                        </items>
                    </menu>
                    <connections>
                        <outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
                    </connections>
                </application>
                <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="LayerX" customModuleProvider="target"/>
                <customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="75" y="0.0"/>
        </scene>
        <!--Window Controller-->
        <scene sceneID="R2V-B0-nI4">
            <objects>
                <windowController id="B8D-0N-5wS" sceneMemberID="viewController">
                    <window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA" customClass="MCWIndow" customModule="LayerX" customModuleProvider="target">
                        <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
                        <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
                        <rect key="contentRect" x="515" y="487" width="480" height="270"/>
                        <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
                        <connections>
                            <outlet property="delegate" destination="B8D-0N-5wS" id="Ikp-UW-Prj"/>
                        </connections>
                    </window>
                    <connections>
                        <segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
                    </connections>
                </windowController>
                <customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="75" y="250"/>
        </scene>
        <!--View Controller-->
        <scene sceneID="hIz-AP-VOD">
            <objects>
                <viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="LayerX" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" id="m2S-Jp-Qdl" customClass="MCMovableView" customModule="LayerX" customModuleProvider="target">
                        <rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
                        <autoresizingMask key="autoresizingMask"/>
                        <subviews>
                            <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="249" verticalCompressionResistancePriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="pOu-B0-2Yd" customClass="MCDragAndDropImageView" customModule="LayerX" customModuleProvider="target">
                                <rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
                                <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="axesIndependently" id="55W-zB-lko"/>
                            </imageView>
                            <textField hidden="YES" wantsLayer="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JAT-ZL-8HB">
                                <rect key="frame" x="454" y="243" width="16" height="17"/>
                                <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" alignment="center" title="0" drawsBackground="YES" id="Mmp-Eh-bBs">
                                    <font key="font" metaFont="system"/>
                                    <color key="textColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                                    <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="calibratedRGB"/>
                                </textFieldCell>
                            </textField>
                            <textField wantsLayer="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8Vs-Az-CYd">
                                <rect key="frame" x="148" y="123" width="184" height="25"/>
                                <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Drop Images here." id="vTq-g5-aKV">
                                    <font key="font" size="20" name="HelveticaNeue-Bold"/>
                                    <color key="textColor" name="scrollBarColor" catalog="System" colorSpace="catalog"/>
                                    <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
                                </textFieldCell>
                            </textField>
                            <imageView hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="3I3-1H-JKb">
                                <rect key="frame" x="446" y="10" width="24" height="24"/>
                                <constraints>
                                    <constraint firstAttribute="width" secondItem="3I3-1H-JKb" secondAttribute="height" multiplier="1:1" id="BQz-pm-nY9"/>
                                    <constraint firstAttribute="width" constant="24" id="x71-Sn-2Dl"/>
                                </constraints>
                                <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="lock" id="4Zf-oV-Kj0"/>
                            </imageView>
                        </subviews>
                        <constraints>
                            <constraint firstAttribute="bottom" secondItem="3I3-1H-JKb" secondAttribute="bottom" constant="10" id="64H-0g-nnO"/>
                            <constraint firstItem="8Vs-Az-CYd" firstAttribute="centerY" secondItem="m2S-Jp-Qdl" secondAttribute="centerY" id="6fI-na-pdX"/>
                            <constraint firstItem="8Vs-Az-CYd" firstAttribute="centerX" secondItem="m2S-Jp-Qdl" secondAttribute="centerX" id="RwW-eB-OYh"/>
                            <constraint firstItem="JAT-ZL-8HB" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" constant="10" id="WnK-c6-NWw"/>
                            <constraint firstItem="pOu-B0-2Yd" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" id="aC7-xh-2BR"/>
                            <constraint firstItem="pOu-B0-2Yd" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" id="lhy-17-EcM"/>
                            <constraint firstAttribute="trailing" secondItem="pOu-B0-2Yd" secondAttribute="trailing" id="qbm-Dq-jeg"/>
                            <constraint firstAttribute="bottom" secondItem="pOu-B0-2Yd" secondAttribute="bottom" id="r2U-99-hj5"/>
                            <constraint firstAttribute="trailing" secondItem="3I3-1H-JKb" secondAttribute="trailing" constant="10" id="und-pJ-9Mz"/>
                            <constraint firstAttribute="trailing" secondItem="JAT-ZL-8HB" secondAttribute="trailing" constant="10" id="xlU-hc-l09"/>
                        </constraints>
                    </view>
                    <connections>
                        <outlet property="imageView" destination="pOu-B0-2Yd" id="OT9-S1-m4L"/>
                        <outlet property="lockIconImageView" destination="3I3-1H-JKb" id="Nka-rj-tDO"/>
                        <outlet property="placeholderTextField" destination="8Vs-Az-CYd" id="env-Po-Bb7"/>
                        <outlet property="sizeTextField" destination="JAT-ZL-8HB" id="vIP-80-PVG"/>
                    </connections>
                </viewController>
                <customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="75" y="655"/>
        </scene>
    </scenes>
    <resources>
        <image name="lock" width="32" height="32"/>
    </resources>
</document>


================================================
FILE: LayerX/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIconFile</key>
	<string></string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.2.0</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>1</string>
	<key>LSMinimumSystemVersion</key>
	<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
	<key>NSHumanReadableCopyright</key>
	<string>Copyright © 2015年 Michael Chen. All rights reserved.</string>
	<key>NSMainStoryboardFile</key>
	<string>Main</string>
	<key>NSPrincipalClass</key>
	<string>NSApplication</string>
</dict>
</plist>


================================================
FILE: LayerX/MCDragAndDropImageView.swift
================================================
//
//  MCDragAndDropImageView.swift
//  LayerX
//
//  Created by Michael Chen on 2015/10/26.
//  Copyright © 2015年 Michael Chen. All rights reserved.
//

import Cocoa

protocol MCDragAndDropImageViewDelegate: class {
	func dragAndDropImageViewDidDrop(_ imageView: MCDragAndDropImageView)
}

class MCDragAndDropImageView: NSImageView {

	weak var delegate: MCDragAndDropImageViewDelegate?

	required init?(coder: NSCoder) {
		super.init(coder: coder)

		registerForDraggedTypes(NSImage.imageTypes.map(NSPasteboard.PasteboardType.init(rawValue:)))

		wantsLayer = true
	}

	override func setNeedsDisplay() {
		alphaValue = image == nil ? 1.0 : 0.6
		super.setNeedsDisplay()
	}

	override func draw(_ dirtyRect: NSRect) {
		super.draw(dirtyRect)

		if let _ = image {
			layer?.backgroundColor = NSColor.clear.cgColor
			return
		}

		layer?.backgroundColor = NSColor(white: isHighlighted ? 0.5 : 0.8, alpha: 1.0).cgColor
	}

	override var mouseDownCanMoveWindow:Bool {
		return true
	}
}

// MARK: - NSDraggingSource

extension MCDragAndDropImageView: NSDraggingSource {

	override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {

		if (NSImage.canInit(with: sender.draggingPasteboard)) {
			isHighlighted = true

			setNeedsDisplay()

			let sourceDragMask = sender.draggingSourceOperationMask
			let pboard = sender.draggingPasteboard

			if pboard.availableType(from: [.fileURL]) == .fileURL {
				if sourceDragMask.rawValue & NSDragOperation.copy.rawValue != 0 {
					return NSDragOperation.copy
				}
			}
		}

		return NSDragOperation()
	}

	override func draggingExited(_ sender: NSDraggingInfo?) {
		isHighlighted = false
		setNeedsDisplay()
	}

	override func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool {
		isHighlighted = false
		setNeedsDisplay()

		return NSImage.canInit(with: sender.draggingPasteboard)
	}

	override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
		if (NSImage.canInit(with: sender.draggingPasteboard)) {
			image = NSImage(pasteboard: sender.draggingPasteboard)
			delegate?.dragAndDropImageViewDidDrop(self)
			setNeedsDisplay()
		}

		return true
	}

	func draggingSession(_ session: NSDraggingSession, sourceOperationMaskFor context: NSDraggingContext) -> NSDragOperation {
		switch context {
		case .outsideApplication: return NSDragOperation()
		case .withinApplication: return .copy
		@unknown default: return NSDragOperation()
		}
	}
}


================================================
FILE: LayerX/MCWindow.swift
================================================
//
//  MCWindow.swift
//  LayerX
//
//  Created by Michael Chen on 2015/10/27.
//  Copyright © 2015年 Michael Chen. All rights reserved.
//

import Cocoa

class MCWIndow: NSWindow {
	override func awakeFromNib() {
		styleMask = [.borderless, .resizable]
		isOpaque = false
		backgroundColor = NSColor.clear
		isMovableByWindowBackground = true
		hasShadow = false
	}

    func moveBy(_ offset: CGPoint) {
        var frame = self.frame
        frame.origin.x += offset.x
        frame.origin.y += offset.y

        setFrame(frame, display: true)
    }

	func fitsWithSize(_ size: NSSize) {
		var frame = self.frame
		if frame.size.width < size.width || frame.size.height < size.height {
			frame.size = size
			setFrame(frame, display: true)
		}
	}

	func resizeTo(_ size: NSSize, animated: Bool) {
		var frame = self.frame
		frame.size = size

		if !animated {
			setFrame(frame, display: true)
			return
		}

		let resizeAnimation = [NSViewAnimation.Key.target: self, NSViewAnimation.Key.endFrame: NSValue(rect: frame)]
		let animations = NSViewAnimation(viewAnimations: [resizeAnimation])
		animations.animationBlockingMode = .blocking
		animations.animationCurve = .easeInOut
		animations.duration = 0.15
		animations.start()
	}

    override func constrainFrameRect(_ frameRect: NSRect, to screen: NSScreen?) -> NSRect {
        return frameRect
    }
}


================================================
FILE: LayerX/ViewController.swift
================================================
//
//  ViewController.swift
//  LayerX
//
//  Created by Michael Chen on 2015/10/26.
//  Copyright © 2015年 Michael Chen. All rights reserved.
//

import Cocoa

class ViewController: NSViewController {

	@IBOutlet weak var imageView: MCDragAndDropImageView!
	@IBOutlet weak var sizeTextField: NSTextField!
	@IBOutlet weak var placeholderTextField: NSTextField!
	@IBOutlet weak var lockIconImageView: NSImageView!

	override var acceptsFirstResponder: Bool {
		return true
	}

	lazy var trackingArea: NSTrackingArea = {
		let options: NSTrackingArea.Options = [.activeAlways, .mouseEnteredAndExited]
		return NSTrackingArea(rect: self.view.bounds, options: options, owner: self, userInfo: nil)
	}()

	deinit {
		NotificationCenter.default.removeObserver(self)
	}

	required init?(coder: NSCoder) {
		super.init(coder: coder)
		appDelegate().viewController = self
	}

	override func viewDidLoad() {
		super.viewDidLoad()

		imageView.delegate = self

		sizeTextField.layer?.cornerRadius = 3
		sizeTextField.layer?.masksToBounds = true

		lockIconImageView.wantsLayer = true
		lockIconImageView.layer?.backgroundColor = NSColor(white: 0.0, alpha: 0.5).cgColor
		lockIconImageView.layer?.cornerRadius = 5
		lockIconImageView.layer?.masksToBounds = true

		NotificationCenter.default.addObserver(self, selector: #selector(windowDidResize(_:)), name: NSWindow.didResizeNotification, object: appDelegate().window)

		view.addTrackingArea(trackingArea)
	}

	@objc func fadeOutSizeTextField() {
		let transition = CATransition()
		sizeTextField.layer?.add(transition, forKey: "fadeOut")
		sizeTextField.layer?.opacity = 0
	}

	@objc func windowDidResize(_ notification: Notification) {
		let window = notification.object as! NSWindow
		let size = window.frame.size
		sizeTextField.stringValue = "\(Int(size.width))x\(Int(size.height))"
		sizeTextField.layer?.opacity = 1

		NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(ViewController.fadeOutSizeTextField), object: nil)
		perform(#selector(ViewController.fadeOutSizeTextField), with: nil, afterDelay: 2)
	}

	// MARK: Mouse events

	override func scrollWheel(with theEvent: NSEvent) {
		guard let _ = imageView.image else { return }

		let delta = theEvent.deltaY * 0.005;
		var alpha = imageView.alphaValue - delta
		alpha = min(alpha, 1)
		alpha = max(alpha, 0.05)
		imageView.alphaValue = alpha
	}

	override func mouseEntered(with theEvent: NSEvent) {
		sizeTextField.layer?.opacity = 1
	}

	override func mouseExited(with theEvent: NSEvent) {
		fadeOutSizeTextField()
	}
}

// MARK: - MCDragAndDropImageViewDelegate

extension ViewController: MCDragAndDropImageViewDelegate {
	func dragAndDropImageViewDidDrop(_ imageView: MCDragAndDropImageView) {

		sizeTextField.isHidden = false
		placeholderTextField.isHidden = true

		appDelegate().actualSize(nil)
	}
}

// MARK: - Movable NSView

class MCMovableView: NSView{
	override var mouseDownCanMoveWindow:Bool {
		return true
	}
}


================================================
FILE: LayerX.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		8C09F9F51BDE2E5C00DD457E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C09F9F41BDE2E5C00DD457E /* AppDelegate.swift */; };
		8C09F9F71BDE2E5C00DD457E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C09F9F61BDE2E5C00DD457E /* ViewController.swift */; };
		8C09F9F91BDE2E5C00DD457E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8C09F9F81BDE2E5C00DD457E /* Assets.xcassets */; };
		8C09F9FC1BDE2E5C00DD457E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8C09F9FA1BDE2E5C00DD457E /* Main.storyboard */; };
		8C09FA041BDE324500DD457E /* MCDragAndDropImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C09FA031BDE324500DD457E /* MCDragAndDropImageView.swift */; };
		8C09FA0C1BDF5F7300DD457E /* MCWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C09FA0B1BDF5F7300DD457E /* MCWindow.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		8C09F9F11BDE2E5C00DD457E /* LayerX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LayerX.app; sourceTree = BUILT_PRODUCTS_DIR; };
		8C09F9F41BDE2E5C00DD457E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
		8C09F9F61BDE2E5C00DD457E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
		8C09F9F81BDE2E5C00DD457E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
		8C09F9FB1BDE2E5C00DD457E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
		8C09F9FD1BDE2E5C00DD457E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		8C09FA031BDE324500DD457E /* MCDragAndDropImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MCDragAndDropImageView.swift; sourceTree = "<group>"; };
		8C09FA0B1BDF5F7300DD457E /* MCWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MCWindow.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		8C09F9EE1BDE2E5C00DD457E /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		8C09F9E81BDE2E5C00DD457E = {
			isa = PBXGroup;
			children = (
				8C09F9F31BDE2E5C00DD457E /* LayerX */,
				8C09F9F21BDE2E5C00DD457E /* Products */,
			);
			sourceTree = "<group>";
		};
		8C09F9F21BDE2E5C00DD457E /* Products */ = {
			isa = PBXGroup;
			children = (
				8C09F9F11BDE2E5C00DD457E /* LayerX.app */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		8C09F9F31BDE2E5C00DD457E /* LayerX */ = {
			isa = PBXGroup;
			children = (
				8C09F9F41BDE2E5C00DD457E /* AppDelegate.swift */,
				8C09FA0B1BDF5F7300DD457E /* MCWindow.swift */,
				8C09F9F61BDE2E5C00DD457E /* ViewController.swift */,
				8C09FA031BDE324500DD457E /* MCDragAndDropImageView.swift */,
				8C09F9F81BDE2E5C00DD457E /* Assets.xcassets */,
				8C09F9FA1BDE2E5C00DD457E /* Main.storyboard */,
				8C09F9FD1BDE2E5C00DD457E /* Info.plist */,
			);
			path = LayerX;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		8C09F9F01BDE2E5C00DD457E /* LayerX */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 8C09FA001BDE2E5C00DD457E /* Build configuration list for PBXNativeTarget "LayerX" */;
			buildPhases = (
				8C09F9ED1BDE2E5C00DD457E /* Sources */,
				8C09F9EE1BDE2E5C00DD457E /* Frameworks */,
				8C09F9EF1BDE2E5C00DD457E /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = LayerX;
			productName = LayerX;
			productReference = 8C09F9F11BDE2E5C00DD457E /* LayerX.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		8C09F9E91BDE2E5C00DD457E /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastUpgradeCheck = 0700;
				ORGANIZATIONNAME = "Michael Chen";
				TargetAttributes = {
					8C09F9F01BDE2E5C00DD457E = {
						CreatedOnToolsVersion = 7.0;
						LastSwiftMigration = 0800;
					};
				};
			};
			buildConfigurationList = 8C09F9EC1BDE2E5C00DD457E /* Build configuration list for PBXProject "LayerX" */;
			compatibilityVersion = "Xcode 3.2";
			developmentRegion = English;
			hasScannedForEncodings = 0;
			knownRegions = (
				English,
				en,
				Base,
			);
			mainGroup = 8C09F9E81BDE2E5C00DD457E;
			productRefGroup = 8C09F9F21BDE2E5C00DD457E /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				8C09F9F01BDE2E5C00DD457E /* LayerX */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		8C09F9EF1BDE2E5C00DD457E /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				8C09F9F91BDE2E5C00DD457E /* Assets.xcassets in Resources */,
				8C09F9FC1BDE2E5C00DD457E /* Main.storyboard in Resources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		8C09F9ED1BDE2E5C00DD457E /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				8C09F9F71BDE2E5C00DD457E /* ViewController.swift in Sources */,
				8C09FA0C1BDF5F7300DD457E /* MCWindow.swift in Sources */,
				8C09F9F51BDE2E5C00DD457E /* AppDelegate.swift in Sources */,
				8C09FA041BDE324500DD457E /* MCDragAndDropImageView.swift in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin PBXVariantGroup section */
		8C09F9FA1BDE2E5C00DD457E /* Main.storyboard */ = {
			isa = PBXVariantGroup;
			children = (
				8C09F9FB1BDE2E5C00DD457E /* Base */,
			);
			name = Main.storyboard;
			sourceTree = "<group>";
		};
/* End PBXVariantGroup section */

/* Begin XCBuildConfiguration section */
		8C09F9FE1BDE2E5C00DD457E /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				CODE_SIGN_IDENTITY = "-";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = dwarf;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 0;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.13;
				MTL_ENABLE_DEBUG_INFO = YES;
				ONLY_ACTIVE_ARCH = YES;
				SDKROOT = macosx;
				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
				SWIFT_VERSION = 5.0;
			};
			name = Debug;
		};
		8C09F9FF1BDE2E5C00DD457E /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				CODE_SIGN_IDENTITY = "-";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
				ENABLE_NS_ASSERTIONS = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				MACOSX_DEPLOYMENT_TARGET = 10.13;
				MTL_ENABLE_DEBUG_INFO = NO;
				SDKROOT = macosx;
				SWIFT_VERSION = 5.0;
			};
			name = Release;
		};
		8C09FA011BDE2E5C00DD457E /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				COMBINE_HIDPI_IMAGES = YES;
				INFOPLIST_FILE = LayerX/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
				PRODUCT_BUNDLE_IDENTIFIER = io.michaelchen.LayerX;
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Debug;
		};
		8C09FA021BDE2E5C00DD457E /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				COMBINE_HIDPI_IMAGES = YES;
				INFOPLIST_FILE = LayerX/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
				PRODUCT_BUNDLE_IDENTIFIER = io.michaelchen.LayerX;
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		8C09F9EC1BDE2E5C00DD457E /* Build configuration list for PBXProject "LayerX" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				8C09F9FE1BDE2E5C00DD457E /* Debug */,
				8C09F9FF1BDE2E5C00DD457E /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		8C09FA001BDE2E5C00DD457E /* Build configuration list for PBXNativeTarget "LayerX" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				8C09FA011BDE2E5C00DD457E /* Debug */,
				8C09FA021BDE2E5C00DD457E /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
/* End XCConfigurationList section */
	};
	rootObject = 8C09F9E91BDE2E5C00DD457E /* Project object */;
}


================================================
FILE: LayerX.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:LayerX.xcodeproj">
   </FileRef>
</Workspace>


================================================
FILE: README.md
================================================
# LayerX

An intuitive app to display transparent images on screen.

[![Demo](http://img.youtube.com/vi/35KixjZBDjY/0.jpg)](http://www.youtube.com/watch?v=35KixjZBDjY)

# System requirements

Support Mac OS X 10.10 or later.

# Features

- [x] Drag and drop images
- [x] Keyboard Shortcuts
- [x] Adjust transparency  
- [x] Lock images
- [X] Aspect ratio scaling

# Keyboard Shortcuts

### Set image

| Key | Action |
|:--- |:---    |
|`⌘ V`| Paste image or file from clipboard. |

### Scale

| Key | Action |
|:---|:---|
|`⌘ 0`| Actual image size.|
|`⌘ +`| Scale up 10%.|
|`⌘ -`| Scale down 10%.|
|`^ ⌘ +`| Scale up 1px.|
|`^ ⌘ -`| Scale down 1px.|

### Move (Arrow keys)

| Key | Action |
|:---|:---|
|`↑`| Move up 1px.|
|`←`| Move left 1px.|
|`→`| Move right 1px.|
|`↓`| Move down 1px.|

### Alpha

|Key|Action|
|:---|:---|
|`⌘ J`| Increase transparency.|
|`⌘ K`| Reduce transparency.|

### Window

|Key|Action|
|:---|:---|
|`⌘ L`| Lock images and make window always on top.|
|`⌘ T`| Make window always on top.|
|`⌘ A`| Keep window on all spaces.|

# Mouse events

| Event | Action |
|:---|:---|
| Scroll up on image | Reduce transparency. |
| Scroll down on image | Increase transparency. |

# Contact

Any suggestions are welcome. Find me at [@yuhua_twit](https://twitter.com/yuhua_twit)

# License

Copyright (c) 2017 Michael Chen (a.k.a. Yuhua Chen)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Download .txt
gitextract_ov5xqwub/

├── .gitignore
├── LayerX/
│   ├── AppDelegate.swift
│   ├── Assets.xcassets/
│   │   ├── AppIcon.appiconset/
│   │   │   └── Contents.json
│   │   ├── Contents.json
│   │   └── lock.imageset/
│   │       └── Contents.json
│   ├── Base.lproj/
│   │   └── Main.storyboard
│   ├── Info.plist
│   ├── MCDragAndDropImageView.swift
│   ├── MCWindow.swift
│   └── ViewController.swift
├── LayerX.xcodeproj/
│   ├── project.pbxproj
│   └── project.xcworkspace/
│       └── contents.xcworkspacedata
└── README.md
Condensed preview — 13 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (63K chars).
[
  {
    "path": ".gitignore",
    "chars": 798,
    "preview": "# Created by https://www.gitignore.io/api/xcode,osx\n\n### Xcode ###\n# Xcode\n#\n# gitignore contributors: remember to updat"
  },
  {
    "path": "LayerX/AppDelegate.swift",
    "chars": 5732,
    "preview": "//\n//  AppDelegate.swift\n//  LayerX\n//\n//  Created by Michael Chen on 2015/10/26.\n//  Copyright © 2015年 Michael Chen. Al"
  },
  {
    "path": "LayerX/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 1271,
    "preview": "{\n  \"images\" : [\n    {\n      \"size\" : \"16x16\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"appIcon-16.png\",\n      \"scale\""
  },
  {
    "path": "LayerX/Assets.xcassets/Contents.json",
    "chars": 62,
    "preview": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "LayerX/Assets.xcassets/lock.imageset/Contents.json",
    "chars": 369,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"Lock-16.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n"
  },
  {
    "path": "LayerX/Base.lproj/Main.storyboard",
    "chars": 28280,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\""
  },
  {
    "path": "LayerX/Info.plist",
    "chars": 1089,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "LayerX/MCDragAndDropImageView.swift",
    "chars": 2423,
    "preview": "//\n//  MCDragAndDropImageView.swift\n//  LayerX\n//\n//  Created by Michael Chen on 2015/10/26.\n//  Copyright © 2015年 Micha"
  },
  {
    "path": "LayerX/MCWindow.swift",
    "chars": 1358,
    "preview": "//\n//  MCWindow.swift\n//  LayerX\n//\n//  Created by Michael Chen on 2015/10/27.\n//  Copyright © 2015年 Michael Chen. All r"
  },
  {
    "path": "LayerX/ViewController.swift",
    "chars": 2957,
    "preview": "//\n//  ViewController.swift\n//  LayerX\n//\n//  Created by Michael Chen on 2015/10/26.\n//  Copyright © 2015年 Michael Chen."
  },
  {
    "path": "LayerX.xcodeproj/project.pbxproj",
    "chars": 10915,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "LayerX.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "chars": 151,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:LayerX.xcodepro"
  },
  {
    "path": "README.md",
    "chars": 2381,
    "preview": "# LayerX\n\nAn intuitive app to display transparent images on screen.\n\n[![Demo](http://img.youtube.com/vi/35KixjZBDjY/0.jp"
  }
]

About this extraction

This page contains the full source code of the yuhua-chen/LayerX GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 13 files (56.4 KB), approximately 15.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!