├── .gitignore
├── LICENSE
├── MultiSelectionSuite.xcworkspace
├── contents.xcworkspacedata
└── xcuserdata
│ └── sascha.xcuserdatad
│ ├── UserInterfaceState.xcuserstate
│ ├── WorkspaceSettings.xcsettings
│ └── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
├── MultiSelectionSuiteApp
├── Libs
│ └── SPScannerCaptureWindow.bundle
│ │ └── Contents
│ │ ├── Info.plist
│ │ ├── MacOS
│ │ └── SPScannerCaptureWindow
│ │ ├── Resources
│ │ ├── Base.lproj
│ │ │ ├── Localizable.strings
│ │ │ ├── SCWError.strings
│ │ │ └── SCWWindow.nib
│ │ └── de.lproj
│ │ │ ├── Localizable.strings
│ │ │ ├── SCWError.strings
│ │ │ └── SCWWindow.strings
│ │ └── _CodeSignature
│ │ └── CodeResources
├── MultiSelectionSuiteApp.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── sascha.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── sascha.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── MultiSelectionSuiteApp.xcscheme
│ │ └── xcschememanagement.plist
└── MultiSelectionSuiteApp
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Base.lproj
│ ├── CaptureWindow.xib
│ ├── CropImageWindow.xib
│ ├── MainMenu.xib
│ └── ZoomImageWindow.xib
│ ├── CaptureWindow.h
│ ├── CaptureWindow.m
│ ├── CaptureWindow.xib
│ ├── CropImageWindow.h
│ ├── CropImageWindow.m
│ ├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── MainMenu.xib
│ ├── SPWindowBundle.h
│ ├── ZoomImageWindow.h
│ ├── ZoomImageWindow.m
│ ├── animals.jpg
│ ├── de.lproj
│ ├── CaptureWindow.strings
│ ├── CropImageWindow.strings
│ ├── MainMenu.strings
│ └── ZoomImageWindow.strings
│ └── main.m
├── MultiSelectionSuiteFramework
├── MultiSelectionSuite.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── sascha.xcuserdatad
│ │ │ ├── UserInterfaceState.xcuserstate
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcuserdata
│ │ └── sascha.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── MultiSelectionSuite.xcscheme
│ │ └── xcschememanagement.plist
├── MultiSelectionSuite
│ ├── Classes
│ │ ├── AddOns
│ │ │ └── Extractors
│ │ │ │ ├── MSSExtractor.h
│ │ │ │ ├── MSSExtractor.m
│ │ │ │ ├── MSSImageExtractor.h
│ │ │ │ ├── MSSImageExtractor.m
│ │ │ │ ├── MSSZoomExtractor.h
│ │ │ │ └── MSSZoomExtractor.m
│ │ ├── Base
│ │ │ ├── MSSCanvas.h
│ │ │ ├── MSSCanvas.m
│ │ │ ├── MSSCanvasController.h
│ │ │ ├── MSSCanvasController.m
│ │ │ ├── MSSHandle.h
│ │ │ ├── MSSHandle.m
│ │ │ ├── MSSHandleStyle.h
│ │ │ ├── MSSHandleStyle.m
│ │ │ ├── MSSSelector.h
│ │ │ ├── MSSSelector.m
│ │ │ ├── MSSSelectorStyle.h
│ │ │ └── MSSSelectorStyle.m
│ │ ├── Others
│ │ │ ├── BottomTop@2x.png
│ │ │ ├── NSImageView+MSSScaledImage.h
│ │ │ ├── NSImageView+MSSScaledImage.m
│ │ │ └── TopBottom@2x.png
│ │ └── Preferences
│ │ │ ├── MSSError.h
│ │ │ ├── MSSError.m
│ │ │ ├── MSSPreferences.h
│ │ │ └── MSSPreferences.m
│ ├── Info.plist
│ ├── MultiSelectionSuite.h
│ ├── de.lproj
│ │ └── MSSError.strings
│ └── en.lproj
│ │ └── MSSError.strings
└── MultiSelectionSuiteFramework.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── sascha.xcuserdatad
│ │ └── WorkspaceSettings.xcsettings
│ └── xcuserdata
│ └── sascha.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── MultiSelectionSuite.xcscheme
│ └── xcschememanagement.plist
└── README.markdown
/.gitignore:
--------------------------------------------------------------------------------
1 | doc
2 | makedoc
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 ckteebe
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/MultiSelectionSuite.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/MultiSelectionSuite.xcworkspace/xcuserdata/sascha.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuite.xcworkspace/xcuserdata/sascha.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/MultiSelectionSuite.xcworkspace/xcuserdata/sascha.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildLocationStyle
6 | UseAppPreferences
7 | CustomBuildLocationType
8 | RelativeToDerivedData
9 | DerivedDataLocationStyle
10 | Default
11 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
12 |
13 | IssueFilterStyle
14 | ShowActiveSchemeOnly
15 | LiveSourceIssuesEnabled
16 |
17 | SnapshotAutomaticallyBeforeSignificantChanges
18 |
19 | SnapshotLocationStyle
20 | Default
21 |
22 |
23 |
--------------------------------------------------------------------------------
/MultiSelectionSuite.xcworkspace/xcuserdata/sascha.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 14B25
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | SPScannerCaptureWindow
11 | CFBundleIdentifier
12 | com.saschapaulus.bundles.scw
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | SPScannerCaptureWindow
17 | CFBundlePackageType
18 | BNDL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | DTCompiler
26 | com.apple.compilers.llvm.clang.1_0
27 | DTPlatformBuild
28 | 6A2008a
29 | DTPlatformVersion
30 | GM
31 | DTSDKBuild
32 | 14A382
33 | DTSDKName
34 | macosx10.10
35 | DTXcode
36 | 0611
37 | DTXcodeBuild
38 | 6A2008a
39 | NSHumanReadableCopyright
40 | Copyright © 2015 Sascha Paulus. All rights reserved.
41 | NSPrincipalClass
42 | SPScannerCaptureWindow
43 |
44 |
45 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/MacOS/SPScannerCaptureWindow:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/MacOS/SPScannerCaptureWindow
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/Base.lproj/Localizable.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/Base.lproj/Localizable.strings
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/Base.lproj/SCWError.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/Base.lproj/SCWError.strings
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/Base.lproj/SCWWindow.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/Base.lproj/SCWWindow.nib
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/de.lproj/Localizable.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/de.lproj/Localizable.strings
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/de.lproj/SCWError.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/de.lproj/SCWError.strings
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/Resources/de.lproj/SCWWindow.strings:
--------------------------------------------------------------------------------
1 |
2 | /* Class = "NSButtonCell"; title = "Close"; ObjectID = "1Nw-rq-52g"; */
3 | "1Nw-rq-52g.title" = "Schließen";
4 |
5 | /* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "1xP-DU-U3C"; */
6 | "1xP-DU-U3C.title" = "Item 2";
7 |
8 | /* Class = "NSTextFieldCell"; title = "Resolution"; ObjectID = "5v5-72-oeJ"; */
9 | "5v5-72-oeJ.title" = "Auflösung";
10 |
11 | /* Class = "NSMenuItem"; title = "Item 3"; ObjectID = "6rd-z9-dBD"; */
12 | "6rd-z9-dBD.title" = "Item 3";
13 |
14 | /* Class = "NSTextFieldCell"; title = "Scanner"; ObjectID = "AaU-n7-SoU"; */
15 | "AaU-n7-SoU.title" = "Scanner";
16 |
17 | /* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "AxK-eE-eZR"; */
18 | "AxK-eE-eZR.title" = "Text Cell";
19 |
20 | /* Class = "NSPanel"; title = "Scanner Settings"; ObjectID = "Bdv-du-xhP"; */
21 | "Bdv-du-xhP.title" = "Scanner Einstellungen";
22 |
23 | /* Class = "NSButtonCell"; title = "As PDF"; ObjectID = "BkO-LE-PiT"; */
24 | "BkO-LE-PiT.title" = "Als PDF";
25 |
26 | /* Class = "NSMenuItem"; title = "Item 3"; ObjectID = "E0E-Fh-ZFv"; */
27 | "E0E-Fh-ZFv.title" = "Item 3";
28 |
29 | /* Class = "NSButtonCell"; title = "Radio"; ObjectID = "Gja-vW-xq4"; */
30 | "Gja-vW-xq4.title" = "Radio";
31 |
32 | /* Class = "NSButtonCell"; title = "Black/White"; ObjectID = "KYG-IZ-Pgp"; */
33 | "KYG-IZ-Pgp.title" = "s/w";
34 |
35 | /* Class = "NSTextFieldCell"; title = "Table View Cell"; ObjectID = "Lgt-U8-CMs"; */
36 | "Lgt-U8-CMs.title" = "Table View Cell";
37 |
38 | /* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "O0k-w2-tph"; */
39 | "O0k-w2-tph.title" = "Item 2";
40 |
41 | /* Class = "NSButtonCell"; title = "Scan & Save"; ObjectID = "OeV-B7-ct7"; */
42 | "OeV-B7-ct7.title" = "Scannen";
43 |
44 | /* Class = "NSMenuItem"; title = "Item 1"; ObjectID = "Prh-kt-xpt"; */
45 | "Prh-kt-xpt.title" = "Item 1";
46 |
47 | /* Class = "NSWindow"; title = "Window"; ObjectID = "QvC-M9-y7g"; */
48 | "QvC-M9-y7g.title" = "Window";
49 |
50 | /* Class = "NSBox"; title = "Box"; ObjectID = "UwR-LH-3G3"; */
51 | "UwR-LH-3G3.title" = "Box";
52 |
53 | /* Class = "NSMenuItem"; title = "Item 3"; ObjectID = "VRN-fb-csU"; */
54 | "VRN-fb-csU.title" = "Item 3";
55 |
56 | /* Class = "NSButtonCell"; title = "Preview"; ObjectID = "aZy-J8-7dH"; */
57 | "aZy-J8-7dH.title" = "Vorschau";
58 |
59 | /* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "d42-L7-Q0u"; */
60 | "d42-L7-Q0u.title" = "Text Cell";
61 |
62 | /* Class = "NSButtonCell"; title = "Grayscale"; ObjectID = "dpA-HZ-dW9"; */
63 | "dpA-HZ-dW9.title" = "Graustufen";
64 |
65 | /* Class = "NSButtonCell"; title = "Improve Image"; ObjectID = "fHC-iZ-3KH"; */
66 | "fHC-iZ-3KH.title" = "Bild verbessern";
67 |
68 | /* Class = "NSButtonCell"; title = "Color"; ObjectID = "jZm-8I-1Hk"; */
69 | "jZm-8I-1Hk.title" = "Farbig";
70 |
71 | /* Class = "NSButtonCell"; title = "Setup"; ObjectID = "li0-Dz-yUp"; */
72 | "li0-Dz-yUp.title" = "Einstellungen";
73 |
74 | /* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "oQF-SL-T1m"; */
75 | "oQF-SL-T1m.title" = "Item 2";
76 |
77 | /* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "t0r-Hx-eso"; */
78 | "t0r-Hx-eso.title" = "Abbruch";
79 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/Libs/SPScannerCaptureWindow.bundle/Contents/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Resources/Base.lproj/Localizable.strings
8 |
9 | hash
10 |
11 | tp46OnJeUpfXDWQp+jjiyi6TPZ0=
12 |
13 | optional
14 |
15 |
16 | Resources/Base.lproj/SCWError.strings
17 |
18 | hash
19 |
20 | wq7Y2pjXYsPX5j4d7MLyRySlS90=
21 |
22 | optional
23 |
24 |
25 | Resources/Base.lproj/SCWWindow.nib
26 |
27 | hash
28 |
29 | DDLJFqBPGS7TZeguM2IsIPVbrgI=
30 |
31 | optional
32 |
33 |
34 | Resources/de.lproj/Localizable.strings
35 |
36 | hash
37 |
38 | R1cgSAGQ0T2tbgi/UyjivI5T1gY=
39 |
40 | optional
41 |
42 |
43 | Resources/de.lproj/SCWError.strings
44 |
45 | hash
46 |
47 | 3Qgzb3o/CIcGeoooxSh//86pCvI=
48 |
49 | optional
50 |
51 |
52 | Resources/de.lproj/SCWWindow.strings
53 |
54 | hash
55 |
56 | 3vxlgHLHesNQRlS+ndGX81eCmBM=
57 |
58 | optional
59 |
60 |
61 |
62 | files2
63 |
64 | Resources/Base.lproj/Localizable.strings
65 |
66 | hash
67 |
68 | tp46OnJeUpfXDWQp+jjiyi6TPZ0=
69 |
70 | optional
71 |
72 |
73 | Resources/Base.lproj/SCWError.strings
74 |
75 | hash
76 |
77 | wq7Y2pjXYsPX5j4d7MLyRySlS90=
78 |
79 | optional
80 |
81 |
82 | Resources/Base.lproj/SCWWindow.nib
83 |
84 | hash
85 |
86 | DDLJFqBPGS7TZeguM2IsIPVbrgI=
87 |
88 | optional
89 |
90 |
91 | Resources/de.lproj/Localizable.strings
92 |
93 | hash
94 |
95 | R1cgSAGQ0T2tbgi/UyjivI5T1gY=
96 |
97 | optional
98 |
99 |
100 | Resources/de.lproj/SCWError.strings
101 |
102 | hash
103 |
104 | 3Qgzb3o/CIcGeoooxSh//86pCvI=
105 |
106 | optional
107 |
108 |
109 | Resources/de.lproj/SCWWindow.strings
110 |
111 | hash
112 |
113 | 3vxlgHLHesNQRlS+ndGX81eCmBM=
114 |
115 | optional
116 |
117 |
118 |
119 | rules
120 |
121 | ^Resources/
122 |
123 | ^Resources/.*\.lproj/
124 |
125 | optional
126 |
127 | weight
128 | 1000
129 |
130 | ^Resources/.*\.lproj/locversion.plist$
131 |
132 | omit
133 |
134 | weight
135 | 1100
136 |
137 | ^version.plist$
138 |
139 |
140 | rules2
141 |
142 | .*\.dSYM($|/)
143 |
144 | weight
145 | 11
146 |
147 | ^(.*/)?\.DS_Store$
148 |
149 | omit
150 |
151 | weight
152 | 2000
153 |
154 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
155 |
156 | nested
157 |
158 | weight
159 | 10
160 |
161 | ^.*
162 |
163 | ^Info\.plist$
164 |
165 | omit
166 |
167 | weight
168 | 20
169 |
170 | ^PkgInfo$
171 |
172 | omit
173 |
174 | weight
175 | 20
176 |
177 | ^Resources/
178 |
179 | weight
180 | 20
181 |
182 | ^Resources/.*\.lproj/
183 |
184 | optional
185 |
186 | weight
187 | 1000
188 |
189 | ^Resources/.*\.lproj/locversion.plist$
190 |
191 | omit
192 |
193 | weight
194 | 1100
195 |
196 | ^[^/]+$
197 |
198 | nested
199 |
200 | weight
201 | 10
202 |
203 | ^embedded\.provisionprofile$
204 |
205 | weight
206 | 20
207 |
208 | ^version\.plist$
209 |
210 | weight
211 | 20
212 |
213 |
214 |
215 |
216 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 2B08E65C1A6D6AEF00487406 /* CropImageWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2B08E65E1A6D6AEF00487406 /* CropImageWindow.xib */; };
11 | 2B08E6611A6D6AF800487406 /* ZoomImageWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2B08E6631A6D6AF800487406 /* ZoomImageWindow.xib */; };
12 | 2B08E67A1A6DBFD900487406 /* SPScannerCaptureWindow.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2B08E6791A6DBFD900487406 /* SPScannerCaptureWindow.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
13 | 2B1C2AF01A65E1E900EB881C /* CropImageWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B1C2AEE1A65E1E900EB881C /* CropImageWindow.m */; };
14 | 2B1C2AF51A65E1FB00EB881C /* ZoomImageWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B1C2AF31A65E1FB00EB881C /* ZoomImageWindow.m */; };
15 | 2B24827E1A5AE0EE000C1F7A /* CaptureWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B24827C1A5AE0EE000C1F7A /* CaptureWindow.m */; };
16 | 2B2482851A5AE1D2000C1F7A /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B2482841A5AE1D2000C1F7A /* Quartz.framework */; };
17 | 2B2482871A5AE1FC000C1F7A /* animals.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 2B2482861A5AE1FC000C1F7A /* animals.jpg */; };
18 | 2B2482CB1A5B4656000C1F7A /* MultiSelectionSuite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B2482CA1A5B4656000C1F7A /* MultiSelectionSuite.framework */; };
19 | 2B7077C61A5AC3C000707A69 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B7077C51A5AC3C000707A69 /* AppDelegate.m */; };
20 | 2B7077C81A5AC3C000707A69 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B7077C71A5AC3C000707A69 /* main.m */; };
21 | 2B7077CA1A5AC3C000707A69 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2B7077C91A5AC3C000707A69 /* Images.xcassets */; };
22 | 2B9549161A5C0C5E00EB11A9 /* CaptureWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2B9549141A5C0C5E00EB11A9 /* CaptureWindow.xib */; };
23 | 2B9549181A5C0DAE00EB11A9 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2B95491A1A5C0DAE00EB11A9 /* MainMenu.xib */; };
24 | /* End PBXBuildFile section */
25 |
26 | /* Begin PBXCopyFilesBuildPhase section */
27 | 2B1C2AF71A65EBEB00EB881C /* CopyFiles */ = {
28 | isa = PBXCopyFilesBuildPhase;
29 | buildActionMask = 2147483647;
30 | dstPath = "";
31 | dstSubfolderSpec = 13;
32 | files = (
33 | 2B08E67A1A6DBFD900487406 /* SPScannerCaptureWindow.bundle in CopyFiles */,
34 | );
35 | runOnlyForDeploymentPostprocessing = 0;
36 | };
37 | /* End PBXCopyFilesBuildPhase section */
38 |
39 | /* Begin PBXFileReference section */
40 | 2B08E6501A6D697C00487406 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
41 | 2B08E6511A6D697C00487406 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/CaptureWindow.xib; sourceTree = ""; };
42 | 2B08E6531A6D698800487406 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/MainMenu.strings; sourceTree = ""; };
43 | 2B08E6551A6D698C00487406 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/CaptureWindow.strings; sourceTree = ""; };
44 | 2B08E65D1A6D6AEF00487406 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/CropImageWindow.xib; sourceTree = ""; };
45 | 2B08E6601A6D6AF200487406 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/CropImageWindow.strings; sourceTree = ""; };
46 | 2B08E6621A6D6AF800487406 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ZoomImageWindow.xib; sourceTree = ""; };
47 | 2B08E6651A6D6B5D00487406 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/ZoomImageWindow.strings; sourceTree = ""; };
48 | 2B08E6791A6DBFD900487406 /* SPScannerCaptureWindow.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = SPScannerCaptureWindow.bundle; path = Libs/SPScannerCaptureWindow.bundle; sourceTree = ""; };
49 | 2B1C2AED1A65E1E900EB881C /* CropImageWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CropImageWindow.h; sourceTree = ""; };
50 | 2B1C2AEE1A65E1E900EB881C /* CropImageWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CropImageWindow.m; sourceTree = ""; };
51 | 2B1C2AF21A65E1FB00EB881C /* ZoomImageWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZoomImageWindow.h; sourceTree = ""; };
52 | 2B1C2AF31A65E1FB00EB881C /* ZoomImageWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZoomImageWindow.m; sourceTree = ""; };
53 | 2B1C2AF81A65EBFF00EB881C /* SPScannerCaptureWindow.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = SPScannerCaptureWindow.bundle; path = "../../../../../../../Library/Developer/Xcode/DerivedData/SPScannerCaptureWindow-fcqkvrzpurajcdckqzbsffrhhfpq/Build/Products/Debug/SPScannerCaptureWindow.bundle"; sourceTree = ""; };
54 | 2B1C2B001A65ED3200EB881C /* SPWindowBundle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SPWindowBundle.h; sourceTree = ""; };
55 | 2B24827B1A5AE0EE000C1F7A /* CaptureWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CaptureWindow.h; sourceTree = ""; };
56 | 2B24827C1A5AE0EE000C1F7A /* CaptureWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CaptureWindow.m; sourceTree = ""; };
57 | 2B2482841A5AE1D2000C1F7A /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree = SDKROOT; };
58 | 2B2482861A5AE1FC000C1F7A /* animals.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = animals.jpg; sourceTree = ""; };
59 | 2B2482CA1A5B4656000C1F7A /* MultiSelectionSuite.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MultiSelectionSuite.framework; path = "../../../../../../Library/Developer/Xcode/DerivedData/MultiSelectionSuite-egxvbyyfhzsysaembhlgxpzaxisx/Build/Products/Debug/MultiSelectionSuite.framework"; sourceTree = ""; };
60 | 2B7077BF1A5AC3C000707A69 /* MultiSelectionSuiteApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MultiSelectionSuiteApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
61 | 2B7077C31A5AC3C000707A69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
62 | 2B7077C41A5AC3C000707A69 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
63 | 2B7077C51A5AC3C000707A69 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
64 | 2B7077C71A5AC3C000707A69 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
65 | 2B7077C91A5AC3C000707A69 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
66 | /* End PBXFileReference section */
67 |
68 | /* Begin PBXFrameworksBuildPhase section */
69 | 2B7077BC1A5AC3C000707A69 /* Frameworks */ = {
70 | isa = PBXFrameworksBuildPhase;
71 | buildActionMask = 2147483647;
72 | files = (
73 | 2B2482CB1A5B4656000C1F7A /* MultiSelectionSuite.framework in Frameworks */,
74 | 2B2482851A5AE1D2000C1F7A /* Quartz.framework in Frameworks */,
75 | );
76 | runOnlyForDeploymentPostprocessing = 0;
77 | };
78 | /* End PBXFrameworksBuildPhase section */
79 |
80 | /* Begin PBXGroup section */
81 | 2B1C2AFA1A65EC1300EB881C /* Crop */ = {
82 | isa = PBXGroup;
83 | children = (
84 | 2B1C2AED1A65E1E900EB881C /* CropImageWindow.h */,
85 | 2B1C2AEE1A65E1E900EB881C /* CropImageWindow.m */,
86 | 2B08E65E1A6D6AEF00487406 /* CropImageWindow.xib */,
87 | );
88 | name = Crop;
89 | sourceTree = "";
90 | };
91 | 2B1C2AFB1A65EC2000EB881C /* Zoom */ = {
92 | isa = PBXGroup;
93 | children = (
94 | 2B1C2AF21A65E1FB00EB881C /* ZoomImageWindow.h */,
95 | 2B1C2AF31A65E1FB00EB881C /* ZoomImageWindow.m */,
96 | 2B08E6631A6D6AF800487406 /* ZoomImageWindow.xib */,
97 | );
98 | name = Zoom;
99 | sourceTree = "";
100 | };
101 | 2B1C2AFC1A65EC2600EB881C /* Scan */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 2B1C2B001A65ED3200EB881C /* SPWindowBundle.h */,
105 | 2B1C2AF81A65EBFF00EB881C /* SPScannerCaptureWindow.bundle */,
106 | );
107 | name = Scan;
108 | sourceTree = "";
109 | };
110 | 2B7077B61A5AC3C000707A69 = {
111 | isa = PBXGroup;
112 | children = (
113 | 2B08E6791A6DBFD900487406 /* SPScannerCaptureWindow.bundle */,
114 | 2B2482CA1A5B4656000C1F7A /* MultiSelectionSuite.framework */,
115 | 2B2482841A5AE1D2000C1F7A /* Quartz.framework */,
116 | 2B7077C11A5AC3C000707A69 /* MultiSelectionSuiteApp */,
117 | 2B7077C01A5AC3C000707A69 /* Products */,
118 | );
119 | sourceTree = "";
120 | };
121 | 2B7077C01A5AC3C000707A69 /* Products */ = {
122 | isa = PBXGroup;
123 | children = (
124 | 2B7077BF1A5AC3C000707A69 /* MultiSelectionSuiteApp.app */,
125 | );
126 | name = Products;
127 | sourceTree = "";
128 | };
129 | 2B7077C11A5AC3C000707A69 /* MultiSelectionSuiteApp */ = {
130 | isa = PBXGroup;
131 | children = (
132 | 2B1C2AFC1A65EC2600EB881C /* Scan */,
133 | 2B1C2AFB1A65EC2000EB881C /* Zoom */,
134 | 2B1C2AFA1A65EC1300EB881C /* Crop */,
135 | 2B95491A1A5C0DAE00EB11A9 /* MainMenu.xib */,
136 | 2B9549141A5C0C5E00EB11A9 /* CaptureWindow.xib */,
137 | 2B24827B1A5AE0EE000C1F7A /* CaptureWindow.h */,
138 | 2B24827C1A5AE0EE000C1F7A /* CaptureWindow.m */,
139 | 2B7077C41A5AC3C000707A69 /* AppDelegate.h */,
140 | 2B7077C51A5AC3C000707A69 /* AppDelegate.m */,
141 | 2B7077C91A5AC3C000707A69 /* Images.xcassets */,
142 | 2B7077C21A5AC3C000707A69 /* Supporting Files */,
143 | );
144 | path = MultiSelectionSuiteApp;
145 | sourceTree = "";
146 | };
147 | 2B7077C21A5AC3C000707A69 /* Supporting Files */ = {
148 | isa = PBXGroup;
149 | children = (
150 | 2B2482861A5AE1FC000C1F7A /* animals.jpg */,
151 | 2B7077C31A5AC3C000707A69 /* Info.plist */,
152 | 2B7077C71A5AC3C000707A69 /* main.m */,
153 | );
154 | name = "Supporting Files";
155 | sourceTree = "";
156 | };
157 | /* End PBXGroup section */
158 |
159 | /* Begin PBXNativeTarget section */
160 | 2B7077BE1A5AC3C000707A69 /* MultiSelectionSuiteApp */ = {
161 | isa = PBXNativeTarget;
162 | buildConfigurationList = 2B7077DC1A5AC3C000707A69 /* Build configuration list for PBXNativeTarget "MultiSelectionSuiteApp" */;
163 | buildPhases = (
164 | 2B7077BB1A5AC3C000707A69 /* Sources */,
165 | 2B7077BC1A5AC3C000707A69 /* Frameworks */,
166 | 2B7077BD1A5AC3C000707A69 /* Resources */,
167 | 2B1C2AF71A65EBEB00EB881C /* CopyFiles */,
168 | );
169 | buildRules = (
170 | );
171 | dependencies = (
172 | );
173 | name = MultiSelectionSuiteApp;
174 | productName = MultiSelectionSuiteApp;
175 | productReference = 2B7077BF1A5AC3C000707A69 /* MultiSelectionSuiteApp.app */;
176 | productType = "com.apple.product-type.application";
177 | };
178 | /* End PBXNativeTarget section */
179 |
180 | /* Begin PBXProject section */
181 | 2B7077B71A5AC3C000707A69 /* Project object */ = {
182 | isa = PBXProject;
183 | attributes = {
184 | LastUpgradeCheck = 0610;
185 | ORGANIZATIONNAME = "Sascha Paulus";
186 | TargetAttributes = {
187 | 2B7077BE1A5AC3C000707A69 = {
188 | CreatedOnToolsVersion = 6.1;
189 | };
190 | };
191 | };
192 | buildConfigurationList = 2B7077BA1A5AC3C000707A69 /* Build configuration list for PBXProject "MultiSelectionSuiteApp" */;
193 | compatibilityVersion = "Xcode 3.2";
194 | developmentRegion = English;
195 | hasScannedForEncodings = 0;
196 | knownRegions = (
197 | en,
198 | de,
199 | Base,
200 | );
201 | mainGroup = 2B7077B61A5AC3C000707A69;
202 | productRefGroup = 2B7077C01A5AC3C000707A69 /* Products */;
203 | projectDirPath = "";
204 | projectRoot = "";
205 | targets = (
206 | 2B7077BE1A5AC3C000707A69 /* MultiSelectionSuiteApp */,
207 | );
208 | };
209 | /* End PBXProject section */
210 |
211 | /* Begin PBXResourcesBuildPhase section */
212 | 2B7077BD1A5AC3C000707A69 /* Resources */ = {
213 | isa = PBXResourcesBuildPhase;
214 | buildActionMask = 2147483647;
215 | files = (
216 | 2B08E6611A6D6AF800487406 /* ZoomImageWindow.xib in Resources */,
217 | 2B7077CA1A5AC3C000707A69 /* Images.xcassets in Resources */,
218 | 2B9549181A5C0DAE00EB11A9 /* MainMenu.xib in Resources */,
219 | 2B9549161A5C0C5E00EB11A9 /* CaptureWindow.xib in Resources */,
220 | 2B08E65C1A6D6AEF00487406 /* CropImageWindow.xib in Resources */,
221 | 2B2482871A5AE1FC000C1F7A /* animals.jpg in Resources */,
222 | );
223 | runOnlyForDeploymentPostprocessing = 0;
224 | };
225 | /* End PBXResourcesBuildPhase section */
226 |
227 | /* Begin PBXSourcesBuildPhase section */
228 | 2B7077BB1A5AC3C000707A69 /* Sources */ = {
229 | isa = PBXSourcesBuildPhase;
230 | buildActionMask = 2147483647;
231 | files = (
232 | 2B7077C81A5AC3C000707A69 /* main.m in Sources */,
233 | 2B1C2AF51A65E1FB00EB881C /* ZoomImageWindow.m in Sources */,
234 | 2B7077C61A5AC3C000707A69 /* AppDelegate.m in Sources */,
235 | 2B24827E1A5AE0EE000C1F7A /* CaptureWindow.m in Sources */,
236 | 2B1C2AF01A65E1E900EB881C /* CropImageWindow.m in Sources */,
237 | );
238 | runOnlyForDeploymentPostprocessing = 0;
239 | };
240 | /* End PBXSourcesBuildPhase section */
241 |
242 | /* Begin PBXVariantGroup section */
243 | 2B08E65E1A6D6AEF00487406 /* CropImageWindow.xib */ = {
244 | isa = PBXVariantGroup;
245 | children = (
246 | 2B08E65D1A6D6AEF00487406 /* Base */,
247 | 2B08E6601A6D6AF200487406 /* de */,
248 | );
249 | name = CropImageWindow.xib;
250 | sourceTree = "";
251 | };
252 | 2B08E6631A6D6AF800487406 /* ZoomImageWindow.xib */ = {
253 | isa = PBXVariantGroup;
254 | children = (
255 | 2B08E6621A6D6AF800487406 /* Base */,
256 | 2B08E6651A6D6B5D00487406 /* de */,
257 | );
258 | name = ZoomImageWindow.xib;
259 | sourceTree = "";
260 | };
261 | 2B9549141A5C0C5E00EB11A9 /* CaptureWindow.xib */ = {
262 | isa = PBXVariantGroup;
263 | children = (
264 | 2B08E6511A6D697C00487406 /* Base */,
265 | 2B08E6551A6D698C00487406 /* de */,
266 | );
267 | name = CaptureWindow.xib;
268 | sourceTree = "";
269 | };
270 | 2B95491A1A5C0DAE00EB11A9 /* MainMenu.xib */ = {
271 | isa = PBXVariantGroup;
272 | children = (
273 | 2B08E6501A6D697C00487406 /* Base */,
274 | 2B08E6531A6D698800487406 /* de */,
275 | );
276 | name = MainMenu.xib;
277 | sourceTree = "";
278 | };
279 | /* End PBXVariantGroup section */
280 |
281 | /* Begin XCBuildConfiguration section */
282 | 2B7077DA1A5AC3C000707A69 /* Debug */ = {
283 | isa = XCBuildConfiguration;
284 | buildSettings = {
285 | ALWAYS_SEARCH_USER_PATHS = NO;
286 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
287 | CLANG_CXX_LIBRARY = "libc++";
288 | CLANG_ENABLE_MODULES = YES;
289 | CLANG_ENABLE_OBJC_ARC = YES;
290 | CLANG_WARN_BOOL_CONVERSION = YES;
291 | CLANG_WARN_CONSTANT_CONVERSION = YES;
292 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
293 | CLANG_WARN_EMPTY_BODY = YES;
294 | CLANG_WARN_ENUM_CONVERSION = YES;
295 | CLANG_WARN_INT_CONVERSION = YES;
296 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
297 | CLANG_WARN_UNREACHABLE_CODE = YES;
298 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
299 | CODE_SIGN_IDENTITY = "-";
300 | COPY_PHASE_STRIP = NO;
301 | ENABLE_STRICT_OBJC_MSGSEND = YES;
302 | GCC_C_LANGUAGE_STANDARD = gnu99;
303 | GCC_DYNAMIC_NO_PIC = NO;
304 | GCC_OPTIMIZATION_LEVEL = 0;
305 | GCC_PREPROCESSOR_DEFINITIONS = (
306 | "DEBUG=1",
307 | "$(inherited)",
308 | );
309 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
310 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
311 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
312 | GCC_WARN_UNDECLARED_SELECTOR = YES;
313 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
314 | GCC_WARN_UNUSED_FUNCTION = YES;
315 | GCC_WARN_UNUSED_VARIABLE = YES;
316 | HEADER_SEARCH_PATHS = (
317 | "$(inherited)",
318 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
319 | );
320 | MACOSX_DEPLOYMENT_TARGET = 10.8;
321 | MTL_ENABLE_DEBUG_INFO = YES;
322 | ONLY_ACTIVE_ARCH = YES;
323 | SDKROOT = macosx;
324 | };
325 | name = Debug;
326 | };
327 | 2B7077DB1A5AC3C000707A69 /* Release */ = {
328 | isa = XCBuildConfiguration;
329 | buildSettings = {
330 | ALWAYS_SEARCH_USER_PATHS = NO;
331 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
332 | CLANG_CXX_LIBRARY = "libc++";
333 | CLANG_ENABLE_MODULES = YES;
334 | CLANG_ENABLE_OBJC_ARC = YES;
335 | CLANG_WARN_BOOL_CONVERSION = YES;
336 | CLANG_WARN_CONSTANT_CONVERSION = YES;
337 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
338 | CLANG_WARN_EMPTY_BODY = YES;
339 | CLANG_WARN_ENUM_CONVERSION = YES;
340 | CLANG_WARN_INT_CONVERSION = YES;
341 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
342 | CLANG_WARN_UNREACHABLE_CODE = YES;
343 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
344 | CODE_SIGN_IDENTITY = "-";
345 | COPY_PHASE_STRIP = YES;
346 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
347 | ENABLE_NS_ASSERTIONS = NO;
348 | ENABLE_STRICT_OBJC_MSGSEND = YES;
349 | GCC_C_LANGUAGE_STANDARD = gnu99;
350 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
351 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
352 | GCC_WARN_UNDECLARED_SELECTOR = YES;
353 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
354 | GCC_WARN_UNUSED_FUNCTION = YES;
355 | GCC_WARN_UNUSED_VARIABLE = YES;
356 | HEADER_SEARCH_PATHS = (
357 | "$(inherited)",
358 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
359 | );
360 | MACOSX_DEPLOYMENT_TARGET = 10.8;
361 | MTL_ENABLE_DEBUG_INFO = NO;
362 | SDKROOT = macosx;
363 | };
364 | name = Release;
365 | };
366 | 2B7077DD1A5AC3C000707A69 /* Debug */ = {
367 | isa = XCBuildConfiguration;
368 | buildSettings = {
369 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
370 | COMBINE_HIDPI_IMAGES = YES;
371 | FRAMEWORK_SEARCH_PATHS = (
372 | "$(inherited)",
373 | /Users/sascha/Desktop,
374 | "$(PROJECT_DIR)",
375 | "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/MultiSelectionSuite-daemarwshbwuqqaxicrxiitewggc/Build/Products/Debug",
376 | "$(LOCAL_LIBRARY_DIR)/Frameworks",
377 | /Users/sascha/DATEN/DEV/Mac/OpenSource/MultiSelectionSuite/MultiSelectionSuiteFramework/build/Debug,
378 | "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/MultiSelectionSuite-egxvbyyfhzsysaembhlgxpzaxisx/Build/Products/Debug",
379 | );
380 | INFOPLIST_FILE = MultiSelectionSuiteApp/Info.plist;
381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
382 | PRODUCT_NAME = "$(TARGET_NAME)";
383 | };
384 | name = Debug;
385 | };
386 | 2B7077DE1A5AC3C000707A69 /* Release */ = {
387 | isa = XCBuildConfiguration;
388 | buildSettings = {
389 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
390 | COMBINE_HIDPI_IMAGES = YES;
391 | FRAMEWORK_SEARCH_PATHS = (
392 | "$(inherited)",
393 | /Users/sascha/Desktop,
394 | "$(PROJECT_DIR)",
395 | "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/MultiSelectionSuite-daemarwshbwuqqaxicrxiitewggc/Build/Products/Debug",
396 | "$(LOCAL_LIBRARY_DIR)/Frameworks",
397 | /Users/sascha/DATEN/DEV/Mac/OpenSource/MultiSelectionSuite/MultiSelectionSuiteFramework/build/Debug,
398 | "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/MultiSelectionSuite-egxvbyyfhzsysaembhlgxpzaxisx/Build/Products/Debug",
399 | );
400 | INFOPLIST_FILE = MultiSelectionSuiteApp/Info.plist;
401 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
402 | PRODUCT_NAME = "$(TARGET_NAME)";
403 | };
404 | name = Release;
405 | };
406 | /* End XCBuildConfiguration section */
407 |
408 | /* Begin XCConfigurationList section */
409 | 2B7077BA1A5AC3C000707A69 /* Build configuration list for PBXProject "MultiSelectionSuiteApp" */ = {
410 | isa = XCConfigurationList;
411 | buildConfigurations = (
412 | 2B7077DA1A5AC3C000707A69 /* Debug */,
413 | 2B7077DB1A5AC3C000707A69 /* Release */,
414 | );
415 | defaultConfigurationIsVisible = 0;
416 | defaultConfigurationName = Release;
417 | };
418 | 2B7077DC1A5AC3C000707A69 /* Build configuration list for PBXNativeTarget "MultiSelectionSuiteApp" */ = {
419 | isa = XCConfigurationList;
420 | buildConfigurations = (
421 | 2B7077DD1A5AC3C000707A69 /* Debug */,
422 | 2B7077DE1A5AC3C000707A69 /* Release */,
423 | );
424 | defaultConfigurationIsVisible = 0;
425 | defaultConfigurationName = Release;
426 | };
427 | /* End XCConfigurationList section */
428 | };
429 | rootObject = 2B7077B71A5AC3C000707A69 /* Project object */;
430 | }
431 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp.xcodeproj/project.xcworkspace/xcuserdata/sascha.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteApp/MultiSelectionSuiteApp.xcodeproj/project.xcworkspace/xcuserdata/sascha.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp.xcodeproj/xcuserdata/sascha.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp.xcodeproj/xcuserdata/sascha.xcuserdatad/xcschemes/MultiSelectionSuiteApp.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp.xcodeproj/xcuserdata/sascha.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MultiSelectionSuiteApp.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 2B7077BE1A5AC3C000707A69
16 |
17 | primary
18 |
19 |
20 | 2B7077D11A5AC3C000707A69
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/AppDelegate.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 |
4 | @class CaptureWindow;
5 |
6 | @interface AppDelegate : NSObject
7 |
8 | @property CaptureWindow *window;
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/AppDelegate.m:
--------------------------------------------------------------------------------
1 |
2 |
3 | #import "AppDelegate.h"
4 | #import "CaptureWindow.h"
5 |
6 | @interface AppDelegate ()
7 |
8 | @end
9 |
10 |
11 | @implementation AppDelegate
12 |
13 | @synthesize window;
14 |
15 | - (void)awakeFromNib {
16 |
17 |
18 | }
19 |
20 |
21 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
22 |
23 | if (!window) {
24 | window = [[CaptureWindow alloc] initWithWindowNibName:@"CaptureWindow"];
25 | }
26 | [window showWindow:nil];
27 |
28 | }
29 |
30 |
31 |
32 | - (void)applicationWillTerminate:(NSNotification *)aNotification {
33 | // Insert code here to tear down your application
34 | }
35 |
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/Base.lproj/CaptureWindow.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
33 |
43 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/Base.lproj/CropImageWindow.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 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/Base.lproj/ZoomImageWindow.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 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/CaptureWindow.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | CaptureWindow.h
5 | ------------------------------------------------------------------------------------
6 | Just the window controller from where everything begins.
7 | Tipp: For a quick start please read the README document.
8 | ------------------------------------------------------------------------------------
9 |
10 | The MIT License (MIT)
11 |
12 | Copyright (c) 2014 Sascha Paulus
13 |
14 | Permission is hereby granted, free of charge, to any person obtaining a copy
15 | of this software and associated documentation files (the "Software"), to deal
16 | in the Software without restriction, including without limitation the rights
17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 | copies of the Software, and to permit persons to whom the Software is
19 | furnished to do so, subject to the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be included in all
22 | copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 | SOFTWARE.
31 |
32 | */
33 |
34 | #import
35 | #import "CropImageWindow.h"
36 | #import "ZoomImageWindow.h"
37 | #import "SPWindowBundle.h"
38 |
39 | @interface CaptureWindow : NSWindowController
40 |
41 | @property (nonatomic) NSWindowController *cropImageWindow;
42 | @property (nonatomic) NSWindowController *zoomImageWindow;
43 |
44 | - (IBAction)cropImage:(id)sender;
45 | - (IBAction)zoomImage:(id)sender;
46 | - (IBAction)scanWindow:(id)sender;
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/CaptureWindow.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | CaptureWindow.m
5 | ------------------------------------------------------------------------------------
6 | Just the window controller from where everything begins.
7 | Tipp: For a quick start please read the README document.
8 | ------------------------------------------------------------------------------------
9 |
10 | The MIT License (MIT)
11 |
12 | Copyright (c) 2014 Sascha Paulus
13 |
14 | Permission is hereby granted, free of charge, to any person obtaining a copy
15 | of this software and associated documentation files (the "Software"), to deal
16 | in the Software without restriction, including without limitation the rights
17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 | copies of the Software, and to permit persons to whom the Software is
19 | furnished to do so, subject to the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be included in all
22 | copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 | SOFTWARE.
31 |
32 | */
33 |
34 |
35 | #import "CaptureWindow.h"
36 |
37 | @interface CaptureWindow ()
38 | @property (nonatomic,strong) SPWindowBundle *scanBundle;
39 | @end
40 |
41 | @implementation CaptureWindow
42 |
43 | - (void)cropImage:(id)sender {
44 |
45 | if(!self.cropImageWindow) {
46 | self.cropImageWindow = [[CropImageWindow alloc] init];
47 | }
48 | [self.cropImageWindow showWindow:self];
49 |
50 | }
51 |
52 |
53 | - (void)zoomImage:(id)sender {
54 | if(!self.zoomImageWindow) {
55 | self.zoomImageWindow = [[ZoomImageWindow alloc] init];
56 | }
57 | [self.zoomImageWindow showWindow:self];
58 |
59 | }
60 |
61 | - (void)scanWindow:(id)sender {
62 |
63 | NSURL *pluginUrl = [[[NSBundle mainBundle] builtInPlugInsURL] URLByAppendingPathComponent:@"SPScannerCaptureWindow.bundle"];
64 |
65 | NSBundle *scannerBundle = [NSBundle bundleWithURL:pluginUrl];
66 |
67 | id currInstance;
68 | Class currPrincipalClass = [scannerBundle principalClass];
69 | if (currPrincipalClass) {
70 | currInstance = [[currPrincipalClass alloc] init];
71 | }
72 |
73 |
74 | if(currInstance) {
75 | self.scanBundle = (SPWindowBundle *)currInstance;
76 | [self.scanBundle openWindowWithDelegate:self asSheet:YES];
77 | }
78 |
79 | }
80 |
81 | #pragma mark - ScannerCaptureWindowDelegate
82 |
83 | - (void)saveContentElements:(NSArray *)elements withProperties:(NSDictionary *)properties {
84 | NSLog(@"Your scanned Images are here: saveContentElements");
85 | }
86 |
87 | @end
88 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/CropImageWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // CropImageWindow.h
3 | // MultiSelectionSuiteApp
4 | //
5 | // Created by Sascha Paulus on 14.01.15.
6 | // Copyright (c) 2015 Sascha Paulus. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface CropImageWindow : NSWindowController
13 |
14 | @property (nonatomic) IBOutlet NSImageView *imageView;
15 | @property (nonatomic) IBOutlet MSSImageExtractor *imageExtractor;
16 |
17 | - (IBAction)saveImages:(id)sender;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/CropImageWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // CropImageWindow.m
3 | // MultiSelectionSuiteApp
4 | //
5 | // Created by Sascha Paulus on 14.01.15.
6 | // Copyright (c) 2015 Sascha Paulus. All rights reserved.
7 | //
8 |
9 | #import "CropImageWindow.h"
10 |
11 | @interface CropImageWindow ()
12 |
13 | @end
14 |
15 | @implementation CropImageWindow
16 |
17 | @synthesize imageExtractor;
18 |
19 | - (NSString *)windowNibName {
20 | return @"CropImageWindow";
21 | }
22 |
23 | - (void)awakeFromNib {
24 |
25 | // Set an example image
26 | NSImage *exampleImage = [NSImage imageNamed:@"animals"];
27 | [self.imageView setImage:exampleImage];
28 |
29 | }
30 |
31 | #pragma mark - MSSExtractorDelegate
32 |
33 | - (void) extractor:(MSSExtractor*)extractor extractElement:(id)element forJob:(NSString*)identifier {
34 |
35 | if ([element isKindOfClass:[NSImage class]]) {
36 |
37 | // NSImage *image = (NSImage*)element;
38 |
39 | if ([identifier isEqualToString:MSSExtractorJobCropping]) {
40 |
41 | }
42 | }
43 |
44 |
45 | }
46 |
47 |
48 | - (void) extractor:(MSSExtractor*)extractor didCompleteWithError:(NSError*)error {
49 |
50 | if(error == nil) {
51 |
52 | // If everything is good ask extractor to save the images
53 | NSOpenPanel *openDialog = [NSOpenPanel openPanel];
54 | [openDialog setCanChooseDirectories:YES];
55 | [openDialog setCanChooseFiles:NO];
56 | [openDialog setAllowsMultipleSelection:NO];
57 | if( [openDialog runModal] == NSModalResponseOK) {
58 | [extractor setSaveDirectory:[openDialog directoryURL]];
59 | for(NSImage *image in extractor.elements) {
60 | [extractor saveImage:image withType:NSJPEGFileType compression:ExtractorImageCompressionLevelNone];
61 | }
62 | }
63 |
64 | } else {
65 | [[NSAlert alertWithError:error] runModal];
66 | }
67 |
68 | }
69 |
70 | - (void) extractor:(MSSExtractor*)extractor didSaveImage:(NSURL*)fileUrl withError:(NSError*)error; {
71 | if(error) {
72 | [[NSAlert alertWithError:error] runModal];
73 | }
74 | }
75 |
76 | - (IBAction)saveImages:(id)sender {
77 | [self.imageExtractor prepareJob:MSSExtractorJobCropping];
78 | }
79 |
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/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 | }
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | com.saschapaulus.apps.mss
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 Sascha Paulus. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/SPWindowBundle.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | #import
4 |
5 | @protocol ScannerCaptureWindowDelegate
6 | - (void)saveContentElements:(NSArray *)elements withProperties:(NSDictionary*)properties;
7 | @end
8 |
9 |
10 | @interface SPWindowBundle : NSObject
11 |
12 | - (BOOL) openWindowWithDelegate:(id)delegate asSheet:(BOOL)sheet;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/ZoomImageWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZoomImageWindow.h
3 | // MultiSelectionSuiteApp
4 | //
5 | // Created by Sascha Paulus on 14.01.15.
6 | // Copyright (c) 2015 Sascha Paulus. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface ZoomImageWindow : NSWindowController
13 |
14 | @property (nonatomic) MSSCanvasController *zoomCanvasController;
15 | @property (nonatomic) MSSCanvas *zoomCanvas;
16 | @property (nonatomic) MSSZoomExtractor *zoomExtractor;
17 | @property (nonatomic) IBOutlet NSImageView *sourceView;
18 | @property (nonatomic) IBOutlet NSImageView *zoomTargetView;
19 | @property (nonatomic) IBOutlet MSSSelectorStyle *zoomSelectorStyle;
20 | @property (nonatomic) IBOutlet MSSHandleStyle *zoomHandleStyle;
21 |
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/ZoomImageWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZoomImageWindow.m
3 | // MultiSelectionSuiteApp
4 | //
5 | // Created by Sascha Paulus on 14.01.15.
6 | // Copyright (c) 2015 Sascha Paulus. All rights reserved.
7 | //
8 |
9 | #import "ZoomImageWindow.h"
10 |
11 | @interface ZoomImageWindow ()
12 |
13 | @end
14 |
15 | @implementation ZoomImageWindow
16 |
17 | @synthesize zoomCanvas;
18 | @synthesize zoomCanvasController;
19 | @synthesize zoomExtractor;
20 |
21 | - (NSString *)windowNibName {
22 | return @"ZoomImageWindow";
23 | }
24 |
25 |
26 | - (void)awakeFromNib {
27 |
28 |
29 | // Setup without interface builder
30 | self.zoomCanvas = [[MSSCanvas alloc] init];
31 | self.zoomCanvasController = [MSSCanvasController canvasControllerForCanvas:zoomCanvas withContentView:self.sourceView];
32 | [self.zoomCanvas setDelegate:zoomCanvasController];
33 | self.zoomExtractor = [[MSSZoomExtractor alloc] init];
34 | [self.zoomExtractor setCanvasController:zoomCanvasController];
35 | [self.zoomExtractor setDelegate:self];
36 | [self.zoomExtractor prepareJob:MSSExtractorJobZoom];
37 | [self.zoomCanvasController setSingleSelectionMode:YES];
38 | [self.zoomCanvasController setSelectorStyle:self.zoomSelectorStyle];
39 | [self.zoomCanvasController setHandleStyle:self.zoomHandleStyle];
40 | [self.zoomCanvasController setContentExtractor:self.zoomExtractor];
41 | }
42 |
43 | #pragma mark - MSSExtractorDelegate
44 |
45 | - (void) extractor:(MSSExtractor*)extractor extractElement:(id)element forJob:(NSString*)identifier {
46 |
47 | if ([element isKindOfClass:[NSImage class]]) {
48 |
49 | NSImage *image = (NSImage*)element;
50 |
51 | if(identifier == MSSExtractorJobZoom) {
52 | [self.zoomTargetView setImage:image];
53 | }
54 | }
55 |
56 |
57 | }
58 |
59 |
60 | - (void) extractor:(MSSExtractor*)extractor didCompleteWithError:(NSError*)error {
61 | }
62 |
63 | - (void) extractor:(MSSExtractor*)extractor didSaveImage:(NSURL*)fileUrl withError:(NSError*)error; {
64 | }
65 |
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/animals.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteApp/MultiSelectionSuiteApp/animals.jpg
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/de.lproj/CaptureWindow.strings:
--------------------------------------------------------------------------------
1 |
2 | /* Class = "NSButtonCell"; title = "Zoom Image"; ObjectID = "P77-cU-SBm"; */
3 | "P77-cU-SBm.title" = "Bild vergrößern";
4 |
5 | /* Class = "NSButtonCell"; title = "Scan"; ObjectID = "Vw1-me-1A6"; */
6 | "Vw1-me-1A6.title" = "Einscannen";
7 |
8 | /* Class = "NSButtonCell"; title = "Crop Image"; ObjectID = "y7c-44-Lgh"; */
9 | "y7c-44-Lgh.title" = "Bild zerschneiden";
10 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/de.lproj/CropImageWindow.strings:
--------------------------------------------------------------------------------
1 |
2 | /* Class = "NSWindow"; title = "Window"; ObjectID = "F0z-JX-Cv5"; */
3 | "F0z-JX-Cv5.title" = "Window";
4 |
5 | /* Class = "NSTextFieldCell"; title = "Hold ⌘ to add another selector. ⌘ + A to highlight all. ⌫ or ⌦ to delete highlighted selectors."; ObjectID = "JRj-H6-t4l"; */
6 | "JRj-H6-t4l.title" = "Halte ⌘ für eine weitere Auswahlbox. ⌘ + A um alle Boxen zu markieren. ⌫ oder ⌦ um markierte Boxen zu löschen.";
7 |
8 | /* Class = "NSButtonCell"; title = "Save"; ObjectID = "mKc-fU-U1a"; */
9 | "mKc-fU-U1a.title" = "Speichern";
10 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/de.lproj/MainMenu.strings:
--------------------------------------------------------------------------------
1 |
2 | /* Class = "NSMenuItem"; title = "MSS Demo App"; ObjectID = "1Xt-HY-uBw"; */
3 | "1Xt-HY-uBw.title" = "MSS Demo App";
4 |
5 | /* Class = "NSMenuItem"; title = "Quit"; ObjectID = "4sb-4s-VLi"; */
6 | "4sb-4s-VLi.title" = "Schließen";
7 |
8 | /* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
9 | "AYu-sK-qS6.title" = "Main Menu";
10 |
11 | /* Class = "NSMenu"; title = "MSS Demo App"; ObjectID = "uQy-DD-JDr"; */
12 | "uQy-DD-JDr.title" = "MSS Demo App";
13 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/de.lproj/ZoomImageWindow.strings:
--------------------------------------------------------------------------------
1 |
2 | /* Class = "NSWindow"; title = "Window"; ObjectID = "F0z-JX-Cv5"; */
3 | "F0z-JX-Cv5.title" = "Window";
4 |
5 | /* Class = "NSTextFieldCell"; title = "Original"; ObjectID = "URH-hl-mUI"; */
6 | "URH-hl-mUI.title" = "Original";
7 |
8 | /* Class = "NSTextFieldCell"; title = "Zoom"; ObjectID = "pfa-VK-fsv"; */
9 | "pfa-VK-fsv.title" = "Vergrößerung";
10 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteApp/MultiSelectionSuiteApp/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // MultiSelectionSuiteApp
4 | //
5 | // Created by Sascha Paulus on 05.01.15.
6 | // Copyright (c) 2015 Sascha Paulus. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite.xcodeproj/project.xcworkspace/xcuserdata/sascha.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteFramework/MultiSelectionSuite.xcodeproj/project.xcworkspace/xcuserdata/sascha.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite.xcodeproj/project.xcworkspace/xcuserdata/sascha.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite.xcodeproj/xcuserdata/sascha.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite.xcodeproj/xcuserdata/sascha.xcuserdatad/xcschemes/MultiSelectionSuite.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite.xcodeproj/xcuserdata/sascha.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MultiSelectionSuite.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 2B24828E1A5AF9B9000C1F7A
16 |
17 | primary
18 |
19 |
20 | 2B7076CE1A5ABE4200707A69
21 |
22 | primary
23 |
24 |
25 | 2B7076D91A5ABE4200707A69
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/AddOns/Extractors/MSSExtractor.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSExtractor.h
5 | ------------------------------------------------------------------------------------
6 | The extractor is an Add-On for SelectorSuite to extract content from the contentView
7 | of the canvasController. It must be derived for each purpose like image cropping
8 | or scanning (see MSSImageExtractor or MSSScanExtractor).
9 | Tipp: For a quick start please read the README document.
10 | ------------------------------------------------------------------------------------
11 |
12 | The MIT License (MIT)
13 |
14 | Copyright (c) 2014 Sascha Paulus
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 |
34 | */
35 |
36 | #import
37 | #import "MSSCanvasController.h"
38 |
39 | @class MSSExtractor;
40 |
41 | /** Defines requirements for a controller object to receive feedback from a MSSExtractor */
42 | @protocol MSSExtractorDelegate
43 |
44 | /** Will be called whenever an element is extracted with a given key.
45 | @param extractor The extractor object from which the element comes
46 | @param element The fragment which has been return from the extractor
47 | @param identifier The name of the extraction job
48 | */
49 | - (void) extractor:(MSSExtractor*)extractor extractElement:(id)element forJob:(NSString*)identifier;
50 | /** Will be called when the extraction is completed
51 | @param extractor The extractor object which extraction has been completed
52 | @param error An error during the extraction (if occurred)
53 | */
54 | - (void) extractor:(MSSExtractor*)extractor didCompleteWithError:(NSError*)error;
55 | @optional
56 | /** Will be called whenever an image has been saved.
57 | @param extractor The extractor which has saved the image
58 | @param fileUrl The URL to the saved file
59 | @param error An error during the saving (if occurred)
60 | */
61 | - (void) extractor:(MSSExtractor*)extractor didSaveImage:(NSURL*)fileUrl withError:(NSError*)error;
62 |
63 | @end
64 |
65 |
66 | IB_DESIGNABLE
67 | /** Extracts content from the contentView of MSSCanvasController or its MSSCanvas. */
68 | @interface MSSExtractor : NSObject {
69 |
70 | }
71 | /** @name Delegation */
72 | /** The controller object to receive feedback from the extractor */
73 | @property (nonatomic) IBOutlet id delegate;
74 | /** @name Properties */
75 | /** Identifies for which extraction job the extracation element is created */
76 | @property (nonatomic, readonly) NSString *jobIdentifier;
77 | /** The ViewController which manages the canvas. */
78 | @property (nonatomic) IBOutlet MSSCanvasController *canvasController;
79 | /** A file prefix which the files will be saved with. */
80 | @property (nonatomic) IBInspectable NSString *filePrefix;
81 | /** The folder URL in which the files will be stored. */
82 | @property (nonatomic) NSURL *saveDirectory;
83 |
84 | /** @name Results */
85 | /** Holds the extracted elements. */
86 | @property (nonatomic, readonly) NSMutableArray *elements;
87 |
88 | /** @name Methods */
89 | /** Saves an image with a chosen file type
90 | @param image The image which should be saved
91 | @param fileType The type of image which should be created
92 | */
93 | - (BOOL) saveImage:(NSImage*)image withType:(NSBitmapImageFileType)fileType compression:(ExtractorImageCompressionLevel)compressionLevel;
94 | /** Extracts each selected part from the content holder. Returing elements are using the given identifier.
95 | @param identifier A unique identifier for the job in order to recognize corresponding return values
96 | */
97 | - (void) prepareJob:(NSString*)identifier;
98 | /** Sets the observation for changes on the canvas */
99 | - (void) setObservation;
100 | /** Will be called whenever an element is extracted.
101 | @param element The element which has been extracted
102 | @param error An error during the extraction (if occurred)
103 | */
104 | - (void) didExtractElement:(id)element withError:(NSError*)error;
105 |
106 | @end
107 |
108 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/AddOns/Extractors/MSSExtractor.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSExtractor.m
5 | ------------------------------------------------------------------------------------
6 | The extractor is an Add-On for SelectorSuite to extract content from the contentView
7 | of the canvasController. It must be derived for each purpose like image cropping
8 | or scanning (see MSSImageExtractor or MSSScanExtractor).
9 | Tipp: For a quick start please read the README document.
10 | ------------------------------------------------------------------------------------
11 |
12 | The MIT License (MIT)
13 |
14 | Copyright (c) 2014 Sascha Paulus
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 |
34 | */
35 |
36 | #import "MSSExtractor.h"
37 | #import "MSSError.h"
38 | #import "MSSPreferences.h"
39 |
40 | @implementation MSSExtractor
41 |
42 | @synthesize saveDirectory;
43 | @synthesize elements = _elements;
44 | @synthesize jobIdentifier = _jobIdentifier;
45 |
46 | #pragma mark - Init
47 |
48 | - (void) commonInit {
49 | _elements = [NSMutableArray array];
50 | [self setObservation];
51 | }
52 |
53 | -(instancetype)init {
54 | self = [super init];
55 | if (self) {
56 | [self commonInit];
57 | }
58 | return self;
59 | }
60 |
61 | #pragma mark - MSSCanvasEventSubscriber
62 |
63 | - (void) setObservation {
64 | return;
65 | }
66 |
67 | - (void)canvasHasChanged {
68 | return;
69 | }
70 |
71 | - (void)selectorHasChanged:(MSSSelector *)selector {
72 | return;
73 | }
74 |
75 |
76 | #pragma mark - Default methods
77 |
78 | - (void) prepareJob:(NSString*)identifier {
79 |
80 | _jobIdentifier = identifier;
81 | }
82 |
83 | - (BOOL) saveImage:(NSImage*)image withType:(NSBitmapImageFileType)fileType compression:(ExtractorImageCompressionLevel)compressionLevel {
84 |
85 |
86 | if(self.saveDirectory==nil) {
87 | NSDictionary *errorDesc = @{ NSLocalizedDescriptionKey : MSS_ERROR_DESC(MSSErrorNoSaveDirectory) };
88 | NSError *error = [NSError errorWithDomain:MSSErrorDomain code:MSSErrorNoSaveDirectory userInfo:errorDesc];
89 | [self.delegate extractor:self didSaveImage:nil withError:error];
90 | return NO;
91 | }
92 |
93 | if([[NSFileManager defaultManager] fileExistsAtPath:[self.saveDirectory path]]) {
94 | NSNumber *isDirectory;
95 | BOOL success = [self.saveDirectory getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];
96 | if(!success || ![isDirectory boolValue]) {
97 | NSDictionary *errorDesc = @{ NSLocalizedDescriptionKey : MSS_ERROR_DESC(MSSErrorSaveDirectoryNotExists) };
98 | NSError *error = [NSError errorWithDomain:MSSErrorDomain code:MSSErrorSaveDirectoryNotExists userInfo:errorDesc];
99 | [self.delegate extractor:self didSaveImage:nil withError:error];
100 | return NO;
101 | }
102 | } else {
103 | NSDictionary *errorDesc = @{ NSLocalizedDescriptionKey : MSS_ERROR_DESC(MSSErrorSaveDirectoryUrlIsNoDirectory) };
104 | NSError *error = [NSError errorWithDomain:MSSErrorDomain code:MSSErrorSaveDirectoryUrlIsNoDirectory userInfo:errorDesc];
105 | [self.delegate extractor:self didSaveImage:nil withError:error];
106 | return NO;
107 | }
108 |
109 | NSString *extention = nil;
110 |
111 | switch (fileType) {
112 | case NSPNGFileType:
113 | extention = @".png";
114 | break;
115 | case NSJPEGFileType:
116 | extention = @".jpg";
117 | break;
118 | case NSGIFFileType:
119 | extention = @".gif";
120 | break;
121 | case NSBMPFileType:
122 | extention = @".bmp";
123 | break;
124 | case NSTIFFFileType:
125 | extention = @".tiff";
126 | break;
127 | default:
128 | break;
129 | }
130 |
131 | if(extention!=nil) {
132 |
133 | int i = 0;
134 | NSURL *saveUrl = nil;
135 | while (saveUrl == nil || [[NSFileManager defaultManager] fileExistsAtPath:[saveUrl path]]) {
136 | i++;
137 | NSString *filename = [NSString stringWithFormat:@"%@%i%@",self.filePrefix,i,extention];
138 | saveUrl = [self.saveDirectory URLByAppendingPathComponent:filename];
139 | }
140 |
141 | CGFloat imageCompression = 1.0;
142 | NSError *error = nil;
143 | NSDictionary *options = nil;
144 | if(fileType == NSJPEGFileType) {
145 | switch (compressionLevel) {
146 | case ExtractorImageCompressionLevelLow:
147 | imageCompression = 0.8;
148 | break;
149 | case ExtractorImageCompressionLevelMiddle:
150 | imageCompression = 0.6;
151 | break;
152 | case ExtractorImageCompressionLevelHigh:
153 | imageCompression = 0.3;
154 | break;
155 | case ExtractorImageCompressionLevelHighest:
156 | imageCompression = 0.1;
157 | break;
158 | default:
159 | imageCompression = 1.0;
160 | break;
161 | }
162 | options = [NSDictionary dictionaryWithObjectsAndKeys:
163 | [NSNumber numberWithDouble:imageCompression], NSImageCompressionFactor,
164 | [NSNumber numberWithBool:NO], NSImageProgressive,
165 | nil];
166 | }
167 |
168 | NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]];
169 | NSData *fileData = [rep representationUsingType:fileType properties:options];
170 | [fileData writeToURL:saveUrl options:NSDataWritingWithoutOverwriting error:&error];
171 | if(error!=nil) {
172 | [self.delegate extractor:self didSaveImage:nil withError:error];
173 | NSDictionary *errorDesc = @{ NSLocalizedDescriptionKey : MSS_ERROR_DESC(MSSErrorImageSavingFailed) };
174 | NSError *error = [NSError errorWithDomain:MSSErrorDomain code:MSSErrorImageSavingFailed userInfo:errorDesc];
175 | [self.delegate extractor:self didSaveImage:nil withError:error];
176 | } else {
177 | [self.delegate extractor:self didSaveImage:saveUrl withError:nil];
178 | }
179 |
180 | } else {
181 |
182 | NSDictionary *errorDesc = @{ NSLocalizedDescriptionKey : MSS_ERROR_DESC(MSSErrorFileTypeNotSupportedYet) };
183 | NSError *error = [NSError errorWithDomain:MSSErrorDomain code:MSSErrorFileTypeNotSupportedYet userInfo:errorDesc];
184 | [self.delegate extractor:self didSaveImage:nil withError:error];
185 | return NO;
186 | }
187 |
188 | return YES;
189 | }
190 |
191 | #pragma mark - delegate notification
192 |
193 | - (void) didExtractElement:(id)element withError:(NSError*)error {
194 |
195 | if(error == nil && element != nil) {
196 | if(self.jobIdentifier == nil) _jobIdentifier = MSSExtractorJobUnknown;
197 | [_elements addObject:element];
198 | [self.delegate extractor:self extractElement:element forJob:self.jobIdentifier];
199 | } else {
200 | [self.delegate extractor:self didCompleteWithError:error];
201 | }
202 | }
203 |
204 |
205 |
206 |
207 | @end
208 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/AddOns/Extractors/MSSImageExtractor.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSImageExtractor.h
5 | ------------------------------------------------------------------------------------
6 | The extractor is an Add-On for SelectorSuite to extract content from the contentView
7 | of the canvasController. This derived version extracts image parts from the
8 | contentView's original image based on the selections.
9 | Tipp: For a quick start please read the README document.
10 | ------------------------------------------------------------------------------------
11 |
12 | The MIT License (MIT)
13 |
14 | Copyright (c) 2014 Sascha Paulus
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 |
34 | */
35 |
36 |
37 | #import
38 | #import "MSSExtractor.h"
39 |
40 | /** A concrete MSSExtractor class optimized for image cropping */
41 | @interface MSSImageExtractor : MSSExtractor
42 |
43 | /** @name States */
44 | /** Determines if everything is ready to save the selected parts. */
45 | @property (nonatomic) BOOL readyForSave;
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/AddOns/Extractors/MSSImageExtractor.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSImageExtractor.m
5 | ------------------------------------------------------------------------------------
6 | The extractor is an Add-On for SelectorSuite to extract content from the contentView
7 | of the canvasController. This derived version extracts image parts from the
8 | contentView's original image based on the selections.
9 | Tipp: For a quick start please read the README document.
10 | ------------------------------------------------------------------------------------
11 |
12 | The MIT License (MIT)
13 |
14 | Copyright (c) 2014 Sascha Paulus
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 |
34 | */
35 |
36 | #import "MSSImageExtractor.h"
37 | #import "MSSError.h"
38 | #import "MSSPreferences.h"
39 | #import "NSImageView+MSSScaledImage.h"
40 | #import "MSSSelector.h"
41 |
42 | @implementation MSSImageExtractor
43 |
44 | @synthesize readyForSave;
45 |
46 | #pragma mark - ReadyStates
47 |
48 | - (void)canvasHasChanged {
49 | [self setReadyForSave:self.canvasController.hasSelectors];
50 | }
51 |
52 |
53 | #pragma mark - MSSExtractor
54 |
55 | - (void) prepareJob:(NSString*)identifier {
56 |
57 | [super prepareJob:identifier];
58 |
59 | [self.elements removeAllObjects];
60 |
61 | if(!self.canvasController.hasSelectors) {
62 | NSDictionary *errorDesc = @{ NSLocalizedDescriptionKey : MSS_ERROR_DESC(MSSErrorNoSelections) };
63 | NSError *error = [NSError errorWithDomain:MSSErrorDomain code:MSSErrorNoSelections userInfo:errorDesc];
64 | [self didExtractElement:nil withError:error];
65 | return;
66 | }
67 |
68 | for(MSSSelector *selector in self.canvasController.selectors) {
69 |
70 | NSSize ratio = [(NSImageView*)self.canvasController.contentView originalImageRatio];
71 | CGFloat x = selector.frame.origin.x / ratio.width;
72 | CGFloat y = selector.frame.origin.y / ratio.height;
73 | CGFloat w = selector.frame.size.width / ratio.width;
74 | CGFloat h = selector.frame.size.height / ratio.height;
75 | NSRect sourceFrame = NSMakeRect(x, y, w, h);
76 | NSRect targetFrame = NSMakeRect(0, 0, w*1.0f, h*1.0f);
77 | NSImage *targetImage = [[NSImage alloc] initWithSize:targetFrame.size];
78 | if(targetImage.size.width > 0 && targetFrame.size.height > 0) {
79 | [targetImage lockFocus];
80 | [[(NSImageView*)self.canvasController.contentView originalImage] drawInRect:targetFrame fromRect:sourceFrame operation:NSCompositeCopy fraction:1.0f];
81 | [targetImage unlockFocus];
82 | [self didExtractElement:targetImage withError:nil];
83 | }
84 |
85 | }
86 |
87 | [self.delegate extractor:self didCompleteWithError:nil];
88 |
89 |
90 | }
91 |
92 |
93 |
94 | @end
95 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/AddOns/Extractors/MSSZoomExtractor.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | -----------------------------------------------------------------------------------------
4 | MSSZoomExtractor.h
5 | -----------------------------------------------------------------------------------------
6 | The extractor is an Add-On for SelectorSuite to extract content from the contentView
7 | of the canvasController. This derived version extracts one part from the contentView's
8 | original image based on the selection and "zooms" it by using the original size.
9 | Tipp: For a quick start please read the README document.
10 | -----------------------------------------------------------------------------------------
11 |
12 | The MIT License (MIT)
13 |
14 | Copyright (c) 2014 Sascha Paulus
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 |
34 | */
35 |
36 | #import "MSSExtractor.h"
37 |
38 | /** A concrete MSSExtractor class optimized for image zooming activities */
39 | @interface MSSZoomExtractor : MSSExtractor
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/AddOns/Extractors/MSSZoomExtractor.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | -----------------------------------------------------------------------------------------
4 | MSSZoomExtractor.m
5 | -----------------------------------------------------------------------------------------
6 | The extractor is an Add-On for SelectorSuite to extract content from the contentView
7 | of the canvasController. This derived version extracts one part from the contentView's
8 | original image based on the selection and "zooms" it by using the original size.
9 | Tipp: For a quick start please read the README document.
10 | -----------------------------------------------------------------------------------------
11 |
12 | The MIT License (MIT)
13 |
14 | Copyright (c) 2014 Sascha Paulus
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 |
34 | */
35 |
36 | #import "MSSZoomExtractor.h"
37 | #import "MSSError.h"
38 | #import "MSSPreferences.h"
39 | #import "NSImageView+MSSScaledImage.h"
40 | #import "MSSSelector.h"
41 |
42 | @implementation MSSZoomExtractor
43 |
44 | - (void) prepareJob:(NSString *)identifier {
45 | [super prepareJob:identifier];
46 | }
47 |
48 | - (void)selectorHasChanged:(MSSSelector *)selector {
49 |
50 | if(selector!=nil) {
51 |
52 | NSRect frame = [self.canvasController defaultRectForFrame:selector.frame];
53 | NSSize ratio = [(NSImageView*)self.canvasController.contentView originalImageRatio];
54 | CGFloat x = frame.origin.x / ratio.width;
55 | CGFloat y = frame.origin.y / ratio.height;
56 | CGFloat w = frame.size.width / ratio.width;
57 | CGFloat h = frame.size.height / ratio.height;
58 | NSRect sourceFrame = NSMakeRect(x, y, w, h);
59 | NSRect targetFrame = NSMakeRect(0, 0, w*1.0f, h*1.0f);
60 | NSImage *targetImage = [[NSImage alloc] initWithSize:targetFrame.size];
61 | if(targetImage.size.width > 0 && targetFrame.size.height > 0) {
62 | [targetImage lockFocus];
63 | [[(NSImageView*)self.canvasController.contentView originalImage] drawInRect:targetFrame fromRect:sourceFrame operation:NSCompositeCopy fraction:1.0f];
64 | [targetImage unlockFocus];
65 | [self didExtractElement:targetImage withError:nil];
66 |
67 | }
68 | }
69 | }
70 |
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSCanvas.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSCanvas.h
5 | ------------------------------------------------------------------------------------
6 | The canvas is a normal NSView which can add as subview on any other view.
7 | This is the place where the MSSSelector(s) are drawn. A canvas can have multiple
8 | selectors. The canvas is controlled by the canvasController who is responsible for
9 | almost every interaction between the canvas, the selectors and the mouse.
10 | The frame of the canvas will be arranged automatically.
11 | Tipp: For a quick start please read the README document.
12 | ------------------------------------------------------------------------------------
13 |
14 | The MIT License (MIT)
15 |
16 | Copyright (c) 2014 Sascha Paulus
17 |
18 | Permission is hereby granted, free of charge, to any person obtaining a copy
19 | of this software and associated documentation files (the "Software"), to deal
20 | in the Software without restriction, including without limitation the rights
21 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22 | copies of the Software, and to permit persons to whom the Software is
23 | furnished to do so, subject to the following conditions:
24 |
25 | The above copyright notice and this permission notice shall be included in all
26 | copies or substantial portions of the Software.
27 |
28 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 | SOFTWARE.
35 |
36 | */
37 |
38 | #import
39 | #import
40 | #import "MSSHandle.h"
41 | #import "MSSSelectorStyle.h"
42 | #import "MSSHandleStyle.h"
43 |
44 | @class MSSCanvas;
45 | @class MSSSelector;
46 | @class MSSExtractor;
47 |
48 | /** Defines requirements for an eventSubscriber object to receive events */
49 | @protocol MSSCanvasEventSubscriber
50 | /** @name Methods */
51 | /** Will be called whenever the canvas has changed */
52 | - (void) canvasHasChanged;
53 | /** Will be called wheneever a selector has changed
54 | @param selector The selector which has been changed
55 | */
56 | - (void) selectorHasChanged:(MSSSelector*)selector;
57 | @end
58 |
59 | /** Defines requirements for a controller object to manage a MSSCanvas */
60 | @protocol MSSCanvasDelegate
61 |
62 | /** @name Properties */
63 | /** Holds all selectors on the canvas */
64 | @property (nonatomic, readonly) NSArray *selectors;
65 | /** Determines the current selector */
66 | @property (atomic) IBOutlet MSSCanvas* view;
67 | /** Determines the chosen SelectorStyle */
68 | @property (nonatomic) IBOutlet MSSSelectorStyle *selectorStyle;
69 | /** Determines the chosen HandleStyle */
70 | @property (nonatomic) IBOutlet MSSHandleStyle *handleStyle;
71 | /** Determines if the canvas has selectors or not */
72 | @property (nonatomic, readonly) BOOL hasSelectors;
73 | /** The view with will contain the canvas as subview */
74 | @property (nonatomic) IBOutlet NSView *contentView;
75 | /** Determines the current selector */
76 | @property (nonatomic, readonly) MSSSelector *currentSelector;
77 | /** Determines if the canvas can have only one selector */
78 | @property (nonatomic) IBInspectable BOOL singleSelectionMode;
79 | /** The object which extracts the content from the contentView */
80 | @property (nonatomic) IBOutlet MSSExtractor *contentExtractor;
81 |
82 | /** @name Methods */
83 | /** Returns a frame with normal (lower-left) origin based on the current frame.
84 | @param frame The frame which should be normalized
85 | */
86 | - (NSRect) defaultRectForFrame:(NSRect)frame;
87 | /** Discards all selectors from the canvas which are marked as selected */
88 | - (void)removeAllSelectorsFromCanvas;
89 | /** Prepares to controller after a canvas has been set */
90 | - (void) prepareController;
91 |
92 | /** Creates a canvasController for a canvas and a contentView
93 | @param theCanvas The canvas to create a controller for
94 | @param theContentView The view (e.g. NSImageView) which provides the content
95 | */
96 | + (instancetype)canvasControllerForCanvas:(MSSCanvas*)theCanvas withContentView:(NSView*)theContentView;
97 |
98 | /** @name Eventhandling */
99 | - (void)mouseDown:(NSEvent *)theEvent;
100 | - (void)mouseDragged:(NSEvent *)theEvent;
101 | - (void)mouseUp:(NSEvent *)theEvent;
102 | - (void)keyDown:(NSEvent *)theEvent;
103 |
104 | @end
105 |
106 | IB_DESIGNABLE
107 | /** Represents a canvas view on which the selectors will be drawn */
108 | @interface MSSCanvas : NSView
109 | /** @name Delegation */
110 | /** The controller of the canvas */
111 | @property (nonatomic) IBOutlet id delegate;
112 | /** @name Properties */
113 | /** Determines if intersections between selections are allowed. (Default: YES) */
114 | @property (nonatomic) IBInspectable BOOL allowIntersections;
115 |
116 | @end
117 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSCanvas.m:
--------------------------------------------------------------------------------
1 |
2 | /*
3 |
4 | ------------------------------------------------------------------------------------
5 | MSSCanvas.m
6 | ------------------------------------------------------------------------------------
7 | The canvas is a normal NSView which can add as subview on any other view.
8 | This is the place where the MSSSelector(s) are drawn. A canvas can have multiple
9 | selectors. The canvas is controlled by the canvasController who is responsible for
10 | almost every interaction between the canvas, the selectors and the mouse.
11 | The frame of the canvas will be arranged automatically.
12 | Tipp: For a quick start please read the README document.
13 | ------------------------------------------------------------------------------------
14 |
15 | The MIT License (MIT)
16 |
17 | Copyright (c) 2014 Sascha Paulus
18 |
19 | Permission is hereby granted, free of charge, to any person obtaining a copy
20 | of this software and associated documentation files (the "Software"), to deal
21 | in the Software without restriction, including without limitation the rights
22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23 | copies of the Software, and to permit persons to whom the Software is
24 | furnished to do so, subject to the following conditions:
25 |
26 | The above copyright notice and this permission notice shall be included in all
27 | copies or substantial portions of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 | SOFTWARE.
36 |
37 | */
38 |
39 | #import "MSSCanvas.h"
40 | #import "MSSSelector.h"
41 | #import "MSSHandle.h"
42 |
43 |
44 | @implementation MSSCanvas
45 |
46 | #pragma mark - Redrawing
47 |
48 | - (void)awakeFromNib {
49 | self.allowIntersections = YES;
50 | }
51 |
52 | - (void)drawRect:(NSRect)dirtyRect {
53 |
54 | /** Draw all selectors */
55 | for (MSSSelector *selector in self.delegate.selectors) {
56 | [selector drawPath];
57 | }
58 | /** Draw the current selector (not part of self.delegate.selectors yet) */
59 | if(self.delegate.currentSelector) {
60 | [self.delegate.currentSelector drawPath];
61 | }
62 | }
63 |
64 | #pragma mark - Events
65 |
66 | - (void)mouseDown:(NSEvent *)theEvent {
67 | [self.delegate mouseDown:theEvent];
68 | }
69 |
70 | - (void)mouseUp:(NSEvent *)theEvent {
71 | [self.delegate mouseUp:theEvent];
72 | }
73 |
74 | - (void)mouseDragged:(NSEvent *)theEvent {
75 | [self.delegate mouseDragged:theEvent];
76 | }
77 |
78 | - (void)keyDown:(NSEvent *)theEvent {
79 | [self.delegate keyDown:theEvent];
80 | }
81 |
82 |
83 | #pragma First Responder
84 |
85 | - (BOOL)acceptsFirstResponder {
86 | return YES;
87 | }
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSCanvasController.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSCanvasController.h
5 | ------------------------------------------------------------------------------------
6 | The canvasController handles any interaction between the canvas, the mouse
7 | and other objects. The controller moves and resizes the canvas's selectors.
8 | Optional canvasController can provide the styles for the selectors and the handles.
9 | Tipp: For a quick start please read the README document.
10 | ------------------------------------------------------------------------------------
11 |
12 | The MIT License (MIT)
13 |
14 | Copyright (c) 2014 Sascha Paulus
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 |
34 | */
35 |
36 | #import
37 | #import "MSSCanvas.h"
38 | #import "MSSSelectorStyle.h"
39 | #import "MSSHandleStyle.h"
40 |
41 | @class MSSExtractor;
42 |
43 | IB_DESIGNABLE
44 | /** Represents a ViewController customized to control a MSSCanvas object */
45 | @interface MSSCanvasController : NSViewController
46 | /** @name Properties */
47 | /** Holds all selectors on the canvas */
48 | @property (nonatomic, readonly) NSArray *selectors;
49 | /** Determines the canvas */
50 | @property (atomic) IBOutlet MSSCanvas* view;
51 | /** Determines the chosen SelectorStyle */
52 | @property (nonatomic) IBOutlet MSSSelectorStyle *selectorStyle;
53 | /** Determines the chosen HandleStyle */
54 | @property (nonatomic) IBOutlet MSSHandleStyle *handleStyle;
55 | /** Determines if the canvas has selectors or not */
56 | @property (nonatomic, readonly) BOOL hasSelectors;
57 | /** The view with will contain the canvas as subview */
58 | @property (nonatomic) IBOutlet NSView *contentView;
59 | /** Determines if the canvas can have only one selector */
60 | @property (nonatomic) IBInspectable BOOL singleSelectionMode;
61 | /** The object which extracts the content from the contentView */
62 | @property (nonatomic) IBOutlet MSSExtractor *contentExtractor;
63 |
64 | /** @name Methods */
65 | - (NSRect) defaultRectForFrame:(NSRect)frame;
66 | - (void)removeAllSelectorsFromCanvas;
67 | - (void) prepareController;
68 | + (instancetype)canvasControllerForCanvas:(MSSCanvas*)theCanvas withContentView:(NSView*)theContentView;
69 |
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSCanvasController.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSCanvasController.m
5 | ------------------------------------------------------------------------------------
6 | The canvasController handles any interaction between the canvas, the mouse
7 | and other objects. The controller moves and resizes the canvas's selectors.
8 | Optional canvasController can provide the styles for the selectors and the handles.
9 | Tipp: For a quick start please read the README document.
10 | ------------------------------------------------------------------------------------
11 |
12 | The MIT License (MIT)
13 |
14 | Copyright (c) 2014 Sascha Paulus
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 | SOFTWARE.
33 |
34 | */
35 |
36 | #import "MSSCanvasController.h"
37 | #import "MSSSelector.h"
38 | #import "MSSHandle.h"
39 | #import "NSImageView+MSSScaledImage.h"
40 | #import "MSSExtractor.h"
41 |
42 | @interface MSSCanvasController ()
43 |
44 | /** All selectors */
45 | @property (nonatomic) NSMutableArray *_selectors;
46 | /** Current selector */
47 | @property (nonatomic) MSSSelector *currentSelector;
48 | /** Current handle */
49 | @property (nonatomic) MSSHandle *handle;
50 | /** Determines the canvas frame based on the contentView type */
51 | @property (nonatomic, readonly) NSRect canvasFrame;
52 |
53 | @property (nonatomic) BOOL cursorCanBeChanged;
54 |
55 |
56 | /** Marks all selectors as unselected and redraws canvas if needed
57 | @param redraw Selectors should be redrawn after change
58 | */
59 | - (void) markAllUnselected:(BOOL)redraw;
60 | /** Marks all selectors as selected and redraws canvas if needed
61 | @param redraw Selectors should be redrawn after change
62 | */
63 | - (void) markAllSelected:(BOOL)redraw;
64 | /** Discards all selectors from the canvas which are marked as selected */
65 | - (void) removeMarkedSelectorsFromCanvas;
66 | /** Creates a new selector and defines him as the current selector object
67 | @param frame The initial frame of the new selector
68 | */
69 | - (void) addSelectorWithFrame:(NSRect)frame;
70 | /** @abstract Creates a new picker selector and defines him as the current selector object.
71 |
72 | @discussion For more details about the distinction between picker and selector checkout the isPicker property of the MSSSelector class.
73 | @param frame The initial frame of the new picker
74 | */
75 | - (void) setPickerWithFrame:(NSRect)frame;
76 | /** Determines if the canvas has current selector object or not */
77 | - (BOOL) hasSelector;
78 | /** Sets or replaces the canvas in the view's subviews */
79 | - (void) arrangeCanvas;
80 | /** Reset the canvas and remove all selections */
81 | - (void) resetCanvas;
82 | /** Will be called whenever something on the contentView has changed
83 | @param notification The notification with information about the change
84 | */
85 | - (void) contentViewDidChange:(NSNotification*)notification;
86 |
87 |
88 | @end
89 |
90 | @implementation MSSCanvasController
91 |
92 | #pragma mark - Init
93 |
94 | - (instancetype)initWithCanvas:(MSSCanvas*)theCanvas withContentView:(NSView*)theContentView {
95 | self = [super init];
96 | if(self) {
97 | self.view = theCanvas;
98 | self.contentView = theContentView;
99 | [self prepareController];
100 | }
101 | return self;
102 | }
103 |
104 | + (instancetype)canvasControllerForCanvas:(MSSCanvas*)theCanvas withContentView:(NSView*)theContentView {
105 | return [[self alloc] initWithCanvas:theCanvas withContentView:theContentView];
106 | }
107 |
108 | - (void)awakeFromNib {
109 |
110 | [self prepareController];
111 | }
112 |
113 | - (void) prepareController {
114 |
115 | self.cursorCanBeChanged = YES;
116 |
117 | NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld;
118 |
119 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentViewDidChange:) name:NSViewFrameDidChangeNotification object:self.contentView];
120 |
121 | if([self.contentView isKindOfClass:[NSImageView class]]) {
122 |
123 | [(NSImageView*)self.contentView setRefusesFirstResponder:YES];
124 |
125 | NSArray *keyPaths = @[@"self.contentView.image",
126 | @"self.contentView.image.size",
127 | @"self.contentView.imageAlignment",
128 | @"self.contentView.imageFrameStyle",
129 | @"self.contentView.imageScaling"];
130 |
131 | for(NSString *keyPath in keyPaths) {
132 |
133 | [self addObserver:self forKeyPath:keyPath options:options context:NULL];
134 | }
135 | }
136 |
137 |
138 | self._selectors = [NSMutableArray array];
139 | self.currentSelector = nil;
140 |
141 | [self arrangeCanvas];
142 |
143 | }
144 |
145 |
146 | #pragma mark - Observation
147 |
148 | - (void) resetCanvas {
149 | [self removeAllSelectorsFromCanvas];
150 | [self arrangeCanvas];
151 | }
152 |
153 | - (void) contentViewDidChange:(NSNotification*)notification {
154 | [self resetCanvas];
155 | }
156 |
157 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
158 | {
159 | [self resetCanvas];
160 | }
161 |
162 | #pragma mark - Events
163 |
164 | /** @abstract If the left mouse button is pressed and no selector is on the canvas or the command key is pressed add a new selector to the canvas and define him as the current selector object. Otherwise determine if an existing selector has been touched. If yes, mark this selector as selected and define him as the current selector object. If not, create a picker selector.
165 | @param theEvent An object encapsulating information about the mouse-down event.
166 | @discussion For more details about the distinction between picker and selector checkout the isPicker property of the MSSSelector class.
167 | */
168 | - (void)mouseDown:(NSEvent *)theEvent {
169 |
170 | self.cursorCanBeChanged = NO;
171 | [self.view.window disableCursorRects];
172 |
173 | [self markAllUnselected:YES];
174 |
175 | NSPoint currentPoint = [self.view convertPoint:[theEvent locationInWindow] fromView:nil];
176 | NSRect initalFrame = NSMakeRect(currentPoint.x, currentPoint.y, 0, 0);
177 | self.currentSelector = nil;
178 |
179 | if(([theEvent modifierFlags] & NSCommandKeyMask) || self.selectors.count == 0) {
180 | [self addSelectorWithFrame:initalFrame];
181 | } else {
182 | BOOL didHitSelector = NO;
183 |
184 | for(MSSSelector *selector in self.selectors) {
185 | if((didHitSelector = [selector intersectsFrame:initalFrame])) {
186 | self.currentSelector = selector;
187 | [self.currentSelector touchedHandle:initalFrame];
188 | break;
189 | }
190 | }
191 | if(!didHitSelector) {
192 | [self setPickerWithFrame:initalFrame];
193 | }
194 | }
195 |
196 | [self.view setNeedsDisplay:YES];
197 | }
198 |
199 | /** If the left mouse button has been released and the canvas has selectors determine if the current selector object is a picker. If yes, mark every intersecting selection as selected. If not, try to drop the current selector object on the canvas. If this is not possible discard the current selector object.
200 | @param theEvent An object encapsulating information about the mouse-up event.
201 | */
202 | - (void)mouseUp:(NSEvent *)theEvent {
203 |
204 | self.cursorCanBeChanged = YES;
205 |
206 | if(self.hasSelector) {
207 | if(self.currentSelector.isPicker) {
208 | for(MSSSelector *selector in self.selectors) {
209 | [selector intersectsFrame:self.currentSelector.frame];
210 | }
211 | self.currentSelector = nil;
212 | } else {
213 | if(self.currentSelector.canDropOnCanvas) {
214 | [self performSelector:@selector(canvasHasChanged)];
215 |
216 | } else {
217 | [self._selectors removeObject:self.currentSelector];
218 | self.currentSelector = nil;
219 | }
220 | }
221 | }
222 | [self.view setNeedsDisplay:YES];
223 |
224 | }
225 |
226 |
227 | /** If the left mouse button is pressed, the mouse has been moved and the canvas has selectors execute the corresponding action of the current selection object.
228 | @param theEvent An object encapsulating information about the mouse-dragged event.
229 | */
230 | - (void)mouseDragged:(NSEvent *)theEvent {
231 |
232 | NSPoint currentPoint = [self.view convertPoint:[theEvent locationInWindow] fromView:nil];
233 |
234 | if(self.hasSelector) {
235 |
236 | if(self.currentSelector.action == SelectorActionInit || self.currentSelector.action == SelectorActionResize) {
237 | [self.currentSelector resizeToPoint:currentPoint];
238 | [self.view setNeedsDisplay:YES];
239 | if([self.currentSelector touchedBoundaries]) {
240 | [self.view setNeedsDisplay:YES];
241 | }
242 | } else if (self.currentSelector.action == SelectorActionMove) {
243 | [self.currentSelector moveSelectorToPoint:currentPoint];
244 | [self.view setNeedsDisplay:YES];
245 | if([self.currentSelector touchedBoundaries]) {
246 | [self.view setNeedsDisplay:YES];
247 | }
248 | }
249 | }
250 |
251 | }
252 |
253 | /** If the DEL or BACKSPACE key is pressed delete all as selected marked selections.
254 | If CMD + A key is pressed mark all selectors as selected.
255 | If the ESC key is pressed mark all selectors as unselected.
256 | @param theEvent An object encapsulating information about the key-down event.
257 | */
258 | - (void)keyDown:(NSEvent *)theEvent {
259 |
260 | if(theEvent.keyCode == 51 || theEvent.keyCode == 117) {
261 | [self removeMarkedSelectorsFromCanvas];
262 | } else if(theEvent.keyCode == 0 && theEvent.modifierFlags&NSCommandKeyMask) {
263 | [self markAllSelected:YES];
264 | } else if(theEvent.keyCode == 53) {
265 | [self markAllUnselected:YES];
266 | }
267 | }
268 |
269 | - (void)mouseEntered:(NSEvent *)theEvent {
270 | if(self.cursorCanBeChanged) {
271 | NSDictionary *userInfo = (NSDictionary *)[theEvent userData];
272 | NSCursor *cursor = [userInfo objectForKey:@"Cursor"];
273 | [cursor set];
274 | }
275 | }
276 |
277 |
278 | - (void)mouseExited:(NSEvent *)theEvent {
279 |
280 | if(self.cursorCanBeChanged) {
281 | [[NSCursor arrowCursor] set];
282 | }
283 | }
284 |
285 | - (BOOL)acceptsFirstResponder {
286 | return YES;
287 | }
288 |
289 |
290 | #pragma mark - Public methods
291 |
292 | - (NSRect) defaultRectForFrame:(NSRect)frame {
293 |
294 | NSRect result = NSZeroRect;
295 |
296 | CGFloat newX = frame.origin.x;
297 | CGFloat newY = frame.origin.y;
298 | CGFloat newW = frame.size.width;
299 | CGFloat newH = frame.size.height;
300 |
301 | if(frame.size.width < 0) {
302 | newX = frame.origin.x + frame.size.width;
303 | newW = fabs(frame.size.width);
304 | }
305 |
306 | if(frame.size.height < 0) {
307 | newY = frame.origin.y + frame.size.height;
308 | newH = fabs(frame.size.height);
309 | }
310 |
311 | result = NSMakeRect(newX, newY, newW, newH);
312 |
313 | return result;
314 |
315 | }
316 |
317 | - (void) removeAllSelectorsFromCanvas {
318 | [self markAllSelected:NO];
319 | [self removeMarkedSelectorsFromCanvas];
320 | }
321 |
322 | - (BOOL) hasSelectors {
323 |
324 | if(self.selectors && self.selectors.count > 0) {
325 | return YES;
326 | }
327 | return NO;
328 |
329 | }
330 |
331 | #pragma mark - Other methods
332 |
333 | - (void) markAllUnselected:(BOOL)redraw {
334 |
335 | for(MSSSelector *selector in self.selectors) {
336 | [selector setUnselected];
337 | }
338 |
339 | if(redraw) {
340 | [self.view setNeedsDisplay:YES];
341 | }
342 | }
343 |
344 | - (void) markAllSelected:(BOOL)redraw {
345 |
346 | for(MSSSelector *selector in self.selectors) {
347 | [selector setSelected];
348 | }
349 |
350 | if(redraw) {
351 | [self.view setNeedsDisplay:YES];
352 | }
353 | }
354 |
355 | - (void) removeMarkedSelectorsFromCanvas {
356 |
357 |
358 | self.currentSelector = nil;
359 | NSMutableIndexSet *discardedItems = [NSMutableIndexSet indexSet];
360 | for(int i=0;i
41 | #import
42 | #import "MSSPreferences.h"
43 |
44 | @class MSSSelector;
45 |
46 | /** Designable NSBezierPath to resize a MSSSelection from different corners */
47 | @interface MSSHandle : NSObject {
48 |
49 | }
50 | /** @name Properties */
51 | /** The handle's MSSSelector */
52 | @property (nonatomic, readonly) MSSSelector* selector;
53 | /** The type (SelectorHandleType) of the handle */
54 | @property (nonatomic, readonly) SelectorHandleType type;
55 | /** The handle's frame */
56 | @property (nonatomic, readonly) NSRect frame;
57 | /** The handle's boundaries */
58 | @property (nonatomic, readonly) NSRect bounds;
59 | /** The handle's NSShadow */
60 | @property (nonatomic, readonly) NSShadow *shadow;
61 | /** The actual NSBezierPath of the handle */
62 | @property (nonatomic, readonly) NSBezierPath *bezierPath;
63 | /** The current NSTrackingArea of the handle */
64 | @property (nonatomic, readonly) NSTrackingArea *trackingArea;
65 | /** @name Methods */
66 | /** Creates a handle with type for a given MSSSelector
67 | @param type The type handle which should be created
68 | @param selector The selector to create the handle for
69 | */
70 | + (instancetype) handleWithType:(SelectorHandleType)type forSelector:(MSSSelector*)selector;
71 | /** Draws the handle on the canvas */
72 | - (void) drawPath;
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSHandle.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSHandle.m
5 | ------------------------------------------------------------------------------------
6 | A handle is a little NSBezierPath (by default a rectangle) element.
7 | The handles are used to resize a MSSSelector starting from the corners.
8 | By default every selector has four handles (one for each corner).
9 | In order to know which corner handle is selected the handle has a type.
10 | Of course the NSBezierPath can be overwritten. This applies for the NSShadow, too.
11 | Every handle can also have a different look (stroke and fill color).
12 | The look is defined by a style which is determinated in the canvasController.
13 | Tipp: For a quick start please read the README document.
14 | ------------------------------------------------------------------------------------
15 |
16 | The MIT License (MIT)
17 |
18 | Copyright (c) 2014 Sascha Paulus
19 |
20 | Permission is hereby granted, free of charge, to any person obtaining a copy
21 | of this software and associated documentation files (the "Software"), to deal
22 | in the Software without restriction, including without limitation the rights
23 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24 | copies of the Software, and to permit persons to whom the Software is
25 | furnished to do so, subject to the following conditions:
26 |
27 | The above copyright notice and this permission notice shall be included in all
28 | copies or substantial portions of the Software.
29 |
30 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 | SOFTWARE.
37 |
38 | */
39 |
40 | #import "MSSHandle.h"
41 | #import "MSSSelector.h"
42 | #import "MSSHandleStyle.h"
43 |
44 | @interface MSSHandle ()
45 |
46 | @property (nonatomic) MSSHandleStyle *handleStyle;
47 |
48 | /** Sets the frame for the handle according to the selectors frame */
49 | - (void) makeHandleFrameWithSelectorFrame;
50 | /** Sets the handles's HandleStyle wheather from a default style or a style which is assigned to the canvas's delegate. */
51 | - (void)setStyle;
52 | /** Update the tracking area */
53 | - (void) updateTrackingArea;
54 |
55 | @end
56 |
57 | @implementation MSSHandle
58 |
59 | @synthesize type = _type;
60 | @synthesize frame = _frame;
61 | @synthesize bounds = _bounds;
62 | @synthesize selector = _selector;
63 | @synthesize trackingArea = _trackingArea;
64 |
65 | #pragma mark - Init & Alloc
66 |
67 | /** Initilizes a handle with a type for a given MSSSelector
68 | @param handleType The type handle which should be created
69 | @param selector The selector to create the handle for
70 | */
71 | - (instancetype) initWithType:(SelectorHandleType)handleType forSelector:(MSSSelector*)selector {
72 |
73 | self = [super init];
74 | if(self) {
75 | _selector = selector;
76 | [self setStyle];
77 | _type = handleType;
78 | }
79 | return self;
80 | }
81 |
82 | + (instancetype) handleWithType:(SelectorHandleType)type forSelector:(MSSSelector*)selector {
83 | id instance = [[self alloc] initWithType:type forSelector:selector];
84 | return instance;
85 | }
86 |
87 | - (void)setStyle {
88 | if([self.selector.canvas.delegate handleStyle]!=nil) {
89 | self.handleStyle = [self.selector.canvas.delegate handleStyle];
90 | } else {
91 | self.handleStyle = [[MSSHandleStyle alloc] init];
92 | }
93 | }
94 |
95 | #pragma mark - Public methods
96 |
97 | - (void) drawPath {
98 |
99 | [self makeHandleFrameWithSelectorFrame];
100 |
101 | NSBezierPath *path = self.bezierPath;
102 | [self.handleStyle.strokeColor setStroke];
103 | [path stroke];
104 |
105 | [NSGraphicsContext saveGraphicsState];
106 | NSShadow *shadow;
107 | if((shadow = self.shadow)!=nil) [shadow set];
108 | [self.handleStyle.fillColor setFill];
109 | [path fill];
110 | [NSGraphicsContext restoreGraphicsState];
111 |
112 | }
113 |
114 | #pragma mark - Internal methods
115 |
116 |
117 | - (void) updateTrackingArea {
118 |
119 | NSRect trackingRect = [self.selector.canvas.delegate defaultRectForFrame:self.frame];
120 | if(self.trackingArea != nil) {
121 | [self.selector.canvas removeTrackingArea:self.trackingArea];
122 | _trackingArea = nil;
123 | }
124 |
125 | NSCursor *cursor = [NSCursor crosshairCursor];
126 | NSPoint hotSpot = NSMakePoint(9,9);
127 | NSBundle *frameworkBundle = [NSBundle bundleForClass:[self class]];
128 | NSString *buttomTopPath = [frameworkBundle pathForImageResource:@"BottomTop"];
129 | NSString *topButtomPath = [frameworkBundle pathForImageResource:@"TopBottom"];
130 | NSImage *buttomTop = [[NSImage alloc] initByReferencingFile:buttomTopPath];
131 | NSImage *topButtom = [[NSImage alloc] initByReferencingFile:topButtomPath];
132 |
133 |
134 | if (self.type == SelectorHandleTypeLowerLeft) {
135 | cursor = [[NSCursor alloc] initWithImage:buttomTop hotSpot:hotSpot];
136 | } else if (self.type == SelectorHandleTypeUpperLeft) {
137 | cursor = [[NSCursor alloc] initWithImage:topButtom hotSpot:hotSpot];
138 | } else if (self.type == SelectorHandleTypeUpperRight) {
139 | cursor = [[NSCursor alloc] initWithImage:buttomTop hotSpot:hotSpot];
140 | } else if (self.type == SelectorHandleTypeLowerRight) {
141 | cursor = [[NSCursor alloc] initWithImage:topButtom hotSpot:hotSpot];
142 | }
143 |
144 | NSTrackingAreaOptions options = NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited;
145 | _trackingArea = [[NSTrackingArea alloc] initWithRect:trackingRect options:options owner:self.selector.canvas userInfo:@{@"Cursor":cursor,@"Rect":NSStringFromRect(trackingRect)}];
146 | [self.selector.canvas addTrackingArea:self.trackingArea];
147 |
148 | }
149 | - (void) makeHandleFrameWithSelectorFrame {
150 |
151 |
152 | CGFloat halfWidth = self.handleStyle.size.width / 2;
153 | CGFloat halfHeight = self.handleStyle.size.height /2;
154 |
155 | NSRect selectorFrame = self.selector.frame;
156 | CGFloat minY = selectorFrame.origin.y;
157 | CGFloat maxY = selectorFrame.origin.y + selectorFrame.size.height;
158 | CGFloat minX = selectorFrame.origin.x;
159 | CGFloat maxX = selectorFrame.origin.x + selectorFrame.size.width;
160 |
161 | switch (self.type) {
162 | case SelectorHandleTypeUpperLeft: {
163 | _frame = NSMakeRect(minX - halfWidth, maxY - halfHeight, self.handleStyle.size.width, self.handleStyle.size.height);
164 | break;
165 | }
166 | case SelectorHandleTypeUpperRight: {
167 | _frame = NSMakeRect(maxX - halfWidth, maxY - halfHeight, self.handleStyle.size.width, self.handleStyle.size.height);
168 | break;
169 | }
170 | case SelectorHandleTypeLowerLeft: {
171 | _frame = NSMakeRect(minX - halfWidth, minY - halfHeight, self.handleStyle.size.width, self.handleStyle.size.height);
172 | break;
173 | }
174 | case SelectorHandleTypeLowerRight: {
175 | _frame = NSMakeRect(maxX - halfWidth, minY - halfHeight, self.handleStyle.size.width, self.handleStyle.size.height);
176 | break;
177 | }
178 | default: {
179 | _frame = NSZeroRect;
180 | break;
181 | }
182 | }
183 |
184 | _bounds = _frame;
185 |
186 | [self updateTrackingArea];
187 |
188 | }
189 |
190 |
191 |
192 | - (NSShadow *) shadow {
193 | return nil;
194 | }
195 |
196 | - (NSBezierPath*) bezierPath {
197 | NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:self.frame];
198 | [path setLineWidth:2.0f];
199 | return path;
200 | }
201 |
202 | @end
203 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSHandleStyle.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | HandleStyle.h
5 | ------------------------------------------------------------------------------------
6 | This class provides properties for the look of a MSSHandle.
7 | If maintained via interface builder it is possible set the values via IB UI.
8 | Tipp: For a quick start please read the README document.
9 | ------------------------------------------------------------------------------------
10 |
11 | The MIT License (MIT)
12 |
13 | Copyright (c) 2014 Sascha Paulus
14 |
15 | Permission is hereby granted, free of charge, to any person obtaining a copy
16 | of this software and associated documentation files (the "Software"), to deal
17 | in the Software without restriction, including without limitation the rights
18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 | copies of the Software, and to permit persons to whom the Software is
20 | furnished to do so, subject to the following conditions:
21 |
22 | The above copyright notice and this permission notice shall be included in all
23 | copies or substantial portions of the Software.
24 |
25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 | SOFTWARE.
32 |
33 | */
34 |
35 | #import
36 |
37 | IB_DESIGNABLE
38 | /** Represents a style object for a MSSHandle. */
39 | @interface MSSHandleStyle : NSObject {
40 |
41 | }
42 | /** @name Properties */
43 | /** Determines the stroke color for a handle. */
44 | @property (nonatomic) IBInspectable NSColor *strokeColor;
45 | /** Determines the fill color for a handle. */
46 | @property (nonatomic) IBInspectable NSColor *fillColor;
47 | /** Determines the size for a handle. */
48 | @property (nonatomic) IBInspectable NSSize size;
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSHandleStyle.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSHandleStyle.m
5 | ------------------------------------------------------------------------------------
6 | This class provides properties for the look of a MSSHandle.
7 | If maintained via interface builder it is possible set the values via IB UI.
8 | Tipp: For a quick start please read the README document.
9 | ------------------------------------------------------------------------------------
10 |
11 | The MIT License (MIT)
12 |
13 | Copyright (c) 2014 Sascha Paulus
14 |
15 | Permission is hereby granted, free of charge, to any person obtaining a copy
16 | of this software and associated documentation files (the "Software"), to deal
17 | in the Software without restriction, including without limitation the rights
18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 | copies of the Software, and to permit persons to whom the Software is
20 | furnished to do so, subject to the following conditions:
21 |
22 | The above copyright notice and this permission notice shall be included in all
23 | copies or substantial portions of the Software.
24 |
25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 | SOFTWARE.
32 |
33 | */
34 |
35 | #import "MSSHandleStyle.h"
36 |
37 | @implementation MSSHandleStyle
38 |
39 | - (instancetype) init {
40 | self = [super init];
41 | if(self != nil) {
42 |
43 | CGFloat red = 0.1054f;
44 | CGFloat green = 0.4531f;
45 | CGFloat blue = 0.7929f;
46 | self.size = NSMakeSize(8.5f, 8.5f);
47 | self.strokeColor = [NSColor whiteColor];
48 | self.fillColor = [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:1.0f];
49 | }
50 | return self;
51 | }
52 |
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSSelector.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSSelector.h
5 | ------------------------------------------------------------------------------------
6 | This class is the actual selection path on a MSSCanvas. A canvas can have
7 | multiple selectors. Basically a selector is a NSBezierPath which interacts with
8 | the mouse activities. Movement and Resizing are controlled by the canvasController.
9 | Their two types of selectors: picker and selector. A normal selector stays drawn
10 | on the canvas and a picker selector is just for the purpose of selecting/collecting
11 | available selectors and mark them as selected. The NSBezierPaths for the picker and
12 | for the selector can be overwritten. Each selector has four handles for resizing.
13 | Every selector can also have a different look (stroke and fill colors).
14 | The look is defined by a style which is determinated in the canvasController.
15 | Tipp: For a quick start please read the README document.
16 | ------------------------------------------------------------------------------------
17 |
18 | The MIT License (MIT)
19 |
20 | Copyright (c) 2014 Sascha Paulus
21 |
22 | Permission is hereby granted, free of charge, to any person obtaining a copy
23 | of this software and associated documentation files (the "Software"), to deal
24 | in the Software without restriction, including without limitation the rights
25 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26 | copies of the Software, and to permit persons to whom the Software is
27 | furnished to do so, subject to the following conditions:
28 |
29 | The above copyright notice and this permission notice shall be included in all
30 | copies or substantial portions of the Software.
31 |
32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 | SOFTWARE.
39 |
40 | */
41 |
42 | #import
43 | #import
44 | #import "MSSPreferences.h"
45 | #import "MSSCanvas.h"
46 | #import "MSSHandle.h"
47 |
48 | /** Represents a designable selection rectangle with handles to resize */
49 | @interface MSSSelector : NSObject {
50 |
51 | }
52 | /** @name Properties */
53 | /** The MSSCanvas on which the selector is drawn */
54 | @property (nonatomic, readonly) MSSCanvas *canvas;
55 | /** The selector's frame */
56 | @property (nonatomic, readonly) NSRect frame;
57 | /** Determines if the selector is selected */
58 | @property (nonatomic, readonly) BOOL isSelected;
59 | /** Determines if the selector is just a picker
60 |
61 | A non-picker selector stays drawn on the canvas and a picker selector is just for the purpose of selecting/collecting available selectors and mark them as selected.
62 | */
63 | @property (nonatomic, readonly) BOOL isPicker;
64 | /** Determines the current SelectorAction */
65 | @property (nonatomic, readonly) SelectorAction action;
66 | /** Holds all handles of the selector */
67 | @property (nonatomic, readonly) NSMutableArray *handles;
68 | /** Determines the current handle */
69 | @property (nonatomic, readonly) MSSHandle *currentHandle;
70 | /** The actual NSBezierPath of the selector */
71 | @property (nonatomic, readonly) NSBezierPath *selectorBezierPath;
72 | /** @abstract The actual NSBezierPath of the selector if the selector is a picker
73 | @discussion For more details about the distinction between picker and selector checkout the isPicker property.
74 | */
75 | @property (nonatomic, readonly) NSBezierPath *pickerBezierPath;
76 | /** The current NSTrackingArea of the handle */
77 | @property (nonatomic, readonly) NSTrackingArea *trackingArea;
78 | /** @name Methods */
79 | /**
80 | @abstract Creates a selector or picker for a given MSSCanvas
81 | @param rect The frame for the selector
82 | @param canvas The canvas on which the selector should be drawn
83 | @param picker Determines if the new selector should be a picker
84 | @discussion For more details about the distinction between picker and selector checkout the isPicker property.
85 | */
86 | + (instancetype) selectorWithFrame:(NSRect)rect forCanvas:canvas asPicker:(BOOL)picker;
87 | /** Determines if a selector's handle has been touched and prepare the corresponding action for the selector
88 | @param rect The frame, which could have touched the handle.
89 | */
90 | - (BOOL) touchedHandle:(NSRect)rect;
91 | /** Determines if the selector's frame intersects with a given NSRect
92 | @param rect The frame, which could have intersected the selector.
93 | */
94 | - (BOOL) intersectsFrame:(NSRect)rect;
95 | /** Draws the selector's NSBezierPath */
96 | - (void) drawPath;
97 | /** Marks the selector as selected */
98 | - (void) setSelected;
99 | /** Marks the selector as unselected */
100 | - (void) setUnselected;
101 | /** Moves the selector to a given point
102 | @param point The point on the canvas to move the selector to.
103 | */
104 | - (void) moveSelectorToPoint:(CGPoint)point;
105 | /** Resizes the selector from the current origin to a given point
106 | @param point The point on the canvas to resize the selector to.
107 | */
108 | - (void) resizeToPoint:(CGPoint)point;
109 | /** Determines if the selector can be dropped on the canvas
110 |
111 | Depending on whether intersections with other selectors is allowed or not or the minimum rectangle size for new selectors does not apply, the dropping of the current selector can be denied. In this case the current selector will be discarded, regardless if the selector is new or already existed and only has been resized or moved.
112 |
113 | */
114 | - (BOOL) canDropOnCanvas;
115 | /** Determines if the selector's frame crosses the canvas boundaries */
116 | - (BOOL) touchedBoundaries;
117 | /** Prepares the selector for a certain action
118 | @param action The SelectorAction to prepare the selector for.
119 | */
120 | - (void) prepareAction:(SelectorAction)action;
121 | /** Removes all tracking areas for this selector */
122 | - (void) removeTrackingAreas;
123 |
124 | @end
125 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSSelectorStyle.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSSelectorStyle.h
5 | ------------------------------------------------------------------------------------
6 | This class provides properties for the look of a MSSSelector.
7 | If maintained via interface builder it is possible set the values via IB UI.
8 | Tipp: For a quick start please read the README document.
9 | ------------------------------------------------------------------------------------
10 |
11 | The MIT License (MIT)
12 |
13 | Copyright (c) 2014 Sascha Paulus
14 |
15 | Permission is hereby granted, free of charge, to any person obtaining a copy
16 | of this software and associated documentation files (the "Software"), to deal
17 | in the Software without restriction, including without limitation the rights
18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 | copies of the Software, and to permit persons to whom the Software is
20 | furnished to do so, subject to the following conditions:
21 |
22 | The above copyright notice and this permission notice shall be included in all
23 | copies or substantial portions of the Software.
24 |
25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 | SOFTWARE.
32 |
33 | */
34 |
35 | #import
36 |
37 | IB_DESIGNABLE
38 | /** Represents a style object for a MSSSelector. */
39 | @interface MSSSelectorStyle : NSObject {
40 |
41 | }
42 | /** @name Properties */
43 | /** Determines the minimum height for a selector */
44 | @property (nonatomic) IBInspectable CGFloat minHeight;
45 | /** Determines the minimum width for a selector */
46 | @property (nonatomic) IBInspectable CGFloat minWidth;
47 | /** @abstract Determines the stroke color for a picker selector.
48 | @discussion For more details about the distinction between picker and selector checkout the isPicker property. */
49 | @property (nonatomic) IBInspectable NSColor *strokeColorPicker;
50 | /** Determines the fill color for a picker selector.
51 | @discussion For more details about the distinction between picker and selector checkout the isPicker property. */
52 | @property (nonatomic) IBInspectable NSColor *fillColorPicker;
53 | /** Determines the stroke color for a selector if it is marked as selected. */
54 | @property (nonatomic) IBInspectable NSColor *strokeColorSelected;
55 | /** Determines the stroke color for a selector if it is NOT marked as selected. */
56 | @property (nonatomic) IBInspectable NSColor *strokeColorUnselected;
57 | /** Determines the fill color for a selector if it is marked as selected. */
58 | @property (nonatomic) IBInspectable NSColor *fillColorSelected;
59 | /** Determines the fill color for a selector if it is NOT marked as selected. */
60 | @property (nonatomic) IBInspectable NSColor *fillColorUnselected;
61 | /** Determines the width of the stroke line if selector is marked as selected */
62 | @property (nonatomic) IBInspectable CGFloat lineWidthSelected;
63 | /** Determines the width of the stroke line if selector is NOT marked as selected */
64 | @property (nonatomic) IBInspectable CGFloat lineWidthUnselected;
65 | /** Determines if the stroke line should be dashed if selector is marked as selected */
66 | @property (nonatomic) IBInspectable BOOL lineDashedSelected;
67 | /** Determines if the stroke line should be dashed if selector is NOT marked as selected */
68 | @property (nonatomic) IBInspectable BOOL lineDashedUnselected;
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Base/MSSSelectorStyle.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSSelectorStyle.m
5 | ------------------------------------------------------------------------------------
6 | This class provides properties for the look of a MSSSelector.
7 | If maintained via interface builder it is possible set the values via IB UI.
8 | Tipp: For a quick start please read the README document.
9 | ------------------------------------------------------------------------------------
10 |
11 | The MIT License (MIT)
12 |
13 | Copyright (c) 2014 Sascha Paulus
14 |
15 | Permission is hereby granted, free of charge, to any person obtaining a copy
16 | of this software and associated documentation files (the "Software"), to deal
17 | in the Software without restriction, including without limitation the rights
18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 | copies of the Software, and to permit persons to whom the Software is
20 | furnished to do so, subject to the following conditions:
21 |
22 | The above copyright notice and this permission notice shall be included in all
23 | copies or substantial portions of the Software.
24 |
25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 | SOFTWARE.
32 |
33 | */
34 |
35 | #import "MSSSelectorStyle.h"
36 |
37 | @implementation MSSSelectorStyle
38 |
39 | - (instancetype)init {
40 | self = [super init];
41 | if(self != nil) {
42 | self.minHeight = 20.0f;
43 | self.minWidth = 20.0f;
44 | self.strokeColorSelected = [NSColor lightGrayColor];
45 | self.strokeColorUnselected = [NSColor lightGrayColor];
46 | self.fillColorSelected = [NSColor colorWithCalibratedRed:0.0f green:0.2f blue:1.0f alpha:0.10f];
47 | self.fillColorUnselected = [NSColor clearColor];
48 | self.strokeColorPicker = self.strokeColorSelected;
49 | self.fillColorPicker = self.fillColorSelected;
50 | self.lineDashedSelected = YES;
51 | self.lineDashedUnselected = YES;
52 | self.lineWidthSelected = 1;
53 | self.lineWidthUnselected = 1;
54 |
55 | }
56 | return self;
57 | }
58 |
59 |
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Others/BottomTop@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Others/BottomTop@2x.png
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Others/NSImageView+MSSScaledImage.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | NSImageView+MSSScaledImage.h
5 | ------------------------------------------------------------------------------------
6 | Category for NSImageView to deal with the original image
7 | ------------------------------------------------------------------------------------
8 |
9 | The MIT License (MIT)
10 |
11 | Copyright (c) 2014 Sascha Paulus
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy
14 | of this software and associated documentation files (the "Software"), to deal
15 | in the Software without restriction, including without limitation the rights
16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 | copies of the Software, and to permit persons to whom the Software is
18 | furnished to do so, subject to the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be included in all
21 | copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 | SOFTWARE.
30 |
31 | */
32 |
33 | #import
34 | #import
35 |
36 | /** Category for NSImageView to deal with the original image and the image's fileURL */
37 | @interface NSImageView (MSSScaledImage)
38 | /** @name Properties */
39 | /** The original image behind the scaled image */
40 | @property (nonatomic, readonly) NSImage *originalImage;
41 | /** The ratio/scale between the controlView's frame and the original image */
42 | @property (nonatomic, readonly) NSSize originalImageRatio;
43 | /** The ratio/scale between the controlView's frame and the scaled image */
44 | @property (nonatomic, readonly) NSSize imageRatio;
45 | /** The frame of the scaled image */
46 | @property (nonatomic, readonly) NSRect scaledImageRect;
47 | /** @abstract The URL of the current image
48 | @discussion If the image is changed by Drag & Drop this value will be set automatically */
49 | @property (nonatomic) NSURL *fileURL;
50 | @end
51 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Others/NSImageView+MSSScaledImage.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | NSimageView+MSSScaledImage.m
5 | ------------------------------------------------------------------------------------
6 | Category for NSImageView to deal with the original image
7 | ------------------------------------------------------------------------------------
8 |
9 | The MIT License (MIT)
10 |
11 | Copyright (c) 2014 Sascha Paulus
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy
14 | of this software and associated documentation files (the "Software"), to deal
15 | in the Software without restriction, including without limitation the rights
16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 | copies of the Software, and to permit persons to whom the Software is
18 | furnished to do so, subject to the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be included in all
21 | copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 | SOFTWARE.
30 |
31 | */
32 |
33 | #import "NSImageView+MSSScaledImage.h"
34 | #import
35 |
36 | @implementation NSImageView (MSSScaledImage)
37 |
38 | @dynamic fileURL;
39 |
40 | - (void) setFileURL:(NSURL*)url {
41 | objc_setAssociatedObject(self, @selector(fileURL), url, OBJC_ASSOCIATION_RETAIN);
42 | }
43 |
44 | - (NSURL*) fileURL {
45 | return objc_getAssociatedObject(self, @selector(fileURL));
46 | }
47 |
48 | - (NSImage*) originalImage {
49 |
50 | CGFloat scale = 1.0f;
51 | // If fileURL exists and the file is a PDF scale it up by 2.5
52 | NSString *fileType;
53 | if(self.fileURL) {
54 | CGImageSourceRef isr = CGImageSourceCreateWithURL((__bridge CFURLRef)(self.fileURL), NULL);
55 | fileType = (__bridge NSString*)CGImageSourceGetType(isr);
56 | CFRelease(isr);
57 | }
58 | if(fileType && [fileType isEqualToString:@"com.adobe.pdf"]) {
59 | scale = 2.5;
60 | }
61 |
62 | NSImageRep *imageRep = [self.image.representations objectAtIndex:0];
63 | CGFloat w = fmaxf(imageRep.size.width, imageRep.pixelsWide);
64 | CGFloat h = fmaxf(imageRep.size.height, imageRep.pixelsHigh);
65 | NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(w*scale, h*scale)];
66 | [image addRepresentation:imageRep];
67 | return image;
68 | }
69 |
70 | - (NSSize) originalImageRatio {
71 |
72 |
73 | NSImage *actualImage = [self originalImage];
74 |
75 | NSSize imageSize = NSMakeSize(actualImage.size.width, actualImage.size.height);
76 | NSRect frameRect = [self.cell drawingRectForBounds:self.bounds];
77 | NSSize frameSize = frameRect.size;
78 |
79 | NSSize ratio = NSZeroSize;
80 | CGFloat ratioX = frameSize.width / imageSize.width;
81 | CGFloat ratioY = frameSize.height / imageSize.height;
82 | CGFloat scale = 1.0f;
83 |
84 | switch (self.imageScaling) {
85 | case NSImageScaleProportionallyDown:
86 | scale = fminf(ratioX, ratioY);
87 | scale = fminf(scale, 1.0f);
88 | ratio = NSMakeSize(scale, scale);
89 | break;
90 | case NSImageScaleProportionallyUpOrDown:
91 | scale = fminf(ratioX, ratioY);
92 | ratio = NSMakeSize(scale, scale);
93 | break;
94 | case NSImageScaleAxesIndependently:
95 | ratio = NSMakeSize(ratioX, ratioY);
96 | break;
97 | default:
98 | ratio = NSMakeSize(scale, scale);
99 | break;
100 | }
101 |
102 | return ratio;
103 |
104 |
105 | }
106 |
107 | - (NSSize) imageRatio {
108 |
109 | NSSize imageSize = self.image.size;
110 |
111 | NSRect frameRect = [self.cell drawingRectForBounds:self.bounds];
112 | NSSize frameSize = frameRect.size;
113 |
114 | NSSize ratio = NSZeroSize;
115 | CGFloat ratioX = frameSize.width / imageSize.width;
116 | CGFloat ratioY = frameSize.height / imageSize.height;
117 | CGFloat scale = 1.0f;
118 |
119 | switch (self.imageScaling) {
120 | case NSImageScaleProportionallyDown:
121 | scale = fminf(ratioX, ratioY);
122 | scale = fminf(scale, 1.0f);
123 | ratio = NSMakeSize(scale, scale);
124 | break;
125 | case NSImageScaleProportionallyUpOrDown:
126 | scale = fminf(ratioX, ratioY);
127 | ratio = NSMakeSize(scale, scale);
128 | break;
129 | case NSImageScaleAxesIndependently:
130 | ratio = NSMakeSize(ratioX, ratioY);
131 | break;
132 | default:
133 | ratio = NSMakeSize(scale, scale);
134 | break;
135 | }
136 |
137 | return ratio;
138 |
139 | }
140 |
141 | - (NSRect) scaledImageRect {
142 |
143 | NSRect scaledRect = NSZeroRect;
144 |
145 | NSSize imageSize = self.image.size;
146 | if (imageSize.width < 1.0 || imageSize.height < 1.0) {
147 | return scaledRect;
148 | }
149 | NSRect frameRect = [self.cell drawingRectForBounds:self.bounds];
150 | NSSize frameSize = frameRect.size;
151 | NSSize ratio = self.imageRatio;
152 |
153 |
154 | CGFloat scaledWidth = imageSize.width * ratio.width;
155 | CGFloat scaledHeight = imageSize.height * ratio.height;
156 | NSSize scaledSize = NSMakeSize(scaledWidth, scaledHeight);
157 |
158 | CGFloat Xmin = 0.0f;
159 | CGFloat Xmax = frameSize.width - scaledSize.width;
160 | CGFloat verticalCenter = (frameSize.width - scaledSize.width) / 2;
161 | CGFloat Ymin = 0.0f;
162 | CGFloat Ymax = frameSize.height - scaledSize.height;
163 | CGFloat horizontalCenter = (frameSize.height - scaledSize.height) / 2;
164 |
165 | switch (self.imageAlignment) {
166 | case NSImageAlignCenter:
167 | scaledRect = NSMakeRect(verticalCenter, horizontalCenter, scaledSize.width, scaledSize.height);
168 | break;
169 | case NSImageAlignLeft:
170 | scaledRect = NSMakeRect(Xmin, horizontalCenter, scaledSize.width, scaledSize.height);
171 | break;
172 | case NSImageAlignRight:
173 | scaledRect = NSMakeRect(Xmax, horizontalCenter, scaledSize.width, scaledSize.height);
174 | break;
175 | case NSImageAlignTop:
176 | scaledRect = NSMakeRect(verticalCenter, Ymax, scaledSize.width, scaledSize.height);
177 | break;
178 | case NSImageAlignTopLeft:
179 | scaledRect = NSMakeRect(Xmin, Ymax, scaledSize.width, scaledSize.height);
180 | break;
181 | case NSImageAlignTopRight:
182 | scaledRect = NSMakeRect(Xmax, Ymax, scaledSize.width, scaledSize.height);
183 | break;
184 | case NSImageAlignBottom:
185 | scaledRect = NSMakeRect(verticalCenter, Ymin, scaledSize.width, scaledSize.height);
186 | break;
187 | case NSImageAlignBottomLeft:
188 | scaledRect = NSMakeRect(Xmin, Ymin, scaledSize.width, scaledSize.height);
189 | break;
190 | case NSImageAlignBottomRight:
191 | scaledRect = NSMakeRect(Xmax, Ymin, scaledSize.width, scaledSize.height);
192 | break;
193 | }
194 |
195 | scaledRect = NSOffsetRect(scaledRect, frameRect.origin.x, frameRect.origin.y);
196 |
197 | return scaledRect;
198 | }
199 |
200 | /** Overwrites the default draggingEntered in order to intercept the draged fileUrl */
201 | - (NSDragOperation)draggingEntered:(id)sender {
202 |
203 | NSPasteboard *pboard = [sender draggingPasteboard];
204 | NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];
205 |
206 | if([[pboard types] containsObject:NSURLPboardType]) {
207 | if(sourceDragMask & NSDragOperationGeneric) {
208 | self.fileURL = [NSURL URLFromPasteboard:pboard];
209 | return NSDragOperationCopy;
210 | }
211 |
212 | }
213 | return NSDragOperationNone;
214 | }
215 |
216 |
217 | @end
218 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Others/TopBottom@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ckteebe/MultiSelectionSuiteFramework/e3840b1a379364416d6113c47391d408d40869b2/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Others/TopBottom@2x.png
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Preferences/MSSError.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSError.h
5 | ------------------------------------------------------------------------------------
6 |
7 | The MIT License (MIT)
8 |
9 | Copyright (c) 2014 Sascha Paulus
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy
12 | of this software and associated documentation files (the "Software"), to deal
13 | in the Software without restriction, including without limitation the rights
14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | copies of the Software, and to permit persons to whom the Software is
16 | furnished to do so, subject to the following conditions:
17 |
18 | The above copyright notice and this permission notice shall be included in all
19 | copies or substantial portions of the Software.
20 |
21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | SOFTWARE.
28 |
29 | */
30 |
31 | #import
32 |
33 | #define MSS_ERROR_KEY(code) [NSString stringWithFormat:@"%d",code]
34 | #define MSS_ERROR_DESC(code) NSLocalizedStringFromTableInBundle(MSS_ERROR_KEY(code), @"MSSError", [NSBundle bundleForClass:[self class]], nil)
35 |
36 | FOUNDATION_EXPORT NSString *const MSSErrorDomain;
37 |
38 | enum {
39 | /** Error if no selection is on the canvas */
40 | MSSErrorNoSelections = 1000,
41 | /** Error if no save directory is given */
42 | MSSErrorNoSaveDirectory,
43 | /** Error if save directory not exists */
44 | MSSErrorSaveDirectoryNotExists,
45 | /** Error if save target is not a directory */
46 | MSSErrorSaveDirectoryUrlIsNoDirectory,
47 | /** Error if saving failed */
48 | MSSErrorImageSavingFailed,
49 | /** Error if given file type is not supported yet */
50 | MSSErrorFileTypeNotSupportedYet,
51 | };
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Preferences/MSSError.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSError.m
5 | ------------------------------------------------------------------------------------
6 |
7 | The MIT License (MIT)
8 |
9 | Copyright (c) 2014 Sascha Paulus
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy
12 | of this software and associated documentation files (the "Software"), to deal
13 | in the Software without restriction, including without limitation the rights
14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | copies of the Software, and to permit persons to whom the Software is
16 | furnished to do so, subject to the following conditions:
17 |
18 | The above copyright notice and this permission notice shall be included in all
19 | copies or substantial portions of the Software.
20 |
21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | SOFTWARE.
28 |
29 | */
30 |
31 | #import "MSSError.h"
32 |
33 | NSString *const MSSErrorDomain = @"com.saschapaulus.frameworks.mss";
34 |
35 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Preferences/MSSPreferences.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSPreferences.h
5 | ------------------------------------------------------------------------------------
6 |
7 | The MIT License (MIT)
8 |
9 | Copyright (c) 2014 Sascha Paulus
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy
12 | of this software and associated documentation files (the "Software"), to deal
13 | in the Software without restriction, including without limitation the rights
14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | copies of the Software, and to permit persons to whom the Software is
16 | furnished to do so, subject to the following conditions:
17 |
18 | The above copyright notice and this permission notice shall be included in all
19 | copies or substantial portions of the Software.
20 |
21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | SOFTWARE.
28 |
29 | */
30 |
31 | #import
32 |
33 | FOUNDATION_EXPORT NSString * const MSSExtractorJobUnknown;
34 | FOUNDATION_EXPORT NSString * const MSSExtractorJobCropping;
35 | FOUNDATION_EXPORT NSString * const MSSExtractorJobOverviewScan;
36 | FOUNDATION_EXPORT NSString * const MSSExtractorJobImageScan;
37 | FOUNDATION_EXPORT NSString * const MSSExtractorJobZoom;
38 |
39 | /** Determines the type of a selector handle */
40 | typedef NS_ENUM(NSInteger, SelectorHandleType) {
41 | /** No handle is selected or handle has no type */
42 | SelectorHandleTypeNoHandle,
43 | /** Selected handle is on the upper left */
44 | SelectorHandleTypeUpperLeft,
45 | /** Selected handle is on the upper right */
46 | SelectorHandleTypeUpperRight,
47 | /** Selected handle is on the lower left */
48 | SelectorHandleTypeLowerLeft,
49 | /** Selected handle is on the upper right */
50 | SelectorHandleTypeLowerRight,
51 | };
52 |
53 | /** Defines to current action of a selector */
54 | typedef NS_ENUM(NSInteger, SelectorAction) {
55 | /** Selector has no action yet */
56 | SelectorActionNone,
57 | /** Selector is about to resize */
58 | SelectorActionResize,
59 | /** Selector is about to move */
60 | SelectorActionMove,
61 | /** Selector is about to initialize */
62 | SelectorActionInit,
63 | };
64 |
65 | /** Determines the current selector position in the canvas boundaries */
66 | typedef NS_ENUM(NSInteger, SelectorBoundariesPosition) {
67 | /** Selector is in boundaries */
68 | SelectorBoundariesPositionInBounderies,
69 | /** Selector is out of boundaries (left side) */
70 | SelectorBoundariesPositionLeftOuterBounderies,
71 | /** Selector is out of boundaries (right side) */
72 | SelectorBoundariesPositionRightOuterBounderies,
73 | /** Selector is out of boundaries (top side) */
74 | SelectorBoundariesPositionUpperOuterBounderies,
75 | /** Selector is out of boundaries (bottom side) */
76 | SelectorBoundariesPositionLowerOuterBounderies,
77 | };
78 |
79 | /** Defines the struture of a boundary */
80 | typedef struct {
81 | /** Position (x,y) of the boundary */
82 | CGFloat position;
83 | /** Size (width,height) of the boundary */
84 | CGFloat size;
85 | } Boundary;
86 |
87 | /** Defines the boundaries of an object */
88 | typedef struct {
89 | /** Boundary on the top side */
90 | Boundary top;
91 | /** Boundary on the bottom side */
92 | Boundary bottom;
93 | /** Boundary on the left side */
94 | Boundary left;
95 | /** Boundary on the right side */
96 | Boundary right;
97 | } Boundaries;
98 |
99 |
100 | /** Defines how much images should be compress */
101 | typedef NS_ENUM(NSInteger, ExtractorImageCompressionLevel) {
102 | /** No compression (Image quality 100%) */
103 | ExtractorImageCompressionLevelNone,
104 | /** Little compression (Image quality 80%) */
105 | ExtractorImageCompressionLevelLow,
106 | /** Medium compression (Image quality 60%) */
107 | ExtractorImageCompressionLevelMiddle,
108 | /** High compression (Image quality 30%) */
109 | ExtractorImageCompressionLevelHigh,
110 | /** Highest compression (Image quality 10%) */
111 | ExtractorImageCompressionLevelHighest,
112 | };
113 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Classes/Preferences/MSSPreferences.m:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ------------------------------------------------------------------------------------
4 | MSSPreferences.m
5 | ------------------------------------------------------------------------------------
6 |
7 | The MIT License (MIT)
8 |
9 | Copyright (c) 2014 Sascha Paulus
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy
12 | of this software and associated documentation files (the "Software"), to deal
13 | in the Software without restriction, including without limitation the rights
14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | copies of the Software, and to permit persons to whom the Software is
16 | furnished to do so, subject to the following conditions:
17 |
18 | The above copyright notice and this permission notice shall be included in all
19 | copies or substantial portions of the Software.
20 |
21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | SOFTWARE.
28 |
29 | */
30 |
31 | #import "MSSPreferences.h"
32 |
33 | NSString * const MSSExtractorJobUnknown = @"MSSExtractorJobUnknown";
34 | NSString * const MSSExtractorJobCropping = @"MSSExtractorJobCropping";
35 | NSString * const MSSExtractorJobOverviewScan = @"MSSExtractorJobOverviewScan";
36 | NSString * const MSSExtractorJobImageScan = @"MSSExtractorJobImageScan";
37 | NSString * const MSSExtractorJobZoom = @"MSSExtractorJobZoom";
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.saschapaulus.frameworks.mss
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 Sascha Paulus. All rights reserved.
25 | NSPrincipalClass
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/MultiSelectionSuite.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 |
4 | //! Project version number for MultiSelectionSuite.
5 | FOUNDATION_EXPORT double MultiSelectionSuiteVersionNumber;
6 |
7 | //! Project version string for MultiSelectionSuite.
8 | FOUNDATION_EXPORT const unsigned char MultiSelectionSuiteVersionString[];
9 |
10 |
11 | #import
12 | #import
13 | #import
14 | #import
15 | #import
16 | #import
17 |
18 | #import
19 | #import
20 |
21 | #import
22 | #import
23 | #import
24 |
25 | #import
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/de.lproj/MSSError.strings:
--------------------------------------------------------------------------------
1 | "1000" = "Es wurde keine Auswahl getroffen";
2 | "1001" = "Es wurde kein Speicherverzeichnis gefunden";
3 | "1002" = "Das genannte Verzeichnis existiert nicht";
4 | "1003" = "Die genannte URL ist kein Verzeichnis";
5 | "1004" = "Ein oder mehrere Bilder konnte nicht gespeichert werden";
6 | "1005" = "Dieser Dateityp wird derzeit nicht unterstützt";
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuite/en.lproj/MSSError.strings:
--------------------------------------------------------------------------------
1 | "1000" = "No selector has been set";
2 | "1001" = "Delegate does not provide saving folder";
3 | "1002" = "The provided saving folder does not exists";
4 | "1003" = "The provided saving URL is no directory";
5 | "1004" = "Saving of one or more images has been failed";
6 | "1005" = "You use a not supported file type";
7 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuiteFramework.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuiteFramework.xcodeproj/project.xcworkspace/xcuserdata/sascha.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuiteFramework.xcodeproj/xcuserdata/sascha.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuiteFramework.xcodeproj/xcuserdata/sascha.xcuserdatad/xcschemes/MultiSelectionSuite.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/MultiSelectionSuiteFramework/MultiSelectionSuiteFramework.xcodeproj/xcuserdata/sascha.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MultiSelectionSuite.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 2B24828E1A5AF9B9000C1F7A
16 |
17 | primary
18 |
19 |
20 | 2B7076CE1A5ABE4200707A69
21 |
22 | primary
23 |
24 |
25 | 2B7076D91A5ABE4200707A69
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # MultiSelectionSuite.framework
2 |
3 | ## About
4 | The "MultiSelectionSuite" Framework provides an easy way to draw multiple, designable and interactive selection paths (mostly rectangles or any thinkable path) on any **MacOS** (not iOS) view. In addition it has out-of-the-box modules to extract the content of the selected areas.
5 |
6 | 
7 |
8 | ## Understand "MultiSelectionSuite"
9 |
10 | **In order to have an easy start it is recommended to read the following lines.**
11 | I will try to keep them as short as possible.
12 |
13 | The base of MSS consists of four classes
14 |
15 | ### MSSSelector
16 | The selector is the actual path (mostly a rectangle) to mark a selection on the content. The selector can have any form since it is a simple NSBezierPath. But if you just like to change colors or lines you don't have to overwrite the MSSSelector class because MSS comes with MSSSelectorStyles which are easily configurable via Interface Builder.
17 |
18 | ### MSSCanvas
19 | To avoid any conflics with the contentView (e.g. NSImageView) all selectors will be drawn on a so called canvas.That's it. :)
20 |
21 | ### MSSCanvasController
22 | The canvasController handles all interactions between the view, the canvas, selectors, the mouse and others. canvasController also takes care of drawing, resizing, moving and removing. You don't even have to add the canvas as subview on your view since the controller takes care of adding and arranging too.
23 |
24 | ### MSSHandle
25 | A handle is a little path (by default a circle) at the selector's corners. The task of a handle is to provide an anchor to resize the selector in different directions. Like the selector, a handle can have any form you like. To change the colors only, MSS provides a style class (MSSHandleStyle) here as well.
26 |
27 | ### AddOn: MSSExtractor
28 | An extractor is not part of the actual base classes but yet quite important. Why ? Well, because all the fancy selectors would be very useless unless you can extract the content out of the selected areas. Because the job of an extractor depends on the purpose (e.g. cropping images) the MSSExtractor class is meant to be "abstract" and must be derived for any new purpose. The example project will make that more clear.
29 |
30 |
31 | ## Quick start & further information
32 |
33 | If you clone the git repository you'll get a complete Xcode workspace including
34 | the framework (MultiSelectionSuite) itself and an example project (MultiSelectionSuiteApp).
35 | If you press "Run" the framework and the example app should be built.
36 |
37 | Now let's take a closer look on the example project:
38 |
39 | ### Understand the example project
40 |
41 | The example project contains three real-world applications for MSS:
42 |
43 | - Image cropping
44 | - Zooming
45 | - Scan data extraction (Using my SPScannerCaptureWindow.bundle)
46 |
47 | **Next:** Open the example project (MultiSelectionSuiteApp) and take a look on the CropImageWindow.xib (under "Crop" Group)
48 |
49 | - The main view under the window containts a normal NSImageView
50 | - This image view is connected to the Outlet "contentView" of the "Canvas Controller" (MSSCanvasController)
51 | - The Outlet "view" of the "Canvas Controller" is connected to the "Canvas" (MSSCanvas)
52 | - Note that the "Canvas" is just somewhere in the room and not a subview of another view
53 | - The Outlet "delegate" of the "Canvas" is connected to the "Canvas Controller"
54 |
55 | **If we only would like to have selectors on the image view without any purpose we would be finish here.**
56 |
57 | **BUT** We're not satisfied yet, cause we want extract some content.
58 |
59 | - The Outlet "canvasController" of "Image Extractor" (MSSImageExtractor) is connected to "Canvas Controller"
60 | - The Outlet "contentExtractor" of "Canvas Controller" is connected to "Image Extractor"
61 | - The Outlet "delegate" of the "Image Extractor" is connected to the "File's owner" (CropImageWindow.h)
62 | - The IBAction of the "Save" button is in the "File's Owner" - so open "CropImageWindow.m"
63 | - The IBAction "saveImages" calls the "prepareJob"-Method of the "Image Extractor" (MSSImageExtractor)
64 | - Note that "CropImageWindow" confirms with the "MSSExtractorDelegate" protocol
65 | - Take look in the "extractor:extractElement:forJob"-Method (in CropImageWindow.h)
66 | - Whenever an extractor pulls content (here: images) this delegate method will be called
67 | - When all extractions are done the "extractor:didCompleteWithError"-Method will be called
68 | - The image extractor comes with a "saveImage:withType"-Method which will be called here
69 | - Note that the extractor contains all "elements" which have been extracted ... **DONE**
70 |
71 | ### Use the framework outside the example project
72 |
73 | The example project uses the product (MultiSelectionSuite.framework) of the framework project (MultiSelectionSuite).
74 | If you like to use the framework outside the example project you can either install
75 | the framework under /Library/Frameworks or embed it as "Private Framework" in your project's Application Bundle. The advantage of latter is there is no need of an installation process
76 | because everything will be inside your Application Bundle. Drawback: In order to use newer versions of the framework you need to rebuild your App, too. However: Here you'll learn about how to embed & link to a private framework in your Application.
77 |
78 | ### Nice to have information
79 |
80 | But how, where and when we assign which content fragment we want ? Well, this is all done in the MSSImageExtractor in cooperation with the canvasController. Since this project is open source and MSSImageExtractor has only one method you'll easily understand how it works.
81 |
82 | ### Strong recommendation
83 |
84 | Since you have a good basic understanding how MSS works and how you can use it in your projects I want to stop here explaining the example project. Of course I encourage you to discover the "Scan" and "Zoom" sections in the project. The "Zoom" section uses the styles for selectors (MSSSelectionStyle) and handles (MSSHandleStyle). You'll be delighted how nice & easy these are to use.
85 |
86 | The "Scan" section uses a special bundle of mine to encapsulate the quite complex scanning process. With "complex" I mean: There's a lot of boiler code which could distract you from learning more about this framework. Btw: The bundle uses the framework as well. If you like to know more about how scanning works in Cocoa: The bundle is open source too. You'll find it [here](https://github.com/ckteebe/SPScannerCaptureWindow).
87 |
88 | In order to understand the complete workflow between the canvasController and the extractors you should make you own extractor. Please keep in mind to derive your extractor from the master class MSSExtractor. If the extractor is useful for others I would be happy if you make it public for everyone by a pull request.
89 |
90 |
91 | ## Documention
92 |
93 | The code documentation of the framework can be found [here](http://assets.saschapaulus.de/mss/doc/v1/).
94 |
--------------------------------------------------------------------------------