├── .gitignore
├── LICENSE
├── MicroPrint UI
├── Base.lproj
│ └── Main.storyboard
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── microprint1024.png
│ │ ├── microprint128.png
│ │ ├── microprint16.png
│ │ ├── microprint16@2x.png
│ │ ├── microprint256-1.png
│ │ ├── microprint256.png
│ │ ├── microprint32.png
│ │ ├── microprint512-1.png
│ │ ├── microprint512.png
│ │ └── microprint64.png
│ ├── Contents.json
│ ├── Micro.imageset
│ │ ├── Contents.json
│ │ ├── Micro.png
│ │ └── Micro@2x.png
│ └── Printbed.imageset
│ │ ├── Contents.json
│ │ ├── Printbed.png
│ │ └── Printbed@2x.png
├── Info.plist
├── TFPAppleScriptSupport.h
├── TFPAppleScriptSupport.m
├── TFPApplicationDelegate.h
├── TFPApplicationDelegate.m
├── TFPBacklashSettingsViewController.h
├── TFPBacklashSettingsViewController.m
├── TFPBedLevelCalibrationViewController.h
├── TFPBedLevelCalibrationViewController.m
├── TFPBedLevelSettingsViewController.h
├── TFPBedLevelSettingsViewController.m
├── TFPCalibrationViewController.h
├── TFPCalibrationViewController.m
├── TFPConsoleViewController.h
├── TFPConsoleViewController.m
├── TFPGCodeDocument.h
├── TFPGCodeDocument.m
├── TFPPrintSettingsViewController.h
├── TFPPrintSettingsViewController.m
├── TFPPrinterCollectionViewItem.h
├── TFPPrinterCollectionViewItem.m
├── TFPPrinterListCollectionView.h
├── TFPPrinterListCollectionView.m
├── TFPPrinterListViewController.h
├── TFPPrinterListViewController.m
├── TFPPrinterOperationsViewController.h
├── TFPPrinterOperationsViewController.m
├── TFPPrintingProgressViewController.h
├── TFPPrintingProgressViewController.m
├── TFPScriptManager.h
├── TFPScriptManager.m
├── TFPUIExtras.h
├── TFPUIExtras.m
├── TFPVisualPrintProgressView.h
├── TFPVisualPrintProgressView.m
├── TFPZeroHeadViewController.h
├── TFPZeroHeadViewController.m
└── main.m
├── README.md
├── microprint.xcodeproj
└── project.pbxproj
└── microprint
├── .DS_Store
├── MAKVONotificationCenter.h
├── MAKVONotificationCenter.m
├── MicroPrint.sdef
├── ORSSerialPort.h
├── ORSSerialPort.m
├── ORSSerialPortManager.h
├── ORSSerialPortManager.m
├── ORSSerialRequest.h
├── ORSSerialRequest.m
├── ProfileTranslations.rtf
├── Sparkle.framework
├── Headers
├── Modules
├── PrivateHeaders
├── Resources
├── Sparkle
└── Versions
│ ├── A
│ ├── Headers
│ │ ├── SUAppcast.h
│ │ ├── SUAppcastItem.h
│ │ ├── SUErrors.h
│ │ ├── SUExport.h
│ │ ├── SUStandardVersionComparator.h
│ │ ├── SUUpdater.h
│ │ ├── SUVersionComparisonProtocol.h
│ │ ├── SUVersionDisplayProtocol.h
│ │ └── Sparkle.h
│ ├── Modules
│ │ └── module.modulemap
│ ├── PrivateHeaders
│ │ └── SUUnarchiver.h
│ ├── Resources
│ │ ├── Autoupdate.app
│ │ │ └── Contents
│ │ │ │ ├── Info.plist
│ │ │ │ ├── MacOS
│ │ │ │ └── Autoupdate
│ │ │ │ ├── PkgInfo
│ │ │ │ └── Resources
│ │ │ │ ├── AppIcon.icns
│ │ │ │ ├── SUStatus.nib
│ │ │ │ ├── ar.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── cs.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── da.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── de.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── el.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── en.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── es.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── fr.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── is.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── it.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── ja.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── ko.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── nb.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── nl.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── pl.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── pt_BR.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── pt_PT.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── ro.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── ru.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── sk.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── sl.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── sv.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── th.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── tr.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── uk.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ ├── zh_CN.lproj
│ │ │ │ └── Sparkle.strings
│ │ │ │ └── zh_TW.lproj
│ │ │ │ └── Sparkle.strings
│ │ ├── Info.plist
│ │ ├── SUModelTranslation.plist
│ │ ├── SUStatus.nib
│ │ ├── ar.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── cs.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── da.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── de.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── el.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── en.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── es.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── fr.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── fr_CA.lproj
│ │ ├── is.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── it.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── ja.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── ko.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── nb.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── nl.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── pl.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── pt.lproj
│ │ ├── pt_BR.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── pt_PT.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── ro.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── ru.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── sk.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── sl.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── sv.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── th.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── tr.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── uk.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ ├── zh_CN.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ │ └── zh_TW.lproj
│ │ │ ├── SUAutomaticUpdateAlert.nib
│ │ │ ├── SUUpdateAlert.nib
│ │ │ ├── SUUpdatePermissionPrompt.nib
│ │ │ └── Sparkle.strings
│ └── Sparkle
│ └── Current
├── TFAsyncOperationCoalescer.h
├── TFAsyncOperationCoalescer.m
├── TFDataBuilder.h
├── TFDataBuilder.m
├── TFP3DVector.h
├── TFP3DVector.m
├── TFPApplicationDebug.h
├── TFPApplicationDebug.m
├── TFPBedLevelCalibration.h
├── TFPBedLevelCalibration.m
├── TFPBedLevelCompensator.h
├── TFPBedLevelCompensator.m
├── TFPDryRunPrinter.h
├── TFPDryRunPrinter.m
├── TFPDryRunPrinterConnection.h
├── TFPDryRunPrinterConnection.m
├── TFPExtras.h
├── TFPExtras.m
├── TFPExtrusionOperation.h
├── TFPExtrusionOperation.m
├── TFPFilament.h
├── TFPFilament.m
├── TFPGCode.h
├── TFPGCode.m
├── TFPGCodeHelpers.h
├── TFPGCodeHelpers.m
├── TFPGCodeProgram.h
├── TFPGCodeProgram.m
├── TFPOperation.h
├── TFPOperation.m
├── TFPPrintJob.h
├── TFPPrintJob.m
├── TFPPrintParameters.h
├── TFPPrintParameters.m
├── TFPPrintStatusController.h
├── TFPPrintStatusController.m
├── TFPPrinter+VirtualEEPROM.h
├── TFPPrinter+VirtualEEPROM.m
├── TFPPrinter.h
├── TFPPrinter.m
├── TFPPrinterConnection.h
├── TFPPrinterConnection.m
├── TFPPrinterHelpers.h
├── TFPPrinterHelpers.m
├── TFPPrinterManager.h
├── TFPPrinterManager.m
├── TFPRaiseHeadOperation.h
├── TFPRaiseHeadOperation.m
├── TFPSlicerProfile.h
├── TFPSlicerProfile.m
├── TFPStopwatch.h
├── TFPStopwatch.m
├── TFPZeroBedOperation.h
├── TFPZeroBedOperation.m
├── TFStringScanner.h
├── TFStringScanner.m
├── TFTimer.h
└── TFTimer.m
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | # CocoaPods
21 | #
22 | # We recommend against adding the Pods directory to your .gitignore. However
23 | # you should judge for yourself, the pros and cons are mentioned at:
24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
25 | #
26 | #Pods/
27 | microprint.xcodeproj/project.xcworkspace/contents.xcworkspacedata
28 | .DS_Store
29 | microprint.xcodeproj/project.xcworkspace
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Tomas Franzén
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 |
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "microprint16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "microprint16@2x.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "microprint32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "microprint64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "microprint128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "microprint256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "microprint256-1.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "microprint512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "microprint512-1.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "microprint1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint1024.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint128.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint16.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint16@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint16@2x.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint256-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint256-1.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint256.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint32.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint512-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint512-1.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint512.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/AppIcon.appiconset/microprint64.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/Micro.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Micro.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "Micro@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/Micro.imageset/Micro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/Micro.imageset/Micro.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/Micro.imageset/Micro@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/Micro.imageset/Micro@2x.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/Printbed.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Printbed.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "Printbed@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/Printbed.imageset/Printbed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/Printbed.imageset/Printbed.png
--------------------------------------------------------------------------------
/MicroPrint UI/Images.xcassets/Printbed.imageset/Printbed@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/MicroPrint UI/Images.xcassets/Printbed.imageset/Printbed@2x.png
--------------------------------------------------------------------------------
/MicroPrint UI/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSAppTransportSecurity
6 |
7 | NSExceptionDomains
8 |
9 | tomasf.se
10 |
11 | NSExceptionAllowsInsecureHTTPLoads
12 |
13 |
14 |
15 | NSAllowsArbitraryLoads
16 |
17 |
18 | CFBundleDevelopmentRegion
19 | en
20 | CFBundleDocumentTypes
21 |
22 |
23 | CFBundleTypeExtensions
24 |
25 | gcode
26 |
27 | CFBundleTypeIconFile
28 |
29 | CFBundleTypeName
30 | G-code file
31 | CFBundleTypeOSTypes
32 |
33 | ????
34 |
35 | CFBundleTypeRole
36 | Viewer
37 | NSDocumentClass
38 | TFPGCodeDocument
39 |
40 |
41 | CFBundleExecutable
42 | $(EXECUTABLE_NAME)
43 | CFBundleIdentifier
44 | $(PRODUCT_BUNDLE_IDENTIFIER)
45 | CFBundleInfoDictionaryVersion
46 | 6.0
47 | CFBundleName
48 | $(PRODUCT_NAME)
49 | CFBundlePackageType
50 | APPL
51 | SUFeedURL
52 | http://tomasf.se/projects/microprint/appcast.xml
53 | SUEnableAutomaticChecks
54 |
55 | SUScheduledCheckInterval
56 | 86400
57 | CFBundleShortVersionString
58 | 201509301800
59 | CFBundleSignature
60 | ????
61 | CFBundleVersion
62 | 201509301800
63 | LSMinimumSystemVersion
64 | $(MACOSX_DEPLOYMENT_TARGET)
65 | NSAppleScriptEnabled
66 |
67 | NSHumanReadableCopyright
68 | Copyright © 2015 Tomas Franzén. All rights reserved.
69 | NSMainStoryboardFile
70 | Main
71 | NSPrincipalClass
72 | NSApplication
73 | OSAScriptingDefinition
74 | MicroPrint.sdef
75 |
76 |
77 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPAppleScriptSupport.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPAppleScriptSupport.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-07-21.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPPrintSettingsViewController.h"
11 |
12 | @interface TFPPrintSettingsViewController (AppleScriptSupport)
13 | @end
14 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPApplicationDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // MicroPrint UI
4 | //
5 | // Created by Tomas Franzén on Mon 2015-07-13.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TFPApplicationDelegate : NSObject
12 | @end
13 |
14 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPApplicationDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // MicroPrint UI
4 | //
5 | // Created by Tomas Franzén on Mon 2015-07-13.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPApplicationDelegate.h"
10 | #import "TFPPrinterManager.h"
11 | #import "TFPPrinter.h"
12 | #import "TFPDryRunPrinter.h"
13 | #import "TFPBedLevelCompensator.h"
14 |
15 | #import "TFPExtras.h"
16 |
17 |
18 | @interface TFPApplicationDelegate ()
19 | @property NSWindow *mainWindow;
20 | @property TFPPrinterContext *debugContext;
21 | @property (copy) void(^debugCancelBlock)();
22 | @end
23 |
24 |
25 | @implementation TFPApplicationDelegate
26 |
27 |
28 | - (void)applicationDidFinishLaunching:(NSNotification *)notification {
29 | self.mainWindow = [NSApp windows].firstObject;
30 | }
31 |
32 |
33 | - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender {
34 | [self.mainWindow makeKeyAndOrderFront:nil];
35 | return NO;
36 | }
37 |
38 |
39 | - (IBAction)openMainWindow:(id)sender {
40 | [self.mainWindow makeKeyAndOrderFront:nil];
41 | }
42 |
43 |
44 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPBacklashSettingsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPBacklashSettings.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-16.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPPrinter.h"
11 |
12 |
13 | @interface TFPBacklashSettingsViewController : NSViewController
14 | @property TFPPrinter *printer;
15 | @end
16 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPBacklashSettingsViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPBacklashSettings.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-16.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPBacklashSettingsViewController.h"
10 |
11 | #import "MAKVONotificationCenter.h"
12 |
13 |
14 | @interface TFPBacklashSettingsViewController ()
15 | @property double xValue;
16 | @property double yValue;
17 | @property double speed;
18 |
19 | @property BOOL hasChanges;
20 | @end
21 |
22 |
23 | @implementation TFPBacklashSettingsViewController
24 |
25 | - (void)viewDidAppear {
26 | [super viewDidAppear];
27 | __weak __typeof__(self) weakSelf = self;
28 |
29 | [self addObserver:self keyPath:@"printer.backlashValues" options:NSKeyValueObservingOptionInitial block:^(MAKVONotification *notification) {
30 | if(!weakSelf.hasChanges) {
31 | weakSelf.xValue = weakSelf.printer.backlashValues.x;
32 | weakSelf.yValue = weakSelf.printer.backlashValues.y;
33 | weakSelf.speed = weakSelf.printer.backlashValues.speed;
34 | weakSelf.hasChanges = NO;
35 | }
36 | }];
37 |
38 | [self addObserver:self keyPath:@[@"xValue", @"yValue", @"speed"] options:0 block:^(MAKVONotification *notification) {
39 | weakSelf.hasChanges = YES;
40 | }];
41 | }
42 |
43 |
44 | - (IBAction)apply:(id)sender {
45 | TFPBacklashValues values = {.x = self.xValue, .y = self.yValue, .speed = self.speed};
46 | self.printer.backlashValues = values;
47 | self.hasChanges = NO;
48 | }
49 |
50 |
51 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPBedLevelCalibrationViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPBedLevelCalibrationViewController.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sat 2015-07-18.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | @class TFPPrinter;
11 | @class TFPBedLevelSettingsViewController;
12 |
13 | @interface TFPBedLevelCalibrationViewController : NSViewController
14 | @property TFPPrinter *printer;
15 | @property (weak) TFPBedLevelSettingsViewController *bedLevelSettingsViewController;
16 | @end
17 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPBedLevelCalibrationViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPBedLevelCalibrationViewController.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sat 2015-07-18.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPBedLevelCalibrationViewController.h"
10 | #import "TFPBedLevelCalibration.h"
11 | #import "TFPExtras.h"
12 | #import "TFPBedLevelSettingsViewController.h"
13 |
14 |
15 | @interface TFPBedLevelCalibrationViewController ()
16 | @property TFPBedLevelCalibration *operation;
17 | @property IBOutlet NSTabView *tabView;
18 | @property IBOutlet NSStepper *levelStepper;
19 | @property TFPBedLevelCalibrationCorner currentCorner;
20 |
21 | @property double startLevel;
22 | @end
23 |
24 |
25 | @implementation TFPBedLevelCalibrationViewController
26 |
27 |
28 | - (void)switchToMovingMode {
29 | [self.tabView selectTabViewItemWithIdentifier:@"moving"];
30 | }
31 |
32 |
33 | - (void)switchToAdjustmentMode {
34 | [self.tabView selectTabViewItemWithIdentifier:@"adjustment"];
35 | }
36 |
37 |
38 | - (NSString*)cornerString {
39 | return @{@(TFPBedLevelCalibrationCornerBackLeft): @"Back-left corner",
40 | @(TFPBedLevelCalibrationCornerBackRight): @"Back-right corner",
41 | @(TFPBedLevelCalibrationCornerBackFrontRight): @"Front-right corner",
42 | @(TFPBedLevelCalibrationCornerBackFrontLeft): @"Front-left corner",
43 | @(TFPBedLevelCalibrationCornerCenter): @"Center"
44 | }[@(self.currentCorner)];
45 | }
46 |
47 |
48 | + (NSSet *)keyPathsForValuesAffectingCornerString {
49 | return @[@"currentCorner"].tf_set;
50 | }
51 |
52 |
53 | - (NSString*)continueString {
54 | if(self.currentCorner == TFPBedLevelCalibrationCornerLast) {
55 | return @"Finish Calibration";
56 | }else{
57 | return @"Next Corner";
58 | }
59 | }
60 |
61 |
62 | + (NSSet *)keyPathsForValuesAffectingContinueString {
63 | return @[@"currentCorner"].tf_set;
64 | }
65 |
66 |
67 | - (IBAction)stepperAction:(NSStepper*)stepper {
68 | if(stepper.doubleValue < 0) {
69 | [self.operation adjustDown];
70 | }else{
71 | [self.operation adjustUp];
72 | }
73 | stepper.doubleValue = 0;
74 | }
75 |
76 |
77 | - (void)viewDidLoad {
78 | [super viewDidLoad];
79 | BOOL alt = !!([NSEvent modifierFlags] & NSAlternateKeyMask);
80 | self.startLevel = alt ? 50 : 3;
81 | }
82 |
83 |
84 | - (void)viewDidAppear {
85 | [super viewDidAppear];
86 | __weak __typeof__(self) weakSelf = self;
87 |
88 | if(self.operation) {
89 | return;
90 | }
91 |
92 | self.operation = [[TFPBedLevelCalibration alloc] initWithPrinter:self.printer];
93 | [self.operation startAtLevel:self.startLevel heightTarget:0.3];
94 |
95 | self.operation.didStartMovingHandler = ^{
96 | [weakSelf switchToMovingMode];
97 | };
98 |
99 | self.operation.didStopAtCornerHandler = ^(TFPBedLevelCalibrationCorner corner){
100 | weakSelf.currentCorner = corner;
101 | [weakSelf switchToAdjustmentMode];
102 | };
103 |
104 | self.operation.didFinishHandler = ^{
105 | [weakSelf dismissController:nil];
106 | };
107 |
108 | [self.view.window makeFirstResponder:self.levelStepper];
109 | }
110 |
111 |
112 | - (BOOL)performKeyEquivalent:(NSEvent *)theEvent {
113 | NSString *string = theEvent.characters;
114 | unichar c = string.length ? [string characterAtIndex:0] : 0;
115 |
116 | if(c == NSUpArrowFunctionKey || c == NSDownArrowFunctionKey) {
117 | [self.levelStepper keyUp:theEvent];
118 | return YES;
119 | } else {
120 | return NO;
121 | }
122 | }
123 |
124 |
125 | - (IBAction)next:(id)sender {
126 | [self.operation continue];
127 | }
128 |
129 |
130 | - (IBAction)cancel:(id)sender {
131 | [self.operation stop];
132 | [self dismissController:nil];
133 | }
134 |
135 |
136 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPBedLevelSettingsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPBedLevelSettingsViewController.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-16.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | @import AppKit;
10 | #import "TFPCalibrationViewController.h"
11 | #import "TFPPrinter.h"
12 |
13 | @interface TFPBedLevelSettingsViewController : TFPCalibrationViewController
14 | @end
15 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPBedLevelSettingsViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPBedLevelSettingsViewController.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-16.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPBedLevelSettingsViewController.h"
10 | #import "TFPBedLevelCalibrationViewController.h"
11 | #import "MAKVONotificationCenter.h"
12 |
13 |
14 | @interface TFPBedLevelSettingsViewController ()
15 | @property double backLeftOffset;
16 | @property double backRightOffset;
17 | @property double frontRightOffset;
18 | @property double frontLeftOffset;
19 | @property double commonOffset;
20 |
21 | @property BOOL hasChanges;
22 |
23 | @property NSWindowController *calibrationWindowController;
24 | @end
25 |
26 |
27 | @implementation TFPBedLevelSettingsViewController
28 |
29 |
30 | - (void)viewDidAppear {
31 | [super viewDidAppear];
32 | __weak __typeof__(self) weakSelf = self;
33 |
34 | [self addObserver:self keyPath:@"printer.bedLevelOffsets" options:NSKeyValueObservingOptionInitial block:^(MAKVONotification *notification) {
35 | if(!weakSelf.hasChanges) {
36 | weakSelf.backLeftOffset = weakSelf.printer.bedLevelOffsets.backLeft;
37 | weakSelf.backRightOffset = weakSelf.printer.bedLevelOffsets.backRight;
38 | weakSelf.frontRightOffset = weakSelf.printer.bedLevelOffsets.frontRight;
39 | weakSelf.frontLeftOffset = weakSelf.printer.bedLevelOffsets.frontLeft;
40 | weakSelf.commonOffset = weakSelf.printer.bedLevelOffsets.common;
41 | weakSelf.hasChanges = NO;
42 | }
43 | }];
44 |
45 | [self addObserver:self keyPath:@[@"backLeftOffset", @"backRightOffset", @"frontRightOffset", @"frontLeftOffset", @"commonOffset"] options:0 block:^(MAKVONotification *notification) {
46 | weakSelf.hasChanges = YES;
47 | }];
48 | }
49 |
50 |
51 | - (IBAction)apply:(id)sender {
52 | TFPBedLevelOffsets offsets;
53 | offsets.backLeft = self.backLeftOffset;
54 | offsets.backRight = self.backRightOffset;
55 | offsets.frontRight = self.frontRightOffset;
56 | offsets.frontLeft = self.frontLeftOffset;
57 | offsets.common = self.commonOffset;
58 |
59 | self.printer.bedLevelOffsets = offsets;
60 | self.hasChanges = NO;
61 | }
62 |
63 |
64 | - (IBAction)interactiveCalibration:(id)sender {
65 | NSWindowController *windowController = [self.storyboard instantiateControllerWithIdentifier:@"BedLevelCalibrationWindowController"];
66 | TFPBedLevelCalibrationViewController *viewController = (TFPBedLevelCalibrationViewController*)windowController.contentViewController;
67 | viewController.printer = self.printer;
68 | viewController.bedLevelSettingsViewController = self;
69 |
70 | [self presentViewControllerAsSheet:viewController];
71 | }
72 |
73 |
74 | - (void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender {
75 | [(TFPCalibrationViewController*)segue.destinationController setPrinter:self.printer];
76 | }
77 |
78 |
79 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPCalibrationViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPCalibrationViewController.h
3 | // microprint
4 | //
5 | // Created by William Waggoner on 8/2/15.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPPrinter.h"
11 |
12 | @interface TFPCalibrationViewController : NSViewController
13 | @property TFPPrinter *printer;
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPCalibrationViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPCalibrationViewController.m
3 | // microprint
4 | //
5 | // Created by William Waggoner on 8/2/15.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPCalibrationViewController.h"
10 |
11 | @interface TFPCalibrationViewController ()
12 |
13 | @end
14 |
15 | @implementation TFPCalibrationViewController
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPConsoleViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPConsoleViewController.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-30.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPPrinter.h"
11 |
12 |
13 | @interface TFPConsoleViewController : NSViewController
14 | @property TFPPrinter *printer;
15 | @end
16 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPConsoleViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPConsoleViewController.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-30.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPConsoleViewController.h"
10 | #import "TFPExtras.h"
11 |
12 | static const NSUInteger consoleMax = 100000;
13 | static const NSUInteger consoleTrim = consoleMax / 10;
14 |
15 |
16 | @interface TFPConsoleViewController ()
17 | @property IBOutlet NSTextView *textView;
18 | @property IBOutlet NSTextField *inputField;
19 | @property unsigned long consoleLength;
20 | @end
21 |
22 |
23 |
24 | @implementation TFPConsoleViewController
25 |
26 |
27 | - (void)appendLine:(NSString*)line attributes:(NSDictionary*)attrs {
28 | line = [line stringByAppendingString:@"\n"];
29 | NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:line attributes:attrs];
30 | [self.textView.textStorage appendAttributedString:attributedString];
31 |
32 | [self.textView scrollRangeToVisible: NSMakeRange(self.textView.string.length, 0)];
33 |
34 | self.consoleLength += attributedString.length;
35 |
36 | if (self.consoleLength > consoleMax) {
37 | [self.textView.textStorage deleteCharactersInRange: NSMakeRange(0, consoleTrim)];
38 | self.consoleLength = self.textView.textStorage.length;
39 | }
40 | }
41 |
42 |
43 | - (void)viewDidAppear {
44 | [super viewDidAppear];
45 | __weak __typeof__(self) weakSelf = self;
46 |
47 | self.consoleLength = 0;
48 |
49 | NSColor *noticeColor = [NSColor colorWithCalibratedRed:0.625 green:0.000 blue:0.026 alpha:1.000];
50 |
51 | NSDictionary *incomingAttributes = @{NSFontAttributeName: [NSFont fontWithName:@"Menlo" size:13]};
52 | NSDictionary *outgoingAttributes = @{NSFontAttributeName: [NSFont fontWithName:@"Menlo-Bold" size:13]};
53 | NSDictionary *noticeAttributes = @{NSFontAttributeName: [NSFont fontWithName:@"Menlo-Italic" size:13], NSForegroundColorAttributeName: noticeColor};
54 |
55 | self.printer.incomingCodeBlock = ^(NSString *line) {
56 | [weakSelf appendLine:line attributes:incomingAttributes];
57 | };
58 | self.printer.outgoingCodeBlock = ^(NSString *line) {
59 | [weakSelf appendLine:line attributes:outgoingAttributes];
60 | };
61 | self.printer.noticeBlock = ^(NSString *line) {
62 | [weakSelf appendLine:line attributes:noticeAttributes];
63 | };
64 |
65 | self.textView.string = @"";
66 | [self.view.window makeFirstResponder:self.inputField];
67 | }
68 |
69 |
70 | - (void)viewDidDisappear {
71 | [super viewDidDisappear];
72 | self.printer.incomingCodeBlock = nil;
73 | self.printer.outgoingCodeBlock = nil;
74 | }
75 |
76 |
77 | - (IBAction)fieldAction:(id)sender {
78 | __block BOOL valid = YES;
79 |
80 | NSArray *codes = [[self.inputField.stringValue componentsSeparatedByString:@"\n"] tf_mapWithBlock:^TFPGCode*(NSString *line) {
81 | TFPGCode *code = [TFPGCode codeWithString:line];
82 | if(!code) {
83 | valid = NO;
84 | }
85 | return code;
86 | }];
87 |
88 | if(valid) {
89 | for(TFPGCode *code in codes) {
90 | [self.printer sendGCode:code responseHandler:nil];
91 | }
92 | self.inputField.stringValue = @"";
93 | } else {
94 | NSBeep();
95 | }
96 | }
97 |
98 |
99 | - (IBAction)clearLog:(id)sender {
100 | [self.textView setString:@""];
101 | }
102 |
103 |
104 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPGCodeDocument.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPGCodeDocument.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-07-13.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPFilament.h"
11 | #import "TFPGCodeHelpers.h"
12 | #import "TFPSlicerProfile.h"
13 |
14 | @class TFP3DVector, TFPPrinter;
15 |
16 |
17 | @interface TFPGCodeDocument : NSDocument
18 | @property TFPGCodeProgram *program;
19 |
20 | @property (readonly) BOOL hasBoundingBox;
21 | @property (readonly) TFPCuboid boundingBox;
22 | @property (readonly) TFPSlicerProfile *slicerProfile;
23 |
24 | @property TFPFilamentType filamentType;
25 | @property NSNumber *temperature;
26 | @property BOOL useThermalBonding;
27 |
28 | @property TFPPrinter *selectedPrinter;
29 | @property NSURL *completionScriptURL;
30 |
31 | - (void)saveSettings;
32 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPPrintSettingsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrintSettingsViewController.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-07-13.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | @class TFPGCodeDocument;
11 |
12 | @interface TFPPrintSettingsViewController : NSViewController
13 | @property (strong) TFPGCodeDocument *document;
14 | @end
15 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPPrinterCollectionViewItem.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinterCollectionViewItem.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-07-14.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TFPPrinterCollectionViewItem : NSCollectionViewItem
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPPrinterListCollectionView.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinterListCollectionView.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-30.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TFPPrinterListCollectionView : NSCollectionView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPPrinterListCollectionView.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinterListCollectionView.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-30.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPPrinterListCollectionView.h"
10 |
11 | @implementation TFPPrinterListCollectionView
12 |
13 | - (NSCollectionViewItem *)newItemForRepresentedObject:(id)object {
14 | NSCollectionViewItem *item = [[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:@"printerItemPrototype"];
15 | item.representedObject = object;
16 | return item;
17 | }
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPPrinterListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // MicroPrint UI
4 | //
5 | // Created by Tomas Franzén on Mon 2015-07-13.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TFPPrinterListViewController : NSViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPPrinterListViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // MicroPrint UI
4 | //
5 | // Created by Tomas Franzén on Mon 2015-07-13.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPPrinterListViewController.h"
10 | #import "TFPPrinterManager.h"
11 | #import "TFPDryRunPrinter.h"
12 | #import "TFPApplicationDelegate.h"
13 | #import "TFPExtras.h"
14 |
15 |
16 | @interface TFPPrinterListViewController ()
17 | @property IBOutlet NSCollectionView *collectionView;
18 | @property TFPPrinterManager *printerManager;
19 |
20 | @property IBOutlet NSPopUpButton *recentsButton;
21 | @end
22 |
23 |
24 |
25 | @implementation TFPPrinterListViewController
26 |
27 | - (void)viewDidLoad {
28 | [super viewDidLoad];
29 |
30 | self.collectionView.itemPrototype = [self.storyboard instantiateControllerWithIdentifier:@"printerItemPrototype"];
31 | self.collectionView.maxItemSize = CGSizeMake(0, 100);
32 |
33 | self.printerManager = [TFPPrinterManager sharedManager];
34 | }
35 |
36 |
37 | - (void)openRecentDocument:(NSMenuItem*)menuItem {
38 | NSURL *URL = menuItem.representedObject;
39 | [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:URL display:YES completionHandler:^(NSDocument * _Nullable document, BOOL documentWasAlreadyOpen, NSError * _Nullable error) {
40 |
41 | }];
42 | }
43 |
44 |
45 | - (void)menuNeedsUpdate:(NSMenu *)menu {
46 | [menu removeAllItems];
47 |
48 | NSMenuItem *titleItem = [[NSMenuItem alloc] initWithTitle:@"Recent Files" action:nil keyEquivalent:@""];
49 | [menu addItem:titleItem];
50 |
51 | NSArray *newItems = [[[NSDocumentController sharedDocumentController] recentDocumentURLs] tf_mapWithBlock:^NSMenuItem*(NSURL *URL) {
52 | NSDictionary *resourceValues = [URL resourceValuesForKeys:@[NSURLEffectiveIconKey, NSURLLocalizedNameKey] error:nil];
53 | NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:resourceValues[NSURLLocalizedNameKey] action:@selector(openRecentDocument:) keyEquivalent:@""];
54 | item.target = self;
55 | item.representedObject = URL;
56 |
57 | NSImage *image = [resourceValues[NSURLEffectiveIconKey] copy];
58 | image.size = CGSizeMake(16, 16);
59 | item.image = image;
60 |
61 | return item;
62 | }];
63 |
64 | for(NSMenuItem *newItem in newItems){
65 | [menu addItem:newItem];
66 | }
67 | }
68 |
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPPrinterOperationsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPFilamentOperationsViewController.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-07-14.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | @class TFPPrinter;
11 |
12 | @interface TFPPrinterOperationsViewController : NSViewController
13 | @property TFPPrinter *printer;
14 | @end
15 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPPrinterOperationsViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPFilamentOperationsViewController.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-07-14.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPPrinterOperationsViewController.h"
10 | #import "TFPExtrusionOperation.h"
11 | #import "TFPRaiseHeadOperation.h"
12 | #import "TFPZeroBedOperation.h"
13 | #import "TFPExtras.h"
14 |
15 |
16 | @interface TFPPrinterOperationsViewController ()
17 | @property IBOutletCollection (NSButton) NSArray *actionButtons;
18 | @property NSArray *actionButtonTitles;
19 |
20 | @property IBOutlet NSButton *retractButton;
21 | @property IBOutlet NSButton *extrudeButton;
22 | @property IBOutlet NSButton *raiseButton;
23 | @property IBOutlet NSButton *closeButton;
24 |
25 | @property IBOutlet NSProgressIndicator *progressIndicator;
26 | @property IBOutlet NSTextField *statusLabel;
27 |
28 | @property TFPOperation *operation;
29 | @end
30 |
31 |
32 | @implementation TFPPrinterOperationsViewController
33 |
34 |
35 | - (void)startRetract:(BOOL)retract {
36 | __weak __typeof__(self) weakSelf = self;
37 |
38 | TFPExtrusionOperation *operation = [[TFPExtrusionOperation alloc] initWithPrinter:self.printer retraction:retract];
39 | self.operation = operation;
40 | self.progressIndicator.hidden = NO;
41 | [weakSelf.progressIndicator setIndeterminate:NO];
42 | [weakSelf.progressIndicator startAnimation:nil];
43 | weakSelf.statusLabel.stringValue = @"Preparing…";
44 |
45 | operation.preparationProgressBlock = ^(double fraction){
46 | weakSelf.progressIndicator.doubleValue = fraction;
47 | };
48 |
49 | operation.extrusionStartedBlock = ^() {
50 | [weakSelf.progressIndicator setIndeterminate:YES];
51 | weakSelf.statusLabel.stringValue = retract ? @"Retracting" : @"Extruding";
52 | };
53 |
54 | operation.extrusionStoppedBlock = ^() {
55 | [weakSelf operationDidStop];
56 | };
57 |
58 | [operation start];
59 | }
60 |
61 |
62 | - (void)operationDidStop {
63 | self.operation = nil;
64 | self.statusLabel.stringValue = @"";
65 | [self.progressIndicator stopAnimation:nil];
66 | self.progressIndicator.hidden = YES;
67 |
68 | [self.actionButtons enumerateObjectsUsingBlock:^(NSButton *button, NSUInteger index, BOOL *stop) {
69 | button.enabled = YES;
70 | button.title = self.actionButtonTitles[index];
71 | button.keyEquivalent = @"";
72 | }];
73 | self.closeButton.enabled = YES;
74 | }
75 |
76 |
77 | - (void)raise {
78 | __weak __typeof__(self) weakSelf = self;
79 | TFPRaiseHeadOperation *operation = [[TFPRaiseHeadOperation alloc] initWithPrinter:self.printer];
80 | operation.targetHeight = 70;
81 | self.progressIndicator.hidden = NO;
82 |
83 | self.operation = operation;
84 |
85 | operation.didStartBlock = ^{
86 | weakSelf.statusLabel.stringValue = @"Raising…";
87 | [weakSelf.progressIndicator setIndeterminate:YES];
88 | [weakSelf.progressIndicator startAnimation:nil];
89 | };
90 |
91 | operation.didStopBlock = ^(BOOL didMove){
92 | [weakSelf operationDidStop];
93 | };
94 |
95 | weakSelf.statusLabel.stringValue = @"Starting…";
96 | [operation start];
97 | }
98 |
99 |
100 | - (void)viewDidLoad {
101 | [super viewDidLoad];
102 | self.actionButtons = @[self.retractButton,
103 | self.extrudeButton,
104 | self.raiseButton,
105 | ];
106 | self.actionButtonTitles = [self.actionButtons valueForKey:@"title"];
107 | }
108 |
109 |
110 | - (void)viewDidAppear {
111 | [super viewDidAppear];
112 | self.view.window.styleMask &= ~NSResizableWindowMask;
113 | }
114 |
115 |
116 | - (IBAction)buttonAction:(id)sender {
117 | if(self.operation) {
118 | [self.operation stop];
119 | self.statusLabel.stringValue = @"Stopping…";
120 | }else{
121 | for(NSButton *button in self.actionButtons) {
122 | if(button != sender) {
123 | button.enabled = NO;
124 | }else{
125 | button.title = @"Stop";
126 | button.keyEquivalent = @"\r";
127 | }
128 | }
129 | self.closeButton.enabled = NO;
130 |
131 | if(sender == self.retractButton) {
132 | [self startRetract:YES];
133 |
134 | }else if(sender == self.extrudeButton) {
135 | [self startRetract:NO];
136 |
137 | }else if(sender == self.raiseButton) {
138 | [self raise];
139 | }
140 | }
141 | }
142 |
143 |
144 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPPrintingProgressViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrintingProgressViewController.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-07-14.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | @class TFPGCodeProgram, TFPPrinter, TFPPrintParameters;
11 |
12 | @interface TFPPrintingProgressViewController : NSViewController
13 | @property TFPGCodeProgram *program;
14 | @property TFPPrinter *printer;
15 | @property TFPPrintParameters *printParameters;
16 |
17 | - (void)start;
18 | @property (copy) void(^endHandler)(BOOL didFinishPrint);
19 |
20 | - (NSString*)elapsedTimeString;
21 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPScriptManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPScriptManager.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-23.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | @import AppKit;
10 |
11 |
12 | @interface TFPScriptManager : NSObject
13 | @property (readonly) NSArray *recentScripts;
14 |
15 | + (instancetype)sharedManager;
16 |
17 | - (void)addRecentScript:(NSURL*)URL;
18 | - (NSOpenPanel*)openPanelForSelectingScript;
19 | - (BOOL)runScriptFile:(NSURL*)URL printName:(NSString*)printName duration:(NSString*)durationString errorInfo:(NSDictionary**)error;
20 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPScriptManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPScriptManager.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-23.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPScriptManager.h"
10 | #import "TFPExtras.h"
11 | @import AppKit;
12 |
13 | static const NSUInteger maxRecentURLCount = 10;
14 |
15 |
16 | @interface TFPScriptManager ()
17 | @property (readwrite) NSArray *recentScripts;
18 | @end
19 |
20 |
21 | @implementation TFPScriptManager
22 |
23 |
24 | + (instancetype)sharedManager {
25 | static TFPScriptManager *singleton;
26 | return singleton ?: (singleton = [self new]);
27 | }
28 |
29 |
30 | - (void)readSavedRecentData {
31 | NSArray *bookmarks = [[NSUserDefaults standardUserDefaults] objectForKey:@"RecentScripts"] ?: @[];
32 |
33 | self.recentScripts = [bookmarks tf_mapWithBlock:^NSURL*(NSData *bookmark) {
34 | return [NSURL URLByResolvingBookmarkData:bookmark options:NSURLBookmarkResolutionWithoutUI | NSURLBookmarkResolutionWithoutMounting relativeToURL:nil bookmarkDataIsStale:nil error:nil];
35 | }];
36 | }
37 |
38 |
39 | - (void)writeRecentData {
40 | NSArray *bookmarks = [self.recentScripts tf_mapWithBlock:^NSData*(NSURL *URL) {
41 | return [URL bookmarkDataWithOptions:0 includingResourceValuesForKeys:nil relativeToURL:nil error:nil];
42 | }];
43 |
44 | [[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:@"RecentScripts"];
45 | }
46 |
47 |
48 | - (instancetype)init {
49 | if(!(self = [super init])) return nil;
50 |
51 | [self readSavedRecentData];
52 |
53 | return self;
54 | }
55 |
56 |
57 | - (void)addRecentScript:(NSURL*)URL {
58 | NSMutableArray *URLs = [self mutableArrayValueForKey:@"recentScripts"];
59 | [URLs removeObject:URL];
60 | [URLs insertObject:URL atIndex:0];
61 |
62 | if(URLs.count > maxRecentURLCount) {
63 | [URLs removeObjectsInRange:NSMakeRange(maxRecentURLCount, URLs.count-maxRecentURLCount)];
64 | }
65 |
66 | [self writeRecentData];
67 | }
68 |
69 |
70 | - (NSOpenPanel*)openPanelForSelectingScript {
71 | NSOpenPanel *openPanel = [NSOpenPanel openPanel];
72 | openPanel.allowedFileTypes = @[@"com.apple.applescript.script", @"scpt"];
73 | return openPanel;
74 | }
75 |
76 |
77 | - (BOOL)runScriptFile:(NSURL*)URL printName:(NSString*)printName duration:(NSString*)durationString errorInfo:(NSDictionary**)error {
78 | NSAppleScript *script = [[NSAppleScript alloc] initWithContentsOfURL:URL error:error];
79 | if(!script) {
80 | return NO;
81 | }
82 |
83 | const FourCharCode kASAppleScriptSuite = 'ascr';
84 | const FourCharCode kASSubroutineEvent = 'psbr';
85 | const FourCharCode keyASSubroutineName = 'snam';
86 |
87 | NSAppleEventDescriptor *event = [NSAppleEventDescriptor appleEventWithEventClass:kASAppleScriptSuite eventID:kASSubroutineEvent targetDescriptor:nil returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
88 |
89 | [event setParamDescriptor:[NSAppleEventDescriptor descriptorWithString:@"printFinished"] forKeyword:keyASSubroutineName];
90 |
91 | NSAppleEventDescriptor *arguments = [NSAppleEventDescriptor listDescriptor];
92 | [arguments insertDescriptor:[NSAppleEventDescriptor descriptorWithString:printName] atIndex:1];
93 | [arguments insertDescriptor:[NSAppleEventDescriptor descriptorWithString:durationString] atIndex:2];
94 | [event setParamDescriptor:arguments forKeyword:keyDirectObject];
95 |
96 | return [script executeAppleEvent:event error:error] != nil;
97 | }
98 |
99 |
100 | @end
101 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPUIExtras.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPUITFPExtras.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-07-14.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPPrinter.h"
11 |
12 |
13 | @interface TFPPrinter (UIExtras)
14 | @property (readonly) NSImage *printerImage;
15 | @end
16 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPUIExtras.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPUIExtras.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-07-14.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPUIExtras.h"
10 | #import "TFPOperation.h"
11 | #import "TFPExtras.h"
12 | @import AppKit;
13 |
14 |
15 | @implementation TFPPrinter (UIExtras)
16 |
17 |
18 | - (NSImage *)printerImage {
19 | static NSMutableDictionary *images;
20 | if(!images) {
21 | images = [NSMutableDictionary new];
22 | }
23 |
24 | NSDictionary *colorMapping = @{
25 | @(TFPPrinterColorBlack): [NSColor colorWithCalibratedWhite:0.245 alpha:1.000],
26 | @(TFPPrinterColorSilver): [NSColor colorWithCalibratedWhite:0.549 alpha:1.000],
27 | @(TFPPrinterColorLightBlue): [NSColor colorWithCalibratedRed:0.220 green:0.761 blue:0.918 alpha:1.000],
28 | @(TFPPrinterColorGreen): [NSColor colorWithCalibratedRed:0.400 green:0.906 blue:0.224 alpha:1.000],
29 | @(TFPPrinterColorOrange): [NSColor colorWithCalibratedRed:0.988 green:0.255 blue:0.149 alpha:1.000],
30 | @(TFPPrinterColorWhite): [NSColor colorWithCalibratedWhite:0.948 alpha:1.000],
31 | @(TFPPrinterColorGrape): [NSColor colorWithDeviceRed:0.441 green:0.299 blue:0.678 alpha:1.000],
32 | @(TFPPrinterColorOther): [NSColor redColor],
33 | };
34 |
35 | NSImage *image = images[@(self.color)];
36 | if(image) {
37 | return image;
38 | }
39 |
40 | image = [[NSImage imageNamed:@"Micro"] copy];
41 | NSColor *color = colorMapping[@(self.color)];
42 |
43 | [image lockFocus];
44 | [color set];
45 | NSRectFillUsingOperation((CGRect){CGPointZero, image.size}, NSCompositeSourceIn);
46 | [image unlockFocus];
47 |
48 | images[@(self.color)] = image;
49 | return image;
50 | }
51 |
52 |
53 | + (NSSet *)keyPathsForValuesAffectingPrinterImage {
54 | return [NSSet setWithObject:@"color"];
55 | }
56 |
57 |
58 | - (NSString*)activityString {
59 | if(self.currentOperation) {
60 | return self.currentOperation.activityDescription;
61 |
62 | }else if(self.pendingConnection) {
63 | return @"Connecting…";
64 |
65 | }else{
66 | return @"Idle";
67 | }
68 | }
69 |
70 |
71 | + (NSSet *)keyPathsForValuesAffectingActivityString {
72 | return @[@"currentOperation.activityDescription", @"pendingConnection"].tf_set;
73 | }
74 |
75 |
76 | - (NSString*)displayName {
77 | return self.serialNumber ?: @"Printer";
78 | }
79 |
80 |
81 | + (NSSet *)keyPathsForValuesAffectingDisplayName {
82 | return @[@"serialNumber"].tf_set;
83 | }
84 |
85 |
86 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPVisualPrintProgressView.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPVisualPrintProgressView.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sat 2015-08-08.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | @class TFPPrintStatusController, TFPPrintParameters;
11 |
12 |
13 | @interface TFPVisualPrintProgressView : NSView
14 | @property CGSize fullViewSize;
15 |
16 | - (void)configureWithPrintStatusController:(TFPPrintStatusController*)statusController parameters:(TFPPrintParameters*)printParameters;
17 | @end
--------------------------------------------------------------------------------
/MicroPrint UI/TFPVisualPrintProgressView.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPVisualPrintProgressView.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sat 2015-08-08.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPVisualPrintProgressView.h"
10 | #import "TFPPrintJob.h"
11 | #import "TFPPrintStatusController.h"
12 |
13 |
14 | @interface TFPVisualPrintProgressView ()
15 | @property id bitmap;
16 |
17 | @property CALayer *drawLayer;
18 | @property CGAffineTransform drawTransform;
19 | @property CGFloat drawScale;
20 | @end
21 |
22 |
23 |
24 | @implementation TFPVisualPrintProgressView
25 |
26 |
27 | - (void)configureWithPrintStatusController:(TFPPrintStatusController*)statusController parameters:(TFPPrintParameters*)printParameters {
28 | __weak __typeof__(self) weakSelf = self;
29 |
30 | TFPCuboid boundingBox = printParameters.boundingBox;
31 | CGSize viewSize = self.fullViewSize;
32 |
33 | CGFloat drawScale = 2;
34 | self.bitmap = CFBridgingRelease(CGBitmapContextCreate(NULL, viewSize.width * drawScale, viewSize.height * drawScale, 8, (viewSize.width*drawScale)*4, [NSColorSpace deviceRGBColorSpace].CGColorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast));
35 |
36 | self.drawLayer = [CALayer layer];
37 | self.drawLayer.bounds = CGRectMake(0, 0, viewSize.width, viewSize.height);
38 | self.drawLayer.backgroundColor = [NSColor whiteColor].CGColor;
39 | self.drawLayer.anchorPoint = CGPointZero;
40 | self.drawLayer.actions = @{@"contents": [NSNull null]};
41 | self.drawLayer.contentsScale = drawScale;
42 | [self.layer addSublayer:self.drawLayer];
43 |
44 | CGFloat margin = 20;
45 | viewSize.width -= 2*margin;
46 | viewSize.height -= 2*margin;
47 |
48 | CGAffineTransform transform = CGAffineTransformIdentity;
49 | double xScale = viewSize.width / boundingBox.xSize;
50 | double yScale = viewSize.height / boundingBox.ySize;
51 | double scale = MIN(xScale, yScale);
52 |
53 | CGFloat xOffset = (viewSize.width - (scale*boundingBox.xSize)) / 2 + margin;
54 | CGFloat yOffset = (viewSize.height - (scale*boundingBox.ySize)) / 2 + margin;
55 | transform = CGAffineTransformTranslate(transform, xOffset, yOffset);
56 | transform = CGAffineTransformScale(transform, scale, scale);
57 | transform = CGAffineTransformTranslate(transform, -boundingBox.x, -boundingBox.y);
58 | self.drawScale = scale;
59 | self.drawTransform = transform;
60 |
61 | CGContextRef context = (__bridge CGContextRef)self.bitmap;
62 | CGContextSetLineCap(context, kCGLineCapRound);
63 | CGContextSetLineWidth(context, self.drawScale * 0.8);
64 | CGContextSetStrokeColorWithColor(context, [NSColor blackColor].CGColor);
65 | CGContextScaleCTM(context, drawScale, drawScale);
66 |
67 |
68 | __block double xAdjustment = 0;
69 | __block double yAdjustment = 0;
70 |
71 | statusController.willMoveHandler = ^(TFPAbsolutePosition from, TFPAbsolutePosition to, double feedRate, TFPGCode *code) {
72 | double distance = TFPAbsolutePositionDistance(from, to);
73 |
74 | if([code.comment hasPrefix:@"BACKLASH"]) {
75 | xAdjustment += from.x - to.x;
76 | yAdjustment += from.y - to.y;
77 | }
78 |
79 | CGAffineTransform transform = weakSelf.drawTransform;
80 | CGPoint fromPoint = CGPointApplyAffineTransform(CGPointMake(from.x + xAdjustment, from.y + yAdjustment), transform);
81 | CGPoint toPoint = CGPointApplyAffineTransform(CGPointMake(to.x + xAdjustment, to.y + yAdjustment), transform);
82 |
83 | /*
84 | double distance = sqrt(pow(to.x - from.x, 2) + pow(to.y - from.y, 2));
85 | double calculatedSpeed = (6288.78 * (feedRate-830))/((feedRate-828.465) * (feedRate+79.5622));
86 | NSTimeInterval estimatedDuration = distance / calculatedSpeed;
87 | estimatedDuration /= weakSelf.printer.speedMultiplier;
88 | */
89 |
90 | if(to.e > from.e && distance > FLT_EPSILON) {
91 | CGMutablePathRef path = (CGMutablePathRef)CFAutorelease(CGPathCreateMutable());
92 | CGPathMoveToPoint(path, NULL, fromPoint.x, fromPoint.y);
93 | CGPathAddLineToPoint(path, NULL, toPoint.x, toPoint.y);
94 |
95 | CGContextRef context = (__bridge CGContextRef)weakSelf.bitmap;
96 |
97 | CGContextAddPath(context, path);
98 | CGContextStrokePath(context);
99 | [weakSelf updateImage];
100 | }
101 | };
102 |
103 | statusController.layerChangeHandler = ^{
104 | CGContextRef context = (__bridge CGContextRef)weakSelf.bitmap;
105 | CGRect entireRect = CGRectMake(0, 0, CGBitmapContextGetWidth(context), CGBitmapContextGetHeight(context));
106 | CGImageRef image = (CGImageRef)CFAutorelease(CGBitmapContextCreateImage(context));
107 |
108 | CGContextSaveGState(context);
109 | CGContextClearRect(context, entireRect);
110 | CGContextSetAlpha(context, 0.5);
111 | CGContextConcatCTM(context, CGAffineTransformInvert(CGContextGetCTM(context)));
112 | CGContextDrawImage(context, entireRect, image);
113 | CGContextRestoreGState(context);
114 | };
115 |
116 | }
117 |
118 |
119 | - (void)setHidden:(BOOL)hidden {
120 | [super setHidden:hidden];
121 | [self updateImage];
122 | }
123 |
124 |
125 | - (void)updateImage {
126 | if(!self.hiddenOrHasHiddenAncestor && self.bitmap) {
127 | self.drawLayer.contents = CFBridgingRelease(CGBitmapContextCreateImage((CGContextRef)self.bitmap));
128 | }
129 | }
130 |
131 |
132 | @end
133 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPZeroHeadViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPZeroHeadViewController.h
3 | // microprint
4 | //
5 | // Created by William Waggoner on 8/1/15.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPCalibrationViewController.h"
11 | #import "TFPPrinter.h"
12 |
13 | @interface TFPZeroHeadViewController : TFPCalibrationViewController
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/MicroPrint UI/TFPZeroHeadViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPZeroHeadViewController.m
3 | // microprint
4 | //
5 | // Created by William Waggoner on 8/1/15.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPZeroHeadViewController.h"
10 | #import "TFPZeroBedOperation.h"
11 | #import "TFPExtras.h"
12 |
13 | @interface TFPZeroHeadViewController ()
14 | @property IBOutlet NSTextField* txtHelp;
15 | @property IBOutlet NSButton* startButton;
16 | @property IBOutlet NSProgressIndicator *progressIndicator;
17 | @property IBOutlet NSTextField *statusLabel;
18 | @property TFPZeroBedOperation* operation;
19 | @end
20 |
21 | @implementation TFPZeroHeadViewController
22 |
23 |
24 | - (void)viewDidLoad {
25 | [super viewDidLoad];
26 | self.operation = nil;
27 | }
28 |
29 |
30 | - (void)start {
31 | __weak __typeof__(self) weakSelf = self;
32 | TFPZeroBedOperation *operation = [[TFPZeroBedOperation alloc] initWithPrinter:self.printer];
33 | self.operation = operation;
34 |
35 | operation.progressFeedback = ^(NSString *msg){
36 | weakSelf.statusLabel.stringValue = msg;
37 | };
38 |
39 | operation.didStopBlock = ^(BOOL completed){
40 | [weakSelf operationDidStop];
41 |
42 | if(completed) {
43 | NSAlert *alert = [NSAlert new];
44 | alert.messageText = @"Bed location calibration finished";
45 | alert.informativeText = @"You should now run the Bed Level Calibration to make sure corner levels are correct.";
46 | [alert addButtonWithTitle:@"OK"];
47 |
48 | [alert beginSheetModalForWindow:weakSelf.view.window completionHandler:^(NSModalResponse returnCode) {
49 | [weakSelf dismissController:nil];
50 | }];
51 | }
52 | };
53 |
54 | [operation start];
55 | }
56 |
57 | - (IBAction)buttonPressed:(id)sender {
58 |
59 | if(sender == self.startButton) {
60 | if(self.operation) {
61 | [self.operation stop];
62 | }else{
63 | self.statusLabel.hidden = NO;
64 | self.progressIndicator.hidden = NO;
65 | self.statusLabel.stringValue = @"Starting…";
66 | [self.progressIndicator setIndeterminate:YES];
67 | [self.progressIndicator startAnimation:nil];
68 | self.startButton.title = @"Stop";
69 | self.startButton.keyEquivalent = @"\r";
70 | [self start];
71 | }
72 | }
73 | }
74 |
75 | - (void)operationDidStop {
76 | self.operation = nil;
77 | self.statusLabel.stringValue = @"";
78 | [self.progressIndicator stopAnimation:nil];
79 | self.statusLabel.hidden = YES;
80 | self.progressIndicator.hidden = YES;
81 | self.startButton.title = @"Start";
82 | self.startButton.keyEquivalent = @"";
83 | }
84 |
85 | @end
86 |
--------------------------------------------------------------------------------
/MicroPrint UI/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // MicroPrint UI
4 | //
5 | // Created by Tomas Franzén on Mon 2015-07-13.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # microprint
2 | #### Printing software for M3D Micro for OS X
3 |
4 | MicroPrint is a command-line program for Mac. It takes a G-code file that you've previously sliced in a slicer like Cura, pre-processes the code the same way M3D does it with bed level measurements, backlash compensation and feed rate translation, and finally feeds it to your printer.
5 |
6 | MicroPrint is currently in alpha stage (or like M3D would call it; "beta!!!"), so don't expect full polish. It's meant for advanced users for now, so you need to be familiar with the command line. Like always, your printer may break if my software does something weird. It very most likely won't, but don't blame me if it does.
7 |
8 | Besides printing, MicroPrint can also do a few other things like retract and extrude filament manually. It extrudes until you press Return instead of the stupid repeating question in M3D's UI.
9 |
10 | Usage examples:
11 |
12 | microprint print teapot.gcode
13 | microprint print MyPrecious0.4mmTestBorder.gcode --filament ABS
14 | microprint extrude --temperature 250
15 | microprint raise
16 |
17 | See more by invoking `microprint --help`
18 |
19 | Here's a good guide for how to use Cura to generate G-code: https://printm3d.com/forums/discussion/1691/guide-how-to-print-abs-out-of-the-box-using-cura
20 |
21 | #### Notes:
22 | * You need to quit the M3D spooler to stop it from hogging the serial port to allow MicroPrint to connect to the printer.
23 | * No graceful aborting of prints. If you ctrl-C the program, it leaves things like the heater and fan running. I hope to fix this soon, too.
24 | * Progress reporting is stupid and is based only on the number of processed G-code lines.
25 | * MicroPrint requires OS X 10.10. It may very well work with older versions of OS X, but I'm not maintaining such compatibility.
26 |
27 | Future ideas:
28 | * Good print time estimation, with both duration and completion time.
29 | * Interactive 0.4 mm border calibration that asks you for corner height measurements and adjusts offsets automatically.
30 | * G-code console for executing raw G-code, with optional feed rate translation
31 |
32 | ##### Simplify3d Setup
33 |
34 | To use Simplify3d effectively you will need to change the Process definition for the Micro3d printer. We suggest that you
35 | make the following changes then save the definition under a different name.
36 |
37 | 1. Edit the Process, usually "Process1"
38 | 1. You should have `M3D Micro` selected as the Profile
39 | 1. Select the `Scripts` tab
40 | 1. Under "Additional terminal commands" **DELETE** the following lines:
41 | * `{STRIP ";"}`
42 | * `{PREPEND ";other temp:210\n;ideal temp:210\n"}`
43 | 1. Click "Save as New" and enter a new name for this profile. `M3D Micro - Microprint` might be a good name.
44 |
45 | If this is successful then the resulting GCode will have the Simplify3d Profile and Layer indicators in it.
46 | Microprint should detect these and display the settings during print setup and the layer progress as the print proceeds.
47 |
--------------------------------------------------------------------------------
/microprint/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/.DS_Store
--------------------------------------------------------------------------------
/microprint/ORSSerialRequest.h:
--------------------------------------------------------------------------------
1 | //
2 | // ORSSerialRequest.h
3 | // ORSSerialPort
4 | //
5 | // Created by Andrew Madsen on 4/21/14.
6 | // Copyright (c) 2014 Andrew Madsen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | // Keep older versions of the compiler happy
12 | #ifndef NS_ASSUME_NONNULL_BEGIN
13 | #define NS_ASSUME_NONNULL_BEGIN
14 | #define NS_ASSUME_NONNULL_END
15 | #define nullable
16 | #define nonnullable
17 | #define __nullable
18 | #endif
19 |
20 | typedef BOOL(^ORSSerialRequestResponseEvaluator)(NSData * __nullable inputData);
21 |
22 | NS_ASSUME_NONNULL_BEGIN
23 |
24 | /**
25 | * An ORSSerialRequest encapsulates a generic "request" command sent via the serial
26 | * port.
27 | *
28 | * An ORSSerialRequest includes data to be sent out via the serial port.
29 | * It also can contain a block which is used to evaluate received
30 | * data to determine if/when a valid response to the request has been received from
31 | * the device on the other end of the port. Arbitrary information can be
32 | * associated with the ORSSerialRequest via its userInfo property.
33 | */
34 | @interface ORSSerialRequest : NSObject
35 |
36 | /**
37 | * Creates and initializes an ORSSerialRequest instance.
38 | *
39 | * @param dataToSend The data to be sent on the serial port.
40 | * @param userInfo An arbitrary userInfo object.
41 | * @param timeout The maximum amount of time in seconds to wait for a response. Pass -1.0 to wait indefinitely.
42 | * @param responseEvaluator A block used to evaluate whether received data constitutes a valid response to the request.
43 | * May be nil. If responseEvaluator is nil, the request is assumed not to require a response, and the next request in the queue will
44 | * be sent immediately.
45 | *
46 | * @return An initialized ORSSerialRequest instance.
47 | */
48 | + (instancetype)requestWithDataToSend:(NSData *)dataToSend
49 | userInfo:(nullable id)userInfo
50 | timeoutInterval:(NSTimeInterval)timeout
51 | responseEvaluator:(nullable ORSSerialRequestResponseEvaluator)responseEvaluator;
52 |
53 | /**
54 | * Initializes an ORSSerialRequest instance.
55 | *
56 | * @param dataToSend The data to be sent on the serial port.
57 | * @param userInfo An arbitrary userInfo object.
58 | * @param timeout The maximum amount of time in seconds to wait for a response. Pass -1.0 to wait indefinitely.
59 | * @param responseEvaluator A block used to evaluate whether received data constitutes a valid response to the request.
60 | * May be nil. If responseEvaluator is nil, the request is assumed not to require a response, and the next request in the queue will
61 | * be sent immediately.
62 | *
63 | * @return An initialized ORSSerialRequest instance.
64 | */
65 | - (instancetype)initWithDataToSend:(NSData *)dataToSend
66 | userInfo:(nullable id)userInfo
67 | timeoutInterval:(NSTimeInterval)timeout
68 | responseEvaluator:(nullable ORSSerialRequestResponseEvaluator)responseEvaluator;
69 |
70 | /**
71 | * Can be used to determine if a block of data is a valid response to the request encapsulated
72 | * by the receiver. If the receiver doesn't have a response data evaulator block, this method
73 | * always returns YES.
74 | *
75 | * @param responseData Data received from a serial port.
76 | *
77 | * @return YES if the data is a valid response, NO otherwise.
78 | */
79 | - (BOOL)dataIsValidResponse:(nullable NSData *)responseData;
80 |
81 | /**
82 | * Data to be sent on the serial port when the receiver is sent.
83 | */
84 | @property (nonatomic, strong, readonly) NSData *dataToSend;
85 |
86 | /**
87 | * Arbitrary object (e.g. NSDictionary) used to store additional data
88 | * about the request.
89 | */
90 | @property (nonatomic, strong, readonly, nullable) id userInfo;
91 |
92 | /**
93 | * The maximum amount of time to wait for a response before timing out.
94 | * Negative values indicate that serial port will wait forever for a response
95 | * without timing out.
96 | */
97 | @property (nonatomic, readonly) NSTimeInterval timeoutInterval;
98 |
99 | /**
100 | * Unique identifier for the request.
101 | */
102 | @property (nonatomic, strong, readonly) NSString *UUIDString;
103 |
104 | @end
105 |
106 | NS_ASSUME_NONNULL_END
--------------------------------------------------------------------------------
/microprint/ORSSerialRequest.m:
--------------------------------------------------------------------------------
1 | //
2 | // ORSSerialRequest.h
3 | // ORSSerialPort
4 | //
5 | // Created by Andrew Madsen on 4/21/14.
6 | // Copyright (c) 2014 Andrew Madsen. All rights reserved.
7 | //
8 |
9 | #import "ORSSerialRequest.h"
10 |
11 | @interface ORSSerialRequest ()
12 |
13 | @property (nonatomic, strong, readwrite) NSData *dataToSend;
14 | @property (nonatomic, strong, readwrite) id userInfo;
15 | @property (nonatomic, readwrite) NSTimeInterval timeoutInterval;
16 | @property (nonatomic, strong) ORSSerialRequestResponseEvaluator responseEvaluator;
17 | @property (nonatomic, strong, readwrite) NSString *UUIDString;
18 |
19 | @end
20 |
21 | @implementation ORSSerialRequest
22 |
23 | + (instancetype)requestWithDataToSend:(NSData *)dataToSend
24 | userInfo:(id)userInfo
25 | timeoutInterval:(NSTimeInterval)timeout
26 | responseEvaluator:(ORSSerialRequestResponseEvaluator)responseEvaluator;
27 | {
28 | return [[self alloc] initWithDataToSend:dataToSend
29 | userInfo:userInfo
30 | timeoutInterval:timeout
31 | responseEvaluator:responseEvaluator];
32 | }
33 |
34 | - (instancetype)initWithDataToSend:(NSData *)dataToSend
35 | userInfo:(id)userInfo
36 | timeoutInterval:(NSTimeInterval)timeout
37 | responseEvaluator:(ORSSerialRequestResponseEvaluator)responseEvaluator;
38 | {
39 | self = [super init];
40 | if (self) {
41 | _dataToSend = dataToSend;
42 | _userInfo = userInfo;
43 | _timeoutInterval = timeout;
44 | _responseEvaluator = responseEvaluator;
45 | CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
46 | _UUIDString = CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuid));
47 | CFRelease(uuid);
48 | }
49 | return self;
50 | }
51 |
52 | - (NSString *)description
53 | {
54 | return [NSString stringWithFormat:@"%@ data: %@ userInfo: %@ timeout interval: %f", [super description], self.dataToSend, self.userInfo, self.timeoutInterval];
55 | }
56 |
57 | - (BOOL)dataIsValidResponse:(NSData *)responseData
58 | {
59 | if (!self.responseEvaluator) return YES;
60 |
61 | return self.responseEvaluator(responseData);
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/microprint/ProfileTranslations.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1252\cocoartf1404
2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Menlo-Regular;\f2\fnil\fcharset0 Menlo-Bold;
3 | }
4 | {\colortbl;\red255\green255\blue255;\red196\green26\blue22;}
5 | \margl1440\margr1440\vieww9000\viewh8400\viewkind0
6 | \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
7 |
8 | \f0\fs32 \cf0 Key name translations for slicers\
9 | \
10 | Keys we are interested in (original Cura names):\
11 | \
12 | \pard\tx577\pardeftab577\pardirnatural\partightenfactor0
13 |
14 | \f1\fs24 \cf2 \CocoaLigature0 layer_height\
15 | wall_thickness\
16 | print_speed\
17 | fill_density\
18 | support\
19 | platform_adhesion\
20 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
21 | \cf0 \CocoaLigature1 \
22 | * Slic3r names for the above:\
23 | \
24 | layer_height\
25 | perimeters * "external perimeters extrusion width"\
26 | perimeter_speed\
27 | fill_density\
28 | support_material (1/0:YES/NO)\
29 | raft_layers > 0 = RAFT(n)/brim_width > 0 = BRIM(n)\
30 | \
31 | * Simplify3d names\
32 | \
33 | \
34 | \
35 | * Table\
36 | \pard\tx2879\pardirnatural\partightenfactor0
37 |
38 | \f2\b \cf0 Original
39 | \f1\b0
40 | \f2\b Slic3r2
41 | \f1\b0 \
42 | \pard\tx2888\pardirnatural\partightenfactor0
43 | \cf0 \
44 | \pard\tx2876\tx5761\pardeftab577\pardirnatural\partightenfactor0
45 | \cf2 \CocoaLigature0 layer_height \cf0 \CocoaLigature1 layer_height\cf2 \CocoaLigature0 \
46 | \pard\tx2884\pardeftab577\pardirnatural\partightenfactor0
47 | \cf2 wall_thickness \cf0 \CocoaLigature1 perimeters * "external perimeters extrusion width"\cf2 \CocoaLigature0 \
48 | \pard\tx2877\pardeftab577\pardirnatural\partightenfactor0
49 | \cf2 print_speed \cf0 \CocoaLigature1 perimeter_speed\cf2 \CocoaLigature0 \
50 | \pard\tx2857\pardeftab577\pardirnatural\partightenfactor0
51 | \cf2 fill_density \cf0 \CocoaLigature1 fill_density\cf2 \CocoaLigature0 \
52 | \pard\tx2884\pardeftab577\pardirnatural\partightenfactor0
53 | \cf2 support \cf0 \CocoaLigature1 support_material (1/0:YES/NO)\cf2 \CocoaLigature0 \
54 | \pard\tx2876\pardeftab577\pardirnatural\partightenfactor0
55 | \cf2 platform_adhesion \cf0 \CocoaLigature1 raft_layers > 0 = RAFT(n)/brim_width > 0 = BRIM(n)\cf2 \CocoaLigature0 \
56 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab577\pardirnatural\partightenfactor0
57 | \cf0 \CocoaLigature1 \
58 | }
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Headers:
--------------------------------------------------------------------------------
1 | Versions/Current/Headers
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Modules:
--------------------------------------------------------------------------------
1 | Versions/Current/Modules
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/PrivateHeaders:
--------------------------------------------------------------------------------
1 | Versions/Current/PrivateHeaders
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Resources:
--------------------------------------------------------------------------------
1 | Versions/Current/Resources
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Sparkle:
--------------------------------------------------------------------------------
1 | Versions/Current/Sparkle
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Headers/SUAppcast.h:
--------------------------------------------------------------------------------
1 | //
2 | // SUAppcast.h
3 | // Sparkle
4 | //
5 | // Created by Andy Matuschak on 3/12/06.
6 | // Copyright 2006 Andy Matuschak. All rights reserved.
7 | //
8 |
9 | #ifndef SUAPPCAST_H
10 | #define SUAPPCAST_H
11 |
12 | #import
13 | #import "SUExport.h"
14 |
15 | @class SUAppcastItem;
16 | SU_EXPORT @interface SUAppcast : NSObject
17 |
18 | @property (copy) NSString *userAgentString;
19 | @property (copy) NSDictionary *httpHeaders;
20 |
21 | - (void)fetchAppcastFromURL:(NSURL *)url completionBlock:(void (^)(NSError *))err;
22 |
23 | @property (readonly, copy) NSArray *items;
24 | @end
25 |
26 | #endif
27 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h:
--------------------------------------------------------------------------------
1 | //
2 | // SUAppcastItem.h
3 | // Sparkle
4 | //
5 | // Created by Andy Matuschak on 3/12/06.
6 | // Copyright 2006 Andy Matuschak. All rights reserved.
7 | //
8 |
9 | #ifndef SUAPPCASTITEM_H
10 | #define SUAPPCASTITEM_H
11 |
12 | #include "SUExport.h"
13 |
14 | SU_EXPORT @interface SUAppcastItem : NSObject
15 | @property (copy, readonly) NSString *title;
16 | @property (copy, readonly) NSDate *date;
17 | @property (copy, readonly) NSString *itemDescription;
18 | @property (strong, readonly) NSURL *releaseNotesURL;
19 | @property (copy, readonly) NSString *DSASignature;
20 | @property (copy, readonly) NSString *minimumSystemVersion;
21 | @property (copy, readonly) NSString *maximumSystemVersion;
22 | @property (strong, readonly) NSURL *fileURL;
23 | @property (copy, readonly) NSString *versionString;
24 | @property (copy, readonly) NSString *displayVersionString;
25 | @property (copy, readonly) NSDictionary *deltaUpdates;
26 | @property (strong, readonly) NSURL *infoURL;
27 |
28 | // Initializes with data from a dictionary provided by the RSS class.
29 | - (instancetype)initWithDictionary:(NSDictionary *)dict;
30 | - (instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString **)error;
31 |
32 | @property (getter=isDeltaUpdate, readonly) BOOL deltaUpdate;
33 | @property (getter=isCriticalUpdate, readonly) BOOL criticalUpdate;
34 |
35 | // Returns the dictionary provided in initWithDictionary; this might be useful later for extensions.
36 | @property (readonly, copy) NSDictionary *propertiesDictionary;
37 |
38 | - (NSURL *)infoURL;
39 |
40 | @end
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Headers/SUErrors.h:
--------------------------------------------------------------------------------
1 | //
2 | // SUErrors.h
3 | // Sparkle
4 | //
5 | // Created by C.W. Betts on 10/13/14.
6 | // Copyright (c) 2014 Sparkle Project. All rights reserved.
7 | //
8 |
9 | #ifndef SUERRORS_H
10 | #define SUERRORS_H
11 |
12 | #import
13 | #import "SUExport.h"
14 |
15 | /**
16 | * Error domain used by Sparkle
17 | */
18 | SU_EXPORT extern NSString *const SUSparkleErrorDomain;
19 |
20 | typedef NS_ENUM(OSStatus, SUError) {
21 | // Appcast phase errors.
22 | SUAppcastParseError = 1000,
23 | SUNoUpdateError = 1001,
24 | SUAppcastError = 1002,
25 | SURunningFromDiskImageError = 1003,
26 |
27 | // Downlaod phase errors.
28 | SUTemporaryDirectoryError = 2000,
29 |
30 | // Extraction phase errors.
31 | SUUnarchivingError = 3000,
32 | SUSignatureError = 3001,
33 |
34 | // Installation phase errors.
35 | SUFileCopyFailure = 4000,
36 | SUAuthenticationFailure = 4001,
37 | SUMissingUpdateError = 4002,
38 | SUMissingInstallerToolError = 4003,
39 | SURelaunchError = 4004,
40 | SUInstallationError = 4005,
41 | SUDowngradeError = 4006
42 | };
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Headers/SUExport.h:
--------------------------------------------------------------------------------
1 | //
2 | // SUExport.h
3 | // Sparkle
4 | //
5 | // Created by Jake Petroules on 2014-08-23.
6 | // Copyright (c) 2014 Sparkle Project. All rights reserved.
7 | //
8 |
9 | #ifndef SUEXPORT_H
10 | #define SUEXPORT_H
11 |
12 | #ifdef BUILDING_SPARKLE
13 | #define SU_EXPORT __attribute__((visibility("default")))
14 | #else
15 | #define SU_EXPORT
16 | #endif
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h:
--------------------------------------------------------------------------------
1 | //
2 | // SUStandardVersionComparator.h
3 | // Sparkle
4 | //
5 | // Created by Andy Matuschak on 12/21/07.
6 | // Copyright 2007 Andy Matuschak. All rights reserved.
7 | //
8 |
9 | #ifndef SUSTANDARDVERSIONCOMPARATOR_H
10 | #define SUSTANDARDVERSIONCOMPARATOR_H
11 |
12 | #import "SUExport.h"
13 | #import "SUVersionComparisonProtocol.h"
14 |
15 | /*!
16 | Sparkle's default version comparator.
17 |
18 | This comparator is adapted from MacPAD, by Kevin Ballard.
19 | It's "dumb" in that it does essentially string comparison,
20 | in components split by character type.
21 | */
22 | SU_EXPORT @interface SUStandardVersionComparator : NSObject
23 |
24 | /*!
25 | Returns a singleton instance of the comparator.
26 | */
27 | + (SUStandardVersionComparator *)defaultComparator;
28 |
29 | /*!
30 | Compares version strings through textual analysis.
31 |
32 | See the implementation for more details.
33 | */
34 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB;
35 | @end
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // SUVersionComparisonProtocol.h
3 | // Sparkle
4 | //
5 | // Created by Andy Matuschak on 12/21/07.
6 | // Copyright 2007 Andy Matuschak. All rights reserved.
7 | //
8 |
9 | #ifndef SUVERSIONCOMPARISONPROTOCOL_H
10 | #define SUVERSIONCOMPARISONPROTOCOL_H
11 |
12 | #import
13 | #import "SUExport.h"
14 |
15 | /*!
16 | Provides version comparison facilities for Sparkle.
17 | */
18 | @protocol SUVersionComparison
19 |
20 | /*!
21 | An abstract method to compare two version strings.
22 |
23 | Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a,
24 | and NSOrderedSame if they are equivalent.
25 | */
26 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD!
27 |
28 | @end
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // SUVersionDisplayProtocol.h
3 | // EyeTV
4 | //
5 | // Created by Uli Kusterer on 08.12.09.
6 | // Copyright 2009 Elgato Systems GmbH. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SUExport.h"
11 |
12 | /*!
13 | Applies special display formatting to version numbers.
14 | */
15 | @protocol SUVersionDisplay
16 |
17 | /*!
18 | Formats two version strings.
19 |
20 | Both versions are provided so that important distinguishing information
21 | can be displayed while also leaving out unnecessary/confusing parts.
22 | */
23 | - (void)formatVersion:(NSString **)inOutVersionA andVersion:(NSString **)inOutVersionB;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Headers/Sparkle.h:
--------------------------------------------------------------------------------
1 | //
2 | // Sparkle.h
3 | // Sparkle
4 | //
5 | // Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07)
6 | // Copyright 2006 Andy Matuschak. All rights reserved.
7 | //
8 |
9 | #ifndef SPARKLE_H
10 | #define SPARKLE_H
11 |
12 | // This list should include the shared headers. It doesn't matter if some of them aren't shared (unless
13 | // there are name-space collisions) so we can list all of them to start with:
14 |
15 | #import
16 | #import
17 | #import
18 | #import
19 | #import
20 | #import
21 | #import
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Modules/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module Sparkle {
2 | umbrella header "Sparkle.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h:
--------------------------------------------------------------------------------
1 | //
2 | // SUUnarchiver.h
3 | // Sparkle
4 | //
5 | // Created by Andy Matuschak on 3/16/06.
6 | // Copyright 2006 Andy Matuschak. All rights reserved.
7 | //
8 |
9 | #ifndef SUUNARCHIVER_H
10 | #define SUUNARCHIVER_H
11 |
12 | @class SUHost;
13 | @protocol SUUnarchiverDelegate;
14 |
15 | @interface SUUnarchiver : NSObject
16 |
17 | @property (copy, readonly) NSString *archivePath;
18 | @property (weak, readonly) NSString *updateHostBundlePath;
19 | @property (weak) id delegate;
20 |
21 | + (SUUnarchiver *)unarchiverForPath:(NSString *)path updatingHostBundlePath:(NSString *)host;
22 |
23 | - (void)start;
24 | @end
25 |
26 | @protocol SUUnarchiverDelegate
27 | - (void)unarchiverDidFinish:(SUUnarchiver *)unarchiver;
28 | - (void)unarchiverDidFail:(SUUnarchiver *)unarchiver;
29 | @optional
30 | - (void)unarchiver:(SUUnarchiver *)unarchiver extractedProgress:(double)progress;
31 | @end
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 14E7f
7 | CFBundleDevelopmentRegion
8 | English
9 | CFBundleExecutable
10 | Autoupdate
11 | CFBundleIconFile
12 | AppIcon
13 | CFBundleIdentifier
14 | org.sparkle-project.Sparkle.Autoupdate
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.10.0 git-9646b0b
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.10.0
25 | DTCompiler
26 | com.apple.compilers.llvm.clang.1_0
27 | DTPlatformBuild
28 | 6D1002
29 | DTPlatformVersion
30 | GM
31 | DTSDKBuild
32 | 14D125
33 | DTSDKName
34 | macosx10.10
35 | DTXcode
36 | 0631
37 | DTXcodeBuild
38 | 6D1002
39 | LSBackgroundOnly
40 | 1
41 | LSMinimumSystemVersion
42 | 10.7
43 | LSUIElement
44 | 1
45 | NSMainNibFile
46 | MainMenu
47 | NSPrincipalClass
48 | NSApplication
49 |
50 |
51 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 14E7f
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | Sparkle
11 | CFBundleIdentifier
12 | org.andymatuschak.Sparkle
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | Sparkle
17 | CFBundlePackageType
18 | FMWK
19 | CFBundleShortVersionString
20 | 1.10.0 git-9646b0b
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.10.0rc1
25 | DTCompiler
26 | com.apple.compilers.llvm.clang.1_0
27 | DTPlatformBuild
28 | 6D1002
29 | DTPlatformVersion
30 | GM
31 | DTSDKBuild
32 | 14D125
33 | DTSDKName
34 | macosx10.10
35 | DTXcode
36 | 0631
37 | DTXcodeBuild
38 | 6D1002
39 | SUAppendVersionNumber
40 | 1
41 | SUEnableAutomatedDowngrades
42 | 0
43 | SUNormalizeInstalledApplicationName
44 | 0
45 | SURelaunchToolName
46 | Autoupdate
47 |
48 |
49 |
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/SUStatus.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/SUStatus.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/fr_CA.lproj:
--------------------------------------------------------------------------------
1 | fr.lproj
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pt.lproj:
--------------------------------------------------------------------------------
1 | pt_BR.lproj
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/A/Sparkle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomasf/microprint/e645933e7c9887de43ab698e6bddd637af4695a5/microprint/Sparkle.framework/Versions/A/Sparkle
--------------------------------------------------------------------------------
/microprint/Sparkle.framework/Versions/Current:
--------------------------------------------------------------------------------
1 | A
--------------------------------------------------------------------------------
/microprint/TFAsyncOperationCoalescer.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFAsyncOperationCoalescer.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sun 2015-08-09.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TFAsyncOperationCoalescer : NSObject
12 | @property (copy) void(^completionBlock)();
13 | @property (copy) void(^progressUpdateBlock)(double progress);
14 |
15 | - (void(^)(double progress))addOperation;
16 | @end
17 |
--------------------------------------------------------------------------------
/microprint/TFAsyncOperationCoalescer.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFAsyncOperationCoalescer.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sun 2015-08-09.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFAsyncOperationCoalescer.h"
10 |
11 | @interface TFAsyncOperationCoalescer ()
12 | @property NSMutableDictionary *operationProgress;
13 | @property NSUInteger operationCount;
14 | @end
15 |
16 |
17 | @implementation TFAsyncOperationCoalescer
18 |
19 |
20 | - (instancetype)init {
21 | if(!(self = [super init])) return nil;
22 |
23 | self.operationProgress = [NSMutableDictionary new];
24 |
25 | return self;
26 | }
27 |
28 |
29 | - (void)updateProgress {
30 | double sum = 0;
31 | BOOL anyIncomplete = NO;
32 | for(NSNumber *ID in self.operationProgress) {
33 | double value = [self.operationProgress[ID] doubleValue];
34 | if(value < 1) {
35 | anyIncomplete = YES;
36 | }
37 | sum += value;
38 | }
39 |
40 | if(!anyIncomplete) {
41 | self.completionBlock();
42 | }else{
43 | if(self.progressUpdateBlock) {
44 | self.progressUpdateBlock(sum / self.operationProgress.count);
45 | }
46 | }
47 | }
48 |
49 |
50 | - (void(^)(double progress))addOperation {
51 | NSUInteger ID = self.operationCount++;
52 | self.operationProgress[@(ID)] = @0;
53 |
54 | return ^(double progress){
55 | if(progress >= 1) {
56 | self.operationProgress[@(ID)] = @1;
57 | }else{
58 | self.operationProgress[@(ID)] = @(progress);
59 | }
60 | [self updateProgress];
61 | };
62 | }
63 |
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/microprint/TFDataBuilder.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFDataBuilder.h
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-06-22.
6 | //
7 |
8 | #import
9 |
10 |
11 | typedef NS_ENUM(NSUInteger, TFDataBuilderByteOrder) {
12 | TFDataBuilderByteOrderBigEndian,
13 | TFDataBuilderByteOrderLittleEndian,
14 | };
15 |
16 |
17 | @interface TFDataBuilder : NSObject
18 | - (instancetype)initWithData:(NSData*)existingData;
19 |
20 | @property TFDataBuilderByteOrder byteOrder;
21 |
22 | - (void)appendData:(NSData*)data;
23 | - (void)appendBytes:(const void *)bytes length:(NSUInteger)length;
24 | - (void)appendString:(NSString*)string; // UTF-8
25 | - (void)appendString:(NSString*)string encoding:(NSStringEncoding)encoding;
26 |
27 | - (void)appendByte:(uint8_t)byte;
28 | - (void)appendInt16:(uint16_t)int16;
29 | - (void)appendInt32:(uint32_t)int32;
30 | - (void)appendInt64:(uint64_t)int64;
31 |
32 | - (void)appendFloat:(float)value;
33 | - (void)appendDouble:(double)value;
34 |
35 | @property (readonly) NSMutableData *data;
36 | @end
37 |
--------------------------------------------------------------------------------
/microprint/TFDataBuilder.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFDataBuilder.m
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-06-22.
6 | //
7 |
8 | #import "TFDataBuilder.h"
9 |
10 | @interface TFDataBuilder ()
11 | @property (readwrite) NSMutableData *data;
12 | @end
13 |
14 |
15 | @implementation TFDataBuilder
16 |
17 |
18 | - (instancetype)initWithData:(NSData*)existingData {
19 | if(!(self = [super init])) return nil;
20 |
21 | self.data = [existingData mutableCopy] ?: [NSMutableData new];
22 |
23 | return self;
24 | }
25 |
26 |
27 | - (instancetype)init {
28 | return [self initWithData:[NSData data]];
29 | }
30 |
31 |
32 | - (void)appendData:(NSData*)data {
33 | [self.data appendData:data];
34 | }
35 |
36 |
37 | - (void)appendString:(NSString*)string {
38 | [self appendString:string encoding:NSUTF8StringEncoding];
39 | }
40 |
41 |
42 | - (void)appendBytes:(const void *)bytes length:(NSUInteger)length {
43 | [self.data appendBytes:bytes length:length];
44 | }
45 |
46 |
47 | - (void)appendString:(NSString*)string encoding:(NSStringEncoding)encoding {
48 | [self appendData:[string dataUsingEncoding:encoding]];
49 | }
50 |
51 |
52 | - (void)appendByte:(uint8_t)byte {
53 | [self.data appendBytes:&byte length:sizeof(byte)];
54 | }
55 |
56 |
57 | - (void)appendInt16:(uint16_t)integer {
58 | if(self.byteOrder == TFDataBuilderByteOrderLittleEndian) {
59 | integer = NSSwapHostShortToLittle(integer);
60 | }else{
61 | integer = NSSwapHostShortToBig(integer);
62 | }
63 | [self.data appendBytes:&integer length:sizeof(integer)];
64 | }
65 |
66 |
67 | - (void)appendInt32:(uint32_t)integer {
68 | if(self.byteOrder == TFDataBuilderByteOrderLittleEndian) {
69 | integer = NSSwapHostIntToLittle(integer);
70 | }else{
71 | integer = NSSwapHostIntToBig(integer);
72 | }
73 | [self.data appendBytes:&integer length:sizeof(integer)];
74 | }
75 |
76 |
77 | - (void)appendInt64:(uint64_t)integer {
78 | if(self.byteOrder == TFDataBuilderByteOrderLittleEndian) {
79 | integer = NSSwapHostLongLongToLittle(integer);
80 | }else{
81 | integer = NSSwapHostLongLongToBig(integer);
82 | }
83 | [self.data appendBytes:&integer length:sizeof(integer)];
84 | }
85 |
86 |
87 | - (void)appendFloat:(float)value {
88 | NSSwappedFloat swapped;
89 | if(self.byteOrder == TFDataBuilderByteOrderLittleEndian) {
90 | swapped = NSSwapHostFloatToLittle(value);
91 | }else{
92 | swapped = NSSwapHostFloatToBig(value);
93 | }
94 | [self.data appendBytes:&swapped length:sizeof(swapped)];
95 | }
96 |
97 |
98 | - (void)appendDouble:(double)value {
99 | NSSwappedDouble swapped;
100 | if(self.byteOrder == TFDataBuilderByteOrderLittleEndian) {
101 | swapped = NSSwapHostDoubleToLittle(value);
102 | }else{
103 | swapped = NSSwapHostDoubleToBig(value);
104 | }
105 | [self.data appendBytes:&swapped length:sizeof(swapped)];
106 | }
107 |
108 |
109 | @end
--------------------------------------------------------------------------------
/microprint/TFP3DVector.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFDecimal3DPoint.h
3 | // MicroPrint
4 | //
5 | //
6 |
7 | #import
8 | #import "TFPGCodeHelpers.h"
9 |
10 | @interface TFP3DVector : NSObject
11 | + (instancetype)vectorWithX:(NSNumber*)x Y:(NSNumber*)Y Z:(NSNumber*)Z;
12 |
13 | + (instancetype)xyVectorWithX:(double)x y:(double)y;
14 | + (instancetype)zVector:(double)z;
15 | + (instancetype)xVector:(double)x;
16 | + (instancetype)yVector:(double)y;
17 |
18 | + (instancetype)zeroVector;
19 | + (instancetype)emptyVector;
20 |
21 | + (instancetype)vectorWithPosition:(TFPAbsolutePosition)position;
22 |
23 | @property (readonly) NSNumber *x;
24 | @property (readonly) NSNumber *y;
25 | @property (readonly) NSNumber *z;
26 |
27 | - (double)distanceToPoint:(TFP3DVector*)point;
28 | - (TFP3DVector*)vectorByDefaultingToValues:(TFP3DVector*)defaults;
29 | - (TFP3DVector*)vectorWithFieldsPresentInVector:(TFP3DVector*)otherVector;
30 |
31 | - (TFP3DVector*)vectorBySettingX:(double)x;
32 | - (TFP3DVector*)vectorBySettingY:(double)y;
33 | - (TFP3DVector*)vectorBySettingZ:(double)z;
34 | - (TFP3DVector*)vectorBySettingY:(double)y z:(double)z;
35 | - (TFP3DVector*)vectorByAdjustingZ:(double)delta;
36 |
37 | - (TFP3DVector*)absoluteVector;
38 |
39 | - (TFP3DVector*)vectorByAdding:(TFP3DVector*)vector;
40 | - (TFP3DVector*)vectorBySubtracting:(TFP3DVector*)vector;
41 | - (TFP3DVector*)vectorByDividingBy:(TFP3DVector*)vector;
42 | - (TFP3DVector*)vectorByMultiplyingBy:(TFP3DVector*)vector;
43 |
44 | - (TFP3DVector*)vectorByDividingByScalar:(double)value;
45 | - (TFP3DVector*)vectorByMultiplyingByScalar:(double)value;
46 | @end
--------------------------------------------------------------------------------
/microprint/TFPApplicationDebug.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPApplicationDelegate+TFPApplicationDebug.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-08-31.
6 | // Copyright © 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPApplicationDelegate.h"
10 |
11 | @interface TFPApplicationDelegate (TFPApplicationDebug)
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/microprint/TFPBedLevelCalibration.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPManualBedLevelCalibration.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sun 2015-07-12.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPOperation.h"
10 |
11 | typedef NS_ENUM(NSUInteger, TFPBedLevelCalibrationCorner) {
12 | TFPBedLevelCalibrationCornerCenter,
13 | TFPBedLevelCalibrationCornerBackLeft,
14 | TFPBedLevelCalibrationCornerBackRight,
15 | TFPBedLevelCalibrationCornerBackFrontRight,
16 | TFPBedLevelCalibrationCornerBackFrontLeft,
17 |
18 | TFPBedLevelCalibrationCornerLast = TFPBedLevelCalibrationCornerBackFrontLeft,
19 | };
20 |
21 |
22 | @interface TFPBedLevelCalibration : TFPOperation
23 | - (BOOL)startAtLevel:(double)startZ heightTarget:(double)heightTarget;
24 |
25 | - (void)adjustUp;
26 | - (void)adjustDown;
27 | @property (readonly) double currentLevel;
28 |
29 | - (void)continue;
30 |
31 | @property (copy) void(^didStartMovingHandler)();
32 | @property (copy) void(^didStopAtCornerHandler)(TFPBedLevelCalibrationCorner corner);
33 | @property (copy) void(^didFinishHandler)();
34 | @end
--------------------------------------------------------------------------------
/microprint/TFPBedLevelCompensator.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPBedLevelCompensator.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-08-20.
6 | // Copyright © 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPPrintParameters.h"
11 |
12 |
13 | @interface TFPBedLevelCompensator : NSObject
14 | - (instancetype)initWithBedLevel:(TFPBedLevelOffsets)level;
15 |
16 | - (double)zAdjustmentAtX:(double)x Y:(double)y;
17 | @end
--------------------------------------------------------------------------------
/microprint/TFPDryRunPrinter.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPDryRunPrinter.h
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Wed 2015-06-24.
6 | //
7 |
8 | #import "TFPPrinter.h"
9 |
10 | @interface TFPDryRunPrinter : TFPPrinter
11 |
12 | + (void)setSpeedMultiplier:(double)multiplier;
13 | @end
14 |
--------------------------------------------------------------------------------
/microprint/TFPDryRunPrinter.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPDryRunPrinter.m
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Wed 2015-06-24.
6 | //
7 |
8 | #import "TFPDryRunPrinter.h"
9 | #import "TFPExtras.h"
10 | #import "TFP3DVector.h"
11 |
12 | static double speedMultiplier = 10;
13 |
14 |
15 | @interface TFPPrinter (Private)
16 | @property (readwrite) BOOL pendingConnection;
17 | @property (readwrite) NSString *serialNumber;
18 | @end
19 |
20 |
21 | @interface TFPDryRunPrinter ()
22 | @property TFP3DVector *simulatedPosition;
23 | @property double feedRate;
24 | @property BOOL relativeMode;
25 | @end
26 |
27 |
28 | @interface TFPPrinter (HelpersPrivate)
29 | - (void)fetchBedOffsetsWithCompletionHandler:(void(^)(BOOL success, TFPBedLevelOffsets offsets))completionHandler;
30 | - (void)setBedOffsets:(TFPBedLevelOffsets)offsets completionHandler:(void(^)(BOOL success))completionHandler;
31 | @end
32 |
33 |
34 |
35 |
36 | @implementation TFPDryRunPrinter
37 |
38 |
39 | - (instancetype)init {
40 | if(!(self = [super init])) return nil;
41 |
42 | self.simulatedPosition = [TFP3DVector zeroVector];
43 |
44 | return self;
45 | }
46 |
47 |
48 | - (void)sendGCode:(TFPGCode*)code responseHandler:(void(^)(BOOL success, NSDictionary *value))block responseQueue:(dispatch_queue_t)queue {
49 | NSInteger G = [code valueForField:'G' fallback:-1];
50 | NSTimeInterval duration = 0.02;
51 |
52 | if(G == 0 || G == 1) {
53 | TFP3DVector *movement = [[code movementVector] vectorByDefaultingToValues:self.simulatedPosition];
54 | self.feedRate = [code valueForField:'F' fallback:self.feedRate];
55 |
56 | if(self.relativeMode) {
57 | movement = [TFP3DVector vectorWithX:@(self.simulatedPosition.x.doubleValue + movement.x.doubleValue)
58 | Y:@(self.simulatedPosition.y.doubleValue + movement.y.doubleValue)
59 | Z:@(self.simulatedPosition.z.doubleValue + movement.z.doubleValue)];
60 | }
61 |
62 | double distance = [self.simulatedPosition distanceToPoint:movement];
63 |
64 | double calculatedSpeed = (6288.78 * (self.feedRate-830))/((self.feedRate-828.465) * (self.feedRate+79.5622));
65 | duration = distance / calculatedSpeed;
66 | duration /= self.speedMultiplier;
67 | self.simulatedPosition = movement;
68 |
69 | } else if(G == 90) {
70 | self.relativeMode = NO;
71 |
72 | } else if(G == 91) {
73 | self.relativeMode = YES;
74 |
75 | } else if(G == 30 || G == 28) {
76 | TFP3DVector *movement = [TFP3DVector vectorWithX:@50 Y:@50 Z:(G == 30 ? @0 : self.simulatedPosition.z)];
77 | self.feedRate = [code valueForField:'F' fallback:self.feedRate];
78 |
79 | double distance = [self.simulatedPosition distanceToPoint:movement];
80 |
81 | double calculatedSpeed = (6288.78 * (self.feedRate-830))/((self.feedRate-828.465) * (self.feedRate+79.5622));
82 | duration = distance / calculatedSpeed;
83 | duration = (duration / self.speedMultiplier) + 4; // At least 4 seconds
84 | self.simulatedPosition = movement;
85 | }
86 |
87 | dispatch_after(dispatch_time(0, duration * NSEC_PER_SEC), queue, ^{
88 | if(block) {
89 | block(YES, @{});
90 | }
91 | });
92 | }
93 |
94 |
95 | - (TFPPrinterColor)color {
96 | return TFPPrinterColorOther;
97 | }
98 |
99 |
100 | - (NSString *)firmwareVersion {
101 | return @"0000000000";
102 | }
103 |
104 |
105 | - (void)fetchBacklashValuesWithCompletionHandler:(void(^)(BOOL success, TFPBacklashValues values))completionHandler {
106 | dispatch_after(dispatch_time(0, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
107 | completionHandler(YES, (TFPBacklashValues){0.33, 0.69, 1500});
108 | });
109 | }
110 |
111 |
112 | - (void)fetchBedOffsetsWithCompletionHandler:(void (^)(BOOL, TFPBedLevelOffsets))completionHandler {
113 | dispatch_after(dispatch_time(0, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
114 | completionHandler(YES, (TFPBedLevelOffsets){-0.30, -0.4, -0.65, -1, -0.95});
115 | });
116 | }
117 |
118 |
119 | - (void)establishConnectionWithCompletionHandler:(void(^)(NSError *error))completionHandler {
120 | self.pendingConnection = YES;
121 | dispatch_after(dispatch_time(0, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
122 | self.serialNumber = @"TEST-00-00-00-00-123-456";
123 | self.pendingConnection = NO;
124 | if(completionHandler) {
125 | completionHandler(nil);
126 | }
127 | });
128 | };
129 |
130 |
131 | - (void)setBedOffsets:(TFPBedLevelOffsets)offsets completionHandler:(void (^)(BOOL))completionHandler {
132 | TFLog(@"Dry run setBedOffsets: %@", TFPBedLevelOffsetsDescription(offsets));
133 | [super setBedOffsets:offsets completionHandler:completionHandler];
134 | }
135 |
136 |
137 | - (double)speedMultiplier {
138 | return speedMultiplier;
139 | }
140 |
141 |
142 | + (void)setSpeedMultiplier:(double)multiplier {
143 | speedMultiplier = multiplier;
144 | }
145 |
146 |
147 | @end
148 |
--------------------------------------------------------------------------------
/microprint/TFPDryRunPrinterConnection.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPDryRunPrinterConnection.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-08-24.
6 | // Copyright © 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPPrinterConnection.h"
10 |
11 | @interface TFPDryRunPrinterConnection : TFPPrinterConnection
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/microprint/TFPDryRunPrinterConnection.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPDryRunPrinterConnection.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-08-24.
6 | // Copyright © 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPDryRunPrinterConnection.h"
10 | #import "TFPGCode.h"
11 | #import "TFPGCodeHelpers.h"
12 | #import "TFPExtras.h"
13 | #import "TFPPrinter+VirtualEEPROM.h"
14 |
15 |
16 | @interface TFPPrinterConnection (Private)
17 | - (void)processIncomingString:(NSString*)incomingLine;
18 | @property dispatch_queue_t serialPortQueue;
19 | @property (readwrite) TFPPrinterConnectionState state;
20 | - (void)finishEstablishment;
21 | @property (copy) void(^connectionCompletionHandler)(NSError *error);
22 | @end
23 |
24 |
25 |
26 | @implementation TFPDryRunPrinterConnection
27 |
28 |
29 | - (instancetype)init {
30 | return [super initWithSerialPort:nil];
31 | }
32 |
33 |
34 | - (void)sendGCode:(TFPGCode*)code {
35 | NSInteger M = [code valueForField:'M' fallback:-1];
36 | NSDictionary *values = nil;
37 |
38 | switch(M) {
39 | case 115:
40 | values = @{@"X-SERIAL_NUMBER": @"DRYRUN0000123456"};
41 | break;
42 |
43 | case 619: {
44 | NSInteger index = [code valueForField:'S'];
45 | float value = 0;
46 |
47 | switch(index) {
48 | case VirtualEEPROMIndexBacklashCompensationX:
49 | value = 0.33;
50 | break;
51 | case VirtualEEPROMIndexBacklashCompensationY:
52 | value = 0.88;
53 | break;
54 | case VirtualEEPROMIndexBacklashCompensationSpeed:
55 | value = 1500;
56 | break;
57 | }
58 |
59 | values = @{@"DT": [NSString stringWithFormat:@"%d", [TFPPrinter encodeVirtualEEPROMIntegerValueForFloat:value]]};
60 | break;
61 | }
62 |
63 | case 105:
64 | dispatch_after(dispatch_time(0, 0.1 * NSEC_PER_SEC), self.serialPortQueue, ^{
65 | [self processIncomingString:@"T:300"];
66 | });
67 | break;
68 | }
69 |
70 | dispatch_after(dispatch_time(0, 0.01 * NSEC_PER_SEC), self.serialPortQueue, ^{
71 | [self respondOKWithValues:values toCode:code];
72 | });
73 | }
74 |
75 |
76 | - (void)respondOKWithValues:(NSDictionary*)values toCode:(TFPGCode*)code {
77 | NSString *valueString = [[values.allKeys tf_mapWithBlock:^id(NSString *key) {
78 | return [NSString stringWithFormat:@"%@:%@", key, values[key]];
79 | }] componentsJoinedByString:@" "] ?: @"";
80 | NSString *lineNumber = [code hasField:'N'] ? [NSString stringWithFormat:@"%hd", code.N] : @"";
81 | NSString *response = [NSString stringWithFormat:@"ok %@ %@", lineNumber, valueString];
82 |
83 | [self processIncomingString:response];
84 | }
85 |
86 |
87 | - (void)openWithCompletionHandler:(void(^)(NSError *error))completionHandler {
88 | self.state = TFPPrinterConnectionStatePending;
89 | self.connectionCompletionHandler = completionHandler;
90 |
91 | dispatch_after(dispatch_time(0, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
92 | [self finishEstablishment];
93 | });
94 | }
95 |
96 |
97 | @end
--------------------------------------------------------------------------------
/microprint/TFPExtras.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPExtras.h
3 | // MicroPrint
4 | //
5 | //
6 |
7 | @import Foundation;
8 | @import CoreGraphics;
9 | #import "ORSSerialPort.h"
10 |
11 |
12 | @interface NSArray (TFPExtras)
13 | - (NSArray*)tf_mapWithBlock:(id(^)(id object))function;
14 | - (NSArray*)tf_selectWithBlock:(BOOL(^)(id object))function;
15 | - (NSArray*)tf_rejectWithBlock:(BOOL(^)(id object))function;
16 | - (NSSet*)tf_set;
17 | @end
18 |
19 |
20 | @interface NSData (TFPExtras)
21 | + (instancetype)tf_singleByte:(uint8_t)byte;
22 |
23 | @property (readonly) NSData *tf_fletcher16Checksum;
24 | - (NSUInteger)tf_offsetOfData:(NSData*)subdata;
25 | - (NSData *)tf_dataByDecodingDeflate;
26 | @end
27 |
28 |
29 | @interface NSIndexSet (TFPExtras)
30 | + (NSIndexSet*)tf_indexSetWithIndexes:(NSInteger)firstIndex, ...; // Terminate with negative
31 | + (NSIndexSet*)ww_indexSetFromArray:(NSArray *)source;
32 | @end
33 |
34 |
35 | extern NSString *const TFPErrorDomain;
36 | extern NSString *const TFPErrorGCodeStringKey;
37 | extern NSString *const TFPErrorGCodeKey;
38 | extern NSString *const TFPErrorGCodeLineKey;
39 |
40 |
41 | enum TFPErrorCodes {
42 | TFPErrorCodeParseError = 1,
43 | TFPErrorCodeIncompatibleCode,
44 | TFPScriptExecutionError,
45 | };
46 |
47 |
48 | extern void TFLog(NSString *format, ...);
49 | extern uint64_t TFNanosecondTime(void);
50 |
51 | extern CGFloat TFPVectorDot(CGVector a, CGVector b);
52 |
53 | extern void TFAssertMainThread();
54 | extern void TFMainThread(void(^block)());
--------------------------------------------------------------------------------
/microprint/TFPExtras.m:
--------------------------------------------------------------------------------
1 | //
2 | // Extras.m
3 | // MicroPrint
4 | //
5 | //
6 |
7 | #import "TFPExtras.h"
8 | #import "zlib.h"
9 | @import MachO;
10 |
11 |
12 | NSString *const TFPErrorDomain = @"TFPErrorDomain";
13 | NSString *const TFPErrorGCodeStringKey = @"GCodeString";
14 | NSString *const TFPErrorGCodeKey = @"GCode";
15 | NSString *const TFPErrorGCodeLineKey = @"GCodeLine";
16 |
17 |
18 | @implementation NSArray (TFPExtras)
19 |
20 | - (NSArray*)tf_mapWithBlock:(id(^)(id object))function {
21 | NSMutableArray *array = [NSMutableArray new];
22 | for(id object in self) {
23 | id value = function(object);
24 | if(value) {
25 | [array addObject:value];
26 | }
27 | }
28 | return array;
29 | }
30 |
31 |
32 | - (NSArray*)tf_selectWithBlock:(BOOL(^)(id object))function {
33 | NSMutableArray *array = [NSMutableArray new];
34 | for(id object in self) {
35 | if(function(object)) {
36 | [array addObject:object];
37 | }
38 | }
39 | return array;
40 | }
41 |
42 |
43 | - (NSArray*)tf_rejectWithBlock:(BOOL(^)(id object))function {
44 | return [self tf_selectWithBlock:^BOOL(id object) {
45 | return !function(object);
46 | }];
47 | }
48 |
49 |
50 | - (NSSet*)tf_set {
51 | return [NSSet setWithArray:self];
52 | }
53 |
54 |
55 | @end
56 |
57 |
58 |
59 | @implementation NSData (TFPExtras)
60 |
61 |
62 | + (instancetype)tf_singleByte:(uint8_t)byte {
63 | return [NSData dataWithBytes:&byte length:1];
64 | }
65 |
66 |
67 | - (NSData*)tf_fletcher16Checksum {
68 | uint8_t check1 = 0;
69 | uint8_t check2 = 0;
70 |
71 | const uint8_t *bytes = self.bytes;
72 | for(int i = 0; i < self.length; i++) {
73 | uint8_t byte = bytes[i];
74 | check1 = (check1 + byte) % 255;
75 | check2 = (check2 + check1) % 255;
76 | }
77 |
78 | NSMutableData *checksum = [NSMutableData data];
79 | [checksum appendBytes:&check1 length:sizeof(check1)];
80 | [checksum appendBytes:&check2 length:sizeof(check2)];
81 | return checksum;
82 | }
83 |
84 |
85 | - (NSUInteger)tf_offsetOfData:(NSData*)subdata {
86 | return [self rangeOfData:subdata options:0 range:NSMakeRange(0, self.length)].location;
87 | }
88 |
89 |
90 | - (NSData *)tf_dataByDecodingDeflate {
91 | NSData *data = self;
92 | if ([data length] == 0) return data;
93 |
94 | NSUInteger full_length = [data length];
95 | NSUInteger half_length = [data length] / 2;
96 |
97 | NSMutableData *decompressed = [NSMutableData dataWithLength:full_length + half_length];
98 | BOOL done = NO;
99 | int status;
100 |
101 | z_stream strm;
102 | strm.next_in = (Bytef *)[data bytes];
103 | strm.avail_in = (uInt)[data length];
104 | strm.total_out = 0;
105 | strm.zalloc = Z_NULL;
106 | strm.zfree = Z_NULL;
107 |
108 | if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
109 | while (!done) {
110 | // Make sure we have enough room and reset the lengths.
111 | if (strm.total_out >= [decompressed length])
112 | [decompressed increaseLengthBy: half_length];
113 | strm.next_out = [decompressed mutableBytes] + strm.total_out;
114 | strm.avail_out = (uInt)([decompressed length] - strm.total_out);
115 |
116 | // Inflate another chunk.
117 | status = inflate (&strm, Z_SYNC_FLUSH);
118 | if (status == Z_STREAM_END) done = YES;
119 | else if (status != Z_OK) break;
120 | }
121 | if (inflateEnd (&strm) != Z_OK) return nil;
122 |
123 | // Set real length.
124 | if (done) {
125 | [decompressed setLength:strm.total_out];
126 | return [NSData dataWithData: decompressed];
127 | } else {
128 | return nil;
129 | }
130 | }
131 |
132 |
133 | @end
134 |
135 |
136 | @implementation NSIndexSet (TFPExtras)
137 |
138 |
139 | + (NSIndexSet*)tf_indexSetWithIndexes:(NSInteger)firstIndex, ... {
140 | va_list list;
141 | va_start(list, firstIndex);
142 |
143 | NSMutableIndexSet *indexes = [NSMutableIndexSet indexSetWithIndex:firstIndex];
144 | NSInteger index;
145 | while((index = va_arg(list, int)) >= 0) {
146 | [indexes addIndex:index];
147 | }
148 |
149 | va_end(list);
150 | return indexes;
151 | }
152 |
153 | + (NSIndexSet*)ww_indexSetFromArray:(NSArray *)source {
154 |
155 | NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
156 |
157 | for (NSNumber *index in source) {
158 | [indexes addIndex:index.intValue];
159 | }
160 |
161 | return indexes;
162 | }
163 |
164 |
165 | @end
166 |
167 |
168 | void TFLog(NSString *format, ...) {
169 | va_list list;
170 | va_start(list, format);
171 | NSString *string = [[NSString alloc] initWithFormat:format arguments:list];
172 | va_end(list);
173 | printf("%s\n", string.UTF8String);
174 | }
175 |
176 |
177 | uint64_t TFNanosecondTime(void) {
178 | mach_timebase_info_data_t info;
179 | mach_timebase_info(&info);
180 | return (mach_absolute_time() * info.numer) / info.denom;
181 | }
182 |
183 |
184 | CGFloat TFPVectorDot(CGVector a, CGVector b) {
185 | return a.dx * b.dx + a.dy * b.dy;
186 | }
187 |
188 |
189 | void TFAssertMainThread() {
190 | NSCAssert([NSThread isMainThread], @"Whoa. This should be on the main thread but isn't!");
191 | }
192 |
193 |
194 | void TFMainThread(void(^block)()) {
195 | if([NSThread isMainThread]) {
196 | block();
197 | }else{
198 | dispatch_async(dispatch_get_main_queue(), block);
199 | }
200 | }
--------------------------------------------------------------------------------
/microprint/TFPExtrusionOperation.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPExtrusionOperation.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sun 2015-06-28.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPOperation.h"
11 |
12 |
13 | @interface TFPExtrusionOperation : TFPOperation
14 | - (instancetype)initWithPrinter:(TFPPrinter*)printer retraction:(BOOL)retract;
15 |
16 | @property double temperature;
17 |
18 | @property (copy) void(^preparationProgressBlock)(double temperature);
19 | @property (copy) void(^extrusionStartedBlock)();
20 | @property (copy) void(^extrusionStoppedBlock)();
21 | @end
--------------------------------------------------------------------------------
/microprint/TFPExtrusionOperation.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPExtrusionOperation.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sun 2015-06-28.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPExtrusionOperation.h"
10 | #import "TFPExtras.h"
11 | #import "TFPGCodeHelpers.h"
12 | #import "TFP3DVector.h"
13 |
14 | #import "TFAsyncOperationCoalescer.h"
15 | #import "MAKVONotificationCenter.h"
16 |
17 |
18 | static const double extrudeStepLength = 0.5;
19 | static const double extrudeFeedRate = 210;
20 | static const double minimumZLevelForOperation = 25;
21 |
22 |
23 |
24 | @interface TFPExtrusionOperation ()
25 | @property BOOL retract;
26 | @property BOOL stopped;
27 |
28 | @property (readwrite) TFPOperationStage stage;
29 |
30 | @property (copy) void(^cancelHeatingBlock)();
31 | @property (copy) void(^cancelMovingBlock)();
32 | @end
33 |
34 |
35 |
36 | @implementation TFPExtrusionOperation
37 | @synthesize stage=_stage;
38 |
39 |
40 | - (instancetype)initWithPrinter:(TFPPrinter*)printer retraction:(BOOL)retract {
41 | if(!(self = [super initWithPrinter:printer])) return nil;
42 |
43 | if(retract) {
44 | self.temperature = 275;
45 | }else{
46 | self.temperature = 230;
47 | }
48 | self.retract = retract;
49 |
50 | return self;
51 | }
52 |
53 |
54 | - (void)extrudeStep {
55 | __weak __typeof__(self) weakSelf = self;
56 | double extrusionLength = self.retract ? -extrudeStepLength : extrudeStepLength;
57 |
58 | [self.printer sendGCode:[TFPGCode codeForExtrusion:extrusionLength feedRate:extrudeFeedRate] responseHandler:^(BOOL success, NSDictionary *value) {
59 | if(!weakSelf.stopped) {
60 | [weakSelf extrudeStep];
61 | }
62 | }];
63 | }
64 |
65 |
66 | - (void)stop {
67 | if(self.cancelHeatingBlock || self.cancelMovingBlock) {
68 | // Prep stage
69 | if(self.cancelHeatingBlock)
70 | self.cancelHeatingBlock();
71 | if(self.cancelMovingBlock)
72 | self.cancelMovingBlock();
73 |
74 | self.cancelMovingBlock = nil;
75 | self.cancelHeatingBlock = nil;
76 |
77 | [self runEndCodeIncludingRetraction:NO];
78 | }else{
79 | [self runEndCodeIncludingRetraction:YES];
80 | }
81 |
82 | self.stopped = YES;
83 | }
84 |
85 |
86 | - (void)runEndCodeIncludingRetraction:(BOOL)retractIfNeeded {
87 | __weak __typeof__(self) weakSelf = self;
88 |
89 | NSMutableArray *steps = [@[
90 | [TFPGCode absoluteModeCode],
91 | [TFPGCode codeForTurningOffHeater],
92 | [TFPGCode turnOffFanCode],
93 | [TFPGCode turnOffMotorsCode],
94 | ] mutableCopy];
95 | if(!self.retract && retractIfNeeded) {
96 | [steps insertObject:[TFPGCode codeForExtrusion:-2 feedRate:extrudeFeedRate] atIndex:0];
97 | }
98 |
99 | self.stage = TFPOperationStageEnding;
100 |
101 | TFPGCodeProgram *end = [TFPGCodeProgram programWithLines:steps];
102 | [self.context runGCodeProgram:end completionHandler:^(BOOL success, NSArray *valueDictionaries) {
103 | if(weakSelf.extrusionStoppedBlock) {
104 | weakSelf.extrusionStoppedBlock();
105 | }
106 | [self ended];
107 | }];
108 | }
109 |
110 |
111 |
112 | - (BOOL)start {
113 | if(![super start]) {
114 | return NO;
115 | }
116 | self.stage = TFPOperationStagePreparation;
117 |
118 | __weak TFPPrinter *printer = self.printer;
119 | __weak __typeof__(self) weakSelf = self;
120 |
121 |
122 | [self.context sendGCode:[TFPGCode codeForSettingFanSpeed:255] responseHandler:nil];
123 | [self.context sendGCode:[TFPGCode absoluteModeCode] responseHandler:nil];
124 |
125 |
126 | TFAsyncOperationCoalescer *coalescer = [TFAsyncOperationCoalescer new];
127 |
128 | void(^heatingProgressBlock)(double progress) = [coalescer addOperation];
129 | self.cancelHeatingBlock = [self.context setHeaterTemperatureAsynchronously:self.temperature progressBlock:^(double currentTemperature) {
130 | heatingProgressBlock(currentTemperature / weakSelf.temperature);
131 | } completionBlock:^{
132 | heatingProgressBlock(1);
133 | weakSelf.cancelHeatingBlock = nil;
134 | }];
135 |
136 |
137 | TFP3DVector *raisedPosition = [TFP3DVector zVector:MAX(self.printer.position.z, minimumZLevelForOperation)];
138 |
139 | void(^moveProgressBlock)(double progress) = [coalescer addOperation];
140 | self.cancelMovingBlock = [self.context moveAsynchronouslyToPosition:raisedPosition feedRate:2900 progressBlock:^(double fraction, TFP3DVector *position) {
141 | moveProgressBlock(fraction);
142 | } completionBlock:^{
143 | moveProgressBlock(1);
144 | weakSelf.cancelMovingBlock = nil;
145 | }];
146 |
147 | coalescer.progressUpdateBlock = ^(double progress) {
148 | if(weakSelf.preparationProgressBlock) {
149 | weakSelf.preparationProgressBlock(progress);
150 | }
151 | };
152 |
153 | coalescer.completionBlock = ^{
154 | if(weakSelf.extrusionStartedBlock) {
155 | weakSelf.extrusionStartedBlock();
156 | }
157 | weakSelf.stage = TFPOperationStageRunning;
158 |
159 | [printer sendGCode:[TFPGCode relativeModeCode] responseHandler:nil];
160 | [weakSelf extrudeStep];
161 | };
162 |
163 | return YES;
164 | }
165 |
166 |
167 | - (TFPOperationKind)kind {
168 | return TFPOperationKindUtility;
169 | }
170 |
171 |
172 | - (NSString *)activityDescription {
173 | return self.retract ? @"Retracting" : @"Extruding";
174 | }
175 |
176 |
177 | @end
--------------------------------------------------------------------------------
/microprint/TFPFilament.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPFilament.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sat 2015-07-11.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 |
11 |
12 | typedef NS_ENUM(NSUInteger, TFPFilamentType) {
13 | TFPFilamentTypeUnknown = 0,
14 | TFPFilamentTypePLA = 'PLA ',
15 | TFPFilamentTypeABS = 'ABS ',
16 | TFPFilamentTypeHIPS = 'HIPS',
17 | TFPFilamentTypeOther = 'othr',
18 | };
19 |
20 |
21 |
22 | @interface TFPFilament : NSObject
23 | + (instancetype)defaultFilament;
24 | + (instancetype)filamentForType:(TFPFilamentType)type;
25 |
26 | + (TFPFilamentType)typeForString:(NSString*)string;
27 |
28 | @property (readonly) TFPFilamentType type;
29 | @property (readonly, copy) NSString *name;
30 |
31 | @property (readonly) double defaultTemperature;
32 |
33 | @property (readonly) NSUInteger fanSpeed;
34 | @property (readonly) double temperatureIncreaseForFirstLayer;
35 | @end
36 |
--------------------------------------------------------------------------------
/microprint/TFPFilament.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPFilament.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sat 2015-07-11.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPFilament.h"
10 |
11 |
12 | @interface TFPFilament ()
13 | @property (readwrite) TFPFilamentType type;
14 | @property (readwrite, copy) NSString *name;
15 |
16 | @property (readwrite) double defaultTemperature;
17 | @end
18 |
19 |
20 |
21 | @implementation TFPFilament
22 |
23 |
24 | + (NSDictionary*)filamentSpecification {
25 | return @{
26 | @(TFPFilamentTypePLA):
27 | @{
28 | @"name": @"PLA",
29 | @"temperature": @215,
30 | },
31 | @(TFPFilamentTypeABS):
32 | @{
33 | @"name": @"ABS",
34 | @"temperature": @275,
35 | },
36 | @(TFPFilamentTypeHIPS):
37 | @{
38 | @"name": @"HIPS",
39 | @"temperature": @265,
40 | },
41 | @(TFPFilamentTypeOther):
42 | @{
43 | @"name": @"Other",
44 | @"temperature": @215,
45 | },
46 | };
47 | }
48 |
49 |
50 | + (instancetype)defaultFilament {
51 | return [self filamentForType:TFPFilamentTypePLA];
52 | }
53 |
54 |
55 | + (instancetype)filamentForType:(TFPFilamentType)type {
56 | return [[self alloc] initWithType:type data:[self filamentSpecification][@(type)]];
57 | }
58 |
59 |
60 | + (TFPFilamentType)typeForString:(NSString*)string {
61 | NSDictionary *names = @{
62 | @"pla" : @(TFPFilamentTypePLA),
63 | @"abs" : @(TFPFilamentTypeABS),
64 | @"hips" : @(TFPFilamentTypeHIPS),
65 | @"other" : @(TFPFilamentTypeOther),
66 | };
67 | NSNumber *type = names[string.lowercaseString];
68 | return type ? type.integerValue : TFPFilamentTypeUnknown;
69 | }
70 |
71 |
72 | - (instancetype)initWithType:(TFPFilamentType)type data:(NSDictionary*)spec {
73 | if(!spec) {
74 | return nil;
75 | }
76 |
77 | if(!(self = [super init])) return nil;
78 |
79 | self.type = type;
80 | self.name = spec[@"name"];
81 | self.defaultTemperature = [spec[@"temperature"] doubleValue];
82 |
83 | return self;
84 | }
85 |
86 |
87 | - (NSUInteger)fanSpeed {
88 | return (self.type == TFPFilamentTypePLA) ? 255 : 50;
89 | }
90 |
91 |
92 | - (double)temperatureIncreaseForFirstLayer {
93 | return (self.type == TFPFilamentTypePLA) ? 10 : 15;
94 | }
95 |
96 |
97 | @end
--------------------------------------------------------------------------------
/microprint/TFPGCode.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFGCodeLine.h
3 | // MicroPrint
4 | //
5 | //
6 |
7 | #import
8 |
9 | @interface TFPGCode : NSObject
10 | + (instancetype)codeWithString:(NSString*)string;
11 | - (instancetype)initWithString:(NSString*)string;
12 |
13 | + (instancetype)codeWithField:(char)field value:(double)value;
14 | + (instancetype)codeWithComment:(NSString*)string;
15 |
16 | - (TFPGCode*)codeBySettingField:(char)field toValue:(double)value;
17 | - (TFPGCode*)codeByAdjustingField:(char)field offset:(double)offset;
18 | - (TFPGCode*)codeBySettingComment:(NSString*)comment;
19 |
20 | @property (readonly, copy) NSString *comment;
21 | @property (readonly) BOOL hasFields;
22 | - (void)enumerateFieldsWithBlock:(void(^)(char field, double value, BOOL *stopFlag))block;
23 |
24 | - (BOOL)hasField:(char)field;
25 | - (double)valueForField:(char)field;
26 | - (double)valueForField:(char)field fallback:(double)fallbackValue;
27 | - (NSNumber*)numberForField:(char)field;
28 |
29 | @property (nonatomic, readonly) int16_t N;
30 |
31 | @property (nonatomic, readonly) uint16_t M;
32 | @property (nonatomic, readonly) uint16_t G;
33 |
34 | @property (nonatomic, readonly) float X;
35 | @property (nonatomic, readonly) float Y;
36 | @property (nonatomic, readonly) float Z;
37 | @property (nonatomic, readonly) float E;
38 | @property (nonatomic, readonly) float F;
39 |
40 | @property (nonatomic, readonly) uint32_t S;
41 | @property (nonatomic, readonly) uint32_t P;
42 |
43 | @property (readonly) NSData *repetierV2Representation;
44 | @property (readonly) NSString *ASCIIRepresentation;
45 | @end
--------------------------------------------------------------------------------
/microprint/TFPGCodeHelpers.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPGCodeHelpers.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-07-13.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPGCode.h"
10 | #import "TFPGCodeProgram.h"
11 |
12 | @class TFP3DVector;
13 |
14 |
15 | @interface TFPGCode (TFPHelpers)
16 | + (instancetype)stopCode;
17 | + (instancetype)waitCodeWithDuration:(NSTimeInterval)seconds;
18 | + (instancetype)waitForCompletionCode;
19 | + (instancetype)findZeroCode;
20 |
21 | // Line numbering
22 | + (instancetype)codeForSettingLineNumber:(uint16_t)lineNumber;
23 | - (instancetype)codeBySettingLineNumber:(uint16_t)lineNumber;
24 |
25 | // Feed rates
26 | + (instancetype)codeForSettingFeedRate:(double)feedRate;
27 |
28 | // Motors
29 | + (instancetype)turnOnMotorsCode;
30 | + (instancetype)turnOffMotorsCode;
31 |
32 | // Positioning
33 | + (instancetype)absoluteModeCode;
34 | + (instancetype)relativeModeCode;
35 | + (instancetype)codeForResettingPosition:(TFP3DVector*)position extrusion:(NSNumber*)E;
36 |
37 | // Moving
38 | + (instancetype)moveHomeCode;
39 | + (instancetype)moveWithPosition:(TFP3DVector*)position extrusion:(NSNumber*)E feedRate:(double)F;
40 | + (instancetype)moveWithPosition:(TFP3DVector*)position feedRate:(double)feedRate;
41 | + (instancetype)codeForGettingPosition;
42 |
43 | // Extrusion
44 | + (instancetype)codeForExtrusion:(double)E feedRate:(double)feedRate;
45 | + (instancetype)resetExtrusionCode;
46 |
47 | // Heater
48 | + (instancetype)codeForHeaterTemperature:(double)temperature waitUntilDone:(BOOL)wait;
49 | + (instancetype)codeForTurningOffHeater;
50 | + (instancetype)codeForReadingHeaterTemperature;
51 |
52 | // Fan
53 | + (instancetype)turnOnFanCode;
54 | + (instancetype)turnOffFanCode;
55 | + (instancetype)codeForSettingFanSpeed:(double)speed;
56 |
57 | // Virtual EEPROM
58 | + (instancetype)codeForReadingVirtualEEPROMAtIndex:(NSUInteger)valueIndex;
59 | + (instancetype)codeForWritingVirtualEEPROMAtIndex:(NSUInteger)valueIndex value:(int32_t)value;
60 |
61 | @property (readonly) NSInteger layerIndexFromComment;
62 |
63 | @property (readonly) TFP3DVector *movementVector;
64 | @end
65 |
66 |
67 | typedef NS_ENUM(NSUInteger, TFPPrintPhase) {
68 | TFPPrintPhaseInvalid,
69 | TFPPrintPhaseSkirt,
70 | TFPPrintPhaseAdhesion,
71 | TFPPrintPhaseModel,
72 | };
73 |
74 |
75 | @interface TFPPrintLayer : NSObject
76 | @property (readonly) NSInteger layerIndex;
77 | @property (readonly) TFPPrintPhase phase;
78 | @property (readonly) NSRange lineRange;
79 | @property (readonly) double minZ;
80 | @property (readonly) double maxZ;
81 | @end
82 |
83 |
84 | typedef struct {
85 | double x;
86 | double y;
87 | double z;
88 | double e;
89 | } TFPAbsolutePosition;
90 |
91 |
92 |
93 | typedef struct {
94 | double x;
95 | double y;
96 | double z;
97 | double xSize;
98 | double ySize;
99 | double zSize;
100 | } TFPCuboid;
101 |
102 |
103 | extern double TFPAbsolutePositionDistance(TFPAbsolutePosition a, TFPAbsolutePosition b);
104 |
105 | extern BOOL TFPCuboidContainsPosition(TFPCuboid cuboid, TFPAbsolutePosition position);
106 | extern BOOL TFPCuboidContainsCuboid(TFPCuboid outer, TFPCuboid inner);
107 | extern TFPCuboid TFPCuboidInfinite;
108 |
109 | extern TFPCuboid TFPCuboidM3DMicroPrintVolumeLower;
110 | extern TFPCuboid TFPCuboidM3DMicroPrintVolumeUpper;
111 |
112 | extern double TFPBoundedTemperature(double temperature);
113 | extern BOOL TFPTemperatureWithinBounds(double temperature);
114 |
115 | @interface TFPGCodeProgram (TFPHelpers)
116 | - (TFPCuboid)measureBoundingBoxWithinBox:(TFPCuboid)limit;
117 | - (TFPCuboid)measureBoundingBox;
118 | - (BOOL)withinM3DMicroPrintableVolume;
119 |
120 | - (void)enumerateMovesWithBlock:(void(^)(TFPAbsolutePosition from, TFPAbsolutePosition to, double feedRate, TFPGCode *code, NSUInteger index))block;
121 |
122 | - (BOOL)validateForM3D:(NSError**)error;
123 |
124 | // Keys are TFPPrintPhases; values are NSRanges
125 | - (NSDictionary *)determinePhaseRanges;
126 |
127 | - (NSArray *)determineLayers;
128 | @end
--------------------------------------------------------------------------------
/microprint/TFPGCodeProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFGCodeProgram.h
3 | // MicroPrint
4 | //
5 |
6 | @import Foundation;
7 | @class TFP3DVector, TFPGCode;
8 |
9 |
10 | @interface TFPGCodeProgram : NSObject
11 | + (instancetype)programWithLines:(NSArray *)lines;
12 | - (instancetype)initWithLines:(NSArray *)lines;
13 | - (instancetype)initWithString:(NSString*)string error:(NSError**)outError;
14 | - (instancetype)initWithFileURL:(NSURL*)URL error:(NSError**)outError;
15 |
16 | @property (copy, readonly) NSArray *lines;
17 |
18 | - (BOOL)writeToFileURL:(NSURL*)URL error:(NSError**)outError;
19 | - (NSString *)ASCIIRepresentation;
20 | @end
--------------------------------------------------------------------------------
/microprint/TFPGCodeProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFGCodeProgram.m
3 | // MicroPrint
4 | //
5 | //
6 |
7 | #import "TFPGCodeProgram.h"
8 | #import "TFPGCode.h"
9 | #import "TFPExtras.h"
10 |
11 | @interface TFPGCodeProgram ()
12 | @property (copy, readwrite) NSArray *lines;
13 | @end
14 |
15 |
16 | @implementation TFPGCodeProgram
17 |
18 |
19 | - (instancetype)initWithLines:(NSArray *)lines {
20 | if(!(self = [super init])) return nil;
21 |
22 | self.lines = lines;
23 |
24 | return self;
25 | }
26 |
27 |
28 | + (instancetype)programWithLines:(NSArray *)lines {
29 | return [[self alloc] initWithLines:lines];
30 | }
31 |
32 |
33 | - (instancetype)initWithString:(NSString*)string error:(NSError**)outError {
34 | NSMutableArray *lines = [NSMutableArray new];
35 | __block BOOL failed = NO;
36 | __block NSString *failedLine;
37 |
38 | [string enumerateLinesUsingBlock:^(NSString *lineString, BOOL *stop) {
39 | TFPGCode *line = [[TFPGCode alloc] initWithString:lineString];
40 | if(!line) {
41 | *stop = YES;
42 | failed = YES;
43 | failedLine = lineString;
44 | return;
45 | }
46 | [lines addObject:line];
47 | }];
48 |
49 | if(failed) {
50 | if(outError) {
51 | NSString *errorString = [NSString stringWithFormat:@"Failed to parse G-code line:\n%@", failedLine];
52 | *outError = [NSError errorWithDomain:TFPErrorDomain code:TFPErrorCodeParseError userInfo:@{TFPErrorGCodeStringKey: failedLine, NSLocalizedRecoverySuggestionErrorKey: errorString}];
53 | }
54 | return nil;
55 | }
56 |
57 | return [self initWithLines:lines];
58 | }
59 |
60 |
61 | - (instancetype)initWithFileURL:(NSURL*)URL error:(NSError**)outError {
62 | NSString *string = [NSString stringWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:NULL];
63 | if(!string) {
64 | if(outError) {
65 | NSString *errorString = @"Failed to parse G-code file. Invalid character encoding?";
66 | *outError = [NSError errorWithDomain:TFPErrorDomain code:TFPErrorCodeParseError userInfo:@{NSLocalizedRecoverySuggestionErrorKey: errorString}];
67 | }
68 | return nil;
69 | }
70 |
71 | return [self initWithString:string error:outError];
72 | }
73 |
74 |
75 | - (BOOL)writeToFileURL:(NSURL*)URL error:(NSError**)outError {
76 | return [[self ASCIIRepresentation] writeToURL:URL atomically:YES encoding:NSUTF8StringEncoding error:outError];
77 | }
78 |
79 |
80 | - (NSString *)ASCIIRepresentation {
81 | return [[self.lines valueForKey:@"ASCIIRepresentation"] componentsJoinedByString:@"\n"];
82 | }
83 |
84 |
85 | - (NSString *)description {
86 | return [[self.lines valueForKey:@"description"] componentsJoinedByString:@"\n"];
87 | }
88 |
89 |
90 | @end
--------------------------------------------------------------------------------
/microprint/TFPOperation.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPOperation.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sat 2015-07-11.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 | #import "TFPPrinter.h"
11 |
12 |
13 | // Make sure these ones are in sync with MicroPrint.sdef
14 |
15 | typedef NS_ENUM(NSUInteger, TFPOperationKind) {
16 | TFPOperationKindIdle = 'idle',
17 | TFPOperationKindPrintJob = 'prjb',
18 | TFPOperationKindCalibration = 'clbr',
19 | TFPOperationKindUtility = 'util',
20 | };
21 |
22 | typedef NS_ENUM(NSUInteger, TFPOperationStage) {
23 | TFPOperationStageIdle = 'idle',
24 | TFPOperationStagePreparation = 'prep',
25 | TFPOperationStageRunning = 'rung',
26 | TFPOperationStageEnding = 'endg',
27 | };
28 |
29 |
30 | @interface TFPOperation : NSObject
31 | - (instancetype)initWithPrinter:(TFPPrinter*)printer;
32 |
33 | @property (readonly, weak) TFPPrinter *printer;
34 | @property (readonly) NSString *activityDescription;
35 |
36 | @property (readonly) TFPOperationKind kind;
37 | @property (readonly) TFPOperationStage stage;
38 |
39 | @property (readonly) TFPPrinterContext *context;
40 | // Override these to customize context:
41 | @property (readonly) TFPPrinterContextOptions printerContextOptions;
42 | @property (readonly) dispatch_queue_t printerContextQueue;
43 |
44 | - (BOOL)start;
45 | - (void)stop;
46 | - (void)ended;
47 | @end
48 |
--------------------------------------------------------------------------------
/microprint/TFPOperation.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPOperation.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sat 2015-07-11.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPOperation.h"
10 |
11 | @interface TFPOperation ()
12 | @property (readwrite, weak) TFPPrinter *printer;
13 | @property (readwrite) TFPPrinterContext *context;
14 | @end
15 |
16 |
17 | @implementation TFPOperation
18 |
19 |
20 | - (instancetype)initWithPrinter:(TFPPrinter*)printer {
21 | if(!(self = [super init])) return nil;
22 |
23 | self.printer = printer;
24 |
25 | return self;
26 | }
27 |
28 |
29 | - (NSString *)activityDescription {
30 | return @"Doing stuff";
31 | }
32 |
33 |
34 | - (BOOL)start {
35 | self.context = [self.printer acquireContextWithOptions:[self printerContextOptions] queue:[self printerContextQueue]];
36 |
37 | if(self.context) {
38 | self.printer.currentOperation = self;
39 | return YES;
40 | } else {
41 | return NO;
42 | }
43 | }
44 |
45 |
46 | - (void)ended {
47 | self.printer.currentOperation = nil;
48 | [self.context invalidate];
49 | }
50 |
51 |
52 | - (void)stop {
53 |
54 | }
55 |
56 |
57 | - (TFPOperationKind)kind {
58 | return TFPOperationKindIdle;
59 | }
60 |
61 |
62 | - (TFPOperationStage)stage {
63 | return TFPOperationStageRunning;
64 | }
65 |
66 |
67 | - (TFPPrinterContextOptions)printerContextOptions {
68 | return 0;
69 | }
70 |
71 |
72 | - (dispatch_queue_t)printerContextQueue {
73 | return nil;
74 | }
75 |
76 |
77 | @end
--------------------------------------------------------------------------------
/microprint/TFPPrintJob.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrintJob.h
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-06-25.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPGCodeProgram.h"
11 | #import "TFPPrintParameters.h"
12 | #import "TFPOperation.h"
13 |
14 |
15 | typedef NS_ENUM(NSUInteger, TFPPrintJobState) {
16 | TFPPrintJobStatePreparing,
17 | TFPPrintJobStateHeating,
18 | TFPPrintJobStatePrinting,
19 | TFPPrintJobStateAborting,
20 | TFPPrintJobStatePausing,
21 | TFPPrintJobStatePaused,
22 | TFPPrintJobStateResuming,
23 | TFPPrintJobStateFinishing,
24 | };
25 |
26 |
27 | @interface TFPPrintJob : TFPOperation
28 | - (instancetype)initWithProgram:(TFPGCodeProgram*)program printer:(TFPPrinter*)printer printParameters:(TFPPrintParameters*)params;
29 |
30 | @property (readonly) TFPGCodeProgram *program;
31 |
32 | @property (readonly) NSUInteger completedRequests; //Observable
33 | @property (readonly) NSTimeInterval elapsedTime;
34 |
35 | @property (readonly) TFPPrintJobState state;
36 | @property (copy, readonly) NSArray *layers;
37 |
38 | @property (copy) void(^progressBlock)(void);
39 | @property (copy) void(^completionBlock)(void);
40 | @property (copy) void(^abortionBlock)(void);
41 |
42 | - (void)abort;
43 | - (void)pause;
44 | - (void)resume;
45 | @end
--------------------------------------------------------------------------------
/microprint/TFPPrintParameters.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrintParameters.h
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-06-22.
6 | //
7 |
8 | @import Foundation;
9 | #import "TFPFilament.h"
10 | #import "TFPGCodeHelpers.h"
11 |
12 |
13 | typedef struct {
14 | double common;
15 | double backLeft;
16 | double backRight;
17 | double frontRight;
18 | double frontLeft;
19 | } TFPBedLevelOffsets;
20 |
21 |
22 | typedef struct {
23 | double x;
24 | double y;
25 | double speed;
26 | } TFPBacklashValues;
27 |
28 |
29 | extern NSString *TFPBedLevelOffsetsDescription(TFPBedLevelOffsets offsets);
30 | extern NSString *TFPBacklashValuesDescription(TFPBacklashValues values);
31 |
32 |
33 | @interface TFPPrintParameters : NSObject
34 | @property (readwrite) BOOL verbose;
35 |
36 | @property (readwrite) TFPFilament *filament;
37 | @property (readwrite) BOOL useThermalBonding;
38 | @property (readwrite, nonatomic) double temperature;
39 |
40 | @property (readwrite) TFPCuboid boundingBox;
41 | @end
--------------------------------------------------------------------------------
/microprint/TFPPrintParameters.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrintParameters.m
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-06-22.
6 | //
7 |
8 | #import "TFPPrintParameters.h"
9 |
10 |
11 | @implementation TFPPrintParameters
12 |
13 |
14 | - (instancetype)init {
15 | if(!(self = [super init])) return nil;
16 |
17 | self.filament = [TFPFilament defaultFilament];
18 | self.useThermalBonding = YES;
19 |
20 | return self;
21 | }
22 |
23 |
24 | - (double)temperature {
25 | if(_temperature < DBL_EPSILON) {
26 | return self.filament.defaultTemperature;
27 | }else{
28 | return _temperature;
29 | }
30 | }
31 |
32 |
33 | @end
34 |
35 |
36 | NSString *TFPBedLevelOffsetsDescription(TFPBedLevelOffsets offsets) {
37 | return [NSString stringWithFormat:@"{ Z: %.02f, BL: %.02f, BR: %.02f, FR: %.02f, FL: %.02f }",
38 | offsets.common,
39 | offsets.backLeft,
40 | offsets.backRight,
41 | offsets.frontRight,
42 | offsets.frontLeft
43 | ];
44 | }
45 |
46 |
47 | NSString *TFPBacklashValuesDescription(TFPBacklashValues values) {
48 | return [NSString stringWithFormat:@"{ X: %.02f, Y: %.02f, speed: %.0f }",
49 | values.x,
50 | values.y,
51 | values.speed
52 | ];
53 | }
--------------------------------------------------------------------------------
/microprint/TFPPrintStatusController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrintStatusController.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Wed 2015-07-15.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPPrintJob.h"
11 | #import "TFPGCodeHelpers.h"
12 |
13 | @interface TFPPrintStatusController : NSObject
14 | - (instancetype)initWithPrintJob:(TFPPrintJob*)printJob;
15 | @property (readonly) TFPPrintJob *printJob;
16 |
17 | // Properties are observable
18 | @property (readonly) NSTimeInterval elapsedTime;
19 | @property (readonly) NSTimeInterval estimatedRemainingTime;
20 | @property (readonly) BOOL hasRemainingTimeEstimate;
21 |
22 | @property (readonly) double printProgress;
23 | @property (readonly) TFPPrintPhase currentPhase;
24 | @property (readonly) double phaseProgress;
25 | @property (readonly) TFPPrintLayer *currentLayer;
26 | @property (readonly) NSUInteger layerCount;
27 |
28 | @property (copy) void(^willMoveHandler)(TFPAbsolutePosition from, TFPAbsolutePosition to, double feedRate, TFPGCode *code);
29 | @property (copy) void(^layerChangeHandler)();
30 | @end
31 |
--------------------------------------------------------------------------------
/microprint/TFPPrinter+VirtualEEPROM.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinter+VirtualEEPROM.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-16.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPPrinter.h"
11 |
12 |
13 | enum VirtualEEPROMIndexes {
14 | VirtualEEPROMIndexBacklashCompensationX = 0,
15 | VirtualEEPROMIndexBacklashCompensationY = 1,
16 |
17 | VirtualEEPROMIndexBedCompensationBackRight = 2,
18 | VirtualEEPROMIndexBedCompensationBackLeft = 3,
19 | VirtualEEPROMIndexBedCompensationFrontLeft = 4,
20 | VirtualEEPROMIndexBedCompensationFrontRight = 5,
21 |
22 | VirtualEEPROMIndexFilamentColor = 6,
23 | VirtualEEPROMIndexFilamentTypeID = 7,
24 | VirtualEEPROMIndexFilamentTemperature = 8,
25 | VirtualEEPROMIndexFilamentAmount = 9,
26 |
27 | VirtualEEPROMIndexBacklashExpansionXPlus = 10,
28 | VirtualEEPROMIndexBacklashExpansionYLPlus = 11,
29 | VirtualEEPROMIndexBacklashExpansionYRPlus = 12,
30 | VirtualEEPROMIndexBacklashExpansionYRMinus = 13,
31 | VirtualEEPROMIndexBacklashExpansionZ = 14,
32 | VirtualEEPROMIndexBacklashExpansionE = 15,
33 |
34 | VirtualEEPROMIndexBedOffsetBackLeft = 16,
35 | VirtualEEPROMIndexBedOffsetBackRight = 17,
36 | VirtualEEPROMIndexBedOffsetFrontRight = 18,
37 | VirtualEEPROMIndexBedOffsetFrontLeft = 19,
38 | VirtualEEPROMIndexBedOffsetCommon = 20,
39 |
40 | VirtualEEPROMIndexReservedForSpooler = 21,
41 |
42 | VirtualEEPROMIndexBacklashCompensationSpeed = 22,
43 |
44 | VirtualEEPROMIndexG32Version = 23,
45 |
46 | VirtualEEPROMIndexG32FirstSample = 64,
47 | // ...
48 | VirtualEEPROMIndexG32LastSample = 126,
49 | };
50 |
51 |
52 | @interface TFPPrinter (VirtualEEPROM)
53 |
54 | + (uint32_t)encodeVirtualEEPROMIntegerValueForFloat:(float)value;
55 | + (float)decodeVirtualEEPROMFloatValueForInteger:(uint32_t)value;
56 |
57 | // Single values, int32
58 | - (void)readVirtualEEPROMValueAtIndex:(NSUInteger)index completionHandler:(void(^)(BOOL success, int32_t value))completionHandler;
59 | - (void)writeVirtualEEPROMValueAtIndex:(NSUInteger)index value:(int32_t)value completionHandler:(void(^)(BOOL success))completionHandler;
60 |
61 | // Single values, converted from/to float
62 | - (void)readVirtualEEPROMFloatValueAtIndex:(NSUInteger)index completionHandler:(void(^)(BOOL success, float value))completionHandler;
63 | - (void)writeVirtualEEPROMFloatValueAtIndex:(NSUInteger)index value:(float)value completionHandler:(void(^)(BOOL success))completionHandler;
64 |
65 | // Multiple values, int32
66 | - (void)readVirtualEEPROMValuesAtIndexes:(NSArray*)indexes completionHandler:(void(^)(BOOL success, NSArray *values))completionHandler;
67 | - (void)writeVirtualEEPROMValues:(NSDictionary*)valuesForIndexes completionHandler:(void(^)(BOOL success))completionHandler;
68 |
69 | // Multiple values, converted from/to float
70 | - (void)readVirtualEEPROMFloatValuesAtIndexes:(NSArray*)indexes completionHandler:(void(^)(BOOL success, NSArray *values))completionHandler;
71 | - (void)writeVirtualEEPROMFloatValues:(NSDictionary*)valuesForIndexes completionHandler:(void(^)(BOOL success))completionHandler;
72 | @end
--------------------------------------------------------------------------------
/microprint/TFPPrinter+VirtualEEPROM.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinter+VirtualEEPROM.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Thu 2015-07-16.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPPrinter+VirtualEEPROM.h"
10 | #import "TFPExtras.h"
11 | #import "TFPGCodeHelpers.h"
12 |
13 |
14 | @implementation TFPPrinter (VirtualEEPROM)
15 |
16 |
17 | + (uint32_t)encodeVirtualEEPROMIntegerValueForFloat:(float)value {
18 | NSSwappedFloat swapped = NSSwapHostFloatToLittle(value);
19 | int32_t intValue;
20 | memcpy(&intValue, &swapped, sizeof(swapped));
21 | return intValue;
22 | }
23 |
24 |
25 | + (float)decodeVirtualEEPROMFloatValueForInteger:(uint32_t)value {
26 | NSSwappedFloat swapped;
27 | memcpy(&swapped, &value, sizeof(float));
28 | return NSSwapLittleFloatToHost(swapped);
29 | }
30 |
31 |
32 | - (void)readVirtualEEPROMValueAtIndex:(NSUInteger)index completionHandler:(void(^)(BOOL success, int32_t value))completionHandler {
33 | [self sendGCode:[TFPGCode codeForReadingVirtualEEPROMAtIndex:index] responseHandler:^(BOOL success, NSDictionary *values) {
34 | if(!success) {
35 | completionHandler(NO, 0);
36 | return;
37 | }
38 | completionHandler(YES, [values[@"DT"] intValue]);
39 | }];
40 | }
41 |
42 |
43 | - (void)writeVirtualEEPROMValueAtIndex:(NSUInteger)index value:(int32_t)value completionHandler:(void(^)(BOOL success))completionHandler {
44 | [self sendGCode:[TFPGCode codeForWritingVirtualEEPROMAtIndex:index value:value] responseHandler:^(BOOL success, NSDictionary *value) {
45 | completionHandler(success);
46 | }];
47 | }
48 |
49 |
50 | - (void)readVirtualEEPROMFloatValueAtIndex:(NSUInteger)index completionHandler:(void(^)(BOOL success, float value))completionHandler {
51 | [self readVirtualEEPROMValueAtIndex:index completionHandler:^(BOOL success, int32_t value) {
52 | completionHandler(success, [self.class decodeVirtualEEPROMFloatValueForInteger:value]);
53 | }];
54 | }
55 |
56 |
57 | - (void)writeVirtualEEPROMFloatValueAtIndex:(NSUInteger)index value:(float)value completionHandler:(void(^)(BOOL success))completionHandler {
58 | int32_t intValue = [self.class encodeVirtualEEPROMIntegerValueForFloat:value];
59 | [self writeVirtualEEPROMValueAtIndex:index value:intValue completionHandler:completionHandler];
60 | }
61 |
62 |
63 | - (void)readVirtualEEPROMValuesAtIndexes:(NSArray*)indexes completionHandler:(void(^)(BOOL success, NSArray *values))completionHandler {
64 | NSMutableArray *values = [NSMutableArray new];
65 | [indexes enumerateObjectsUsingBlock:^(NSNumber *indexNumber, NSUInteger index, BOOL *stop) {
66 | [self readVirtualEEPROMValueAtIndex:indexNumber.integerValue completionHandler:^(BOOL success, int32_t value) {
67 | [values addObject:@(value)];
68 | if(index == indexes.count-1) {
69 | completionHandler(YES, values);
70 | }
71 | }];
72 | }];
73 | }
74 |
75 |
76 | - (void)readVirtualEEPROMFloatValuesAtIndexes:(NSArray*)indexes completionHandler:(void(^)(BOOL success, NSArray *values))completionHandler {
77 | [self readVirtualEEPROMValuesAtIndexes:indexes completionHandler:^(BOOL success, NSArray *values) {
78 | NSArray *floatValues = [values tf_mapWithBlock:^NSNumber*(NSNumber *intNumber) {
79 | return @([self.class decodeVirtualEEPROMFloatValueForInteger:intNumber.intValue]);
80 | }];
81 |
82 | completionHandler(success, floatValues);
83 | }];
84 | }
85 |
86 |
87 | - (void)writeVirtualEEPROMValues:(NSArray*)values forIndexes:(NSArray*)keys completionHandler:(void(^)(BOOL success))completionHandler {
88 | [keys enumerateObjectsUsingBlock:^(NSNumber *indexNumber, NSUInteger index, BOOL *stop) {
89 | uint32_t value = [values[index] unsignedIntValue];
90 |
91 | [self writeVirtualEEPROMValueAtIndex:indexNumber.unsignedIntegerValue value:value completionHandler:^(BOOL success) {
92 | if(index == keys.count-1) {
93 | completionHandler(YES);
94 | }
95 | }];
96 | }];
97 | }
98 |
99 |
100 | - (void)writeVirtualEEPROMValues:(NSDictionary*)valuesForIndexes completionHandler:(void(^)(BOOL success))completionHandler {
101 | NSMutableArray *keys = [NSMutableArray new];
102 | NSMutableArray *values = [NSMutableArray new];
103 | [valuesForIndexes enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, NSNumber *value, BOOL *stop) {
104 | [keys addObject:key];
105 | [values addObject:value];
106 | }];
107 |
108 | [self writeVirtualEEPROMValues:values forIndexes:keys completionHandler:completionHandler];
109 | }
110 |
111 |
112 | - (void)writeVirtualEEPROMFloatValues:(NSDictionary*)valuesForIndexes completionHandler:(void(^)(BOOL success))completionHandler {
113 | NSMutableDictionary *intValuesForIndexes = [NSMutableDictionary new];
114 | for(NSNumber *key in valuesForIndexes) {
115 | NSNumber *floatNumber = valuesForIndexes[key];
116 | intValuesForIndexes[key] = @([self.class encodeVirtualEEPROMIntegerValueForFloat:floatNumber.floatValue]);
117 | }
118 |
119 | [self writeVirtualEEPROMValues:intValuesForIndexes completionHandler:completionHandler];
120 | }
121 |
122 |
123 | @end
124 |
--------------------------------------------------------------------------------
/microprint/TFPPrinter.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinter.h
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-06-23.
6 | //
7 |
8 | #import
9 | #import "ORSSerialPort.h"
10 | #import "TFPGCode.h"
11 | #import "TFPPrintParameters.h"
12 | #import "TFPGCodeProgram.h"
13 |
14 | @class TFPOperation, TFPPrinterConnection, TFPPrinterContext;
15 |
16 |
17 | typedef NS_ENUM(NSUInteger, TFPPrinterColor) {
18 | TFPPrinterColorUndetermined,
19 | TFPPrinterColorBlack,
20 | TFPPrinterColorSilver,
21 | TFPPrinterColorLightBlue,
22 | TFPPrinterColorGreen,
23 | TFPPrinterColorOrange,
24 | TFPPrinterColorWhite,
25 | TFPPrinterColorGrape,
26 | TFPPrinterColorOther,
27 | };
28 |
29 |
30 | typedef NS_ENUM(NSUInteger, TFPPrinterResponseErrorCode) {
31 | TFPPrinterResponseErrorCodeM110MissingLineNumber = 1000,
32 | TFPPrinterResponseErrorCodeCannotColdExtrude,
33 | TFPPrinterResponseErrorCodeCannotCalibrateInUnknownState,
34 | TFPPrinterResponseErrorCodeUnknownGCode,
35 | TFPPrinterResponseErrorCodeUnknownMCode,
36 | TFPPrinterResponseErrorCodeUnknownCommand,
37 | TFPPrinterResponseErrorCodeHeaterFailed,
38 | TFPPrinterResponseErrorCodeMoveTooLarge,
39 | TFPPrinterResponseErrorCodeIdleTimeHeaterAndMotorsTurnedOff,
40 | TFPPrinterResponseErrorCodeTargetAddressOutOfRange,
41 |
42 | TFPPrinterResponseErrorCodeMin = TFPPrinterResponseErrorCodeM110MissingLineNumber,
43 | TFPPrinterResponseErrorCodeMax = TFPPrinterResponseErrorCodeTargetAddressOutOfRange,
44 | };
45 |
46 |
47 | typedef NS_OPTIONS(NSUInteger, TFPPrinterContextOptions) {
48 | TFPPrinterContextOptionConcurrent = 1<<0,
49 |
50 | TFPPrinterContextOptionDisableLevelCompensation = 1<<1,
51 | TFPPrinterContextOptionDisableBacklashCompensation = 1<<2,
52 | TFPPrinterContextOptionDisableFeedRateConversion = 1<<3,
53 |
54 | TFPPrinterContextOptionDisableCompensation = TFPPrinterContextOptionDisableLevelCompensation | TFPPrinterContextOptionDisableBacklashCompensation,
55 | };
56 |
57 |
58 | extern const NSString *TFPPrinterResponseErrorCodeKey;
59 | typedef NSDictionary* TFPGCodeResponseDictionary;
60 |
61 |
62 |
63 | @interface TFPPrinter : NSObject
64 | - (instancetype)initWithConnection:(TFPPrinterConnection*)connection;
65 | @property (readonly) TFPPrinterConnection *connection;
66 |
67 | @property TFPOperation *currentOperation;
68 |
69 | - (void)establishConnectionWithCompletionHandler:(void(^)(NSError *error))completionHandler;
70 | - (BOOL)printerShouldBeInvalidatedWithRemovedSerialPorts:(NSArray*)ports;
71 | @property (readonly) BOOL pendingConnection;
72 |
73 | @property (copy) void(^outgoingCodeBlock)(NSString *string);
74 | @property (copy) void(^incomingCodeBlock)(NSString *string);
75 | @property (copy) void(^noticeBlock)(NSString *string);
76 |
77 | - (void)sendNotice:(NSString*)noticeFormat, ...;
78 |
79 | // Sending of G-code. Response queue is main.
80 | // If success is YES, value dictionary contains parameters from OK response
81 | // If success is NO, value dictionary contains an NSNumber-wrapped TFPPrinterResponseErrorCode in TFPPrinterResponseErrorCodeKey
82 |
83 | - (void)sendGCode:(TFPGCode*)code responseHandler:(void(^)(BOOL success, TFPGCodeResponseDictionary value))block;
84 |
85 | - (TFPPrinterContext*)acquireContextWithOptions:(TFPPrinterContextOptions)options queue:(dispatch_queue_t)queue;
86 |
87 |
88 | + (NSString*)descriptionForErrorCode:(TFPPrinterResponseErrorCode)code;
89 |
90 | // State (observable)
91 | @property (readonly) TFPPrinterColor color;
92 | @property (readonly, copy) NSString *serialNumber;
93 | @property (readonly, copy) NSString *firmwareVersion;
94 | @property (readonly) NSComparisonResult firmwareVersionComparedToTestedRange;
95 |
96 | @property (nonatomic) double feedrate;
97 | @property (readonly) double heaterTargetTemperature;
98 | @property (readonly) double heaterTemperature;
99 |
100 | @property (readonly) BOOL hasValidZLevel;
101 | @property (readonly) BOOL hasOutOfBoundsZLevel;
102 |
103 | @property (nonatomic, readonly) TFPBedLevelOffsets bedBaseOffsets;
104 | @property (nonatomic) TFPBedLevelOffsets bedLevelOffsets;
105 | @property (readonly) BOOL hasAllZeroBedLevelOffsets;
106 |
107 | @property (nonatomic) TFPBacklashValues backlashValues;
108 |
109 | @property (nonatomic) TFPAbsolutePosition position;
110 |
111 | + (NSString*)nameForPrinterColor:(TFPPrinterColor)color;
112 | + (NSString*)minimumTestedFirmwareVersion;
113 | + (NSString*)maximumTestedFirmwareVersion;
114 | @end
115 |
116 |
117 | @interface TFPPrinterContext : NSObject
118 | @property (readonly) TFPPrinter *printer;
119 |
120 | - (void)sendGCode:(TFPGCode*)code responseHandler:(void(^)(BOOL success, TFPGCodeResponseDictionary value))block;
121 | - (void)runGCodeProgram:(TFPGCodeProgram*)program completionHandler:(void(^)(BOOL success, NSArray *values))completionHandler;
122 |
123 | - (void)invalidate;
124 | @end
125 |
126 |
127 | #import "TFPPrinterHelpers.h"
--------------------------------------------------------------------------------
/microprint/TFPPrinterConnection.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinterConnection.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Wed 2015-07-29.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 |
11 | @class TFPGCode, ORSSerialPort;
12 |
13 |
14 | typedef NS_ENUM(NSInteger, TFPPrinterMessageType) {
15 | TFPPrinterMessageTypeInvalid,
16 | TFPPrinterMessageTypeConfirmation, // value = nil or NSDictionary
17 | TFPPrinterMessageTypeSkipNotice, // value = nil
18 | TFPPrinterMessageTypeError, // value = NSNumber for error code
19 | TFPPrinterMessageTypeResendRequest, // value = nil
20 | TFPPrinterMessageTypeTemperatureUpdate, // value = NSNumber for temperature
21 | TFPPrinterMessageTypeUnknown, // value = NSString with raw incoming line
22 | };
23 |
24 |
25 | typedef NS_ENUM(NSUInteger, TFPPrinterConnectionState) {
26 | TFPPrinterConnectionStateDisconnected,
27 | TFPPrinterConnectionStatePending,
28 | TFPPrinterConnectionStateConnected,
29 | };
30 |
31 |
32 | @interface TFPPrinterConnection : NSObject
33 | - (instancetype)initWithSerialPort:(ORSSerialPort*)serialPort;
34 | @property (readonly) ORSSerialPort *serialPort;
35 |
36 | - (void)openWithCompletionHandler:(void(^)(NSError *error))completionHandler;
37 | - (void)sendGCode:(TFPGCode*)code;
38 |
39 | @property (readonly) TFPPrinterConnectionState state;
40 |
41 | // Blocks are called on a private queue, remember to dispatch!
42 | @property (copy) void(^messageHandler)(TFPPrinterMessageType type, NSInteger lineNumber, id value);
43 | @property (copy) void(^rawLineHandler)(NSString *line);
44 | @end
--------------------------------------------------------------------------------
/microprint/TFPPrinterHelpers.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinterHelpers.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sun 2015-08-02.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPPrinter.h"
10 |
11 | @interface TFPPrinter (CommandHelpers)
12 | - (void)setBacklashValues:(TFPBacklashValues)values completionHandler:(void(^)(BOOL success))completionHandler;
13 | - (void)fetchPositionWithCompletionHandler:(void(^)(BOOL success, TFP3DVector *position, NSNumber *E))completionHandler;
14 | @end
15 |
16 |
17 |
18 | @interface TFPPrinterContext (CommandHelpers)
19 | - (void)setRelativeMode:(BOOL)relative completionHandler:(void(^)(BOOL success))completionHandler;
20 | - (void)moveToPosition:(TFP3DVector*)position usingFeedRate:(double)F completionHandler:(void(^)(BOOL success))completionHandler;
21 | - (void)waitForExecutionCompletionWithHandler:(void(^)())completionHandler;
22 |
23 | - (void(^)())setHeaterTemperatureAsynchronously:(double)targetTemperature progressBlock:(void(^)(double currentTemperature))progressBlock completionBlock:(void(^)())completionBlock;
24 |
25 | - (void(^)())moveAsynchronouslyToPosition:(TFP3DVector*)targetPosition feedRate:(double)feedRate progressBlock:(void(^)(double fraction, TFP3DVector *position))progressBlock completionBlock:(void(^)())completionBlock;
26 | @end
--------------------------------------------------------------------------------
/microprint/TFPPrinterManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinterManager.h
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-06-23.
6 | //
7 |
8 | #import
9 |
10 |
11 | @interface TFPPrinterManager : NSObject
12 |
13 | + (instancetype)sharedManager;
14 |
15 | - (void)startDryRunMode;
16 |
17 | @property (readonly) NSArray *printers; // Observable
18 | @end
--------------------------------------------------------------------------------
/microprint/TFPPrinterManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPPrinterManager.m
3 | // MicroPrint
4 | //
5 | // Created by Tomas Franzén on Tue 2015-06-23.
6 | //
7 |
8 | #import "TFPPrinterManager.h"
9 | #import "TFPPrinter.h"
10 | #import "TFPExtras.h"
11 | #import "TFPDryRunPrinterConnection.h"
12 | #import "TFPPrinterConnection.h"
13 |
14 | #import "MAKVONotificationCenter.h"
15 | #import "ORSSerialPortManager.h"
16 |
17 |
18 | static const uint16_t M3DMicroUSBVendorID = 0x03EB;
19 | static const uint16_t M3DMicroUSBProductID = 0x2404;
20 |
21 |
22 | @interface TFPPrinterManager ()
23 | @property (readwrite) NSArray *printers; // Observable
24 | @end
25 |
26 |
27 | @implementation TFPPrinterManager
28 |
29 |
30 | + (instancetype)sharedManager {
31 | static TFPPrinterManager *singleton;
32 | return singleton ?: (singleton = [self new]);
33 | }
34 |
35 |
36 | - (void)startDryRunMode {
37 | TFPPrinter *printer = [[TFPPrinter alloc] initWithConnection:[TFPDryRunPrinterConnection new]];
38 | [[self mutableArrayValueForKey:@"printers"] addObject:printer];
39 | }
40 |
41 |
42 | - (NSArray*)printersForSerialPorts:(NSArray*)serialPorts {
43 | return [[serialPorts tf_selectWithBlock:^BOOL(ORSSerialPort *port) {
44 | return port.USBVendorID.unsignedShortValue == M3DMicroUSBVendorID && port.USBProductID.unsignedShortValue == M3DMicroUSBProductID;
45 | }] tf_mapWithBlock:^TFPPrinter*(ORSSerialPort *serialPort) {
46 | TFPPrinterConnection *connection = [[TFPPrinterConnection alloc] initWithSerialPort:serialPort];
47 | return [[TFPPrinter alloc] initWithConnection:connection];
48 | }];
49 | }
50 |
51 |
52 | - (instancetype)init {
53 | if(!(self = [super init])) return nil;
54 | __weak __typeof__(self) weakSelf = self;
55 |
56 | self.printers = [self printersForSerialPorts:[ORSSerialPortManager sharedSerialPortManager].availablePorts];
57 |
58 | [[ORSSerialPortManager sharedSerialPortManager] addObserver:self keyPath:@"availablePorts" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld block:^(MAKVONotification *notification) {
59 | NSMutableArray *printers = [weakSelf mutableArrayValueForKey:@"printers"];
60 |
61 | if(notification.kind == NSKeyValueChangeRemoval) {
62 | NSArray *removedPrinters = [weakSelf.printers tf_selectWithBlock:^BOOL(TFPPrinter *printer) {
63 | return [printer printerShouldBeInvalidatedWithRemovedSerialPorts:notification.oldValue];
64 | }];
65 | [printers removeObjectsInArray:removedPrinters];
66 |
67 | }else{
68 | NSArray *existingPorts = [self.printers valueForKeyPath:@"connection.serialPort"];
69 | NSArray *newSerialPorts = [notification.newValue tf_rejectWithBlock:^BOOL(id object) {
70 | return [existingPorts containsObject:object];
71 | }];
72 |
73 | dispatch_after(dispatch_time(0, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
74 | [printers addObjectsFromArray:[weakSelf printersForSerialPorts:newSerialPorts]];
75 | });
76 | }
77 | }];
78 |
79 | return self;
80 | }
81 |
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/microprint/TFPRaiseHeadOperation.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPRaiseHeadOperation.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sun 2015-06-28.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 | #import "TFPOperation.h"
11 |
12 | @interface TFPRaiseHeadOperation : TFPOperation
13 | @property double targetHeight;
14 |
15 | @property (copy) void(^didStartBlock)();
16 | @property (copy) void(^didStopBlock)(BOOL didRaise);
17 | @end
--------------------------------------------------------------------------------
/microprint/TFPRaiseHeadOperation.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPRaiseHeadOperation.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Sun 2015-06-28.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPRaiseHeadOperation.h"
10 | #import "TFPExtras.h"
11 | #import "TFPGCodeHelpers.h"
12 | #import "TFP3DVector.h"
13 |
14 |
15 | @interface TFPRaiseHeadOperation ()
16 | @property BOOL stopped;
17 | @property (readwrite) TFPOperationStage stage;
18 | @end
19 |
20 |
21 | static const double raiseStep = 0.1;
22 |
23 |
24 | @implementation TFPRaiseHeadOperation
25 | @synthesize stage=_stage;
26 |
27 |
28 | - (void)raiseStepFromZ:(double)Z toLevel:(double)targetHeight completionHandler:(void(^)())completionHandler {
29 | if(self.stopped || Z >= targetHeight) {
30 | completionHandler();
31 | return;
32 | }
33 |
34 | Z += raiseStep;
35 |
36 | TFP3DVector *position = [TFP3DVector zVector:Z];
37 | [self.context moveToPosition:position usingFeedRate:2900 completionHandler:^(BOOL success) {
38 | [self raiseStepFromZ:Z toLevel:targetHeight completionHandler:completionHandler];
39 | }];
40 | }
41 |
42 |
43 | - (BOOL)start {
44 | if(![super start]) {
45 | return NO;
46 | }
47 |
48 | double targetHeight = self.targetHeight;
49 | self.stage = TFPOperationStagePreparation;
50 |
51 | [self.printer fetchPositionWithCompletionHandler:^(BOOL success, TFP3DVector *position, NSNumber *E) {
52 | [self.context setRelativeMode:NO completionHandler:^(BOOL success) {
53 | double Z = position.z.doubleValue;
54 |
55 | if(Z < targetHeight) {
56 | if(self.didStartBlock) {
57 | self.didStartBlock();
58 | }
59 | self.stage = TFPOperationStageRunning;
60 |
61 | [self raiseStepFromZ:Z toLevel:targetHeight completionHandler:^{
62 | self.stage = TFPOperationStageEnding;
63 |
64 | [self.printer sendGCode:[TFPGCode turnOffMotorsCode] responseHandler:^(BOOL success, NSDictionary *value) {
65 | if(self.didStopBlock) {
66 | self.didStopBlock(YES);
67 | }
68 | [self ended];
69 | }];
70 | }];
71 | }else{
72 | if(self.didStopBlock) {
73 | self.didStopBlock(NO);
74 | }
75 | [self ended];
76 | }
77 | }];
78 | }];
79 |
80 | return YES;
81 | }
82 |
83 |
84 | - (void)stop {
85 | [super stop];
86 | self.stopped = YES;
87 | }
88 |
89 |
90 | - (TFPOperationKind)kind {
91 | return TFPOperationKindUtility;
92 | }
93 |
94 |
95 | - (NSString *)activityDescription {
96 | return @"Raising Print Head";
97 | }
98 |
99 |
100 | @end
--------------------------------------------------------------------------------
/microprint/TFPSlicerProfile.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPSlicerProfile.h
3 | // microprint
4 | //
5 | // Created by William Waggoner on 9/13/15.
6 | // Copyright © 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TFPGCode.h"
11 | #import "TFPExtras.h"
12 | #import "TFPGCodeHelpers.h"
13 |
14 | typedef NS_ENUM (NSInteger, SlicerProfileType) {
15 | CuraProfile,
16 | Slic3rProfile,
17 | S3dProfile,
18 | };
19 |
20 | @interface TFPSlicerProfile : NSObject
21 | @property SlicerProfileType profileType;
22 | - (instancetype)initFromLines: (NSArray *)lines;
23 | - (void)setValue:(id)value forUndefinedKey:(NSString *)key;
24 | - (id)objectForKeyedSubscript:(id)key;
25 | - (id)valueForUndefinedKey:(NSString *)key;
26 | - (BOOL)loadCuraProfile:(NSArray *)lines;
27 | - (BOOL)loadSlic3rProfile:(NSArray *)lines;
28 | - (NSString *)formattedValueForKey:(NSString *)key;
29 | @end
30 |
--------------------------------------------------------------------------------
/microprint/TFPStopwatch.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPStopwatch.h
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-08-10.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TFPStopwatch : NSObject
12 | - (void)start;
13 | - (void)stop;
14 | - (void)reset;
15 |
16 | @property (readonly) NSTimeInterval elapsedTime;
17 | @end
18 |
--------------------------------------------------------------------------------
/microprint/TFPStopwatch.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPStopwatch.m
3 | // microprint
4 | //
5 | // Created by Tomas Franzén on Mon 2015-08-10.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPStopwatch.h"
10 | #import "TFPExtras.h"
11 | #import "TFTimer.h"
12 |
13 |
14 | @interface TFPStopwatch ()
15 | @property NSTimeInterval storedTime;
16 | @property uint64_t startTime;
17 |
18 | @property TFTimer *updateTimer;
19 | @end
20 |
21 |
22 | @implementation TFPStopwatch
23 |
24 |
25 | - (void)start {
26 | __weak __typeof__(self) weakSelf = self;
27 |
28 | self.startTime = TFNanosecondTime();
29 | self.updateTimer = [TFTimer timerWithInterval:1 repeating:YES block:^{
30 | [weakSelf willChangeValueForKey:@"elapsedTime"];
31 | [weakSelf didChangeValueForKey:@"elapsedTime"];
32 | }];
33 | }
34 |
35 |
36 | - (void)stop {
37 | self.storedTime = self.elapsedTime;
38 | self.startTime = 0;
39 | self.updateTimer = nil;
40 | }
41 |
42 |
43 | - (void)reset {
44 | [self stop];
45 | self.storedTime = 0;
46 | }
47 |
48 |
49 | - (NSTimeInterval)elapsedTime {
50 | double duration = self.storedTime;
51 | if(self.startTime > 0) {
52 | duration += ((double)(TFNanosecondTime() - self.startTime)) / NSEC_PER_SEC;
53 | }
54 | return duration;
55 | }
56 |
57 |
58 | @end
--------------------------------------------------------------------------------
/microprint/TFPZeroBedOperation.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFPZeroBedOperation.h
3 | // microprint
4 | //
5 | // Created by William Waggoner on 7/29/15.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPOperation.h"
10 |
11 | @interface TFPZeroBedOperation : TFPOperation
12 | @property (copy) void(^progressFeedback)(NSString *msg);
13 | @property (copy) void(^didStopBlock)(BOOL completed);
14 | @end
15 |
--------------------------------------------------------------------------------
/microprint/TFPZeroBedOperation.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFPZeroBedOperation.m
3 | // microprint
4 | //
5 | // Created by William Waggoner on 7/29/15.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFPZeroBedOperation.h"
10 | #import "TFPExtras.h"
11 | #import "TFPGCodeHelpers.h"
12 | #import "TFP3DVector.h"
13 |
14 |
15 | @interface TFPZeroBedOperation ()
16 | @property BOOL stopped;
17 | @property (readwrite) TFPOperationStage stage;
18 | @end
19 |
20 |
21 |
22 | @implementation TFPZeroBedOperation
23 | @synthesize stage=_stage;
24 |
25 |
26 | - (BOOL)start {
27 | if(![super start]) {
28 | return NO;
29 | }
30 |
31 | const double temperature = 150; // Warm it up a bit
32 | const double moveFeedRate = 2900;
33 |
34 | TFP3DVector *parkingLocation = [TFP3DVector vectorWithX:nil Y:@90 Z:@10];
35 |
36 |
37 | TFPGCodeProgram *prep = [TFPGCodeProgram programWithLines:@[
38 | [TFPGCode codeForHeaterTemperature:temperature waitUntilDone:YES],
39 | [TFPGCode codeForTurningOffHeater],
40 | [TFPGCode turnOffFanCode],
41 | ]];
42 |
43 | TFPGCodeProgram *park = [TFPGCodeProgram programWithLines:@[
44 | [TFPGCode absoluteModeCode],
45 | [TFPGCode moveWithPosition:parkingLocation feedRate:moveFeedRate],
46 | [TFPGCode waitForCompletionCode],
47 | ]];
48 |
49 | if(self.progressFeedback) {
50 | self.progressFeedback(@"Heating up…");
51 | }
52 |
53 | self.stage = TFPOperationStagePreparation;
54 |
55 | [self.context runGCodeProgram:prep completionHandler:^(BOOL success, NSArray *valueDictionaries) {
56 | if (self.stopped) {
57 | [self doStopCompleted:NO];
58 |
59 | }else{
60 | if(self.progressFeedback) {
61 | self.progressFeedback(@"Finding Bed Location…");
62 | }
63 |
64 | self.stage = TFPOperationStageRunning;
65 | [self.context sendGCode:[TFPGCode findZeroCode] responseHandler:^(BOOL success, TFPGCodeResponseDictionary value) {
66 | self.stage = TFPOperationStageEnding;
67 | if (self.stopped) {
68 | [self doStopCompleted:NO];
69 |
70 | }else{
71 | if(self.progressFeedback) {
72 | self.progressFeedback(@"Parking Print Head…");
73 | }
74 |
75 | [self.context runGCodeProgram:park completionHandler:^(BOOL success, NSArray *valueDictionaries) {
76 | [self doStopCompleted:YES];
77 | }];
78 | }
79 | }];
80 | }
81 | }];
82 |
83 | return YES;
84 | }
85 |
86 |
87 | - (void)stop {
88 | [super stop];
89 | self.stopped = YES;
90 | if(self.progressFeedback) {
91 | self.progressFeedback(@"Stopping...");
92 | }
93 | }
94 |
95 |
96 | - (NSString *)activityDescription {
97 | return @"Calibrating bed location";
98 | }
99 |
100 |
101 | - (void)doStopCompleted:(BOOL)completed {
102 | [self ended];
103 | if(self.didStopBlock) {
104 | self.didStopBlock(completed);
105 | }
106 | }
107 |
108 |
109 | - (TFPOperationKind)kind {
110 | return TFPOperationKindCalibration;
111 | }
112 |
113 |
114 | @end
--------------------------------------------------------------------------------
/microprint/TFStringScanner.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | typedef enum {
4 | TFTokenTypeIdentifier,
5 | TFTokenTypeNumeric,
6 | TFTokenTypeSymbol,
7 | } TFTokenType;
8 |
9 |
10 | @interface TFStringScanner : NSObject
11 |
12 | @property (readonly, copy, nonatomic) NSString *string;
13 | @property (nonatomic) NSUInteger location;
14 | @property (readonly, getter=isAtEnd, nonatomic) BOOL atEnd;
15 | @property (readonly, nonatomic) TFTokenType lastTokenType;
16 |
17 | + (id)scannerWithString:(NSString*)string;
18 | - (id)initWithString:(NSString*)string;
19 |
20 | - (void)addMulticharacterSymbol:(NSString*)symbol;
21 | - (void)addMulticharacterSymbols:(NSString*)symbol, ...;
22 | - (void)removeMulticharacterSymbol:(NSString*)symbol;
23 |
24 | - (unichar)scanCharacter;
25 | - (NSString*)scanForLength:(NSUInteger)length;
26 | - (NSString*)scanStringFromCharacterSet:(NSCharacterSet*)set;
27 |
28 | - (BOOL)scanString:(NSString*)substring;
29 | - (NSString*)scanToString:(NSString*)substring;
30 | - (BOOL)scanWhitespace;
31 | - (NSString*)scanToEnd;
32 |
33 | - (NSString*)scanToken;
34 | - (BOOL)scanToken:(NSString*)matchToken;
35 | - (NSString*)peekToken;
36 |
37 | @end
--------------------------------------------------------------------------------
/microprint/TFTimer.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFTimer.h
3 | // Tåg
4 | //
5 | // Created by Tomas Franzén on sön 2015-03-29.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TFTimer : NSObject
12 | + (instancetype)timerWithInterval:(NSTimeInterval)interval repeating:(BOOL)repeat block:(void(^)())action;
13 | - (void)invalidate;
14 | @end
--------------------------------------------------------------------------------
/microprint/TFTimer.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFTimer.m
3 | // Tåg
4 | //
5 | // Created by Tomas Franzén on sön 2015-03-29.
6 | // Copyright (c) 2015 Tomas Franzén. All rights reserved.
7 | //
8 |
9 | #import "TFTimer.h"
10 |
11 | @interface TFTimer ()
12 | @property (weak) NSTimer *timer;
13 | @end
14 |
15 |
16 |
17 | @implementation NSObject (TFTimerBlockInvocation)
18 |
19 | - (void)tftimer_invoke {
20 | ((void(^)())self)();
21 | }
22 |
23 | @end
24 |
25 |
26 |
27 | @implementation TFTimer
28 |
29 |
30 | - (instancetype)initWithInterval:(NSTimeInterval)interval repeating:(BOOL)repeat block:(void(^)())action {
31 | if(!(self = [super init])) return nil;
32 |
33 | action = [action copy];
34 | self.timer = [NSTimer scheduledTimerWithTimeInterval:interval target:action selector:@selector(tftimer_invoke) userInfo:nil repeats:repeat];
35 |
36 | return self;
37 | }
38 |
39 |
40 | + (instancetype)timerWithInterval:(NSTimeInterval)interval repeating:(BOOL)repeat block:(void(^)())action {
41 | return [[self alloc] initWithInterval:interval repeating:repeat block:action];
42 | }
43 |
44 |
45 | - (void)dealloc {
46 | [self invalidate];
47 | }
48 |
49 |
50 | - (void)invalidate {
51 | [self.timer invalidate];
52 | self.timer = nil;
53 | }
54 |
55 |
56 | @end
--------------------------------------------------------------------------------