├── .gitignore
├── README.md
├── Snip.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ └── SnipManager.xcscheme
└── xcuserdata
│ └── liupeng.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ └── Snip.xcscheme
├── Snip
├── AppDelegate.h
├── AppDelegate.m
├── Base.lproj
│ └── MainMenu.xib
├── DemoViewController.h
├── DemoViewController.m
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── app.icns
└── main.m
├── SnipManager
├── DrawPathInfo.h
├── DrawPathInfo.m
├── DrawPathView.h
├── DrawPathView.m
├── ImageButton.h
├── ImageButton.m
├── Info.plist
├── MouseEventProtocol.h
├── NSColor+Helper.h
├── NSColor+Helper.m
├── Resource
│ └── Images.bundle
│ │ ├── ScreenCapture_toolbar_arrow_effect.tiff
│ │ ├── ScreenCapture_toolbar_arrow_ineffect.tiff
│ │ ├── ScreenCapture_toolbar_cross_normal.tiff
│ │ ├── ScreenCapture_toolbar_ellipse_effect.tiff
│ │ ├── ScreenCapture_toolbar_ellipse_ineffect.tiff
│ │ ├── ScreenCapture_toolbar_export.tiff
│ │ ├── ScreenCapture_toolbar_rect_effect.tiff
│ │ ├── ScreenCapture_toolbar_rect_ineffect.tiff
│ │ └── ScreenCapture_toolbar_tick_normal.tiff
├── SimpleLabelView.h
├── SimpleLabelView.m
├── SnipManager.h
├── SnipManager.m
├── SnipUtil.h
├── SnipUtil.m
├── SnipView.h
├── SnipView.m
├── SnipWindow.h
├── SnipWindow.m
├── SnipWindowController.h
├── SnipWindowController.m
├── SnipWindowController.xib
├── ToolContainer.h
└── ToolContainer.m
├── SnipTests
├── Info.plist
└── SnipTests.m
└── src.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | */build/*
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | project.xcworkspace
14 | profile
15 | *.moved-aside
16 | DerivedData
17 | .idea/
18 | .svn/
19 | *.hmap
20 | xcshareddata
21 | .last-build-date
22 | .xcodebuild_output
23 |
24 | Carthage
25 | Pods
26 | dmg-releases
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Capture Screen For Multi Screens On Mac
2 | There are many implementation about capture screen for mac.
3 |
4 | A sample is in xcode sample code.
5 |
6 | And mogutt also show code in https://github.com/mogutt/TTMacClient.
7 |
8 | But on dual monitors mode, they are all not work,
9 |
10 | even weixin's mac client and http://snip.qq.com/.
11 |
12 | Only QQ is powerful and perfect.
13 |
14 | And it's not open source.
15 |
16 |
17 | #So, I try to do the capture screen sample to support dual monitors.
18 |
19 | 
20 |
--------------------------------------------------------------------------------
/Snip.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 06C042CE1BBB77AB00B3B473 /* DrawPathInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042B71BBB77AB00B3B473 /* DrawPathInfo.h */; settings = {ASSET_TAGS = (); }; };
11 | 06C042CF1BBB77AB00B3B473 /* DrawPathInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042B81BBB77AB00B3B473 /* DrawPathInfo.m */; settings = {ASSET_TAGS = (); }; };
12 | 06C042D01BBB77AB00B3B473 /* DrawPathView.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042B91BBB77AB00B3B473 /* DrawPathView.h */; settings = {ASSET_TAGS = (); }; };
13 | 06C042D11BBB77AB00B3B473 /* DrawPathView.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042BA1BBB77AB00B3B473 /* DrawPathView.m */; settings = {ASSET_TAGS = (); }; };
14 | 06C042D21BBB77AB00B3B473 /* ImageButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042BB1BBB77AB00B3B473 /* ImageButton.h */; settings = {ASSET_TAGS = (); }; };
15 | 06C042D31BBB77AB00B3B473 /* ImageButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042BC1BBB77AB00B3B473 /* ImageButton.m */; settings = {ASSET_TAGS = (); }; };
16 | 06C042D41BBB77AB00B3B473 /* MouseEventProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042BD1BBB77AB00B3B473 /* MouseEventProtocol.h */; settings = {ASSET_TAGS = (); }; };
17 | 06C042D51BBB77AB00B3B473 /* NSColor+Helper.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042BE1BBB77AB00B3B473 /* NSColor+Helper.h */; settings = {ASSET_TAGS = (); }; };
18 | 06C042D61BBB77AB00B3B473 /* NSColor+Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042BF1BBB77AB00B3B473 /* NSColor+Helper.m */; settings = {ASSET_TAGS = (); }; };
19 | 06C042D71BBB77AB00B3B473 /* SimpleLabelView.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042C01BBB77AB00B3B473 /* SimpleLabelView.h */; settings = {ASSET_TAGS = (); }; };
20 | 06C042D81BBB77AB00B3B473 /* SimpleLabelView.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042C11BBB77AB00B3B473 /* SimpleLabelView.m */; settings = {ASSET_TAGS = (); }; };
21 | 06C042D91BBB77AB00B3B473 /* SnipManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042C21BBB77AB00B3B473 /* SnipManager.m */; settings = {ASSET_TAGS = (); }; };
22 | 06C042DA1BBB77AB00B3B473 /* SnipUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042C31BBB77AB00B3B473 /* SnipUtil.h */; settings = {ASSET_TAGS = (); }; };
23 | 06C042DB1BBB77AB00B3B473 /* SnipUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042C41BBB77AB00B3B473 /* SnipUtil.m */; settings = {ASSET_TAGS = (); }; };
24 | 06C042DC1BBB77AB00B3B473 /* SnipView.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042C51BBB77AB00B3B473 /* SnipView.h */; settings = {ASSET_TAGS = (); }; };
25 | 06C042DD1BBB77AB00B3B473 /* SnipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042C61BBB77AB00B3B473 /* SnipView.m */; settings = {ASSET_TAGS = (); }; };
26 | 06C042DE1BBB77AB00B3B473 /* SnipWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042C71BBB77AB00B3B473 /* SnipWindow.h */; settings = {ASSET_TAGS = (); }; };
27 | 06C042DF1BBB77AB00B3B473 /* SnipWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042C81BBB77AB00B3B473 /* SnipWindow.m */; settings = {ASSET_TAGS = (); }; };
28 | 06C042E01BBB77AB00B3B473 /* SnipWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042C91BBB77AB00B3B473 /* SnipWindowController.h */; settings = {ASSET_TAGS = (); }; };
29 | 06C042E11BBB77AB00B3B473 /* SnipWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042CA1BBB77AB00B3B473 /* SnipWindowController.m */; settings = {ASSET_TAGS = (); }; };
30 | 06C042E21BBB77AB00B3B473 /* SnipWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 06C042CB1BBB77AB00B3B473 /* SnipWindowController.xib */; settings = {ASSET_TAGS = (); }; };
31 | 06C042E31BBB77AB00B3B473 /* ToolContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 06C042CC1BBB77AB00B3B473 /* ToolContainer.h */; settings = {ASSET_TAGS = (); }; };
32 | 06C042E41BBB77AB00B3B473 /* ToolContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 06C042CD1BBB77AB00B3B473 /* ToolContainer.m */; settings = {ASSET_TAGS = (); }; };
33 | 06C043551BBBBA5400B3B473 /* SnipManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06EC06A01BBABE1A00D3384D /* SnipManager.framework */; };
34 | 06C0436B1BBBBF1200B3B473 /* Images.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 06C0436A1BBBBF1200B3B473 /* Images.bundle */; settings = {ASSET_TAGS = (); }; };
35 | 06EC06A31BBABE1A00D3384D /* SnipManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 06EC06A21BBABE1A00D3384D /* SnipManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
36 | 326AA0B71A7D116E00507232 /* DemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 326AA0B61A7D116E00507232 /* DemoViewController.m */; };
37 | 32E071C61A7C6A5A0094D5DE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E071C51A7C6A5A0094D5DE /* AppDelegate.m */; };
38 | 32E071C81A7C6A5A0094D5DE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E071C71A7C6A5A0094D5DE /* main.m */; };
39 | 32E071CA1A7C6A5A0094D5DE /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 32E071C91A7C6A5A0094D5DE /* Images.xcassets */; };
40 | 32E071CD1A7C6A5A0094D5DE /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32E071CB1A7C6A5A0094D5DE /* MainMenu.xib */; };
41 | 32E071D91A7C6A5A0094D5DE /* SnipTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E071D81A7C6A5A0094D5DE /* SnipTests.m */; };
42 | D29A35711A8398BD00DD41BC /* app.icns in Resources */ = {isa = PBXBuildFile; fileRef = D29A35701A8398BD00DD41BC /* app.icns */; };
43 | /* End PBXBuildFile section */
44 |
45 | /* Begin PBXContainerItemProxy section */
46 | 32E071D31A7C6A5A0094D5DE /* PBXContainerItemProxy */ = {
47 | isa = PBXContainerItemProxy;
48 | containerPortal = 32E071B71A7C6A5A0094D5DE /* Project object */;
49 | proxyType = 1;
50 | remoteGlobalIDString = 32E071BE1A7C6A5A0094D5DE;
51 | remoteInfo = Snip;
52 | };
53 | /* End PBXContainerItemProxy section */
54 |
55 | /* Begin PBXFileReference section */
56 | 06C042B71BBB77AB00B3B473 /* DrawPathInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawPathInfo.h; sourceTree = ""; };
57 | 06C042B81BBB77AB00B3B473 /* DrawPathInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawPathInfo.m; sourceTree = ""; };
58 | 06C042B91BBB77AB00B3B473 /* DrawPathView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawPathView.h; sourceTree = ""; };
59 | 06C042BA1BBB77AB00B3B473 /* DrawPathView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawPathView.m; sourceTree = ""; };
60 | 06C042BB1BBB77AB00B3B473 /* ImageButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageButton.h; sourceTree = ""; };
61 | 06C042BC1BBB77AB00B3B473 /* ImageButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageButton.m; sourceTree = ""; };
62 | 06C042BD1BBB77AB00B3B473 /* MouseEventProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MouseEventProtocol.h; sourceTree = ""; };
63 | 06C042BE1BBB77AB00B3B473 /* NSColor+Helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+Helper.h"; sourceTree = ""; };
64 | 06C042BF1BBB77AB00B3B473 /* NSColor+Helper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSColor+Helper.m"; sourceTree = ""; };
65 | 06C042C01BBB77AB00B3B473 /* SimpleLabelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLabelView.h; sourceTree = ""; };
66 | 06C042C11BBB77AB00B3B473 /* SimpleLabelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimpleLabelView.m; sourceTree = ""; };
67 | 06C042C21BBB77AB00B3B473 /* SnipManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SnipManager.m; sourceTree = ""; };
68 | 06C042C31BBB77AB00B3B473 /* SnipUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnipUtil.h; sourceTree = ""; };
69 | 06C042C41BBB77AB00B3B473 /* SnipUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SnipUtil.m; sourceTree = ""; };
70 | 06C042C51BBB77AB00B3B473 /* SnipView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnipView.h; sourceTree = ""; };
71 | 06C042C61BBB77AB00B3B473 /* SnipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SnipView.m; sourceTree = ""; };
72 | 06C042C71BBB77AB00B3B473 /* SnipWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnipWindow.h; sourceTree = ""; };
73 | 06C042C81BBB77AB00B3B473 /* SnipWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SnipWindow.m; sourceTree = ""; };
74 | 06C042C91BBB77AB00B3B473 /* SnipWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnipWindowController.h; sourceTree = ""; };
75 | 06C042CA1BBB77AB00B3B473 /* SnipWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SnipWindowController.m; sourceTree = ""; };
76 | 06C042CB1BBB77AB00B3B473 /* SnipWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SnipWindowController.xib; sourceTree = ""; };
77 | 06C042CC1BBB77AB00B3B473 /* ToolContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ToolContainer.h; sourceTree = ""; };
78 | 06C042CD1BBB77AB00B3B473 /* ToolContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ToolContainer.m; sourceTree = ""; };
79 | 06C0436A1BBBBF1200B3B473 /* Images.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Images.bundle; sourceTree = ""; };
80 | 06EC06A01BBABE1A00D3384D /* SnipManager.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SnipManager.framework; sourceTree = BUILT_PRODUCTS_DIR; };
81 | 06EC06A21BBABE1A00D3384D /* SnipManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SnipManager.h; sourceTree = ""; };
82 | 06EC06A41BBABE1A00D3384D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
83 | 326AA0B51A7D116E00507232 /* DemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoViewController.h; sourceTree = ""; };
84 | 326AA0B61A7D116E00507232 /* DemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoViewController.m; sourceTree = ""; };
85 | 32E071BF1A7C6A5A0094D5DE /* Snip.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Snip.app; sourceTree = BUILT_PRODUCTS_DIR; };
86 | 32E071C31A7C6A5A0094D5DE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
87 | 32E071C41A7C6A5A0094D5DE /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
88 | 32E071C51A7C6A5A0094D5DE /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
89 | 32E071C71A7C6A5A0094D5DE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
90 | 32E071C91A7C6A5A0094D5DE /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
91 | 32E071CC1A7C6A5A0094D5DE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
92 | 32E071D21A7C6A5A0094D5DE /* SnipTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SnipTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
93 | 32E071D71A7C6A5A0094D5DE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
94 | 32E071D81A7C6A5A0094D5DE /* SnipTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SnipTests.m; sourceTree = ""; };
95 | D29A35701A8398BD00DD41BC /* app.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = app.icns; sourceTree = ""; };
96 | /* End PBXFileReference section */
97 |
98 | /* Begin PBXFrameworksBuildPhase section */
99 | 06EC069C1BBABE1A00D3384D /* Frameworks */ = {
100 | isa = PBXFrameworksBuildPhase;
101 | buildActionMask = 2147483647;
102 | files = (
103 | );
104 | runOnlyForDeploymentPostprocessing = 0;
105 | };
106 | 32E071BC1A7C6A5A0094D5DE /* Frameworks */ = {
107 | isa = PBXFrameworksBuildPhase;
108 | buildActionMask = 2147483647;
109 | files = (
110 | 06C043551BBBBA5400B3B473 /* SnipManager.framework in Frameworks */,
111 | );
112 | runOnlyForDeploymentPostprocessing = 0;
113 | };
114 | 32E071CF1A7C6A5A0094D5DE /* Frameworks */ = {
115 | isa = PBXFrameworksBuildPhase;
116 | buildActionMask = 2147483647;
117 | files = (
118 | );
119 | runOnlyForDeploymentPostprocessing = 0;
120 | };
121 | /* End PBXFrameworksBuildPhase section */
122 |
123 | /* Begin PBXGroup section */
124 | 06C043691BBBBF1200B3B473 /* Resource */ = {
125 | isa = PBXGroup;
126 | children = (
127 | 06C0436A1BBBBF1200B3B473 /* Images.bundle */,
128 | );
129 | path = Resource;
130 | sourceTree = "";
131 | };
132 | 06EC06A11BBABE1A00D3384D /* SnipManager */ = {
133 | isa = PBXGroup;
134 | children = (
135 | 06C043691BBBBF1200B3B473 /* Resource */,
136 | 06EC06A21BBABE1A00D3384D /* SnipManager.h */,
137 | 06C042C21BBB77AB00B3B473 /* SnipManager.m */,
138 | 06C042B71BBB77AB00B3B473 /* DrawPathInfo.h */,
139 | 06C042B81BBB77AB00B3B473 /* DrawPathInfo.m */,
140 | 06C042B91BBB77AB00B3B473 /* DrawPathView.h */,
141 | 06C042BA1BBB77AB00B3B473 /* DrawPathView.m */,
142 | 06C042BB1BBB77AB00B3B473 /* ImageButton.h */,
143 | 06C042BC1BBB77AB00B3B473 /* ImageButton.m */,
144 | 06C042BD1BBB77AB00B3B473 /* MouseEventProtocol.h */,
145 | 06C042BE1BBB77AB00B3B473 /* NSColor+Helper.h */,
146 | 06C042BF1BBB77AB00B3B473 /* NSColor+Helper.m */,
147 | 06C042C01BBB77AB00B3B473 /* SimpleLabelView.h */,
148 | 06C042C11BBB77AB00B3B473 /* SimpleLabelView.m */,
149 | 06C042C31BBB77AB00B3B473 /* SnipUtil.h */,
150 | 06C042C41BBB77AB00B3B473 /* SnipUtil.m */,
151 | 06C042C51BBB77AB00B3B473 /* SnipView.h */,
152 | 06C042C61BBB77AB00B3B473 /* SnipView.m */,
153 | 06C042C71BBB77AB00B3B473 /* SnipWindow.h */,
154 | 06C042C81BBB77AB00B3B473 /* SnipWindow.m */,
155 | 06C042C91BBB77AB00B3B473 /* SnipWindowController.h */,
156 | 06C042CA1BBB77AB00B3B473 /* SnipWindowController.m */,
157 | 06C042CB1BBB77AB00B3B473 /* SnipWindowController.xib */,
158 | 06C042CC1BBB77AB00B3B473 /* ToolContainer.h */,
159 | 06C042CD1BBB77AB00B3B473 /* ToolContainer.m */,
160 | 06EC06A41BBABE1A00D3384D /* Info.plist */,
161 | );
162 | path = SnipManager;
163 | sourceTree = "";
164 | };
165 | 32E071B61A7C6A5A0094D5DE = {
166 | isa = PBXGroup;
167 | children = (
168 | 32E071C11A7C6A5A0094D5DE /* Snip */,
169 | 32E071D51A7C6A5A0094D5DE /* SnipTests */,
170 | 06EC06A11BBABE1A00D3384D /* SnipManager */,
171 | 32E071C01A7C6A5A0094D5DE /* Products */,
172 | );
173 | sourceTree = "";
174 | };
175 | 32E071C01A7C6A5A0094D5DE /* Products */ = {
176 | isa = PBXGroup;
177 | children = (
178 | 32E071BF1A7C6A5A0094D5DE /* Snip.app */,
179 | 32E071D21A7C6A5A0094D5DE /* SnipTests.xctest */,
180 | 06EC06A01BBABE1A00D3384D /* SnipManager.framework */,
181 | );
182 | name = Products;
183 | sourceTree = "";
184 | };
185 | 32E071C11A7C6A5A0094D5DE /* Snip */ = {
186 | isa = PBXGroup;
187 | children = (
188 | D29A35701A8398BD00DD41BC /* app.icns */,
189 | 32E071C41A7C6A5A0094D5DE /* AppDelegate.h */,
190 | 32E071C51A7C6A5A0094D5DE /* AppDelegate.m */,
191 | 32E071C91A7C6A5A0094D5DE /* Images.xcassets */,
192 | 32E071CB1A7C6A5A0094D5DE /* MainMenu.xib */,
193 | 32E071C21A7C6A5A0094D5DE /* Supporting Files */,
194 | 326AA0B51A7D116E00507232 /* DemoViewController.h */,
195 | 326AA0B61A7D116E00507232 /* DemoViewController.m */,
196 | );
197 | path = Snip;
198 | sourceTree = "";
199 | };
200 | 32E071C21A7C6A5A0094D5DE /* Supporting Files */ = {
201 | isa = PBXGroup;
202 | children = (
203 | 32E071C31A7C6A5A0094D5DE /* Info.plist */,
204 | 32E071C71A7C6A5A0094D5DE /* main.m */,
205 | );
206 | name = "Supporting Files";
207 | sourceTree = "";
208 | };
209 | 32E071D51A7C6A5A0094D5DE /* SnipTests */ = {
210 | isa = PBXGroup;
211 | children = (
212 | 32E071D81A7C6A5A0094D5DE /* SnipTests.m */,
213 | 32E071D61A7C6A5A0094D5DE /* Supporting Files */,
214 | );
215 | path = SnipTests;
216 | sourceTree = "";
217 | };
218 | 32E071D61A7C6A5A0094D5DE /* Supporting Files */ = {
219 | isa = PBXGroup;
220 | children = (
221 | 32E071D71A7C6A5A0094D5DE /* Info.plist */,
222 | );
223 | name = "Supporting Files";
224 | sourceTree = "";
225 | };
226 | /* End PBXGroup section */
227 |
228 | /* Begin PBXHeadersBuildPhase section */
229 | 06EC069D1BBABE1A00D3384D /* Headers */ = {
230 | isa = PBXHeadersBuildPhase;
231 | buildActionMask = 2147483647;
232 | files = (
233 | 06C042E01BBB77AB00B3B473 /* SnipWindowController.h in Headers */,
234 | 06C042DA1BBB77AB00B3B473 /* SnipUtil.h in Headers */,
235 | 06C042D41BBB77AB00B3B473 /* MouseEventProtocol.h in Headers */,
236 | 06EC06A31BBABE1A00D3384D /* SnipManager.h in Headers */,
237 | 06C042CE1BBB77AB00B3B473 /* DrawPathInfo.h in Headers */,
238 | 06C042DE1BBB77AB00B3B473 /* SnipWindow.h in Headers */,
239 | 06C042D71BBB77AB00B3B473 /* SimpleLabelView.h in Headers */,
240 | 06C042DC1BBB77AB00B3B473 /* SnipView.h in Headers */,
241 | 06C042D21BBB77AB00B3B473 /* ImageButton.h in Headers */,
242 | 06C042D01BBB77AB00B3B473 /* DrawPathView.h in Headers */,
243 | 06C042E31BBB77AB00B3B473 /* ToolContainer.h in Headers */,
244 | 06C042D51BBB77AB00B3B473 /* NSColor+Helper.h in Headers */,
245 | );
246 | runOnlyForDeploymentPostprocessing = 0;
247 | };
248 | /* End PBXHeadersBuildPhase section */
249 |
250 | /* Begin PBXNativeTarget section */
251 | 06EC069F1BBABE1A00D3384D /* SnipManager */ = {
252 | isa = PBXNativeTarget;
253 | buildConfigurationList = 06EC06AB1BBABE1A00D3384D /* Build configuration list for PBXNativeTarget "SnipManager" */;
254 | buildPhases = (
255 | 06EC069B1BBABE1A00D3384D /* Sources */,
256 | 06EC069C1BBABE1A00D3384D /* Frameworks */,
257 | 06EC069D1BBABE1A00D3384D /* Headers */,
258 | 06EC069E1BBABE1A00D3384D /* Resources */,
259 | );
260 | buildRules = (
261 | );
262 | dependencies = (
263 | );
264 | name = SnipManager;
265 | productName = SnipManager;
266 | productReference = 06EC06A01BBABE1A00D3384D /* SnipManager.framework */;
267 | productType = "com.apple.product-type.framework";
268 | };
269 | 32E071BE1A7C6A5A0094D5DE /* Snip */ = {
270 | isa = PBXNativeTarget;
271 | buildConfigurationList = 32E071DC1A7C6A5A0094D5DE /* Build configuration list for PBXNativeTarget "Snip" */;
272 | buildPhases = (
273 | 32E071BB1A7C6A5A0094D5DE /* Sources */,
274 | 32E071BC1A7C6A5A0094D5DE /* Frameworks */,
275 | 32E071BD1A7C6A5A0094D5DE /* Resources */,
276 | );
277 | buildRules = (
278 | );
279 | dependencies = (
280 | );
281 | name = Snip;
282 | productName = Snip;
283 | productReference = 32E071BF1A7C6A5A0094D5DE /* Snip.app */;
284 | productType = "com.apple.product-type.application";
285 | };
286 | 32E071D11A7C6A5A0094D5DE /* SnipTests */ = {
287 | isa = PBXNativeTarget;
288 | buildConfigurationList = 32E071DF1A7C6A5A0094D5DE /* Build configuration list for PBXNativeTarget "SnipTests" */;
289 | buildPhases = (
290 | 32E071CE1A7C6A5A0094D5DE /* Sources */,
291 | 32E071CF1A7C6A5A0094D5DE /* Frameworks */,
292 | 32E071D01A7C6A5A0094D5DE /* Resources */,
293 | );
294 | buildRules = (
295 | );
296 | dependencies = (
297 | 32E071D41A7C6A5A0094D5DE /* PBXTargetDependency */,
298 | );
299 | name = SnipTests;
300 | productName = SnipTests;
301 | productReference = 32E071D21A7C6A5A0094D5DE /* SnipTests.xctest */;
302 | productType = "com.apple.product-type.bundle.unit-test";
303 | };
304 | /* End PBXNativeTarget section */
305 |
306 | /* Begin PBXProject section */
307 | 32E071B71A7C6A5A0094D5DE /* Project object */ = {
308 | isa = PBXProject;
309 | attributes = {
310 | LastUpgradeCheck = 0700;
311 | ORGANIZATIONNAME = isee15;
312 | TargetAttributes = {
313 | 06EC069F1BBABE1A00D3384D = {
314 | CreatedOnToolsVersion = 7.0;
315 | };
316 | 32E071BE1A7C6A5A0094D5DE = {
317 | CreatedOnToolsVersion = 6.1.1;
318 | };
319 | 32E071D11A7C6A5A0094D5DE = {
320 | CreatedOnToolsVersion = 6.1.1;
321 | TestTargetID = 32E071BE1A7C6A5A0094D5DE;
322 | };
323 | };
324 | };
325 | buildConfigurationList = 32E071BA1A7C6A5A0094D5DE /* Build configuration list for PBXProject "Snip" */;
326 | compatibilityVersion = "Xcode 3.2";
327 | developmentRegion = English;
328 | hasScannedForEncodings = 0;
329 | knownRegions = (
330 | en,
331 | Base,
332 | );
333 | mainGroup = 32E071B61A7C6A5A0094D5DE;
334 | productRefGroup = 32E071C01A7C6A5A0094D5DE /* Products */;
335 | projectDirPath = "";
336 | projectRoot = "";
337 | targets = (
338 | 32E071BE1A7C6A5A0094D5DE /* Snip */,
339 | 32E071D11A7C6A5A0094D5DE /* SnipTests */,
340 | 06EC069F1BBABE1A00D3384D /* SnipManager */,
341 | );
342 | };
343 | /* End PBXProject section */
344 |
345 | /* Begin PBXResourcesBuildPhase section */
346 | 06EC069E1BBABE1A00D3384D /* Resources */ = {
347 | isa = PBXResourcesBuildPhase;
348 | buildActionMask = 2147483647;
349 | files = (
350 | 06C042E21BBB77AB00B3B473 /* SnipWindowController.xib in Resources */,
351 | 06C0436B1BBBBF1200B3B473 /* Images.bundle in Resources */,
352 | );
353 | runOnlyForDeploymentPostprocessing = 0;
354 | };
355 | 32E071BD1A7C6A5A0094D5DE /* Resources */ = {
356 | isa = PBXResourcesBuildPhase;
357 | buildActionMask = 2147483647;
358 | files = (
359 | 32E071CA1A7C6A5A0094D5DE /* Images.xcassets in Resources */,
360 | 32E071CD1A7C6A5A0094D5DE /* MainMenu.xib in Resources */,
361 | D29A35711A8398BD00DD41BC /* app.icns in Resources */,
362 | );
363 | runOnlyForDeploymentPostprocessing = 0;
364 | };
365 | 32E071D01A7C6A5A0094D5DE /* Resources */ = {
366 | isa = PBXResourcesBuildPhase;
367 | buildActionMask = 2147483647;
368 | files = (
369 | );
370 | runOnlyForDeploymentPostprocessing = 0;
371 | };
372 | /* End PBXResourcesBuildPhase section */
373 |
374 | /* Begin PBXSourcesBuildPhase section */
375 | 06EC069B1BBABE1A00D3384D /* Sources */ = {
376 | isa = PBXSourcesBuildPhase;
377 | buildActionMask = 2147483647;
378 | files = (
379 | 06C042D31BBB77AB00B3B473 /* ImageButton.m in Sources */,
380 | 06C042E11BBB77AB00B3B473 /* SnipWindowController.m in Sources */,
381 | 06C042CF1BBB77AB00B3B473 /* DrawPathInfo.m in Sources */,
382 | 06C042E41BBB77AB00B3B473 /* ToolContainer.m in Sources */,
383 | 06C042DD1BBB77AB00B3B473 /* SnipView.m in Sources */,
384 | 06C042DB1BBB77AB00B3B473 /* SnipUtil.m in Sources */,
385 | 06C042DF1BBB77AB00B3B473 /* SnipWindow.m in Sources */,
386 | 06C042D61BBB77AB00B3B473 /* NSColor+Helper.m in Sources */,
387 | 06C042D11BBB77AB00B3B473 /* DrawPathView.m in Sources */,
388 | 06C042D81BBB77AB00B3B473 /* SimpleLabelView.m in Sources */,
389 | 06C042D91BBB77AB00B3B473 /* SnipManager.m in Sources */,
390 | );
391 | runOnlyForDeploymentPostprocessing = 0;
392 | };
393 | 32E071BB1A7C6A5A0094D5DE /* Sources */ = {
394 | isa = PBXSourcesBuildPhase;
395 | buildActionMask = 2147483647;
396 | files = (
397 | 326AA0B71A7D116E00507232 /* DemoViewController.m in Sources */,
398 | 32E071C81A7C6A5A0094D5DE /* main.m in Sources */,
399 | 32E071C61A7C6A5A0094D5DE /* AppDelegate.m in Sources */,
400 | );
401 | runOnlyForDeploymentPostprocessing = 0;
402 | };
403 | 32E071CE1A7C6A5A0094D5DE /* Sources */ = {
404 | isa = PBXSourcesBuildPhase;
405 | buildActionMask = 2147483647;
406 | files = (
407 | 32E071D91A7C6A5A0094D5DE /* SnipTests.m in Sources */,
408 | );
409 | runOnlyForDeploymentPostprocessing = 0;
410 | };
411 | /* End PBXSourcesBuildPhase section */
412 |
413 | /* Begin PBXTargetDependency section */
414 | 32E071D41A7C6A5A0094D5DE /* PBXTargetDependency */ = {
415 | isa = PBXTargetDependency;
416 | target = 32E071BE1A7C6A5A0094D5DE /* Snip */;
417 | targetProxy = 32E071D31A7C6A5A0094D5DE /* PBXContainerItemProxy */;
418 | };
419 | /* End PBXTargetDependency section */
420 |
421 | /* Begin PBXVariantGroup section */
422 | 32E071CB1A7C6A5A0094D5DE /* MainMenu.xib */ = {
423 | isa = PBXVariantGroup;
424 | children = (
425 | 32E071CC1A7C6A5A0094D5DE /* Base */,
426 | );
427 | name = MainMenu.xib;
428 | sourceTree = "";
429 | };
430 | /* End PBXVariantGroup section */
431 |
432 | /* Begin XCBuildConfiguration section */
433 | 06EC06A91BBABE1A00D3384D /* Debug */ = {
434 | isa = XCBuildConfiguration;
435 | buildSettings = {
436 | COMBINE_HIDPI_IMAGES = YES;
437 | CURRENT_PROJECT_VERSION = 1;
438 | DEBUG_INFORMATION_FORMAT = dwarf;
439 | DEFINES_MODULE = YES;
440 | DYLIB_COMPATIBILITY_VERSION = 1;
441 | DYLIB_CURRENT_VERSION = 1;
442 | DYLIB_INSTALL_NAME_BASE = "@rpath";
443 | ENABLE_TESTABILITY = YES;
444 | FRAMEWORK_VERSION = A;
445 | GCC_NO_COMMON_BLOCKS = YES;
446 | INFOPLIST_FILE = SnipManager/Info.plist;
447 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
448 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
449 | MACOSX_DEPLOYMENT_TARGET = 10.11;
450 | PRODUCT_BUNDLE_IDENTIFIER = com.hj.SnipManager;
451 | PRODUCT_NAME = "$(TARGET_NAME)";
452 | SKIP_INSTALL = YES;
453 | VERSIONING_SYSTEM = "apple-generic";
454 | VERSION_INFO_PREFIX = "";
455 | };
456 | name = Debug;
457 | };
458 | 06EC06AA1BBABE1A00D3384D /* Release */ = {
459 | isa = XCBuildConfiguration;
460 | buildSettings = {
461 | COMBINE_HIDPI_IMAGES = YES;
462 | COPY_PHASE_STRIP = NO;
463 | CURRENT_PROJECT_VERSION = 1;
464 | DEFINES_MODULE = YES;
465 | DYLIB_COMPATIBILITY_VERSION = 1;
466 | DYLIB_CURRENT_VERSION = 1;
467 | DYLIB_INSTALL_NAME_BASE = "@rpath";
468 | FRAMEWORK_VERSION = A;
469 | GCC_NO_COMMON_BLOCKS = YES;
470 | INFOPLIST_FILE = SnipManager/Info.plist;
471 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
472 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
473 | MACOSX_DEPLOYMENT_TARGET = 10.11;
474 | PRODUCT_BUNDLE_IDENTIFIER = com.hj.SnipManager;
475 | PRODUCT_NAME = "$(TARGET_NAME)";
476 | SKIP_INSTALL = YES;
477 | VERSIONING_SYSTEM = "apple-generic";
478 | VERSION_INFO_PREFIX = "";
479 | };
480 | name = Release;
481 | };
482 | 32E071DA1A7C6A5A0094D5DE /* Debug */ = {
483 | isa = XCBuildConfiguration;
484 | buildSettings = {
485 | ALWAYS_SEARCH_USER_PATHS = NO;
486 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
487 | CLANG_CXX_LIBRARY = "libc++";
488 | CLANG_ENABLE_MODULES = YES;
489 | CLANG_ENABLE_OBJC_ARC = YES;
490 | CLANG_WARN_BOOL_CONVERSION = YES;
491 | CLANG_WARN_CONSTANT_CONVERSION = YES;
492 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
493 | CLANG_WARN_EMPTY_BODY = YES;
494 | CLANG_WARN_ENUM_CONVERSION = YES;
495 | CLANG_WARN_INT_CONVERSION = YES;
496 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
497 | CLANG_WARN_UNREACHABLE_CODE = YES;
498 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
499 | CODE_SIGN_IDENTITY = "-";
500 | COPY_PHASE_STRIP = NO;
501 | ENABLE_STRICT_OBJC_MSGSEND = YES;
502 | ENABLE_TESTABILITY = YES;
503 | GCC_C_LANGUAGE_STANDARD = gnu99;
504 | GCC_DYNAMIC_NO_PIC = NO;
505 | GCC_OPTIMIZATION_LEVEL = 0;
506 | GCC_PREPROCESSOR_DEFINITIONS = (
507 | "DEBUG=1",
508 | "$(inherited)",
509 | );
510 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
511 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
512 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
513 | GCC_WARN_UNDECLARED_SELECTOR = YES;
514 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
515 | GCC_WARN_UNUSED_FUNCTION = YES;
516 | GCC_WARN_UNUSED_VARIABLE = YES;
517 | MACOSX_DEPLOYMENT_TARGET = 10.10;
518 | MTL_ENABLE_DEBUG_INFO = YES;
519 | ONLY_ACTIVE_ARCH = YES;
520 | SDKROOT = macosx;
521 | };
522 | name = Debug;
523 | };
524 | 32E071DB1A7C6A5A0094D5DE /* Release */ = {
525 | isa = XCBuildConfiguration;
526 | buildSettings = {
527 | ALWAYS_SEARCH_USER_PATHS = NO;
528 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
529 | CLANG_CXX_LIBRARY = "libc++";
530 | CLANG_ENABLE_MODULES = YES;
531 | CLANG_ENABLE_OBJC_ARC = YES;
532 | CLANG_WARN_BOOL_CONVERSION = YES;
533 | CLANG_WARN_CONSTANT_CONVERSION = YES;
534 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
535 | CLANG_WARN_EMPTY_BODY = YES;
536 | CLANG_WARN_ENUM_CONVERSION = YES;
537 | CLANG_WARN_INT_CONVERSION = YES;
538 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
539 | CLANG_WARN_UNREACHABLE_CODE = YES;
540 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
541 | CODE_SIGN_IDENTITY = "-";
542 | COPY_PHASE_STRIP = YES;
543 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
544 | ENABLE_NS_ASSERTIONS = NO;
545 | ENABLE_STRICT_OBJC_MSGSEND = YES;
546 | GCC_C_LANGUAGE_STANDARD = gnu99;
547 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
548 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
549 | GCC_WARN_UNDECLARED_SELECTOR = YES;
550 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
551 | GCC_WARN_UNUSED_FUNCTION = YES;
552 | GCC_WARN_UNUSED_VARIABLE = YES;
553 | MACOSX_DEPLOYMENT_TARGET = 10.10;
554 | MTL_ENABLE_DEBUG_INFO = NO;
555 | SDKROOT = macosx;
556 | };
557 | name = Release;
558 | };
559 | 32E071DD1A7C6A5A0094D5DE /* Debug */ = {
560 | isa = XCBuildConfiguration;
561 | buildSettings = {
562 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
563 | COMBINE_HIDPI_IMAGES = YES;
564 | INFOPLIST_FILE = Snip/Info.plist;
565 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
566 | PRODUCT_BUNDLE_IDENTIFIER = "cn.z.$(PRODUCT_NAME:rfc1034identifier)";
567 | PRODUCT_NAME = "$(TARGET_NAME)";
568 | };
569 | name = Debug;
570 | };
571 | 32E071DE1A7C6A5A0094D5DE /* Release */ = {
572 | isa = XCBuildConfiguration;
573 | buildSettings = {
574 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
575 | COMBINE_HIDPI_IMAGES = YES;
576 | INFOPLIST_FILE = Snip/Info.plist;
577 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
578 | PRODUCT_BUNDLE_IDENTIFIER = "cn.z.$(PRODUCT_NAME:rfc1034identifier)";
579 | PRODUCT_NAME = "$(TARGET_NAME)";
580 | };
581 | name = Release;
582 | };
583 | 32E071E01A7C6A5A0094D5DE /* Debug */ = {
584 | isa = XCBuildConfiguration;
585 | buildSettings = {
586 | BUNDLE_LOADER = "$(TEST_HOST)";
587 | COMBINE_HIDPI_IMAGES = YES;
588 | FRAMEWORK_SEARCH_PATHS = (
589 | "$(DEVELOPER_FRAMEWORKS_DIR)",
590 | "$(inherited)",
591 | );
592 | GCC_PREPROCESSOR_DEFINITIONS = (
593 | "DEBUG=1",
594 | "$(inherited)",
595 | );
596 | INFOPLIST_FILE = SnipTests/Info.plist;
597 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
598 | PRODUCT_BUNDLE_IDENTIFIER = "cn.z.$(PRODUCT_NAME:rfc1034identifier)";
599 | PRODUCT_NAME = "$(TARGET_NAME)";
600 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Snip.app/Contents/MacOS/Snip";
601 | };
602 | name = Debug;
603 | };
604 | 32E071E11A7C6A5A0094D5DE /* Release */ = {
605 | isa = XCBuildConfiguration;
606 | buildSettings = {
607 | BUNDLE_LOADER = "$(TEST_HOST)";
608 | COMBINE_HIDPI_IMAGES = YES;
609 | FRAMEWORK_SEARCH_PATHS = (
610 | "$(DEVELOPER_FRAMEWORKS_DIR)",
611 | "$(inherited)",
612 | );
613 | INFOPLIST_FILE = SnipTests/Info.plist;
614 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
615 | PRODUCT_BUNDLE_IDENTIFIER = "cn.z.$(PRODUCT_NAME:rfc1034identifier)";
616 | PRODUCT_NAME = "$(TARGET_NAME)";
617 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Snip.app/Contents/MacOS/Snip";
618 | };
619 | name = Release;
620 | };
621 | /* End XCBuildConfiguration section */
622 |
623 | /* Begin XCConfigurationList section */
624 | 06EC06AB1BBABE1A00D3384D /* Build configuration list for PBXNativeTarget "SnipManager" */ = {
625 | isa = XCConfigurationList;
626 | buildConfigurations = (
627 | 06EC06A91BBABE1A00D3384D /* Debug */,
628 | 06EC06AA1BBABE1A00D3384D /* Release */,
629 | );
630 | defaultConfigurationIsVisible = 0;
631 | defaultConfigurationName = Release;
632 | };
633 | 32E071BA1A7C6A5A0094D5DE /* Build configuration list for PBXProject "Snip" */ = {
634 | isa = XCConfigurationList;
635 | buildConfigurations = (
636 | 32E071DA1A7C6A5A0094D5DE /* Debug */,
637 | 32E071DB1A7C6A5A0094D5DE /* Release */,
638 | );
639 | defaultConfigurationIsVisible = 0;
640 | defaultConfigurationName = Release;
641 | };
642 | 32E071DC1A7C6A5A0094D5DE /* Build configuration list for PBXNativeTarget "Snip" */ = {
643 | isa = XCConfigurationList;
644 | buildConfigurations = (
645 | 32E071DD1A7C6A5A0094D5DE /* Debug */,
646 | 32E071DE1A7C6A5A0094D5DE /* Release */,
647 | );
648 | defaultConfigurationIsVisible = 0;
649 | defaultConfigurationName = Release;
650 | };
651 | 32E071DF1A7C6A5A0094D5DE /* Build configuration list for PBXNativeTarget "SnipTests" */ = {
652 | isa = XCConfigurationList;
653 | buildConfigurations = (
654 | 32E071E01A7C6A5A0094D5DE /* Debug */,
655 | 32E071E11A7C6A5A0094D5DE /* Release */,
656 | );
657 | defaultConfigurationIsVisible = 0;
658 | defaultConfigurationName = Release;
659 | };
660 | /* End XCConfigurationList section */
661 | };
662 | rootObject = 32E071B71A7C6A5A0094D5DE /* Project object */;
663 | }
664 |
--------------------------------------------------------------------------------
/Snip.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Snip.xcodeproj/xcshareddata/xcschemes/SnipManager.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/Snip.xcodeproj/xcuserdata/liupeng.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
24 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Snip.xcodeproj/xcuserdata/liupeng.xcuserdatad/xcschemes/Snip.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
79 |
80 |
84 |
85 |
89 |
90 |
94 |
95 |
96 |
97 |
103 |
105 |
111 |
112 |
113 |
114 |
116 |
117 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/Snip/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : NSObject
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Snip/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @property(weak) IBOutlet NSWindow *window;
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
19 | // Insert code here to initialize your application
20 | }
21 |
22 | - (void)applicationWillTerminate:(NSNotification *)aNotification {
23 | // Insert code here to tear down your application
24 | }
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/Snip/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
--------------------------------------------------------------------------------
/Snip/DemoViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoViewController.h
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DemoViewController : NSViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Snip/DemoViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoViewController.m
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "DemoViewController.h"
10 | #import "SnipManager.h"
11 |
12 | @interface DemoViewController ()
13 | @property(weak) IBOutlet NSImageView *backImageView;
14 |
15 | @end
16 |
17 | @implementation DemoViewController
18 |
19 | - (void)awakeFromNib {
20 | // Do view setup here.
21 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onEndCapture:) name:kNotifyCaptureEnd object:nil];
22 | }
23 |
24 | - (void)dealloc {
25 | [[NSNotificationCenter defaultCenter] removeObserver:self];
26 | }
27 |
28 | - (void)onEndCapture:(NSNotification *)notification {
29 | if (notification.userInfo[@"image"]) {
30 | self.backImageView.image = notification.userInfo[@"image"];
31 | return;
32 | }
33 | // NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
34 | // NSArray *classArray = [NSArray arrayWithObject:[NSImage class]];
35 | // NSDictionary *options = [NSDictionary dictionary];
36 | // BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options];
37 | // if(ok) {
38 | // NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options];
39 | // NSImage *image = [objectsToPaste objectAtIndex:0];
40 | // self.backImageView.image = image;
41 | // //[self.view.window setBackgroundColor:[NSColor colorWithPatternImage:image]];
42 | // } else {
43 | // NSLog(@"Error: Clipboard doesn't seem to contain an image.");
44 | // }
45 | }
46 |
47 | - (IBAction)onStart:(id)sender {
48 | [[SnipManager sharedInstance] startCapture];
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/Snip/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "mac",
5 | "size": "16x16",
6 | "scale": "1x"
7 | },
8 | {
9 | "idiom": "mac",
10 | "size": "16x16",
11 | "scale": "2x"
12 | },
13 | {
14 | "idiom": "mac",
15 | "size": "32x32",
16 | "scale": "1x"
17 | },
18 | {
19 | "idiom": "mac",
20 | "size": "32x32",
21 | "scale": "2x"
22 | },
23 | {
24 | "idiom": "mac",
25 | "size": "128x128",
26 | "scale": "1x"
27 | },
28 | {
29 | "idiom": "mac",
30 | "size": "128x128",
31 | "scale": "2x"
32 | },
33 | {
34 | "idiom": "mac",
35 | "size": "256x256",
36 | "scale": "1x"
37 | },
38 | {
39 | "idiom": "mac",
40 | "size": "256x256",
41 | "scale": "2x"
42 | },
43 | {
44 | "idiom": "mac",
45 | "size": "512x512",
46 | "scale": "1x"
47 | },
48 | {
49 | "idiom": "mac",
50 | "size": "512x512",
51 | "scale": "2x"
52 | }
53 | ],
54 | "info": {
55 | "version": 1,
56 | "author": "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/Snip/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 | app
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSHumanReadableCopyright
28 | Copyright © 2015年 isee15. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Snip/app.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/Snip/app.icns
--------------------------------------------------------------------------------
/Snip/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char *argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/SnipManager/DrawPathInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // DrawPathInfo.h
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/4.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SnipManager.h"
11 |
12 | @interface DrawPathInfo : NSObject
13 |
14 | @property NSPoint startPoint;
15 | @property NSPoint endPoint;
16 | @property DRAW_TYPE drawType;
17 |
18 | - (instancetype)initWith:(NSPoint)startPoint andEndPoint:(NSPoint)endPoint andType:(DRAW_TYPE)drawType;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/SnipManager/DrawPathInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // DrawPathInfo.m
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/4.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "DrawPathInfo.h"
10 |
11 | @implementation DrawPathInfo
12 |
13 | - (instancetype)initWith:(NSPoint)startPoint andEndPoint:(NSPoint)endPoint andType:(DRAW_TYPE)drawType
14 | {
15 | if (self = [super init]) {
16 | _startPoint = startPoint;
17 | _endPoint = endPoint;
18 | _drawType = drawType;
19 | }
20 | return self;
21 | }
22 | @end
23 |
--------------------------------------------------------------------------------
/SnipManager/DrawPathView.h:
--------------------------------------------------------------------------------
1 | //
2 | // DrawPathView.h
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/5.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "DrawPathInfo.h"
11 |
12 | @interface DrawPathView : NSView
13 | @property NSMutableArray *rectArray;
14 | @property DrawPathInfo *currentInfo;
15 |
16 | - (void)drawFinishCommentInRect:(NSRect)imageRect;
17 | @end
18 |
--------------------------------------------------------------------------------
/SnipManager/DrawPathView.m:
--------------------------------------------------------------------------------
1 | //
2 | // DrawPathView.m
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/5.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "DrawPathView.h"
10 | #import "SnipUtil.h"
11 |
12 | @implementation DrawPathView
13 |
14 | - (instancetype)init
15 | {
16 | if (self = [super init]) {
17 | _rectArray = [NSMutableArray array];
18 | }
19 | return self;
20 | }
21 |
22 | - (NSRect)rectFromScreen:(NSRect)rect
23 | {
24 | NSRect rectRet = [self.window convertRectFromScreen:rect];
25 | rectRet.origin.x -= self.frame.origin.x;
26 | rectRet.origin.y -= self.frame.origin.y;
27 | return rectRet;
28 | }
29 |
30 | - (void)drawRect:(NSRect)dirtyRect
31 | {
32 | [super drawRect:dirtyRect];
33 | if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_EDIT) {
34 | [self drawCommentInRect:self.bounds];
35 | if (self.currentInfo) {
36 | [self drawShape:self.currentInfo inBackground:NO];
37 | }
38 | }
39 | // Drawing code here.
40 | }
41 |
42 | - (void)drawCommentInRect:(NSRect)imageRect
43 | {
44 | NSBezierPath *path = [NSBezierPath bezierPathWithRect:imageRect];
45 | [path addClip];
46 | [[NSColor redColor] set];
47 | for (DrawPathInfo *info in self.rectArray) {
48 | [self drawShape:info inBackground:NO];
49 | }
50 | }
51 |
52 | - (void)drawFinishCommentInRect:(NSRect)imageRect
53 | {
54 | NSBezierPath *path = [NSBezierPath bezierPathWithRect:imageRect];
55 | [path addClip];
56 | [[NSColor redColor] set];
57 | for (DrawPathInfo *info in self.rectArray) {
58 | [self drawShape:info inBackground:YES];
59 | }
60 | }
61 |
62 | - (void)drawShape:(DrawPathInfo *)info inBackground:(BOOL)bIn
63 | {
64 | NSRect rect = NSMakeRect(info.startPoint.x, info.startPoint.y, info.endPoint.x - info.startPoint.x, info.endPoint.y - info.startPoint.y);
65 | if (bIn) {
66 | rect = [self.window convertRectFromScreen:rect];
67 | }
68 | else {
69 | rect = [self rectFromScreen:rect];
70 | }
71 | NSBezierPath *rectPath = [NSBezierPath bezierPath];
72 | [rectPath setLineWidth:4];
73 | [rectPath setLineCapStyle:NSRoundLineCapStyle];
74 | [rectPath setLineJoinStyle:NSRoundLineJoinStyle];
75 | switch (info.drawType) {
76 | case DRAW_TYPE_RECT:
77 | rect = [SnipUtil uniformRect:rect];
78 | if (rect.size.width * rect.size.width < 1e-2) return;
79 | [rectPath appendBezierPathWithRect:rect];
80 | [rectPath stroke];
81 | break;
82 | case DRAW_TYPE_ELLIPSE:
83 | rect = [SnipUtil uniformRect:rect];
84 | if (rect.size.width * rect.size.width < 1e-2) return;
85 | [rectPath appendBezierPathWithOvalInRect:rect];
86 | [rectPath stroke];
87 | break;
88 | case DRAW_TYPE_ARROW: {
89 | // arrow
90 | CGFloat x0 = rect.origin.x;
91 | CGFloat y0 = rect.origin.y;
92 | CGFloat x1 = x0 + rect.size.width;
93 | CGFloat y1 = y0 + rect.size.height;
94 |
95 | [rectPath moveToPoint:CGPointZero];
96 | CGFloat ex1 = sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
97 | if (abs(rect.size.width) < 5 && abs(rect.size.height) < 5) return;
98 | [rectPath lineToPoint:NSMakePoint(ex1, 0)];
99 | [rectPath lineToPoint:NSMakePoint(ex1 - 8, 5)];
100 | [rectPath lineToPoint:NSMakePoint(ex1 - 2, 0)];
101 | [rectPath lineToPoint:NSMakePoint(ex1 - 8, -5)];
102 | [rectPath lineToPoint:NSMakePoint(ex1, 0)];
103 | [rectPath closePath];
104 |
105 | NSAffineTransform *af = [NSAffineTransform transform];
106 | [af translateXBy:x0 yBy:y0];
107 | [af rotateByRadians:atan2(y1 - y0, x1 - x0)];
108 | [rectPath transformUsingAffineTransform:af];
109 | [rectPath fill];
110 | [rectPath stroke];
111 | }
112 | break;
113 | }
114 | }
115 |
116 | @end
117 |
--------------------------------------------------------------------------------
/SnipManager/ImageButton.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageButton.h
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/5.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ImageButton : NSImageView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SnipManager/ImageButton.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageButton.m
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/5.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "ImageButton.h"
10 |
11 | @implementation ImageButton
12 |
13 | - (void)drawRect:(NSRect)dirtyRect
14 | {
15 | [super drawRect:dirtyRect];
16 |
17 | // Drawing code here.
18 | }
19 |
20 | - (void)mouseDown:(NSEvent *)theEvent
21 | {
22 | [NSApp sendAction:self.action
23 | to:self.target
24 | from:self];
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/SnipManager/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSHumanReadableCopyright
24 | Copyright © 2015 isee15. All rights reserved.
25 | NSPrincipalClass
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/SnipManager/MouseEventProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // MouseEventProtocol.h
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/5.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol MouseEventProtocol
12 |
13 | - (void)mouseDown:(NSEvent *)theEvent;
14 |
15 | - (void)mouseUp:(NSEvent *)theEvent;
16 |
17 | - (void)mouseDragged:(NSEvent *)theEvent;
18 |
19 | - (void)mouseMoved:(NSEvent *)theEvent;
20 | @end
21 |
--------------------------------------------------------------------------------
/SnipManager/NSColor+Helper.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSColor+Helper.h
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/5.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSColor (Helper)
12 | + (NSColor *)colorFromInt:(int)colorValue;
13 | + (NSColor*)colorWithHex:(NSString *)hexValue alpha:(CGFloat)alphaValue;
14 | @end
15 |
--------------------------------------------------------------------------------
/SnipManager/NSColor+Helper.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSColor+Helper.m
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/5.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "NSColor+Helper.h"
10 |
11 | @implementation NSColor (Helper)
12 |
13 | + (NSColor *)colorFromInt:(int)colorValue
14 | {
15 | float b = colorValue & 0xff;
16 | float g = (colorValue & 0xff00) >> 8;
17 | float r = (colorValue & 0xff0000) >> 16;
18 | return [NSColor colorWithRed:r / 255 green:g / 255 blue:b / 255 alpha:1];
19 | }
20 |
21 | + (NSColor*)colorWithHex:(NSString *)hexValue alpha:(CGFloat)alphaValue
22 | {
23 | NSScanner *scanner = [NSScanner scannerWithString:hexValue];
24 | unsigned hexNum;
25 | if (![scanner scanHexInt:&hexNum]){
26 | return [NSColor blackColor];
27 | }
28 | return [NSColor colorWithRed:((float)((hexNum & 0xFF0000) >> 16))/255.0
29 | green:((float)((hexNum & 0xFF00) >> 8))/255.0
30 | blue:((float)(hexNum & 0xFF))/255.0 alpha:alphaValue];
31 | }
32 | @end
33 |
--------------------------------------------------------------------------------
/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_arrow_effect.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_arrow_effect.tiff
--------------------------------------------------------------------------------
/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_arrow_ineffect.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_arrow_ineffect.tiff
--------------------------------------------------------------------------------
/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_cross_normal.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_cross_normal.tiff
--------------------------------------------------------------------------------
/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_ellipse_effect.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_ellipse_effect.tiff
--------------------------------------------------------------------------------
/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_ellipse_ineffect.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_ellipse_ineffect.tiff
--------------------------------------------------------------------------------
/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_export.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_export.tiff
--------------------------------------------------------------------------------
/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_rect_effect.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_rect_effect.tiff
--------------------------------------------------------------------------------
/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_rect_ineffect.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_rect_ineffect.tiff
--------------------------------------------------------------------------------
/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_tick_normal.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/SnipManager/Resource/Images.bundle/ScreenCapture_toolbar_tick_normal.tiff
--------------------------------------------------------------------------------
/SnipManager/SimpleLabelView.h:
--------------------------------------------------------------------------------
1 | //
2 | // FlatView.h
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/6.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SimpleLabelView : NSView
12 | @property NSString *text;
13 | @end
14 |
--------------------------------------------------------------------------------
/SnipManager/SimpleLabelView.m:
--------------------------------------------------------------------------------
1 | //
2 | // FlatView.m
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/6.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "SimpleLabelView.h"
10 |
11 | @implementation SimpleLabelView
12 |
13 | - (void)drawRect:(NSRect)dirtyRect
14 | {
15 | [super drawRect:dirtyRect];
16 | NSBezierPath *bgPath = [NSBezierPath bezierPathWithRoundedRect:self.bounds xRadius:6 yRadius:6];
17 | [bgPath setClip];
18 | [[NSColor colorWithCalibratedWhite:0.0 alpha:0.8f] setFill];
19 | NSRectFill(self.bounds);
20 | if (self.text.length > 0) {
21 | NSDictionary *stringAttributes = @{NSForegroundColorAttributeName : [NSColor colorWithCalibratedWhite:1.0 alpha:1.0],
22 | NSFontAttributeName : [NSFont boldSystemFontOfSize:12.0]};
23 | NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:self.text attributes:stringAttributes];
24 | NSRect stringRect = [attrStr boundingRectWithSize:self.bounds.size options:(NSStringDrawingUsesFontLeading | NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin)];
25 |
26 | [attrStr drawAtPoint:NSMakePoint((self.bounds.size.width - stringRect.size.width) / 2, (self.bounds.size.height - stringRect.size.height) / 2)];
27 | }
28 | // Drawing code here.
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/SnipManager/SnipManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // SnipManager.h
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | typedef NS_ENUM(NSInteger, CAPTURE_STATE)
13 | {
14 | CAPTURE_STATE_IDLE,
15 | CAPTURE_STATE_HILIGHT,
16 | CAPTURE_STATE_FIRSTMOUSEDOWN,
17 | CAPTURE_STATE_READYADJUST,
18 | CAPTURE_STATE_ADJUST,
19 | CAPTURE_STATE_EDIT,
20 | CAPTURE_STATE_DONE,
21 | };
22 |
23 | typedef NS_ENUM(int, DRAW_TYPE)
24 | {
25 | DRAW_TYPE_RECT,
26 | DRAW_TYPE_ELLIPSE,
27 | DRAW_TYPE_ARROW
28 | };
29 |
30 | #define kNotifyCaptureEnd @"kNotifyCaptureEnd"
31 | #define kNotifyMouseLocationChange @"kNotifyMouseLocationChange"
32 | extern const double kBORDER_LINE_WIDTH;
33 | extern const int kBORDER_LINE_COLOR;
34 | extern const int kKEY_ESC_CODE;
35 |
36 |
37 | @interface SnipManager : NSObject
38 |
39 | @property NSMutableArray *windowControllerArray;
40 |
41 | @property NSMutableArray *arrayRect;
42 |
43 | @property CAPTURE_STATE captureState;
44 |
45 | @property DRAW_TYPE drawType;
46 |
47 | @property NSBundle *bundle;
48 |
49 | @property BOOL isWorking;
50 |
51 | + (instancetype)sharedInstance;
52 |
53 | - (void)endCapture:(NSImage *)image;
54 |
55 | - (void)startCapture;
56 |
57 | - (void)configExportPath:(NSString *)path;
58 |
59 | - (NSString* )getExportPath;
60 |
61 | - (NSImage *)getImageFromResource:(NSString *) imageName;
62 | @end
63 |
--------------------------------------------------------------------------------
/SnipManager/SnipManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // SnipManager.m
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "SnipManager.h"
10 | #import "SnipWindowController.h"
11 | #import "SnipView.h"
12 | #import "SnipWindow.h"
13 |
14 | const double kBORDER_LINE_WIDTH = 2.0;
15 | const int kBORDER_LINE_COLOR = 0x1191FE;
16 | const int kKEY_ESC_CODE = 53;
17 |
18 | @interface SnipManager ()
19 | {
20 | NSString *exportPath;
21 | }
22 | @end
23 |
24 | @implementation SnipManager
25 |
26 | + (instancetype)sharedInstance
27 | {
28 | static SnipManager *sharedSingleton = nil;
29 | static dispatch_once_t onceToken;
30 | dispatch_once(&onceToken, ^(void) {
31 | sharedSingleton = [[self alloc] init];
32 | sharedSingleton.windowControllerArray = [NSMutableArray array];
33 | [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:sharedSingleton
34 | selector:@selector(screenChanged:)
35 | name:NSWorkspaceActiveSpaceDidChangeNotification
36 | object:[NSWorkspace sharedWorkspace]];
37 | [[NSNotificationCenter defaultCenter] addObserver:sharedSingleton selector:@selector(screenChanged:) name:NSApplicationDidChangeScreenParametersNotification object:nil];
38 | NSBundle *frameworkBundle = [NSBundle bundleForClass:self];
39 | NSString *imagesBundlePath = [frameworkBundle pathForResource:@"Images" ofType:@"bundle"];
40 | if (imagesBundlePath)
41 | {
42 | sharedSingleton.bundle = [NSBundle bundleWithPath:imagesBundlePath];
43 | }
44 | });
45 | return sharedSingleton;
46 | }
47 |
48 | - (void)dealloc
49 | {
50 | [[NSNotificationCenter defaultCenter] removeObserver:self];
51 | [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
52 | }
53 |
54 | - (void)screenChanged:(NSNotification *)notify
55 | {
56 | if (self.isWorking) {
57 | [self endCapture:nil];
58 | }
59 | }
60 |
61 | - (void)clearController
62 | {
63 | if (_windowControllerArray) {
64 | [_windowControllerArray removeAllObjects];
65 | }
66 | }
67 |
68 | - (void)startCapture
69 | {
70 |
71 | if (self.isWorking) return;
72 | self.isWorking = YES;
73 | self.arrayRect = [NSMutableArray array];
74 | //CFArrayRef windowArray = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
75 | NSArray *windows = (__bridge NSArray *) CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
76 | NSUInteger count = [windows count];
77 | for (NSUInteger i = 0; i < count; i++) {
78 | NSDictionary *windowDescriptionDictionary = windows[i];
79 | // CGRect bounds;
80 | // CGRectMakeWithDictionaryRepresentation((__bridge CFDictionaryRef) windowDescriptionDictionary[(id) kCGWindowBounds], &bounds);
81 | //NSLog(@"------%@",NSStringFromRect(bounds));
82 | [self.arrayRect addObject:windowDescriptionDictionary];
83 | }
84 | //CFRelease(windowArray);
85 |
86 | for (NSScreen *screen in [NSScreen screens]) {
87 | // SnipWindowController *snipController = [[SnipWindowController alloc] initWithWindowNibName:@"SnipWindowController"];
88 | SnipWindowController *snipController = [[SnipWindowController alloc] init];
89 | SnipWindow *snipWindow = [[SnipWindow alloc] initWithContentRect:[screen frame] styleMask:NSNonactivatingPanelMask backing:NSBackingStoreBuffered defer:NO screen:screen];
90 | snipController.window = snipWindow;
91 | SnipView *snipView = [[SnipView alloc] initWithFrame:NSMakeRect(0, 0, [screen frame].size.width, [screen frame].size.height)];
92 | snipWindow.contentView = snipView;
93 | [self.windowControllerArray addObject:snipController];
94 | self.captureState = CAPTURE_STATE_HILIGHT;
95 | [snipController startCaptureWithScreen:screen];
96 | }
97 | }
98 |
99 | - (void)endCapture:(NSImage *)image
100 | {
101 | if (!self.isWorking) return;
102 | self.isWorking = NO;
103 | for (SnipWindowController *windowController in self.windowControllerArray) {
104 | [windowController.window orderOut:nil];
105 | }
106 | [self clearController];
107 | [[NSNotificationCenter defaultCenter] postNotificationName:kNotifyCaptureEnd object:nil userInfo:image == nil ? nil : @{@"image" : image}];
108 | }
109 |
110 | - (void)configExportPath:(NSString *)path {
111 | exportPath = path;
112 | }
113 |
114 | - (NSString* )getExportPath {
115 | if (exportPath) {
116 | return [self checkSnipFolder:exportPath];
117 | }
118 | exportPath = [NSSearchPathForDirectoriesInDomains(NSPicturesDirectory, NSUserDomainMask, YES) firstObject];
119 | return [self checkSnipFolder:exportPath];
120 | }
121 |
122 | - (NSString* )checkSnipFolder:(NSString* )rootPath {
123 | if (![[NSFileManager defaultManager] fileExistsAtPath:rootPath]) {
124 | [[NSFileManager defaultManager] createDirectoryAtPath:rootPath attributes:nil];
125 | }
126 | NSString *path = [NSString stringWithFormat:@"%@/snip",rootPath];
127 | if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
128 | [[NSFileManager defaultManager] createDirectoryAtPath:path attributes:nil];
129 | }
130 | return path;
131 | }
132 |
133 | - (NSImage *)getImageFromResource:(NSString *) imageName {
134 | if (self.bundle) {
135 | NSString* s =[[self.bundle resourcePath] stringByAppendingPathComponent:imageName];
136 | return [[NSImage alloc] initWithContentsOfFile:s];
137 | }
138 | return nil;
139 | }
140 | @end
141 |
--------------------------------------------------------------------------------
/SnipManager/SnipUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // SnipUtil.h
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "ImageButton.h"
12 |
13 | @interface SnipUtil : NSObject
14 | + (CGImageRef)screenShot:(NSScreen *)screen;
15 |
16 | + (BOOL)isPoint:(NSPoint)point inRect:(NSRect)rect;
17 |
18 | + (double)pointDistance:(NSPoint)p1 toPoint:(NSPoint)p2;
19 |
20 | + (NSRect)uniformRect:(NSRect)rect;
21 |
22 | + (NSRect)rectToZero:(NSRect)rect;
23 |
24 | + (NSRect)cgWindowRectToScreenRect:(CGRect)windowRect;
25 |
26 | + (ImageButton *)createButton:(NSImage *)image withAlternate:(NSImage *)alter;
27 | @end
28 |
--------------------------------------------------------------------------------
/SnipManager/SnipUtil.m:
--------------------------------------------------------------------------------
1 | //
2 | // SnipUtil.m
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "SnipUtil.h"
10 |
11 | @implementation SnipUtil
12 | + (CGImageRef)screenShot:(NSScreen *)screen
13 | {
14 | CFArrayRef windowsRef = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
15 |
16 | NSRect rect = [screen frame];
17 | NSRect mainRect = [NSScreen mainScreen].frame;
18 | for (NSScreen *subScreen in [NSScreen screens]) {
19 | if ((int) subScreen.frame.origin.x == 0 && (int) subScreen.frame.origin.y == 0) {
20 | mainRect = subScreen.frame;
21 | }
22 | }
23 | rect = NSMakeRect(rect.origin.x, (mainRect.size.height) - (rect.origin.y + rect.size.height), rect.size.width, rect.size.height);
24 |
25 | NSLog(@"screenShot: %@", NSStringFromRect(rect));
26 | CGImageRef imgRef = CGWindowListCreateImageFromArray(rect, windowsRef, kCGWindowImageDefault);
27 | CFRelease(windowsRef);
28 |
29 | return imgRef;
30 | }
31 |
32 | + (BOOL)isPoint:(NSPoint)point inRect:(NSRect)rect
33 | {
34 | //if (NSPointInRect(point, rect))
35 | //NSLog(@"point:%@ in rect:%@",NSStringFromPoint(point),NSStringFromRect(rect));
36 | return NSPointInRect(point, rect);
37 | }
38 |
39 | + (double)pointDistance:(NSPoint)p1 toPoint:(NSPoint)p2
40 | {
41 | return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
42 | }
43 |
44 | + (NSRect)uniformRect:(NSRect)rect
45 | {
46 | double x = rect.origin.x;
47 | double y = rect.origin.y;
48 | double w = rect.size.width;
49 | double h = rect.size.height;
50 | if (w < 0) {
51 | x += w;
52 | w = -w;
53 | }
54 | if (h < 0) {
55 | y += h;
56 | h = -h;
57 | }
58 | return NSMakeRect(x, y, w, h);
59 | }
60 |
61 | + (NSRect)rectToZero:(NSRect)rect
62 | {
63 | return NSOffsetRect(rect, -rect.origin.x, -rect.origin.y);
64 | }
65 |
66 | + (NSRect)cgWindowRectToScreenRect:(CGRect)windowRect
67 | {
68 | NSRect mainRect = [NSScreen mainScreen].frame;
69 | //NSRect snipRect = screen.frame;
70 | for (NSScreen *screen in [NSScreen screens]) {
71 | if ((int) screen.frame.origin.x == 0 && (int) screen.frame.origin.y == 0) {
72 | mainRect = screen.frame;
73 | }
74 | }
75 | NSRect rect = NSMakeRect(windowRect.origin.x, mainRect.size.height - windowRect.size.height - windowRect.origin.y, windowRect.size.width, windowRect.size.height);
76 | return rect;
77 | }
78 |
79 | + (ImageButton *)createButton:(NSImage *)image withAlternate:(NSImage *)alter
80 | {
81 | ImageButton *button = [[ImageButton alloc] init];
82 | //button.bordered = NO;
83 | //button.bezelStyle = NSShadowlessSquareBezelStyle;
84 | [button setImage:image];
85 | //[button setAlternateImage:alter];
86 | return button;
87 | }
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/SnipManager/SnipView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SnipView.h
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "DrawPathInfo.h"
11 | #import "ToolContainer.h"
12 | #import "DrawPathView.h"
13 |
14 | @interface SnipView : NSView
15 | @property NSImage *image;
16 | @property NSRect drawingRect;
17 | @property DrawPathView *pathView;
18 |
19 | @property(nonatomic, strong) NSTrackingArea *trackingArea;
20 | //@property NSMutableArray *rectArray;
21 | //@property DrawPathInfo *currentInfo;
22 | @property ToolContainer *toolContainer;
23 |
24 | - (void)setupTrackingArea:(NSRect)rect;
25 |
26 | - (void)setupTool;
27 |
28 | - (void)setupDrawPath;
29 |
30 | - (void)showToolkit;
31 |
32 | - (void)hideToolkit;
33 |
34 | - (void)showTip;
35 |
36 | - (void)hideTip;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/SnipManager/SnipView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SnipView.m
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "SnipView.h"
10 | #import "NSColor+Helper.h"
11 | #import "SimpleLabelView.h"
12 |
13 | const int kDRAG_POINT_NUM = 8;
14 | const int kDRAG_POINT_LEN = 5;
15 |
16 | @interface SnipView ()
17 | @property SimpleLabelView *tipView;
18 |
19 | @end
20 |
21 | @implementation SnipView
22 |
23 |
24 | - (instancetype)initWithCoder:(NSCoder *)coder
25 | {
26 |
27 | if (self = [super initWithCoder:coder]) {
28 | //_rectArray = [NSMutableArray array];
29 |
30 | }
31 | return self;
32 | }
33 |
34 | - (void)setupTrackingArea:(NSRect)rect
35 | {
36 | self.trackingArea = [[NSTrackingArea alloc] initWithRect:rect options:NSTrackingMouseMoved | NSTrackingActiveAlways owner:self userInfo:nil];
37 | NSLog(@"track init:%@", NSStringFromRect(self.frame));
38 | [self addTrackingArea:self.trackingArea];
39 | }
40 |
41 | - (void)setupTool
42 | {
43 | self.toolContainer = [[ToolContainer alloc] init];
44 | [self addSubview:self.toolContainer];
45 | [self hideToolkit];
46 |
47 | self.tipView = [[SimpleLabelView alloc] init];
48 | [self addSubview:self.tipView];
49 | [self hideTip];
50 | }
51 |
52 | - (void)setupDrawPath
53 | {
54 | if (self.pathView != nil) return;
55 | NSLog(@"setupDrawPath");
56 | self.pathView = [[DrawPathView alloc] init];
57 | [self addSubview:self.pathView];
58 | NSRect imageRect = NSIntersectionRect(self.drawingRect, self.bounds);
59 | [self.pathView setFrame:imageRect];
60 | [self.pathView setHidden:NO];
61 | }
62 |
63 | - (void)showToolkit
64 | {
65 | NSLog(@"show toolkit:%@",self);
66 | NSRect imageRect = NSIntersectionRect(self.drawingRect, self.bounds);
67 | double y = imageRect.origin.y - 28;
68 | double x = imageRect.origin.x + imageRect.size.width;
69 | if (y < 0) y = 0;
70 | int margin = 10;
71 | int toolWidth = 35 * 6 + margin * 2 - (35-28);
72 | if (x < toolWidth) x = toolWidth;
73 | if (!NSEqualRects(self.toolContainer.frame,NSMakeRect(x - toolWidth, y, toolWidth, 26))) {
74 | [self.toolContainer setFrame:NSMakeRect(x - toolWidth, y, toolWidth, 26)];
75 | }
76 | if (self.toolContainer.isHidden) {
77 | [self.toolContainer setHidden:NO];
78 | }
79 | }
80 |
81 | - (void)hideToolkit
82 | {
83 | [self.toolContainer setHidden:YES];
84 | }
85 |
86 | //- (void)mouseMoved:(NSEvent *)theEvent
87 | //{
88 | // [super mouseMoved:theEvent];
89 | // NSLog(@"snipview track mouse moved:%@",self);
90 | //
91 | //}
92 | - (void)showTip
93 | {
94 | NSPoint mouseLocation = [NSEvent mouseLocation];
95 | NSRect frame = self.window.frame;
96 | if (mouseLocation.x > frame.origin.x + frame.size.width - 100) {
97 | mouseLocation.x -= 100;
98 | }
99 | if (mouseLocation.x < frame.origin.x) {
100 | mouseLocation.x = frame.origin.x;
101 | }
102 | if (mouseLocation.y > frame.origin.y + frame.size.height - 26) {
103 | mouseLocation.y -= 26;
104 | }
105 | if (mouseLocation.y < frame.origin.y) {
106 | mouseLocation.y = frame.origin.y;
107 | }
108 |
109 | NSRect rect = NSMakeRect(mouseLocation.x, mouseLocation.y, 100, 25);
110 | NSRect imageRect = NSIntersectionRect(self.drawingRect, self.bounds);
111 | self.tipView.text = [NSString stringWithFormat:@"%dX%d", (int) imageRect.size.width, (int) imageRect.size.height];
112 | [self.tipView setFrame:[self.window convertRectFromScreen:rect]];
113 | [self.tipView setHidden:NO];
114 | }
115 |
116 | - (void)hideTip
117 | {
118 | [self.tipView setHidden:YES];
119 | }
120 |
121 | - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
122 | {
123 | return YES;
124 | }
125 |
126 | - (NSRect)pointRect:(int)index inRect:(NSRect)rect
127 | {
128 | double x = 0, y = 0;
129 | switch (index) {
130 | case 0:
131 | x = NSMinX(rect);
132 | y = NSMaxY(rect);
133 | break;
134 | case 1:
135 | x = NSMidX(rect);
136 | y = NSMaxY(rect);
137 | break;
138 | case 2:
139 | x = NSMaxX(rect);
140 | y = NSMaxY(rect);
141 | break;
142 | case 3:
143 | x = NSMinX(rect);
144 | y = NSMidY(rect);
145 | break;
146 | case 4:
147 | x = NSMaxX(rect);
148 | y = NSMidY(rect);
149 | break;
150 | case 5:
151 | x = NSMinX(rect);
152 | y = NSMinY(rect);
153 | break;
154 | case 6:
155 | x = NSMidX(rect);
156 | y = NSMinY(rect);
157 | break;
158 | case 7:
159 | x = NSMaxX(rect);
160 | y = NSMinY(rect);
161 | break;
162 |
163 | default:
164 | break;
165 | }
166 | return NSMakeRect(x - kDRAG_POINT_LEN, y - kDRAG_POINT_LEN, kDRAG_POINT_LEN * 2, kDRAG_POINT_LEN * 2);
167 | }
168 |
169 | - (void)drawRect:(NSRect)dirtyRect
170 | {
171 | NSDisableScreenUpdates();
172 | [super drawRect:dirtyRect];
173 | /*if (self.window.screen)
174 | {
175 | [[NSColor whiteColor] set];
176 | for (NSDictionary *dir in [SnipManager sharedInstance].arrayRect) {
177 | CGRect windowRect;
178 | CGRectMakeWithDictionaryRepresentation((__bridge CFDictionaryRef) dir[(id) kCGWindowBounds], &windowRect);
179 | NSRect rect = [SnipUtil cgWindowRectToWindowRect:windowRect inScreen:self.window.screen];
180 | NSBezierPath *rectPath = [NSBezierPath bezierPath];
181 | [rectPath setLineWidth:0.5];
182 | [rectPath appendBezierPathWithRect:rect];
183 | [rectPath stroke];
184 | }
185 | }*/
186 |
187 | if (self.image) {
188 | NSRect imageRect = NSIntersectionRect(self.drawingRect, self.bounds);
189 | [self.image drawInRect:imageRect fromRect:imageRect operation:NSCompositeSourceOver fraction:1.0];
190 | [[NSColor colorFromInt:kBORDER_LINE_COLOR] set];
191 | NSBezierPath *rectPath = [NSBezierPath bezierPath];
192 | [rectPath setLineWidth:kBORDER_LINE_WIDTH];
193 | [rectPath removeAllPoints];
194 | [rectPath appendBezierPathWithRect:imageRect];
195 | [rectPath stroke];
196 | if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_ADJUST) {
197 | [[NSColor whiteColor] set];
198 | for (int i = 0; i < kDRAG_POINT_NUM; i++) {
199 | NSBezierPath *adjustPath = [NSBezierPath bezierPath];
200 | [adjustPath removeAllPoints];
201 | [adjustPath appendBezierPathWithOvalInRect:[self pointRect:i inRect:imageRect]];
202 | [adjustPath fill];
203 | }
204 | }
205 | // else if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_EDIT) {
206 | // [self drawCommentInRect:imageRect];
207 | // if (self.currentInfo) {
208 | // NSRect rect = NSMakeRect(self.currentInfo.startPoint.x, self.currentInfo.startPoint.y, self.currentInfo.endPoint.x-self.currentInfo.startPoint.x, self.currentInfo.endPoint.y-self.currentInfo.startPoint.y);
209 | // rect = [SnipUtil uniformRect:rect];
210 | // rect = [self.window convertRectFromScreen:rect];
211 | // NSBezierPath *rectPath = [NSBezierPath bezierPath];
212 | // [rectPath setLineWidth:1.5];
213 | // [rectPath appendBezierPathWithRect:rect];
214 | // [rectPath stroke];
215 | // }
216 | // }
217 | }
218 | if (self.toolContainer != nil && !self.toolContainer.isHidden) {
219 | [self showToolkit];
220 | }
221 | // Drawing code here.
222 | NSEnableScreenUpdates();
223 | }
224 |
225 | @end
226 |
--------------------------------------------------------------------------------
/SnipManager/SnipWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // SnipWindow.h
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "MouseEventProtocol.h"
11 |
12 | @interface SnipWindow : NSPanel
13 |
14 | @property(weak) id mouseDelegate;
15 | @end
16 |
--------------------------------------------------------------------------------
/SnipManager/SnipWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // SnipWindow.m
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "SnipWindow.h"
10 | #import "SnipManager.h"
11 |
12 | @interface SnipWindow ()
13 | @end
14 |
15 | @implementation SnipWindow
16 |
17 | //- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag
18 | //{
19 | // // Using NSBorderlessWindowMask results in a window without a title bar.
20 | // if (self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]) {
21 | // [self setAcceptsMouseMovedEvents:YES];
22 | // self.movable = NO;
23 | // self.movableByWindowBackground = NO;
24 | // }
25 | // return self;
26 | //}
27 |
28 | - (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)screen
29 | {
30 | if (self = [super initWithContentRect:contentRect styleMask:aStyle backing:NSBackingStoreBuffered defer:NO screen:screen]) {
31 | [self setAcceptsMouseMovedEvents:YES];
32 | [self setFloatingPanel:YES];
33 | [self setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorFullScreenAuxiliary];
34 | [self setMovableByWindowBackground:NO];
35 | [self setExcludedFromWindowsMenu:YES];
36 | [self setAlphaValue:1.0];
37 | [self setOpaque:NO];
38 | [self setHasShadow:NO];
39 | [self setHidesOnDeactivate:NO];
40 | [self setLevel:kCGMaximumWindowLevel];
41 | [self setRestorable:NO];
42 | [self disableSnapshotRestoration];
43 | [self setLevel:kCGMaximumWindowLevel];
44 |
45 | self.movable = NO;
46 | }
47 | return self;
48 | }
49 |
50 | - (void)dealloc
51 | {
52 | NSLog(@"snip window dealloc");
53 | }
54 |
55 | - (void)mouseMoved:(NSEvent *)theEvent
56 | {
57 | //[super mouseMoved:theEvent];
58 | [self.mouseDelegate mouseMoved:theEvent];
59 |
60 | }
61 |
62 | - (BOOL)canBecomeKeyWindow
63 | {
64 | return YES;
65 | }
66 |
67 | - (BOOL)canBecomeMainWindow
68 | {
69 | return YES;
70 | }
71 |
72 | - (void)mouseDown:(NSEvent *)theEvent
73 | {
74 | //[super mouseDown:theEvent];
75 | [self.mouseDelegate mouseDown:theEvent];
76 | }
77 |
78 | - (void)mouseUp:(NSEvent *)theEvent
79 | {
80 | //[super mouseUp:theEvent];
81 | [self.mouseDelegate mouseUp:theEvent];
82 | }
83 |
84 | - (void)mouseDragged:(NSEvent *)theEvent
85 | {
86 | //[super mouseDragged:theEvent];
87 | [self.mouseDelegate mouseDragged:theEvent];
88 |
89 | }
90 |
91 | - (void)keyDown:(NSEvent *)event
92 | {
93 | if ([event keyCode] == kKEY_ESC_CODE) {
94 | NSLog(@"Escape has been pressed");
95 | [self orderOut:nil];
96 | [[SnipManager sharedInstance] endCapture:nil];
97 | return;
98 | }
99 | [super keyDown:event];
100 | }
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/SnipManager/SnipWindowController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SnipWindowController.h
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "MouseEventProtocol.h"
12 |
13 | @interface SnipWindowController : NSWindowController
14 |
15 | - (void)startCaptureWithScreen:(NSScreen *)screen;
16 | @end
17 |
--------------------------------------------------------------------------------
/SnipManager/SnipWindowController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SnipWindowController.m
3 | // Snip
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "SnipWindowController.h"
10 | #import "SnipWindow.h"
11 | #import "SnipUtil.h"
12 | #import "SnipView.h"
13 |
14 | const int kAdjustKnown = 8;
15 |
16 | @interface SnipWindowController ()
17 | //@property SnipWindow *window;
18 | @property(weak) SnipView *snipView;
19 | @property NSImage *originImage;
20 | @property NSImage *darkImage;
21 | @property(assign) NSRect captureWindowRect;
22 | @property(assign) NSRect dragWindowRect;
23 |
24 | @property NSRect lastRect;
25 | @property NSPoint startPoint;
26 | @property NSPoint endPoint;
27 | @property int dragDirection;
28 |
29 | @property NSPoint rectBeginPoint;
30 | @property NSPoint rectEndPoint;
31 | @property BOOL rectDrawing;
32 | @end
33 |
34 | @implementation SnipWindowController
35 |
36 | - (void)windowDidLoad
37 | {
38 | [super windowDidLoad];
39 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
40 | }
41 |
42 | - (void)dealloc
43 | {
44 | [[NSNotificationCenter defaultCenter] removeObserver:self];
45 | }
46 |
47 | - (void)doSnapshot:(NSScreen *)screen
48 | {
49 | // 获取所有OnScreen的窗口
50 | //kCGWindowListExcludeDesktopElements
51 |
52 | CGImageRef imgRef = [SnipUtil screenShot:screen];
53 |
54 | NSRect mainFrame = [screen frame];
55 | self.originImage = [[NSImage alloc] initWithCGImage:imgRef size:mainFrame.size];
56 | self.darkImage = [[NSImage alloc] initWithCGImage:imgRef size:mainFrame.size];
57 | CGImageRelease(imgRef);
58 |
59 | // 对darkImage做暗化处理
60 | [self.darkImage lockFocus];
61 | [[NSColor colorWithCalibratedWhite:0 alpha:0.33] set];
62 | NSRectFillUsingOperation([SnipUtil rectToZero:mainFrame], NSCompositeSourceAtop);
63 | [self.darkImage unlockFocus];
64 |
65 | }
66 |
67 | - (void)captureAppScreen
68 | {
69 | NSScreen *screen = self.window.screen;
70 | NSPoint mouseLocation = [NSEvent mouseLocation];
71 | //NSLog(@"screen:%@ mouse:%@",NSStringFromRect(screen.frame),NSStringFromPoint(mouseLocation));
72 | NSRect screenFrame = [screen frame];
73 | self.captureWindowRect = screenFrame;
74 | double minArea = screenFrame.size.width * screenFrame.size.height;
75 | for (NSDictionary *dir in [SnipManager sharedInstance].arrayRect) {
76 | CGRect windowRect;
77 | CGRectMakeWithDictionaryRepresentation((__bridge CFDictionaryRef) dir[(id) kCGWindowBounds], &windowRect);
78 | NSRect rect = [SnipUtil cgWindowRectToScreenRect:windowRect];
79 | int layer = 0;
80 | CFNumberRef numberRef = (__bridge CFNumberRef) dir[(id) kCGWindowLayer];
81 | CFNumberGetValue(numberRef, kCFNumberSInt32Type, &layer);
82 | if (layer < 0) continue;
83 | if ([SnipUtil isPoint:mouseLocation inRect:rect]) {
84 | if (layer == 0) {
85 | self.captureWindowRect = rect;
86 | break;
87 | }
88 | else {
89 | if (rect.size.width * rect.size.height < minArea) {
90 | self.captureWindowRect = rect;
91 | minArea = rect.size.width * rect.size.height;
92 | break;
93 | }
94 |
95 | }
96 | }
97 |
98 | }
99 | //NSLog(@"capture-----%@",NSStringFromRect(self.captureWindowRect));
100 | if ([SnipUtil isPoint:mouseLocation inRect:screenFrame]) {
101 | [self redrawView:self.originImage];
102 | }
103 | else {
104 | [self redrawView:nil];
105 | [[NSNotificationCenter defaultCenter] postNotificationName:kNotifyMouseLocationChange object:nil userInfo:@{@"context":self}];
106 | }
107 | }
108 |
109 | - (void)redrawView:(NSImage *)image
110 | {
111 | self.captureWindowRect = NSIntersectionRect(self.captureWindowRect, self.window.frame);
112 | if (image != nil && (int) self.lastRect.origin.x == (int) self.captureWindowRect.origin.x
113 | && (int) self.lastRect.origin.y == (int) self.captureWindowRect.origin.y
114 | && (int) self.lastRect.size.width == (int) self.captureWindowRect.size.width
115 | && (int) self.lastRect.size.height == (int) self.captureWindowRect.size.height) {
116 | return;
117 | }
118 | if (self.snipView.image == nil && image == nil) return;
119 | dispatch_async(dispatch_get_main_queue(), ^() {
120 | [self.snipView setImage:image];
121 | NSRect rect = [self.window convertRectFromScreen:self.captureWindowRect];
122 | [self.snipView setDrawingRect:rect];
123 | [self.snipView setNeedsDisplay:YES];
124 | self.lastRect = self.captureWindowRect;
125 | //NSLog(@"redraw hilight:[%@]", NSStringFromRect(rect));
126 | });
127 |
128 | }
129 |
130 | - (NSPoint)dragPointCenter:(int)index
131 | {
132 | double x = 0, y = 0;
133 | switch (index) {
134 | case 0:
135 | x = NSMinX(self.captureWindowRect);
136 | y = NSMaxY(self.captureWindowRect);
137 | break;
138 | case 1:
139 | x = NSMidX(self.captureWindowRect);
140 | y = NSMaxY(self.captureWindowRect);
141 | break;
142 | case 2:
143 | x = NSMaxX(self.captureWindowRect);
144 | y = NSMaxY(self.captureWindowRect);
145 | break;
146 | case 3:
147 | x = NSMinX(self.captureWindowRect);
148 | y = NSMidY(self.captureWindowRect);
149 | break;
150 | case 4:
151 | x = NSMaxX(self.captureWindowRect);
152 | y = NSMidY(self.captureWindowRect);
153 | break;
154 | case 5:
155 | x = NSMinX(self.captureWindowRect);
156 | y = NSMinY(self.captureWindowRect);
157 | break;
158 | case 6:
159 | x = NSMidX(self.captureWindowRect);
160 | y = NSMinY(self.captureWindowRect);
161 | break;
162 | case 7:
163 | x = NSMaxX(self.captureWindowRect);
164 | y = NSMinY(self.captureWindowRect);
165 | break;
166 |
167 | default:
168 | break;
169 | }
170 | return NSMakePoint(x, y);
171 | }
172 |
173 |
174 | - (int)dragDirectionFromPoint:(NSPoint)point
175 | {
176 | if (NSWidth(self.captureWindowRect) <= kAdjustKnown * 2 || NSHeight(self.captureWindowRect) <= kAdjustKnown * 2) {
177 | if (NSPointInRect(point, self.captureWindowRect)) {
178 | return 8;
179 | }
180 | }
181 | NSRect innerRect = NSInsetRect(self.captureWindowRect, kAdjustKnown, kAdjustKnown);
182 | if (NSPointInRect(point, innerRect)) {
183 | return 8;
184 | }
185 | NSRect outerRect = NSInsetRect(self.captureWindowRect, -kAdjustKnown, -kAdjustKnown);
186 | if (!NSPointInRect(point, outerRect)) {
187 | return -1;
188 | }
189 | double minDistance = kAdjustKnown * kAdjustKnown;
190 | int ret = -1;
191 | for (int i = 0; i < 8; i++) {
192 | NSPoint dragPoint = [self dragPointCenter:i];
193 | double distance = [SnipUtil pointDistance:dragPoint toPoint:point];
194 | if (distance < minDistance) {
195 | minDistance = distance;
196 | ret = i;
197 | }
198 | }
199 | return ret;
200 | }
201 |
202 | - (void)setupToolClick
203 | {
204 | __weak __typeof__(self) weakSelf = self;
205 | self.snipView.toolContainer.toolClick = ^(long index) {
206 | __typeof__(self) strongSelf = weakSelf;
207 | switch (index) {
208 | case ActionShapeRect:
209 | [SnipManager sharedInstance].drawType = DRAW_TYPE_RECT;
210 | [SnipManager sharedInstance].captureState = CAPTURE_STATE_EDIT;
211 | [strongSelf.snipView setupDrawPath];
212 | [strongSelf.snipView setNeedsDisplay:YES];
213 | break;
214 | case ActionShapeEllipse:
215 | [SnipManager sharedInstance].drawType = DRAW_TYPE_ELLIPSE;
216 | [SnipManager sharedInstance].captureState = CAPTURE_STATE_EDIT;
217 | [strongSelf.snipView setupDrawPath];
218 | [strongSelf.snipView setNeedsDisplay:YES];
219 | break;
220 | case ActionShapeArrow:
221 | [SnipManager sharedInstance].drawType = DRAW_TYPE_ARROW;
222 | [SnipManager sharedInstance].captureState = CAPTURE_STATE_EDIT;
223 | [strongSelf.snipView setupDrawPath];
224 | [strongSelf.snipView setNeedsDisplay:YES];
225 | break;
226 | case ActionExport:
227 | [strongSelf onExportImage];
228 | [[SnipManager sharedInstance] endCapture:nil];
229 | break;
230 | case ActionCancel:
231 | [[SnipManager sharedInstance] endCapture:nil];
232 | break;
233 | case ActionOK:
234 | [strongSelf onOK];
235 | break;
236 | default:
237 | break;
238 | }
239 | };
240 |
241 | }
242 |
243 | - (void)startCaptureWithScreen:(NSScreen *)screen
244 | {
245 | [self doSnapshot:screen];
246 |
247 | [self.window setBackgroundColor:[NSColor colorWithPatternImage:self.darkImage]];
248 | NSRect screenFrame = [screen frame];
249 | screenFrame.size.width /= 1;
250 | screenFrame.size.height /= 1;
251 | [self.window setFrame:screenFrame display:YES animate:NO];
252 |
253 | self.snipView = self.window.contentView;
254 | ((SnipWindow *) self.window).mouseDelegate = self;
255 | [self.snipView setupTrackingArea:self.window.screen.frame];
256 |
257 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onNotifyMouseChange:) name:kNotifyMouseLocationChange object:nil];
258 | [self showWindow:nil];
259 | //[self.window makeKeyAndOrderFront:nil];
260 | [self captureAppScreen];
261 | }
262 |
263 | - (void)onNotifyMouseChange:(NSNotification *)notify
264 | {
265 | if (notify.userInfo[@"context"] == self) return;
266 | if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_HILIGHT && self.window.isVisible && [SnipUtil isPoint:[NSEvent mouseLocation] inRect:self.window.screen.frame]) {
267 |
268 | __weak __typeof__(self) weakSelf = self;
269 | dispatch_async(dispatch_get_main_queue(), ^() {
270 | __typeof__(self) strongSelf = weakSelf;
271 | [strongSelf showWindow:nil];
272 | //[self.window makeKeyAndOrderFront:nil];
273 | [strongSelf captureAppScreen];
274 | });
275 |
276 | }
277 | }
278 |
279 | - (void)mouseDown:(NSEvent *)event
280 | {
281 | if ([event clickCount] == 2) {
282 | if ([SnipManager sharedInstance].captureState != CAPTURE_STATE_HILIGHT) {
283 | [self onOK];
284 | }
285 | }
286 |
287 | if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_HILIGHT) {
288 | [SnipManager sharedInstance].captureState = CAPTURE_STATE_FIRSTMOUSEDOWN;
289 | self.startPoint = [NSEvent mouseLocation];
290 | [self.snipView setupTool];
291 | [self setupToolClick];
292 | }
293 | else if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_ADJUST) {
294 | self.startPoint = [NSEvent mouseLocation];
295 | self.captureWindowRect = [SnipUtil uniformRect:self.captureWindowRect];
296 | self.dragWindowRect = self.captureWindowRect;
297 | self.dragDirection = [self dragDirectionFromPoint:[NSEvent mouseLocation]];
298 | }
299 | if ([SnipManager sharedInstance].captureState != CAPTURE_STATE_EDIT) {
300 | [self.snipView hideToolkit];
301 | }
302 | else {
303 | NSPoint mouseLocation = [NSEvent mouseLocation];
304 | if (NSPointInRect(mouseLocation, self.captureWindowRect)) {
305 | self.rectBeginPoint = mouseLocation;
306 | self.rectDrawing = YES;
307 | }
308 | }
309 | }
310 |
311 | - (void)mouseUp:(NSEvent *)theEvent
312 | {
313 | if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_FIRSTMOUSEDOWN || [SnipManager sharedInstance].captureState == CAPTURE_STATE_READYADJUST) {
314 | [SnipManager sharedInstance].captureState = CAPTURE_STATE_ADJUST;
315 | [self.snipView setNeedsDisplay:YES];
316 | }
317 | if ([SnipManager sharedInstance].captureState != CAPTURE_STATE_EDIT) {
318 | [self.snipView showToolkit];
319 | [self.snipView hideTip];
320 | [self.snipView setNeedsDisplay:YES];
321 | }
322 | else {
323 | if (self.rectDrawing) {
324 | self.rectDrawing = NO;
325 | self.rectEndPoint = [NSEvent mouseLocation];
326 | [self.snipView.pathView.rectArray addObject:[[DrawPathInfo alloc] initWith:self.rectBeginPoint andEndPoint:self.rectEndPoint andType:[SnipManager sharedInstance].drawType]];
327 | [self.snipView setNeedsDisplayInRect:[self.window convertRectFromScreen:self.captureWindowRect]];
328 | }
329 | }
330 |
331 | }
332 |
333 | - (void)mouseDragged:(NSEvent *)theEvent
334 | {
335 | if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_FIRSTMOUSEDOWN
336 | || [SnipManager sharedInstance].captureState == CAPTURE_STATE_READYADJUST) {
337 | [SnipManager sharedInstance].captureState = CAPTURE_STATE_READYADJUST;
338 | self.endPoint = [NSEvent mouseLocation];
339 |
340 | self.captureWindowRect = NSUnionRect(NSMakeRect(self.startPoint.x, self.startPoint.y, 1, 1), NSMakeRect(self.endPoint.x, self.endPoint.y, 1, 1));
341 | self.captureWindowRect = NSIntersectionRect(self.captureWindowRect, self.window.frame);
342 | [self redrawView:self.originImage];
343 | }
344 | else if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_EDIT) {
345 | if (self.rectDrawing) {
346 | self.rectEndPoint = [NSEvent mouseLocation];
347 | self.snipView.pathView.currentInfo = [[DrawPathInfo alloc] initWith:self.rectBeginPoint andEndPoint:self.rectEndPoint andType:[SnipManager sharedInstance].drawType];
348 | [self.snipView.pathView setNeedsDisplay:YES];
349 | }
350 | }
351 | else if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_ADJUST) {
352 | if (self.dragDirection == -1) return;
353 | NSPoint mouseLocation = [NSEvent mouseLocation];
354 | self.endPoint = mouseLocation;
355 | CGFloat deltaX = self.endPoint.x - self.startPoint.x;
356 | CGFloat deltaY = self.endPoint.y - self.startPoint.y;
357 | NSRect rect = self.dragWindowRect;
358 | switch (self.dragDirection) {
359 | case 8: {
360 | rect = NSOffsetRect(rect, self.endPoint.x - self.startPoint.x, self.endPoint.y - self.startPoint.y);
361 | if (!NSContainsRect(self.window.frame, rect)) {
362 | NSRect rcOrigin = self.window.frame;
363 | if (rect.origin.x < rcOrigin.origin.x) {
364 | rect.origin.x = rcOrigin.origin.x;
365 | }
366 | if (rect.origin.y < rcOrigin.origin.y) {
367 | rect.origin.y = rcOrigin.origin.y;
368 | }
369 | if (rect.origin.x > rcOrigin.origin.x + rcOrigin.size.width - rect.size.width) {
370 | rect.origin.x = rcOrigin.origin.x + rcOrigin.size.width - rect.size.width;
371 | }
372 | if (rect.origin.y > rcOrigin.origin.y + rcOrigin.size.height - rect.size.height) {
373 | rect.origin.y = rcOrigin.origin.y + rcOrigin.size.height - rect.size.height;
374 | }
375 | self.endPoint = NSMakePoint(self.startPoint.x + rect.origin.x - self.dragWindowRect.origin.x, self.startPoint.y + rect.origin.y - self.dragWindowRect.origin.y);
376 | }
377 | }
378 | break;
379 | case 7: {
380 | rect.origin.y += deltaY;
381 | rect.size.width += deltaX;
382 | rect.size.height -= deltaY;
383 |
384 | }
385 | break;
386 | case 6: {
387 | rect.origin.y += deltaY;
388 | rect.size.height -= deltaY;
389 | }
390 | break;
391 | case 5: {
392 | rect.origin.x += deltaX;
393 | rect.origin.y += deltaY;
394 | rect.size.width -= deltaX;
395 | rect.size.height -= deltaY;
396 | }
397 | break;
398 | case 4: {
399 | rect.size.width += deltaX;
400 | }
401 | break;
402 | case 3: {
403 | rect.origin.x += deltaX;
404 | rect.size.width -= deltaX;
405 | }
406 | break;
407 | case 2: {
408 | rect.size.width += deltaX;
409 | rect.size.height += deltaY;
410 | }
411 | break;
412 | case 1: {
413 | rect.size.height += deltaY;
414 | }
415 | break;
416 | case 0: {
417 | rect.origin.x += deltaX;
418 | rect.size.width -= deltaX;
419 | rect.size.height += deltaY;
420 | }
421 | break;
422 | default:
423 | break;
424 | }
425 | self.dragWindowRect = rect;
426 | if ((int) rect.size.width == 0) rect.size.width = 1;
427 | if ((int) rect.size.height == 0) rect.size.height = 1;
428 | self.captureWindowRect = [SnipUtil uniformRect:rect];
429 | self.startPoint = self.endPoint;
430 | [self.snipView showTip];
431 | [self redrawView:self.originImage];
432 | }
433 | }
434 |
435 | - (void)mouseMoved:(NSEvent *)theEvent
436 | {
437 | if ([SnipManager sharedInstance].captureState == CAPTURE_STATE_HILIGHT) {
438 | [self captureAppScreen];
439 | }
440 | }
441 |
442 | - (void)onOK
443 | {
444 | //获取截屏的图片
445 | NSImage *pasteImage = [self getCaptureImage];
446 | // 把选择的截图保存到粘贴板
447 | if (pasteImage != nil) {
448 | NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
449 | [pasteBoard clearContents];
450 | [pasteBoard writeObjects:@[pasteImage]];
451 | }
452 | [[SnipManager sharedInstance] endCapture:pasteImage];
453 | [self.window orderOut:nil];
454 |
455 | }
456 |
457 | - (void)onExportImage {
458 | NSImage *pasteImage = [self getCaptureImage];
459 | if (pasteImage != nil) {
460 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
461 | formatter.dateFormat = @"yyyy-MM-dd-HH-mm-ss";
462 | NSString *imagePath = [NSString stringWithFormat:@"%@/snip-%@.png",[[SnipManager sharedInstance] getExportPath],[formatter stringFromDate:[NSDate new]]];
463 | [self saveImage:pasteImage atPath:imagePath];
464 | NSLog(@"onExportImage: %@",imagePath);
465 | }
466 | }
467 |
468 | - (NSImage *)getCaptureImage {
469 | [self.originImage lockFocus];
470 | NSRect rect = NSIntersectionRect(self.captureWindowRect, self.window.frame);
471 | [self.snipView.pathView drawFinishCommentInRect:[self.window convertRectFromScreen:rect]];
472 | //先设置 下面一个实例
473 | NSBitmapImageRep *bits = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[self.window convertRectFromScreen:rect]];
474 |
475 | [self.originImage unlockFocus];
476 |
477 | //再设置后面要用到得 props属性
478 | NSDictionary *imageProps = @{NSImageCompressionFactor : @(1.0)};
479 |
480 | //之后 转化为NSData 以便存到文件中
481 | NSData *imageData = [bits representationUsingType:NSJPEGFileType properties:imageProps];
482 |
483 | return [[NSImage alloc] initWithData:imageData];
484 | }
485 |
486 | - (void)saveImage:(NSImage *)image atPath:(NSString *)path {
487 |
488 | CGImageRef cgRef = [image CGImageForProposedRect:NULL
489 | context:nil
490 | hints:nil];
491 | NSBitmapImageRep *newRep = [[NSBitmapImageRep alloc] initWithCGImage:cgRef];
492 | [newRep setSize:[image size]]; // if you want the same resolution
493 | NSData *pngData = [newRep representationUsingType:NSPNGFileType properties:nil];
494 | [pngData writeToFile:path atomically:YES];
495 | }
496 |
497 | @end
498 |
--------------------------------------------------------------------------------
/SnipManager/SnipWindowController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/SnipManager/ToolContainer.h:
--------------------------------------------------------------------------------
1 | //
2 | // ToolContainer.h
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/5.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, ActionType)
12 | {
13 | ActionCancel,
14 | ActionOK,
15 | ActionExport,
16 | ActionShapeRect,
17 | ActionShapeEllipse,
18 | ActionShapeArrow
19 | };
20 |
21 | @interface ToolContainer : NSView
22 | @property(nonatomic, copy) void (^toolClick)(long index);
23 | @end
24 |
--------------------------------------------------------------------------------
/SnipManager/ToolContainer.m:
--------------------------------------------------------------------------------
1 | //
2 | // ToolContainer.m
3 | // Snip
4 | //
5 | // Created by isee15 on 15/2/5.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import "ToolContainer.h"
10 | #import "SnipUtil.h"
11 | #import "SnipManager.h"
12 |
13 | @interface ToolContainer ()
14 | @property ImageButton *rectButton;
15 | @property ImageButton *ellipseButton;
16 | @property ImageButton *arrowButton;
17 | @property ImageButton *cancelButton;
18 | @property ImageButton *exportButton;
19 | @property ImageButton *okButton;
20 | @end
21 |
22 | @implementation ToolContainer
23 |
24 | - (instancetype)init
25 | {
26 | if (self = [super init]) {
27 |
28 | _rectButton = [SnipUtil createButton: [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_rect_ineffect.tiff"] withAlternate:nil];
29 | _rectButton.tag = ActionShapeRect;
30 |
31 | _ellipseButton = [SnipUtil createButton:[[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_ellipse_ineffect.tiff"] withAlternate:nil];
32 | _ellipseButton.tag = ActionShapeEllipse;
33 |
34 | _arrowButton = [SnipUtil createButton:[[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_arrow_ineffect.tiff"] withAlternate:nil];
35 | _arrowButton.tag = ActionShapeArrow;
36 |
37 | _exportButton = [SnipUtil createButton:[[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_export.tiff"] withAlternate:nil];
38 | _exportButton.tag = ActionExport;
39 |
40 | _cancelButton = [SnipUtil createButton:[[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_cross_normal.tiff"] withAlternate:nil];
41 | _cancelButton.tag = ActionCancel;
42 |
43 | _okButton = [SnipUtil createButton:[[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_tick_normal.tiff"] withAlternate:nil];
44 | _okButton.tag = ActionOK;
45 |
46 | _rectButton.target = self;
47 | _rectButton.action = @selector(onToolClick:);
48 | _ellipseButton.target = self;
49 | _ellipseButton.action = @selector(onToolClick:);
50 | _arrowButton.target = self;
51 | _arrowButton.action = @selector(onToolClick:);
52 | _exportButton.target = self;
53 | _exportButton.action = @selector(onToolClick:);
54 | _cancelButton.target = self;
55 | _cancelButton.action = @selector(onToolClick:);
56 | _okButton.target = self;
57 | _okButton.action = @selector(onToolClick:);
58 |
59 | [self addSubview:_rectButton];
60 | [self addSubview:_ellipseButton];
61 | [self addSubview:_arrowButton];
62 | [self addSubview:_exportButton];
63 | [self addSubview:_cancelButton];
64 | [self addSubview:_okButton];
65 | }
66 | return self;
67 | }
68 |
69 |
70 | - (void)drawRect:(NSRect)dirtyRect
71 | {
72 | [super drawRect:dirtyRect];
73 | NSBezierPath *bgPath = [NSBezierPath bezierPathWithRoundedRect:self.bounds xRadius:3 yRadius:3];
74 | [bgPath setClip];
75 | [[NSColor colorWithCalibratedWhite:0.0 alpha:0.8f] setFill];
76 | NSRectFill(self.bounds);
77 | // Drawing code here.
78 | }
79 |
80 | - (void)setFrame:(NSRect)frame
81 | {
82 | [super setFrame:frame];
83 | int step = 35;
84 | int margin = 10;
85 | [self.rectButton setFrame:NSMakeRect(margin, 0, 28, 26)];
86 | [self.ellipseButton setFrame:NSMakeRect(margin+step * 1, 0, 28, 26)];
87 | [self.arrowButton setFrame:NSMakeRect(margin+step * 2, 0, 28, 26)];
88 | [self.exportButton setFrame:NSMakeRect(margin+step * 3, 0, 28, 26)];
89 | [self.cancelButton setFrame:NSMakeRect(margin+step * 4, 0, 28, 26)];
90 | [self.okButton setFrame:NSMakeRect(margin+step * 5, 0, 28, 26)];
91 |
92 | }
93 |
94 | - (void)onToolClick:(NSControl *)sender
95 | {
96 | //need refactor
97 | if (sender == self.rectButton) {
98 | self.rectButton.image = [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_rect_effect.tiff"];
99 | self.ellipseButton.image = [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_ellipse_ineffect.tiff"];
100 | self.arrowButton.image = [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_arrow_ineffect.tiff"];
101 | }
102 | else if (sender == self.ellipseButton) {
103 | self.rectButton.image = [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_rect_ineffect.tiff"];
104 | self.ellipseButton.image = [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_ellipse_effect.tiff"];
105 | self.arrowButton.image = [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_arrow_ineffect.tiff"];
106 | }
107 | else if (sender == self.arrowButton) {
108 | self.rectButton.image = [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_rect_ineffect.tiff"];
109 | self.ellipseButton.image = [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_ellipse_ineffect.tiff"];
110 | self.arrowButton.image = [[SnipManager sharedInstance] getImageFromResource:@"ScreenCapture_toolbar_arrow_effect.tiff"];
111 | }
112 | if (self.toolClick) {
113 | self.toolClick([sender tag]);
114 | }
115 |
116 | }
117 |
118 | - (void)mouseDown:(NSEvent *)theEvent
119 | {
120 | }
121 |
122 |
123 | @end
124 |
--------------------------------------------------------------------------------
/SnipTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SnipTests/SnipTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SnipTests.m
3 | // SnipTests
4 | //
5 | // Created by rz on 15/1/31.
6 | // Copyright (c) 2015年 isee15. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface SnipTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation SnipTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/src.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yihuds/SnipManager/7901c2785dbff4d64ff9695dd0cfa1c3670b22d9/src.png
--------------------------------------------------------------------------------