├── README.md
├── MDraw
├── en.lproj
│ └── InfoPlist.strings
├── MDrawArc.h
├── MDrawAngle.h
├── MDrawFatArrow.h
├── MDraw-Prefix.pch
├── MDrawComment.h
├── MDrawMeasurementInfo.h
├── MUndoManager.h
├── MDrawText.h
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── LaunchImage.launchimage
│ │ └── Contents.json
├── MDrawArrow.h
├── MDrawEllipse.h
├── MDrawFreeline.h
├── MDrawLine.h
├── ViewController.h
├── AppDelegate.h
├── MDraw-Info.plist
├── main.m
├── MDrawPolyline.h
├── MDrawTool_Subclass.h
├── MUndoManager.m
├── MDrawRect.h
├── MDrawText.m
├── MDrawMeasurementInfo.m
├── MDrawComment.m
├── MDrawArc.m
├── MDrawFatArrow.m
├── MDrawAngle.m
├── MDrawEllipse.m
├── AppDelegate.m
├── MDrawArrow.m
├── ViewController.m
├── MDrawView.h
├── MDrawTool.h
├── MDrawLine.m
├── MDrawFreeline.m
├── MDrawTool.m
├── MDrawRect.m
├── MDrawPolyline.m
├── Base.lproj
│ └── Main.storyboard
├── MDrawMath.h
└── MDrawView.m
├── MDrawTests
├── en.lproj
│ └── InfoPlist.strings
├── MDrawTests-Info.plist
└── MDrawTests.m
├── MDraw.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcuserdata
│ └── gaoyq.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── MDraw.xcscheme
└── project.pbxproj
├── .gitignore
└── LICENSE
/README.md:
--------------------------------------------------------------------------------
1 | MDraw
2 | =====
3 |
4 | A simple demo for drawing tools on iOS
5 |
--------------------------------------------------------------------------------
/MDraw/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/MDrawTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/MDraw/MDrawArc.h:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawArc.h
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/5/14.
6 | //
7 | //
8 |
9 | #import "MDrawAngle.h"
10 |
11 | @interface MDrawArc : MDrawAngle
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/MDraw.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MDraw/MDrawAngle.h:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawAngle.h
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/6/14.
6 | //
7 | //
8 |
9 | #import "MDrawPolyline.h"
10 |
11 | @interface MDrawAngle : MDrawPolyline
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/MDraw/MDrawFatArrow.h:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawFatArrow.h
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/5/14.
6 | //
7 | //
8 |
9 | #import "MDrawLine.h"
10 |
11 | @interface MDrawFatArrow : MDrawLine
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
--------------------------------------------------------------------------------
/MDraw/MDraw-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #endif
17 |
--------------------------------------------------------------------------------
/MDraw/MDrawComment.h:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawComment.h
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/11/14.
6 | //
7 | //
8 |
9 | #import "MDrawText.h"
10 |
11 | @protocol MDrawCommentDelegate
12 |
13 | -(void)drawTool:(MDrawTool *)tool isAdded:(BOOL)added;
14 |
15 | @end
16 |
17 | @interface MDrawComment : MDrawText
18 |
19 | @property (nonatomic,weak) id delegate;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/MDraw/MDrawMeasurementInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawMeasurementInfo.h
3 | // MDraw
4 | //
5 | // Created by Gao Yongqing on 9/5/14.
6 | // Copyright (c) 2014 Motic China Group Co., Ltd. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "MDrawTool.h"
11 |
12 | /**
13 | * Show measurement info for tools.
14 | */
15 | @interface MDrawMeasurementInfo : NSObject
16 |
17 | @property (nonatomic,weak,readonly) MDrawTool *tool;
18 |
19 | - (instancetype)initWithTool:(MDrawTool *)aTool;
20 |
21 | - (void)draw:(CGContextRef)ctx;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/MDraw/MUndoManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // MUndoManager.h
3 | // MDraw
4 | //
5 | // Created by Gao Yongqing on 8/28/13.
6 | // Copyright (c) 2013 Motic China Group Co., Ltd. All rights reserved.
7 | //
8 | // Provide a simple undo/redo manager for drawing tools.
9 |
10 | #import
11 |
12 | @interface MUndoManager : NSObject
13 |
14 | -(id)initWithTools:(NSMutableArray *)tools;
15 |
16 | -(BOOL)undo;
17 | -(BOOL)redo;
18 | -(void)removeTool:(id)tool;
19 | -(void)addTool:(id)tool;
20 | /**
21 | * Remove all tools and histories
22 | */
23 | -(void)reset;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/MDraw/MDrawText.h:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawText.h
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/10/14.
6 | //
7 | //
8 |
9 | #import "MDrawRect.h"
10 |
11 | @interface MDrawText : MDrawRect
12 |
13 | @property (nonatomic,strong) NSString *text;
14 |
15 | @property (nonatomic,strong) UIColor *backgroundColor;
16 |
17 | /**
18 | * Init a DrawText with frame and text
19 | *
20 | * @param frame The frame for text tool
21 | * @param text The text to display
22 | *
23 | * @return An instance of MDrawText
24 | */
25 | -(id)initWithFrame:(CGRect)frame andText:(NSString *)text;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/MDraw.xcodeproj/xcuserdata/gaoyq.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MDraw.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 33E28B7317C20DA200EFC071
16 |
17 | primary
18 |
19 |
20 | 33E28B9417C20DA200EFC071
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/MDraw/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "ipad",
5 | "size" : "29x29",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "ipad",
10 | "size" : "29x29",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "ipad",
15 | "size" : "40x40",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "ipad",
20 | "size" : "40x40",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "ipad",
25 | "size" : "76x76",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "ipad",
30 | "size" : "76x76",
31 | "scale" : "2x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/MDrawTests/MDrawTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | motic.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/MDraw/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "ipad",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "1x"
9 | },
10 | {
11 | "orientation" : "landscape",
12 | "idiom" : "ipad",
13 | "extent" : "full-screen",
14 | "minimum-system-version" : "7.0",
15 | "scale" : "1x"
16 | },
17 | {
18 | "orientation" : "portrait",
19 | "idiom" : "ipad",
20 | "extent" : "full-screen",
21 | "minimum-system-version" : "7.0",
22 | "scale" : "2x"
23 | },
24 | {
25 | "orientation" : "landscape",
26 | "idiom" : "ipad",
27 | "extent" : "full-screen",
28 | "minimum-system-version" : "7.0",
29 | "scale" : "2x"
30 | }
31 | ],
32 | "info" : {
33 | "version" : 1,
34 | "author" : "xcode"
35 | }
36 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 xmkevin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | 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, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/MDraw/MDrawArrow.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawLine.h"
23 |
24 | @interface MDrawArrow : MDrawLine
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/MDraw/MDrawEllipse.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawRect.h"
23 |
24 | @interface MDrawEllipse : MDrawRect
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/MDraw/MDrawFreeline.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawRect.h"
23 |
24 | @interface MDrawFreeline : MDrawRect
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/MDraw/MDrawLine.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawTool_Subclass.h"
23 |
24 | @interface MDrawLine : MDrawTool
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/MDraw/ViewController.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import
23 |
24 | @interface ViewController : UIViewController
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/MDraw/AppDelegate.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import
23 |
24 | @interface AppDelegate : UIResponder
25 |
26 | @property (strong, nonatomic) UIWindow *window;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/MDraw/MDraw-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | motic.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations~ipad
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationPortraitUpsideDown
37 | UIInterfaceOrientationLandscapeLeft
38 | UIInterfaceOrientationLandscapeRight
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/MDraw/main.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import
23 |
24 | #import "AppDelegate.h"
25 |
26 | int main(int argc, char * argv[])
27 | {
28 | @autoreleasepool {
29 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/MDraw/MDrawPolyline.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawTool_Subclass.h"
23 |
24 | @interface MDrawPolyline : MDrawTool
25 | {
26 | @protected
27 | NSMutableArray *_points;
28 | CGPoint _movePoint;
29 | int _moveHandleIndex;
30 | BOOL _closePath;
31 | }
32 |
33 |
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/MDraw/MDrawTool_Subclass.h:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawTool_Subclass.h
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 3/3/14.
6 | //
7 | //
8 |
9 | #import "MDrawTool.h"
10 |
11 | @interface MDrawTool (ForSubClassEyesOnly)
12 |
13 | /**
14 | * Draw moving handlers
15 | *
16 | * @param ctx the context to draw
17 | * @param point the handle location
18 | */
19 | -(void)drawHandle:(CGContextRef)ctx atPoint:(CGPoint)point;
20 |
21 | /**
22 | * Determine whether or not the point is on the handle
23 | *
24 | * @param point a point to test
25 | * @param handlePoint the handle point
26 | *
27 | * @return YES if the point is on the handle, otherwise NO
28 | */
29 | -(BOOL)isPoint:(CGPoint)point onHandle:(CGPoint)handlePoint;
30 |
31 | /**
32 | * Draw measurement information for tool
33 | *
34 | * @param ctx The context to draw
35 | * @param view The parent viewer.
36 | */
37 | -(void)drawMeasurement:(CGContextRef)ctx inView:(UIView *)view;
38 |
39 | /**
40 | * Convert pixels to current tool's unit by calibration.
41 | *
42 | * @param pixels original pixel values
43 | * @param square Is calculate area.
44 | *
45 | * @return Value of current unit
46 | */
47 | -(CGFloat)unitConvert:(CGFloat)pixels isSquare:(BOOL)square;
48 |
49 | /**
50 | * This method is for subclass to call, drawing without measurement information
51 | *
52 | * @param ctx Context to draw on
53 | * @param view The container view
54 | * @param noMeasurement YES: no draw measurement information
55 | */
56 | -(void)draw:(CGContextRef)ctx inView:(UIView *)view withoutMeasurement:(BOOL)noMeasurement;
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/MDraw/MUndoManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // MUndoManager.m
3 | // MDraw
4 | //
5 | // Created by Gao Yongqing on 8/28/13.
6 | // Copyright (c) 2013 Motic China Group Co., Ltd. All rights reserved.
7 | //
8 |
9 | #import "MUndoManager.h"
10 |
11 | @implementation MUndoManager
12 | {
13 | NSMutableArray *_tools;
14 | NSMutableArray *_undoTools;
15 | NSMutableArray *_redoTools;
16 | }
17 |
18 | -(id)initWithTools:(NSMutableArray *)tools
19 | {
20 | self = [super init];
21 | if(self)
22 | {
23 | _tools = tools;
24 | _undoTools = [[NSMutableArray alloc] init];
25 | _redoTools = [[NSMutableArray alloc] init];
26 | }
27 |
28 | return self;
29 | }
30 |
31 | -(BOOL)undo
32 | {
33 | if(_undoTools.count == 0 )
34 | {
35 | return NO;
36 | }
37 |
38 | id lastTool = [_undoTools lastObject];
39 | [_tools removeObject:lastTool];
40 | [_undoTools removeObject:lastTool];
41 | [_redoTools addObject:lastTool];
42 |
43 | return YES;
44 | }
45 |
46 | -(BOOL)redo
47 | {
48 | if(_redoTools.count == 0 )
49 | {
50 | return NO;
51 | }
52 |
53 | id tool = [_redoTools lastObject];
54 | [_redoTools removeObject:tool];
55 | [_undoTools addObject:tool];
56 | [_tools addObject:tool];
57 |
58 | return YES;
59 | }
60 |
61 | -(void)removeTool:(id)tool
62 | {
63 | [_tools removeObject:tool];
64 | [_redoTools addObject:tool];
65 | }
66 |
67 | -(void)addTool:(id)tool
68 | {
69 | [_redoTools removeAllObjects];
70 |
71 | [_tools addObject:tool];
72 | [_undoTools addObject:tool];
73 | }
74 |
75 | -(void)reset
76 | {
77 | [_redoTools removeAllObjects];
78 | [_undoTools removeAllObjects];
79 | }
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/MDraw/MDrawRect.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawLine.h"
23 |
24 | enum MDrawMoveDirection {
25 | MDrawMoveDirectionNone = 0,
26 | MDrawMoveDirectionWhole = 1,
27 | MDrawMoveDirectionTL = 2,
28 | MDrawMoveDirectionTM = 3,
29 | MDrawMoveDirectionTR = 4,
30 | MDrawMoveDirectionRM = 5,
31 | MDrawMoveDirectionBR = 6,
32 | MDrawMoveDirectionBM = 7,
33 | MDrawMoveDirectionBL = 8,
34 | MDrawMoveDirectionLM = 9
35 | };
36 |
37 | @interface MDrawRect : MDrawLine
38 | {
39 | @protected
40 | enum MDrawMoveDirection _moveDirection;
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/MDrawTests/MDrawTests.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import
23 |
24 | @interface MDrawTests : XCTestCase
25 |
26 | @end
27 |
28 | @implementation MDrawTests
29 |
30 | - (void)setUp
31 | {
32 | [super setUp];
33 | // Put setup code here. This method is called before the invocation of each test method in the class.
34 | }
35 |
36 | - (void)tearDown
37 | {
38 | // Put teardown code here. This method is called after the invocation of each test method in the class.
39 | [super tearDown];
40 | }
41 |
42 | - (void)testExample
43 | {
44 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
45 | }
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/MDraw/MDrawText.m:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawText.m
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/10/14.
6 | //
7 | //
8 |
9 | #import "MDrawText.h"
10 |
11 | @implementation MDrawText
12 | {
13 | UILabel *_label; // Use a label to display text;
14 | }
15 |
16 | -(id)initWithFrame:(CGRect)frame andText:(NSString *)text
17 | {
18 | if(self = [super init])
19 | {
20 | _startPoint = frame.origin;
21 | _endPoint = CGPointMake(_startPoint.x + frame.size.width, _startPoint.y + frame.size.height);
22 |
23 | self.text = text;
24 | }
25 |
26 | return self;
27 | }
28 |
29 | -(void)draw:(CGContextRef)ctx
30 | {
31 | if(!self.backgroundColor)
32 | {
33 | self.backgroundColor = [UIColor colorWithRed:255 green:255 blue:255 alpha:0.5];
34 | }
35 |
36 | if(!_label)
37 | {
38 | _label = [[UILabel alloc] init];
39 | _label.adjustsFontSizeToFitWidth = YES;
40 | _label.textAlignment = NSTextAlignmentLeft;
41 | _label.textColor = self.color;
42 | _label.font = [UIFont systemFontOfSize:60];
43 | _label.minimumScaleFactor = 0.001f;
44 | _label.numberOfLines = 0;
45 |
46 | _label.layer.borderWidth =2;
47 | _label.layer.borderColor = self.color.CGColor;
48 |
49 | }
50 |
51 | CGRect frame = self.frame;
52 |
53 | CGContextSaveGState(ctx);
54 |
55 |
56 | if([self.text length] > 0)
57 | {
58 | _label.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
59 | _label.text = self.text;
60 | CGContextTranslateCTM(ctx, frame.origin.x, frame.origin.y);
61 | [_label.layer drawInContext:ctx];
62 |
63 | }
64 | else
65 | {
66 | CGContextSetFillColorWithColor(ctx, self.backgroundColor.CGColor);
67 | CGContextFillRect(ctx, frame);
68 | }
69 |
70 | CGContextRestoreGState(ctx);
71 |
72 | }
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/MDraw/MDrawMeasurementInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawMeasurementInfo.m
3 | // MDraw
4 | //
5 | // Created by Gao Yongqing on 9/5/14.
6 | // Copyright (c) 2014 Motic China Group Co., Ltd. All rights reserved.
7 | //
8 |
9 | #import "MDrawMeasurementInfo.h"
10 |
11 | @implementation MDrawMeasurementInfo
12 |
13 | @synthesize tool = _tool;
14 |
15 | - (id)init
16 | {
17 | [NSException raise:@"InitException" format:@"Should call initWithTool to create an instance."];
18 |
19 | return nil;
20 | }
21 |
22 | - (instancetype)initWithTool:(MDrawTool *)aTool
23 | {
24 | if (self = [super init]) {
25 | _tool = aTool;
26 | }
27 |
28 | return self;
29 | }
30 |
31 | - (void)draw:(CGContextRef)ctx
32 | {
33 | NSString *text = self.tool.measureText;
34 | if(text == Nil)
35 | {
36 | return;
37 | }
38 |
39 | CGSize textSize = CGSizeZero;
40 | UIFont *textFont = [UIFont systemFontOfSize:14];
41 |
42 | if(text != Nil)
43 | {
44 | textSize= [text sizeWithFont:textFont
45 | constrainedToSize:CGSizeMake(1024, 99999.0)
46 | lineBreakMode:NSLineBreakByWordWrapping];
47 |
48 | }
49 |
50 | CGRect textFrame = [self calculateTextFrameWithTextSize:textSize forToolFrame:self.tool.frame];
51 | CGRect textBgFrame = CGRectMake(textFrame.origin.x - 10, textFrame.origin.y - 10, textFrame.size.width + 20, textFrame.size.height + 20);
52 | CGContextSetFillColorWithColor(ctx, [UIColor colorWithRed:255 green:255 blue:255 alpha:0.5].CGColor);
53 | CGContextFillRect(ctx, textBgFrame);
54 |
55 | [text drawWithRect:textFrame options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: textFont} context:Nil];
56 | }
57 |
58 | -(CGRect)calculateTextFrameWithTextSize:(CGSize)textSize forToolFrame:(CGRect)toolFrame
59 | {
60 | static CGFloat MARGIN = 20;
61 |
62 | CGRect textFrame = CGRectZero;
63 | CGPoint midPoint = CGRectMid(toolFrame);
64 | textFrame = CGRectMake(midPoint.x - textSize.width / 2.0f, toolFrame.origin.y - textSize.height - MARGIN, textSize.width, textSize.height);
65 |
66 | return textFrame;
67 |
68 | }
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/MDraw/MDrawComment.m:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawComment.m
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/11/14.
6 | //
7 | //
8 |
9 | #import "MDrawComment.h"
10 |
11 | @implementation MDrawComment
12 |
13 | -(void)drawUp:(CGPoint)point
14 | {
15 | [super drawUp:point];
16 |
17 | [self promoteText];
18 | }
19 |
20 | -(void)draw:(CGContextRef)ctx
21 | {
22 | [super draw:ctx];
23 |
24 | CGRect frame = self.frame;
25 |
26 | if (self.selected)
27 | {
28 | [self drawHandle:ctx atPoint:CGRectTL(frame)];
29 | [self drawHandle:ctx atPoint:CGRectTM(frame)];
30 | [self drawHandle:ctx atPoint:CGRectTR(frame)];
31 | [self drawHandle:ctx atPoint:CGRectRM(frame)];
32 | [self drawHandle:ctx atPoint:CGRectBR(frame)];
33 | [self drawHandle:ctx atPoint:CGRectBM(frame)];
34 | [self drawHandle:ctx atPoint:CGRectBL(frame)];
35 | [self drawHandle:ctx atPoint:CGRectLM(frame)];
36 | }
37 | }
38 |
39 | #pragma Mark - Alert view delegate
40 |
41 | -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
42 | {
43 | BOOL added = buttonIndex == 1;
44 |
45 | if ( added )
46 | {
47 | self.text = [[alertView textFieldAtIndex:0] text];
48 |
49 | //Give a minimize size for comment.
50 | CGRect frame = self.frame;
51 | CGFloat width = frame.size.width < 200 ? 200 : frame.size.width;
52 | CGFloat height = frame.size.height < 150 ? 150 : frame.size.height;
53 | _endPoint = CGPointMake(frame.origin.x + width, frame.origin.y + height);
54 |
55 | }
56 |
57 | if(self.delegate)
58 | {
59 | [self.delegate drawTool:self isAdded:added];
60 | }
61 |
62 | }
63 |
64 | -(void)promoteText
65 | {
66 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle: NSLocalizedString(@"enterYourText", nil)
67 | message:nil
68 | delegate:self
69 | cancelButtonTitle:NSLocalizedString(@"Cancel", nil)
70 | otherButtonTitles:NSLocalizedString(@"Confirm", nil), nil];
71 | alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
72 | [alertView show];
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/MDraw/MDrawArc.m:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawArc.m
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/5/14.
6 | //
7 | //
8 |
9 | #import "MDrawArc.h"
10 |
11 | @implementation MDrawArc
12 |
13 | -(void)drawUp:(CGPoint)point
14 | {
15 | _movePoint = CGPointZero;
16 | if(self.finalized)
17 | {
18 | return;
19 | }
20 |
21 | [_points addObject:[NSValue valueWithCGPoint:CGPointMidPoint(_startPoint, point)]];
22 | [_points addObject:[NSValue valueWithCGPoint:point]];
23 | [self finalize];
24 | }
25 |
26 | -(void)draw:(CGContextRef)ctx
27 | {
28 | if(self.finalized)
29 | {
30 | CGPoint from = [_points[0] CGPointValue];
31 | CGPoint arc = [_points[1] CGPointValue];
32 | CGPoint to = [_points[2] CGPointValue];
33 |
34 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
35 | CGContextSetLineWidth(ctx, 3);
36 | CGContextBeginPath(ctx);
37 | CGContextMoveToPoint(ctx, from.x, from.y);
38 | CGContextAddQuadCurveToPoint(ctx, arc.x, arc.y, to.x, to.y);
39 | CGContextStrokePath(ctx);
40 |
41 | if (self.selected)
42 | {
43 | [self drawHandle:ctx atPoint:from];
44 | [self drawHandle:ctx atPoint:arc];
45 | [self drawHandle:ctx atPoint:to];
46 | }
47 | }
48 | else
49 | {
50 | [super draw:ctx];
51 | }
52 |
53 |
54 | }
55 |
56 | -(NSString *)measureText
57 | {
58 | static NSString *lengthString, *distanceString;
59 | if (!lengthString)
60 | {
61 | lengthString = NSLocalizedString(@"Length", Nil);
62 | distanceString = NSLocalizedString(@"Distance", Nil);
63 | }
64 |
65 | CGPoint p1 = [[_points objectAtIndex:0] CGPointValue];
66 | CGPoint arcPoint = [[_points objectAtIndex:1] CGPointValue];
67 | CGPoint p2 = [[_points objectAtIndex:2] CGPointValue];
68 |
69 | CGFloat length = CGArcLength(p1, arcPoint, p2);
70 | CGFloat distance = CGPointDistance(p1, p2);
71 |
72 |
73 | return [NSString stringWithFormat:@"%@: %0.2f %@\n%@: %0.2f %@",
74 | lengthString,
75 | [self unitConvert:length isSquare:NO],
76 | self.unit,
77 | distanceString,
78 | [self unitConvert:distance isSquare:NO],
79 | self.unit];
80 | }
81 |
82 | @end
83 |
--------------------------------------------------------------------------------
/MDraw/MDrawFatArrow.m:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawFatArrow.m
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/5/14.
6 | //
7 | //
8 |
9 | #import "MDrawFatArrow.h"
10 |
11 | @implementation MDrawFatArrow
12 |
13 | -(BOOL)hitTest:(CGPoint)point
14 | {
15 | return CGPointInRect(point, self.frame);
16 | }
17 |
18 | -(void)draw:(CGContextRef)ctx
19 | {
20 | CGFloat length = CGPointDistance(_startPoint, _endPoint);
21 | CGSize dSize = CGPointOffset(_startPoint, _endPoint);
22 |
23 | // Draw an arrow at the horizontal line and then rotate it.
24 | // Here are the horizontal points.
25 | CGPoint p1 = CGPointZero;
26 | CGPoint p2 = CGPointMake(p1.x + length * 0.6, p1.y + length * 0.4);
27 | CGPoint p3 = CGPointMake(p1.x + length * 0.6, p1.y + length * 0.15);
28 | CGPoint p4 = CGPointMake(p1.x + length, p1.y + length * 0.15);
29 | CGPoint p5 = CGPointMake(p1.x + length, p1.y - length * 0.15);
30 | CGPoint p6 = CGPointMake(p1.x + length * 0.6, p1.y - length * 0.15);
31 | CGPoint p7 = CGPointMake(p1.x + length * 0.6, p1.y - length * 0.4);
32 |
33 | CGContextSaveGState(ctx);
34 |
35 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
36 | CGContextSetFillColorWithColor(ctx, self.color.CGColor);
37 | CGContextSetLineWidth(ctx, self.lineWidth);
38 |
39 |
40 | CGContextBeginPath(ctx);
41 |
42 | CGContextTranslateCTM(ctx, _startPoint.x,_startPoint.y);
43 | CGContextRotateCTM(ctx, atan2f(dSize.height,dSize.width));
44 |
45 | CGContextMoveToPoint(ctx, p1.x, p1.y);
46 | CGContextAddLineToPoint(ctx, p2.x, p2.y);
47 | CGContextAddLineToPoint(ctx, p3.x, p3.y);
48 | CGContextAddLineToPoint(ctx, p4.x, p4.y);
49 | CGContextAddLineToPoint(ctx, p5.x, p5.y);
50 | CGContextAddLineToPoint(ctx, p6.x, p6.y);
51 | CGContextAddLineToPoint(ctx, p7.x, p7.y);
52 | CGContextClosePath(ctx);
53 |
54 | CGContextFillPath(ctx);
55 | CGContextStrokePath(ctx);
56 |
57 |
58 | CGContextRestoreGState(ctx);
59 |
60 | if (self.selected)
61 | {
62 | CGContextSaveGState(ctx);
63 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
64 | CGContextSetFillColorWithColor(ctx, self.color.CGColor);
65 |
66 | [self drawHandle:ctx atPoint:_startPoint];
67 | [self drawHandle:ctx atPoint:_endPoint];
68 |
69 | CGContextRestoreGState(ctx);
70 | }
71 |
72 |
73 | }
74 |
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/MDraw/MDrawAngle.m:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawAngle.m
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/6/14.
6 | //
7 | //
8 |
9 | #import "MDrawAngle.h"
10 |
11 | @implementation MDrawAngle
12 |
13 | -(id)init
14 | {
15 | if(self = [super init])
16 | {
17 | _closePath = NO;
18 | }
19 |
20 | return self;
21 | }
22 |
23 | -(id)initWithStartPoint:(CGPoint)startPoint
24 | {
25 | if(self = [super initWithStartPoint:startPoint])
26 | {
27 | _closePath = NO;
28 | }
29 |
30 | return self;
31 | }
32 |
33 |
34 |
35 | -(void)drawUp:(CGPoint)point
36 | {
37 | _movePoint = CGPointZero;
38 |
39 | if(self.finalized)
40 | {
41 | return;
42 | }
43 |
44 | BOOL isStartPoint = NO;
45 | if(_points.count > 0 )
46 | {
47 | CGPoint startPoint = [[_points objectAtIndex:0] CGPointValue];
48 | if([self isPoint:point onHandle:startPoint])
49 | {
50 | isStartPoint = YES;
51 | }
52 | }
53 |
54 | if(!isStartPoint)
55 | {
56 | [_points addObject:[NSValue valueWithCGPoint:point]];
57 | }
58 |
59 | if(_points.count >=3)
60 | {
61 | [self finalize];
62 | }
63 | }
64 |
65 | -(void)draw:(CGContextRef)ctx
66 | {
67 | [super draw:ctx];
68 |
69 | if(self.finalized)
70 | {
71 | CGPoint p1 = [_points[0] CGPointValue];
72 | CGPoint p2 = [_points[1] CGPointValue];
73 | CGPoint p3 = [_points[2] CGPointValue];
74 |
75 | CGFloat line1 = CGPointDistance(p2, p1);
76 | CGFloat line2 = CGPointDistance(p2, p3);
77 | CGFloat minLength = MIN(line1, line2);
78 | CGFloat arcRadius = minLength > 20 ? 20 : minLength;
79 |
80 | CGFloat radian1 = CGVectorRadian(p2,p1);
81 | CGFloat radian2 = CGVectorRadian(p2,p3);
82 |
83 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
84 | CGContextBeginPath(ctx);
85 | CGContextAddArc(ctx, p2.x, p2.y, arcRadius,radian1,radian2, 0);
86 | CGContextStrokePath(ctx);
87 | }
88 |
89 | }
90 |
91 | -(NSString *)measureText
92 | {
93 | static NSString *degreeString;
94 | if(!degreeString)
95 | {
96 | degreeString = NSLocalizedString(@"Degree", Nil);
97 | }
98 |
99 | CGPoint p1 = [[_points objectAtIndex:0] CGPointValue];
100 | CGPoint arcPoint = [[_points objectAtIndex:1] CGPointValue];
101 | CGPoint p2 = [[_points objectAtIndex:2] CGPointValue];
102 |
103 | return [NSString stringWithFormat:@"%@ : %0.2f",
104 | degreeString,
105 | CGAngleDegree(p1, arcPoint, p2)];
106 | }
107 |
108 |
109 | @end
110 |
--------------------------------------------------------------------------------
/MDraw/MDrawEllipse.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawEllipse.h"
23 |
24 | @implementation MDrawEllipse
25 |
26 | -(void)draw:(CGContextRef)ctx
27 | {
28 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
29 | CGContextSetLineWidth(ctx, self.lineWidth);
30 |
31 | CGContextBeginPath(ctx);
32 | CGContextAddEllipseInRect(ctx, self.frame);
33 | CGContextStrokePath(ctx);
34 |
35 | if (self.selected)
36 | {
37 | CGRect frame = self.frame;
38 | [self drawHandle:ctx atPoint:CGRectTL(frame)];
39 | [self drawHandle:ctx atPoint:CGRectTM(frame)];
40 | [self drawHandle:ctx atPoint:CGRectTR(frame)];
41 | [self drawHandle:ctx atPoint:CGRectRM(frame)];
42 | [self drawHandle:ctx atPoint:CGRectBR(frame)];
43 | [self drawHandle:ctx atPoint:CGRectBM(frame)];
44 | [self drawHandle:ctx atPoint:CGRectBL(frame)];
45 | [self drawHandle:ctx atPoint:CGRectLM(frame)];
46 | }
47 |
48 | }
49 |
50 | -(NSString *)measureText
51 | {
52 | static NSString *radiusString, *areaString, *perimeterString;
53 | if(!radiusString)
54 | {
55 | radiusString = NSLocalizedString(@"Radius", nil);
56 | areaString = NSLocalizedString(@"Area", nil);
57 | perimeterString = NSLocalizedString(@"Perimeter", nil);
58 | }
59 |
60 | CGFloat radius = fabs((_startPoint.x - _endPoint.x)/2.0);
61 | CGFloat area = M_PI * pow(radius, 2);
62 | CGFloat perimeter = 2 * M_PI * radius;
63 |
64 | return [NSString stringWithFormat:@"%@: %0.2f %@\n%@: %0.2f sq%@\n%@: %0.2f %@",
65 | radiusString,
66 | [self unitConvert:radius isSquare:NO],
67 | self.unit,
68 | areaString,
69 | [self unitConvert:area isSquare:YES],
70 | self.unit,
71 | perimeterString,
72 | [self unitConvert:perimeter isSquare:NO],
73 | self.unit];
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/MDraw/AppDelegate.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "AppDelegate.h"
23 |
24 | @implementation AppDelegate
25 |
26 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
27 | {
28 | // Override point for customization after application launch.
29 | return YES;
30 | }
31 |
32 | - (void)applicationWillResignActive:(UIApplication *)application
33 | {
34 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
35 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
36 | }
37 |
38 | - (void)applicationDidEnterBackground:(UIApplication *)application
39 | {
40 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
41 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
42 | }
43 |
44 | - (void)applicationWillEnterForeground:(UIApplication *)application
45 | {
46 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
47 | }
48 |
49 | - (void)applicationDidBecomeActive:(UIApplication *)application
50 | {
51 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
52 | }
53 |
54 | - (void)applicationWillTerminate:(UIApplication *)application
55 | {
56 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/MDraw/MDrawArrow.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawArrow.h"
23 |
24 | @implementation MDrawArrow
25 |
26 | - (NSString *)measureText
27 | {
28 | return nil;
29 | }
30 |
31 | -(void)draw:(CGContextRef)ctx
32 | {
33 |
34 | if(CGPointEqualToPoint(_startPoint, _endPoint))
35 | {
36 | return;
37 | }
38 |
39 | CGSize dSize = CGPointOffset(_startPoint, _endPoint);
40 | //Draw a triagnle as the arrow, the default angle is 15 degree
41 | //And the default half length is 2x line width.
42 | float radian = 15.0 /180.0 * M_PI;
43 | float length = self.lineWidth * 2;
44 | float x = length / tanf(radian);
45 | CGPoint p1 = CGPointZero;
46 | CGPoint p2 = CGPointMake(x, p1.y - length);
47 | CGPoint p3 = CGPointMake(x, p1.y + length);
48 |
49 | float lineRadian = atan2f(dSize.height, dSize.width);
50 | float xOffset = x * cosf(lineRadian);
51 | float yOffset = x * sinf(lineRadian);
52 | CGPoint newStartPoint = CGPointMake(_startPoint.x + xOffset, _startPoint.y + yOffset);
53 |
54 |
55 | CGContextSaveGState(ctx);
56 |
57 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
58 | CGContextSetFillColorWithColor(ctx, self.color.CGColor);
59 | CGContextSetLineWidth(ctx, self.lineWidth);
60 |
61 | //Draw line
62 | CGContextBeginPath(ctx);
63 | CGContextMoveToPoint(ctx, newStartPoint.x, newStartPoint.y);
64 | CGContextAddLineToPoint(ctx, _endPoint.x, _endPoint.y);
65 | CGContextClosePath(ctx);
66 | CGContextStrokePath(ctx);
67 |
68 | //Draw the arrow
69 | CGContextBeginPath(ctx);
70 | CGContextTranslateCTM(ctx, _startPoint.x,_startPoint.y);
71 | CGContextRotateCTM(ctx, atan2f(dSize.height,dSize.width));
72 | CGContextMoveToPoint(ctx, p1.x, p1.y);
73 | CGContextAddLineToPoint(ctx, p2.x, p2.y);
74 | CGContextAddLineToPoint(ctx, p3.x, p3.y);
75 | CGContextClosePath(ctx);
76 | CGContextFillPath(ctx);
77 |
78 | CGContextRestoreGState(ctx);
79 |
80 | if (self.selected)
81 | {
82 | [self drawHandle:ctx atPoint:_startPoint];
83 | [self drawHandle:ctx atPoint:_endPoint];
84 | }
85 | }
86 |
87 | @end
88 |
--------------------------------------------------------------------------------
/MDraw/ViewController.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "ViewController.h"
23 |
24 | #import "MDrawView.h"
25 | #import "MDrawLine.h"
26 | #import "MDrawRect.h"
27 | #import "MDrawEllipse.h"
28 | #import "MDrawFreeline.h"
29 | #import "MDrawPolyline.h"
30 |
31 | @interface ViewController ()
32 |
33 | @end
34 |
35 | @implementation ViewController
36 | {
37 | __weak IBOutlet MDrawView *drawView;
38 | }
39 |
40 | - (void)viewDidLoad
41 | {
42 | [super viewDidLoad];
43 | // Do any additional setup after loading the view, typically from a nib.
44 |
45 | // drawView = [[MDrawView alloc] initWithFrame:self.view.frame];
46 | // [self.view addSubview:drawView];
47 |
48 | drawView.showMeasurement = YES;
49 | }
50 |
51 | - (void)didReceiveMemoryWarning
52 | {
53 | [super didReceiveMemoryWarning];
54 | // Dispose of any resources that can be recreated.
55 | }
56 |
57 | - (UIBarPosition)positionForBar:(id)bar
58 | {
59 | return UIBarPositionTopAttached;
60 | }
61 |
62 | -(IBAction)drawLine:(id)sender
63 | {
64 | [drawView beginDrawingForType:[MDrawLine class]];
65 | }
66 |
67 | -(IBAction)drawRect:(id)sender
68 | {
69 | [drawView beginDrawingForType:[MDrawRect class]];
70 | }
71 |
72 | -(IBAction)drawEllipse:(id)sender
73 | {
74 | [drawView beginDrawingForType:[MDrawEllipse class]];
75 | }
76 |
77 | -(IBAction)drawFreeline:(id)sender
78 | {
79 | [drawView beginDrawingForType:[MDrawFreeline class]];
80 | }
81 |
82 | -(IBAction)drawPolyline:(id)sender
83 | {
84 | [drawView beginDrawingForType:[MDrawPolyline class]];
85 | }
86 |
87 | -(IBAction)drawArrow:(id)sender
88 | {
89 | [drawView beginDrawingForType:[MDrawArrow class]];
90 | }
91 |
92 | - (IBAction)drawArc:(id)sender
93 | {
94 | [drawView beginDrawingForType:[MDrawArc class]];
95 | }
96 |
97 | - (IBAction)drawAngle:(id)sender
98 | {
99 | [drawView beginDrawingForType:[MDrawAngle class]];
100 | }
101 |
102 | -(IBAction)undo:(id)sender
103 | {
104 | [drawView undo];
105 | }
106 |
107 | -(IBAction)redo:(id)sender
108 | {
109 | [drawView redo];
110 | }
111 |
112 |
113 |
114 | @end
115 |
--------------------------------------------------------------------------------
/MDraw/MDrawView.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import
23 | #import "MDrawTool.h"
24 | #import "MDrawLine.h"
25 | #import "MDrawRect.h"
26 | #import "MDrawEllipse.h"
27 | #import "MDrawFreeline.h"
28 | #import "MDrawPolyline.h"
29 | #import "MDrawArrow.h"
30 | #import "MDrawAngle.h"
31 | #import "MDrawArc.h"
32 | #import "MDrawText.h"
33 | #import "MDrawComment.h"
34 |
35 | @interface MDrawView : UIView
36 |
37 |
38 | @property (nonatomic,readonly) MDrawTool *activeTool;
39 | @property (nonatomic,readonly) BOOL drawing;
40 |
41 | /**
42 | * The color of new drawing tool
43 | **/
44 | @property (nonatomic) UIColor *color;
45 | /**
46 | * The default line width of new tool
47 | **/
48 | @property (nonatomic) CGFloat lineWidth;
49 |
50 | /**
51 | * Whether or not there are tools.
52 | */
53 | @property (nonatomic,readonly) BOOL hasTools;
54 |
55 | /**
56 | * Tools on the view
57 | */
58 | @property (nonatomic,readonly) NSArray *tools;
59 |
60 | /**
61 | * Whether the view recevies gestures
62 | **/
63 | @property (nonatomic) BOOL enableGesture;
64 |
65 | /**
66 | * YES to show measurement information.
67 | */
68 | @property (nonatomic) BOOL showMeasurement;
69 |
70 | /**
71 | * um/pixel, if calibrated. default is 0.
72 | */
73 | @property (nonatomic) CGFloat calibration;
74 |
75 | /**
76 | * Unit of measurement information
77 | */
78 | @property (nonatomic,strong) NSString *unit;
79 |
80 | /**
81 | * Whether or not the tools is dirty
82 | */
83 | @property (nonatomic,readonly) BOOL isDirty;
84 |
85 | /**
86 | * Undo the drawing
87 | **/
88 | -(BOOL)undo;
89 |
90 | /**
91 | * Redo the drawing
92 | **/
93 | -(BOOL)redo;
94 |
95 | /**
96 | * Select the drawing tool type
97 | **/
98 | -(void)beginDrawingForType:(Class)toolType;
99 |
100 | /**
101 | * Stop drawing.
102 | **/
103 | -(void)finalizeDrawing;
104 |
105 | -(void)drawDown:(CGPoint)point;
106 | -(void)drawMoveFromPoint:(CGPoint)srcPoint toPoint:(CGPoint)point;
107 | -(void)drawUp:(CGPoint)point;
108 |
109 | /**
110 | * Delete the active tool
111 | **/
112 | -(void)deleteCurrentTool;
113 |
114 | /**
115 | * Clear all tools
116 | **/
117 | -(void)clearTools;
118 |
119 | -(void)selectNone;
120 |
121 | @end
122 |
--------------------------------------------------------------------------------
/MDraw.xcodeproj/xcuserdata/gaoyq.xcuserdatad/xcschemes/MDraw.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
61 |
62 |
68 |
69 |
70 |
71 |
72 |
73 |
79 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/MDraw/MDrawTool.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import
23 | #include "MDrawMath.h"
24 | //#include "UIColor+String.h"
25 |
26 | #define HANDLE_SIZE 20
27 | #define NEAR_WIDTH 10
28 |
29 | @protocol MDrawToolProtocol
30 |
31 |
32 | /**
33 | * Name of the tool.
34 | */
35 | @property (nonatomic,strong)NSString *name;
36 |
37 | /**
38 | * Is the tool selected
39 | */
40 | @property (nonatomic) BOOL selected;
41 |
42 | /**
43 | * Is the tool finalized (finish drawing)
44 | **/
45 | @property (nonatomic,readonly) BOOL finalized;
46 |
47 | /**
48 | * Frame of this tool
49 | **/
50 | @property (nonatomic,readonly) CGRect frame;
51 |
52 | /**
53 | * Line width
54 | **/
55 | @property (nonatomic)CGFloat lineWidth;
56 |
57 | /**
58 | * Line color
59 | **/
60 | @property (nonatomic,strong)UIColor *color;
61 |
62 |
63 | /**
64 | * Init the tool with a start point.
65 | **/
66 | -(id)initWithStartPoint:(CGPoint )startPoint;
67 |
68 | /**
69 | * Draw mouse down (touchesBegan)
70 | **/
71 | -(void)drawDown:(CGPoint)point;
72 |
73 | /**
74 | * Draw mouse move (touchesMove)
75 | **/
76 | -(void)drawMove:(CGPoint)point;
77 |
78 | /**
79 | * Draw mouse up (touchesEnd)
80 | **/
81 | -(void)drawUp:(CGPoint)point;
82 |
83 | /**
84 | * Finalize the drawing
85 | **/
86 | -(void)finalize;
87 |
88 | /**
89 | * Hit test to see whether or not the point is on the tool
90 | **/
91 | -(BOOL)hitTest:(CGPoint)point;
92 |
93 | /**
94 | * Determine whether or not the point hits a handle
95 | * If it hits a handle, then it can move the tool
96 | **/
97 | -(BOOL)hitOnHandle:(CGPoint)point;
98 |
99 | /**
100 | * Move the tool or the selected handle to the new position.
101 | **/
102 | -(void)moveByOffset:(CGSize)offset;
103 |
104 | /**
105 | * Stop move the handle
106 | **/
107 | -(void)stopMoveHandle;
108 |
109 | /**
110 | * Draw itself on the context
111 | *
112 | * @param ctx context to draw on
113 | *
114 | * @param view The view to draw on
115 | */
116 | -(void)draw:(CGContextRef)ctx;
117 |
118 | @end
119 |
120 | @protocol MDrawToolMeasurementProtocol
121 |
122 | /**
123 | * YES to show measurement information while No to hide
124 | */
125 | @property (nonatomic,assign) BOOL showMeasurement;
126 |
127 | /**
128 | * How many μm per pixel, default value is 0, means it does not have a calibration.
129 | */
130 | @property (nonatomic,assign) CGFloat calibration;
131 |
132 | /**
133 | * Displaying unit, default is px;
134 | */
135 | @property (nonatomic,strong) NSString *unit;
136 |
137 | /**
138 | * Get the measure text for this tool.
139 | */
140 | @property (nonatomic, readonly) NSString *measureText;
141 |
142 | /**
143 | * Draw measurement information
144 | *
145 | * @param ctx The context to draw on.
146 | */
147 | - (void)drawMeasurement:(CGContextRef)ctx;
148 |
149 | @end
150 |
151 | /**
152 | * Base class of draw tool
153 | **/
154 | @interface MDrawTool : NSObject
155 | {
156 | @protected
157 | BOOL _finalized;
158 | CGPoint _startPoint, _endPoint;
159 | CGFloat _unitScale;
160 | }
161 |
162 | @end
163 |
--------------------------------------------------------------------------------
/MDraw/MDrawLine.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawLine.h"
23 |
24 | @implementation MDrawLine
25 | {
26 | // 0 : no hited, 1 : startPoint, 2: endPoint, 3: Middle point
27 | int _handleHitStatus;
28 | }
29 |
30 | -(BOOL)hitTest:(CGPoint)point
31 | {
32 | float distance = CGPointToLineDistance(point, _startPoint, _endPoint);
33 | if(distance <= NEAR_WIDTH)
34 | {
35 | return YES;
36 | }
37 |
38 | return NO;
39 | }
40 |
41 | -(BOOL)hitOnHandle:(CGPoint)point
42 | {
43 | _handleHitStatus = 0;
44 |
45 | if([self isPoint:point onHandle:_startPoint])
46 | {
47 | _handleHitStatus = 1;
48 | return YES;
49 | }
50 |
51 | if([self isPoint:point onHandle:_endPoint])
52 | {
53 | _handleHitStatus = 2;
54 | return YES;
55 | }
56 |
57 | if([self hitTest:point])
58 | {
59 | _handleHitStatus = 3;
60 | return YES;
61 | }
62 |
63 | return NO;
64 | }
65 |
66 | -(void)moveByOffset:(CGSize)offset
67 | {
68 |
69 | if(_handleHitStatus == 1)
70 | {
71 | _startPoint = CGPointAddOffset(_startPoint, offset);
72 | }
73 | else if(_handleHitStatus == 2)
74 | {
75 | _endPoint = CGPointAddOffset(_endPoint, offset);
76 | }
77 | else if(_handleHitStatus == 3)
78 | {
79 | _startPoint.x += offset.width;
80 | _startPoint.y += offset.height;
81 | _endPoint.x += offset.width;
82 | _endPoint.y += offset.height;
83 | }
84 | }
85 |
86 | -(void)stopMoveHandle
87 | {
88 | _handleHitStatus = 0;
89 | }
90 |
91 | -(void)drawDown:(CGPoint)point
92 | {
93 | _startPoint = point;
94 | _endPoint = point;
95 | }
96 |
97 | -(void)drawMove:(CGPoint)point
98 | {
99 | _endPoint = point;
100 | }
101 |
102 | -(void)drawUp:(CGPoint)point
103 | {
104 | if(self.finalized)
105 | {
106 | return;
107 | }
108 |
109 | _endPoint = point;
110 |
111 | if(!CGPointEqualToPoint(_startPoint, point))
112 | {
113 | [self finalize];
114 | }
115 | }
116 |
117 | -(void)finalize
118 | {
119 | _finalized = YES;
120 | self.selected = YES;
121 | }
122 |
123 | -(void)draw:(CGContextRef)ctx
124 | {
125 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
126 | CGContextSetLineWidth(ctx, self.lineWidth);
127 |
128 | CGContextBeginPath(ctx);
129 | CGContextMoveToPoint(ctx, _startPoint.x, _startPoint.y);
130 | CGContextAddLineToPoint(ctx, _endPoint.x, _endPoint.y);
131 | CGContextStrokePath(ctx);
132 |
133 | if (self.selected)
134 | {
135 | [self drawHandle:ctx atPoint:_startPoint];
136 | [self drawHandle:ctx atPoint:_endPoint];
137 | }
138 |
139 | }
140 |
141 | -(NSString *)measureText
142 | {
143 | static NSString *lengthText;
144 | if(!lengthText)
145 | {
146 | lengthText = NSLocalizedString(@"Length", nil);
147 | }
148 |
149 | CGFloat length = CGPointDistance(_startPoint, _endPoint);
150 | length = [self unitConvert:length isSquare:NO];
151 |
152 | return [NSString stringWithFormat:@"%@ : %0.2f %@",
153 | lengthText,
154 | length,
155 | self.unit];
156 |
157 | }
158 |
159 | @end
160 |
--------------------------------------------------------------------------------
/MDraw/MDrawFreeline.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawFreeline.h"
23 |
24 | @implementation MDrawFreeline
25 | {
26 | NSMutableArray *_points;
27 | }
28 |
29 | -(id)init
30 | {
31 | if(self = [super init])
32 | {
33 | _points = [[NSMutableArray alloc] init];
34 | }
35 |
36 | return self;
37 | }
38 |
39 | -(id)initWithStartPoint:(CGPoint)startPoint
40 | {
41 | self = [super initWithStartPoint:startPoint];
42 | if(self)
43 | {
44 | _points = [[NSMutableArray alloc] init];
45 | }
46 |
47 | return self;
48 | }
49 |
50 | -(CGRect)frame
51 | {
52 | CGPoint tl, rb;
53 |
54 | if(_points.count > 0 )
55 | {
56 | CGPoint firstPoint = [[_points objectAtIndex:0] CGPointValue];
57 | tl = firstPoint;
58 | rb = firstPoint;
59 | }
60 |
61 | for (NSValue *pValue in _points)
62 | {
63 | CGPoint p = [pValue CGPointValue];
64 |
65 | tl.x = MIN(tl.x, p.x);
66 | tl.y = MIN(tl.y, p.y);
67 | rb.x = MAX(rb.x, p.x);
68 | rb.y = MAX(rb.y, p.y);
69 | }
70 |
71 | return CGRectMake(tl.x,
72 | tl.y,
73 | fabsf(rb.x - tl.x),
74 | fabsf(rb.y - tl.y));
75 |
76 |
77 | }
78 |
79 | -(void)drawMove:(CGPoint)point
80 | {
81 | [_points addObject:[NSValue valueWithCGPoint:point]];
82 | }
83 |
84 | -(void)drawUp:(CGPoint)point
85 | {
86 | [_points addObject:[NSValue valueWithCGPoint:point]];
87 | [self finalize];
88 | }
89 |
90 | -(void)finalize
91 | {
92 | _finalized = YES;
93 | self.selected = YES;
94 | }
95 |
96 | -(BOOL)hitOnHandle:(CGPoint)point
97 | {
98 | _moveDirection = MDrawMoveDirectionNone;
99 |
100 | CGRect frame = self.frame;
101 |
102 | if(CGPointInRect(point, frame))
103 | {
104 | _moveDirection = MDrawMoveDirectionWhole;
105 | return YES;
106 | }
107 |
108 | return NO;
109 | }
110 |
111 | -(void)moveByOffset:(CGSize)offset
112 | {
113 | if(_moveDirection == MDrawMoveDirectionWhole)
114 | {
115 | for (int i = 0; i < _points.count; i++) {
116 | CGPoint p = [[_points objectAtIndex:i] CGPointValue];
117 | p.x += offset.width;
118 | p.y += offset.height;
119 |
120 | [_points replaceObjectAtIndex:i withObject:[NSValue valueWithCGPoint:p]];
121 | }
122 | }
123 | }
124 |
125 | -(void)draw:(CGContextRef)ctx
126 | {
127 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
128 | CGContextSetLineWidth(ctx, self.lineWidth);
129 |
130 | CGContextBeginPath(ctx);
131 | if(_points.count > 0 )
132 | {
133 | CGPoint p = [[_points objectAtIndex:0] CGPointValue];
134 | CGContextMoveToPoint(ctx, p.x, p.y);
135 |
136 | for (int i = 1; i < _points.count; i++)
137 | {
138 | CGPoint p = [[_points objectAtIndex:i] CGPointValue];
139 | CGContextAddLineToPoint(ctx, p.x, p.y);
140 | }
141 |
142 | }
143 |
144 | CGContextStrokePath(ctx);
145 |
146 | if (self.selected)
147 | {
148 | [self drawHandle:ctx atPoint:CGRectMid(self.frame)];
149 |
150 | }
151 |
152 | }
153 |
154 | -(NSString *)measureText
155 | {
156 | static NSString *lengthString;
157 | if(!lengthString)
158 | {
159 | lengthString = NSLocalizedString(@"Length", Nil);
160 | }
161 |
162 | CGFloat length = CGPolygonLength(_points);
163 |
164 | return [NSString stringWithFormat:@"%@: %0.2f %@",
165 | lengthString,
166 | [self unitConvert:length isSquare:NO],
167 | self.unit];
168 | }
169 |
170 | @end
171 |
--------------------------------------------------------------------------------
/MDraw/MDrawTool.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawTool.h"
23 | #import "MDrawMeasurementInfo.h"
24 |
25 |
26 | @implementation MDrawTool
27 | {
28 | UIColor *_handleFillColor;
29 | NSString *_unit;
30 |
31 | MDrawMeasurementInfo *_measurement;
32 | }
33 |
34 | @synthesize name;
35 | @synthesize selected;
36 | @synthesize finalized = _finalized;
37 | @synthesize lineWidth;
38 | @synthesize color;
39 | @synthesize showMeasurement;
40 | @synthesize calibration;
41 | @synthesize measureText;
42 |
43 | -(id)init
44 | {
45 | if(self = [super init])
46 | {
47 | _handleFillColor = [UIColor colorWithRed:255 green:255 blue:255 alpha:0.6];
48 | self.lineWidth = 3;
49 | self.calibration = 0;
50 | self.unit = @"px";
51 | _unitScale = 1;
52 | }
53 |
54 | return self;
55 | }
56 |
57 | -(id)initWithStartPoint:(CGPoint)startPoint
58 | {
59 | if(self=[self init])
60 | {
61 | _startPoint = startPoint;
62 | _endPoint = startPoint;
63 | }
64 |
65 | return self;
66 | }
67 |
68 | -(NSString *)unit
69 | {
70 | return [_unit copy];
71 | }
72 |
73 | -(void)setUnit:(NSString *)unit
74 | {
75 | _unit = unit;
76 | _unitScale = 1;
77 |
78 | if([_unit isEqualToString:@"μm"] || [_unit isEqualToString:@"um"])
79 | {
80 | _unitScale = 1;
81 | }
82 | else if([_unit isEqualToString:@"mm"])
83 | {
84 | _unitScale = 1 / 1000.0;
85 | }
86 | else if([_unit isEqualToString:@"cm"])
87 | {
88 | _unitScale = 1 / 1000000.0;
89 | }
90 | }
91 |
92 | -(CGRect)frame
93 | {
94 | return CGRectMake(MIN(_startPoint.x, _endPoint.x),
95 | MIN(_startPoint.y, _endPoint.y),
96 | fabsf(_endPoint.x - _startPoint.x),
97 | fabsf(_endPoint.y - _startPoint.y));
98 | }
99 |
100 | -(void)drawDown:(CGPoint)point
101 | {
102 | }
103 |
104 | -(void)drawMove:(CGPoint)point
105 | {
106 | }
107 |
108 | -(void)drawUp:(CGPoint)point
109 | {
110 | }
111 |
112 | -(void)finalize:(CGPoint)point
113 | {
114 | _endPoint = point;
115 | }
116 |
117 | -(BOOL)hitTest:(CGPoint)point
118 | {
119 | return CGPointInRect(point, self.frame);
120 | }
121 |
122 | -(BOOL)hitOnHandle:(CGPoint)point
123 | {
124 | return NO;
125 | }
126 |
127 | -(void)moveByOffset:(CGSize)offset
128 | {
129 | }
130 |
131 | -(void)stopMoveHandle
132 | {
133 | }
134 |
135 | -(void)draw:(CGContextRef)ctx
136 | {
137 | }
138 |
139 | - (void)drawMeasurement:(CGContextRef)ctx
140 | {
141 | BOOL needDraw = self.showMeasurement && self.finalized && !self.selected && self.measureText;
142 | if (!needDraw) {
143 | return;
144 | }
145 |
146 | if (!_measurement) {
147 | _measurement = [[MDrawMeasurementInfo alloc] initWithTool:self];
148 | }
149 |
150 | [_measurement draw:ctx];
151 | }
152 |
153 | #pragma mark - protected methods
154 |
155 | -(void)drawHandle:(CGContextRef)ctx atPoint:(CGPoint)point
156 | {
157 | CGContextSetFillColorWithColor(ctx, _handleFillColor.CGColor);
158 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
159 | CGRect handleRect = CGRectMake(point.x- HANDLE_SIZE /2, point.y- HANDLE_SIZE /2, HANDLE_SIZE, HANDLE_SIZE);
160 | CGContextSetLineWidth(ctx, 2);
161 | CGContextFillEllipseInRect(ctx, handleRect);
162 | CGContextStrokeEllipseInRect(ctx, handleRect);
163 | }
164 |
165 | -(BOOL)isPoint:(CGPoint)point onHandle:(CGPoint)handlePoint
166 | {
167 | CGRect handleRect = CGRectMake(handlePoint.x- HANDLE_SIZE /2, handlePoint.y- HANDLE_SIZE /2, HANDLE_SIZE, HANDLE_SIZE);
168 | return CGPointInRect(point, handleRect);
169 | }
170 |
171 | -(CGFloat)unitConvert:(CGFloat)pixels isSquare:(BOOL)square
172 | {
173 | if (self.calibration == 0) {
174 | return pixels;
175 | }
176 |
177 | CGFloat result = pixels * self.calibration * _unitScale;
178 | if(square)
179 | {
180 | result *= ( self.calibration * _unitScale );
181 | }
182 |
183 | return result;
184 | }
185 |
186 | @end
187 |
--------------------------------------------------------------------------------
/MDraw/MDrawRect.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawRect.h"
23 |
24 | @implementation MDrawRect
25 | {
26 |
27 | }
28 |
29 | -(void)drawDown:(CGPoint)point
30 | {
31 | }
32 |
33 | -(void)drawMove:(CGPoint)point
34 | {
35 | _endPoint = point;
36 | }
37 |
38 | -(void)drawUp:(CGPoint)point
39 | {
40 | _endPoint = point;
41 | [self finalize];
42 | }
43 |
44 | -(void)finalize
45 | {
46 | _finalized = YES;
47 | self.selected = YES;
48 | }
49 |
50 | -(BOOL)hitTest:(CGPoint)point
51 | {
52 | return CGPointInRect(point, self.frame);
53 | }
54 |
55 | -(BOOL)hitOnHandle:(CGPoint)point
56 | {
57 |
58 | _moveDirection = MDrawMoveDirectionNone;
59 |
60 | CGRect frame = self.frame;
61 | //After moving , start point and end point may not longer be the top left and bottom right
62 | // Here to correct.
63 | _startPoint = frame.origin;
64 | _endPoint = CGPointMake(_startPoint.x + frame.size.width, _startPoint.y + frame.size.height);
65 |
66 | if([self isPoint:point onHandle:CGRectTL(frame)])
67 | {
68 | _moveDirection = MDrawMoveDirectionTL;
69 | return YES;
70 | }
71 | if([self isPoint:point onHandle:CGRectTM(frame)])
72 | {
73 | _moveDirection = MDrawMoveDirectionTM;
74 | return YES;
75 | }
76 | if([self isPoint:point onHandle:CGRectTR(frame)])
77 | {
78 | _moveDirection = MDrawMoveDirectionTR;
79 | return YES;
80 | }
81 | if([self isPoint:point onHandle:CGRectRM(frame)])
82 | {
83 | _moveDirection = MDrawMoveDirectionRM;
84 | return YES;
85 | }
86 | if([self isPoint:point onHandle:CGRectBR(frame)])
87 | {
88 | _moveDirection = MDrawMoveDirectionBR;
89 | return YES;
90 | }
91 | if([self isPoint:point onHandle:CGRectBM(frame)])
92 | {
93 | _moveDirection = MDrawMoveDirectionBM;
94 | return YES;
95 | }
96 | if([self isPoint:point onHandle:CGRectBL(frame)])
97 | {
98 | _moveDirection = MDrawMoveDirectionBL;
99 | return YES;
100 | }
101 | if([self isPoint:point onHandle:CGRectLM(frame)])
102 | {
103 | _moveDirection = MDrawMoveDirectionLM;
104 | return YES;
105 | }
106 | if(CGPointInRect(point, frame))
107 | {
108 | _moveDirection = MDrawMoveDirectionWhole;
109 | return YES;
110 | }
111 |
112 | return NO;
113 | }
114 |
115 | -(void)moveByOffset:(CGSize)offset
116 | {
117 | switch (_moveDirection) {
118 | case MDrawMoveDirectionTL:
119 | _startPoint = CGPointAddOffset(_startPoint, offset);
120 | break;
121 | case MDrawMoveDirectionTM:
122 | _startPoint.y += offset.height;
123 | break;
124 | case MDrawMoveDirectionTR:
125 | _startPoint.y += offset.height;
126 | _endPoint.x += offset.width;
127 | break;
128 | case MDrawMoveDirectionRM:
129 | _endPoint.x += offset.width;
130 | break;
131 | case MDrawMoveDirectionBR:
132 | _endPoint = CGPointAddOffset(_endPoint, offset);
133 | break;
134 | case MDrawMoveDirectionBM:
135 | _endPoint.y += offset.height;
136 | break;
137 | case MDrawMoveDirectionBL:
138 | _startPoint.x += offset.width;
139 | _endPoint.y += offset.height;
140 | break;
141 | case MDrawMoveDirectionLM:
142 | _startPoint.x += offset.width;
143 | break;
144 | case MDrawMoveDirectionWhole:
145 | {
146 | _startPoint = CGPointAddOffset(_startPoint, offset);
147 | _endPoint = CGPointAddOffset(_endPoint, offset);
148 | break;
149 | }
150 | default:
151 | break;
152 | }
153 | }
154 |
155 | -(void)stopMoveHandle
156 | {
157 | _moveDirection = MDrawMoveDirectionNone;
158 | }
159 |
160 | -(void)draw:(CGContextRef)ctx
161 | {
162 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
163 | CGContextSetLineWidth(ctx, self.lineWidth);
164 |
165 | CGContextBeginPath(ctx);
166 | CGContextAddRect(ctx, self.frame);
167 | CGContextStrokePath(ctx);
168 |
169 | if (self.selected)
170 | {
171 | CGRect frame = self.frame;
172 | [self drawHandle:ctx atPoint:CGRectTL(frame)];
173 | [self drawHandle:ctx atPoint:CGRectTM(frame)];
174 | [self drawHandle:ctx atPoint:CGRectTR(frame)];
175 | [self drawHandle:ctx atPoint:CGRectRM(frame)];
176 | [self drawHandle:ctx atPoint:CGRectBR(frame)];
177 | [self drawHandle:ctx atPoint:CGRectBM(frame)];
178 | [self drawHandle:ctx atPoint:CGRectBL(frame)];
179 | [self drawHandle:ctx atPoint:CGRectLM(frame)];
180 | }
181 |
182 | }
183 |
184 | -(NSString *)measureText
185 | {
186 | static NSString *widthString, *heightString, *areaString;
187 | if(!widthString)
188 | {
189 | widthString = NSLocalizedString(@"Width", nil);
190 | heightString = NSLocalizedString(@"Height", Nil);
191 | areaString = NSLocalizedString(@"Area", Nil);
192 | }
193 |
194 | CGRect frame = self.frame;
195 |
196 | return [NSString stringWithFormat:@"%@: %0.2f %@\n%@: %0.2f %@\n%@: %0.2f sq%@",
197 | widthString,
198 | [self unitConvert:frame.size.width isSquare:NO],
199 | self.unit,
200 | heightString,
201 | [self unitConvert:frame.size.height isSquare:NO],
202 | self.unit,
203 | areaString,
204 | [self unitConvert:frame.size.width * frame.size.height isSquare:YES],
205 | self.unit];
206 | }
207 |
208 | @end
209 |
--------------------------------------------------------------------------------
/MDraw/MDrawPolyline.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawPolyline.h"
23 |
24 | @implementation MDrawPolyline
25 |
26 |
27 | -(id)init
28 | {
29 | if(self = [super init])
30 | {
31 | _points = [[NSMutableArray alloc] init];
32 | _movePoint= CGPointZero;
33 | _moveHandleIndex = -1;
34 | _closePath = YES;
35 | }
36 |
37 | return self;
38 | }
39 |
40 | -(id)initWithStartPoint:(CGPoint)startPoint
41 | {
42 | self = [super initWithStartPoint:startPoint];
43 | if(self)
44 | {
45 | _points = [[NSMutableArray alloc] init];
46 | _movePoint= CGPointZero;
47 | _moveHandleIndex = -1;
48 | _closePath = YES;
49 | [_points addObject:[NSValue valueWithCGPoint:startPoint]];
50 | }
51 |
52 | return self;
53 | }
54 |
55 |
56 |
57 | -(CGRect)frame
58 | {
59 | CGPoint tl, rb;
60 |
61 | if(_points.count > 0 )
62 | {
63 | CGPoint firstPoint = [[_points objectAtIndex:0] CGPointValue];
64 | tl = firstPoint;
65 | rb = firstPoint;
66 | }
67 |
68 | for (NSValue *pValue in _points)
69 | {
70 | CGPoint p = [pValue CGPointValue];
71 |
72 | tl.x = MIN(tl.x, p.x);
73 | tl.y = MIN(tl.y, p.y);
74 | rb.x = MAX(rb.x, p.x);
75 | rb.y = MAX(rb.y, p.y);
76 | }
77 |
78 | return CGRectMake(tl.x,
79 | tl.y,
80 | fabsf(rb.x - tl.x),
81 | fabsf(rb.y - tl.y));
82 | }
83 |
84 | -(void)drawDown:(CGPoint)point
85 | {
86 |
87 | }
88 |
89 | -(void)drawMove:(CGPoint)point
90 | {
91 | _movePoint = point;
92 | }
93 |
94 | -(void)drawUp:(CGPoint)point
95 | {
96 | _movePoint = CGPointZero;
97 |
98 | BOOL isStartPoint = NO;
99 | if(_points.count > 0 )
100 | {
101 | CGPoint startPoint = [[_points objectAtIndex:0] CGPointValue];
102 | if([self isPoint:point onHandle:startPoint])
103 | {
104 | isStartPoint = YES;
105 | }
106 | }
107 |
108 | if(!isStartPoint)
109 | {
110 | [_points addObject:[NSValue valueWithCGPoint:point]];
111 | }
112 |
113 | //User close this shape by clicking the start point.
114 | if(isStartPoint && _points.count > 1)
115 | {
116 | [self finalize];
117 | }
118 | }
119 |
120 | -(void)finalize
121 | {
122 | _finalized = YES;
123 | self.selected = YES;
124 | }
125 |
126 | -(BOOL)hitOnHandle:(CGPoint)point
127 | {
128 | _moveHandleIndex = -1;
129 |
130 |
131 | if(_points.count > 0 )
132 | {
133 | for (int i = 0; i < _points.count; i++)
134 | {
135 | CGPoint handlePoint = [[_points objectAtIndex:i] CGPointValue];
136 | if([self isPoint:point onHandle:handlePoint])
137 | {
138 | _moveHandleIndex = i;
139 | return YES;
140 | }
141 | }
142 |
143 | if(CGPointInRect(point, self.frame))
144 | {
145 | _moveHandleIndex = -2;
146 | return YES;
147 | }
148 | }
149 |
150 | return NO;
151 | }
152 |
153 | -(void)moveByOffset:(CGSize)offset
154 | {
155 | if(_moveHandleIndex >= 0)
156 | {
157 | CGPoint movePoint = [[_points objectAtIndex:_moveHandleIndex] CGPointValue];
158 | movePoint = CGPointAddOffset(movePoint, offset);
159 | [_points replaceObjectAtIndex:_moveHandleIndex withObject:[NSValue valueWithCGPoint:movePoint]];
160 | }
161 | else if( _moveHandleIndex == -2) // move the shape
162 | {
163 | for (int i = 0; i < _points.count; i++)
164 | {
165 | CGPoint p = [[_points objectAtIndex:i] CGPointValue];
166 | [_points replaceObjectAtIndex:i withObject:[NSValue valueWithCGPoint:CGPointMake(p.x + offset.width, p.y + offset.height)]];
167 | }
168 | }
169 | }
170 |
171 | -(void)stopMoveHandle
172 | {
173 | _moveHandleIndex = -1;
174 | }
175 |
176 | -(void)draw:(CGContextRef)ctx
177 | {
178 | CGContextSetStrokeColorWithColor(ctx, self.color.CGColor);
179 | CGContextSetLineWidth(ctx, self.lineWidth);
180 |
181 | CGContextBeginPath(ctx);
182 | if(_points.count > 0 )
183 | {
184 | CGPoint p = [[_points objectAtIndex:0] CGPointValue];
185 | CGContextMoveToPoint(ctx, p.x, p.y);
186 |
187 | for (int i = 1; i < _points.count; i++)
188 | {
189 | CGPoint p = [[_points objectAtIndex:i] CGPointValue];
190 | CGContextAddLineToPoint(ctx, p.x, p.y);
191 | }
192 |
193 |
194 | if(!self.finalized && !CGPointEqualToPoint(_movePoint, CGPointZero))
195 | {
196 | CGContextAddLineToPoint(ctx, _movePoint.x,_movePoint.y);
197 | }
198 |
199 | //Close the shape
200 | if(self.finalized && _closePath)
201 | {
202 | CGContextClosePath(ctx);
203 | }
204 |
205 | }
206 |
207 | CGContextStrokePath(ctx);
208 |
209 | if (self.selected || !self.finalized)
210 | {
211 | for (int i = 0; i < _points.count; i++)
212 | {
213 | CGPoint p = [[_points objectAtIndex:i] CGPointValue];
214 | [self drawHandle:ctx atPoint:p];
215 | }
216 |
217 | }
218 |
219 | }
220 |
221 | -(NSString *)measureText
222 | {
223 | static NSString *lengthString, *areaString;
224 | if(!lengthString)
225 | {
226 | lengthString = NSLocalizedString(@"Length", Nil);
227 | areaString = NSLocalizedString(@"Area", Nil);
228 | }
229 |
230 | CGFloat length = CGPolygonLength(_points);
231 | CGFloat area = CGPolygonArea(_points);
232 | return [NSString stringWithFormat:@"%@: %0.2f %@\n%@: %0.2f sq%@",
233 | lengthString,
234 | [self unitConvert:length isSquare:NO],
235 | self.unit,
236 | areaString,
237 | [self unitConvert:area isSquare:YES],
238 | self.unit];
239 | }
240 |
241 | @end
242 |
--------------------------------------------------------------------------------
/MDraw/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/MDraw/MDrawMath.h:
--------------------------------------------------------------------------------
1 | //
2 | // MDrawMath.h
3 | // Motics
4 | //
5 | // Created by Gao Yongqing on 2/6/14.
6 | //
7 | //
8 |
9 |
10 |
11 | #ifndef Motics_MDrawMath_h
12 | #define Motics_MDrawMath_h
13 |
14 | #import
15 |
16 |
17 | CG_INLINE float CGPointDistance(CGPoint p1, CGPoint p2)
18 | {
19 | CGFloat dx = p2.x - p1.x;
20 | CGFloat dy = p2.y - p1.y;
21 | return sqrt(dx*dx + dy*dy);
22 | }
23 |
24 | CG_INLINE CGSize CGPointOffset(CGPoint p1, CGPoint p2)
25 | {
26 | CGFloat dx = p2.x - p1.x;
27 | CGFloat dy = p2.y - p1.y;
28 | return CGSizeMake(dx, dy);
29 | }
30 |
31 | CG_INLINE CGPoint CGPointAddOffset(CGPoint p, CGSize offset)
32 | {
33 | return CGPointMake(p.x + offset.width, p.y + offset.height);
34 | }
35 |
36 | CG_INLINE CGPoint CGPointMidPoint(CGPoint p1, CGPoint p2)
37 | {
38 | return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
39 | }
40 |
41 | CG_INLINE float CGPointToLineDistance(CGPoint p, CGPoint p1,CGPoint p2)
42 | {
43 | float a = p1.y - p2.y;
44 | float b = p2.x - p1.x;
45 | float c = (p1.x - b) * p1.y - p1.x * (p1.y + a);
46 |
47 | return fabsf(a * p.x + b * p.y + c) / sqrtf(a*a + b*b);
48 | }
49 |
50 | CG_INLINE BOOL CGPointInRect(CGPoint p, CGRect rect)
51 | {
52 | return (p.x >= rect.origin.x &&
53 | p.x <= (rect.origin.x + rect.size.width) &&
54 | p.y >= rect.origin.y &&
55 | p.y <= (rect.origin.y + rect.size.height));
56 | }
57 |
58 | CG_INLINE CGPoint CGRectTL(CGRect rect)
59 | {
60 | return rect.origin;
61 | }
62 |
63 | CG_INLINE CGPoint CGRectTM(CGRect rect)
64 | {
65 | return CGPointMake(rect.origin.x + rect.size.width * 0.5, rect.origin.y);
66 | }
67 |
68 | CG_INLINE CGPoint CGRectTR(CGRect rect)
69 | {
70 | return CGPointMake(rect.origin.x + rect.size.width, rect.origin.y);
71 | }
72 |
73 | CG_INLINE CGPoint CGRectRM(CGRect rect)
74 | {
75 | return CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height * 0.5);
76 | }
77 |
78 | CG_INLINE CGPoint CGRectBR(CGRect rect)
79 | {
80 | return CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
81 | }
82 |
83 | CG_INLINE CGPoint CGRectBM(CGRect rect)
84 | {
85 | return CGPointMake(rect.origin.x + rect.size.width * 0.5, rect.origin.y + rect.size.height);
86 | }
87 |
88 | CG_INLINE CGPoint CGRectBL(CGRect rect)
89 | {
90 | return CGPointMake(rect.origin.x , rect.origin.y + rect.size.height);
91 | }
92 |
93 | CG_INLINE CGPoint CGRectLM(CGRect rect)
94 | {
95 | return CGPointMake(rect.origin.x , rect.origin.y + rect.size.height * 0.5);
96 | }
97 |
98 | CG_INLINE CGPoint CGRectMid(CGRect rect)
99 | {
100 | return CGPointMake(rect.origin.x + rect.size.width * 0.5, rect.origin.y + rect.size.height * 0.5);
101 | }
102 |
103 | /**
104 | * 三点画圆,计算圆心X坐标
105 | * 三点确定的圆的圆心到三点的距离相等,就有以下两个不等式:
106 | * (x - x1 )^2 + (y-y1) ^2 = (x-x2)^2 + (y-y2)^2 = (x-x3)^2 + (y-y3)^2
107 | * 根据两个不等式,可以推出 x 和 y
108 | *
109 | * @param x1 x of point 1
110 | * @param y1 y of point 1
111 | * @param x2 x of point 2
112 | * @param y2 y of point 2
113 | * @param x3 x of point 3
114 | * @param y3 y of point 3
115 | *
116 | * @return x of center point
117 | */
118 | CG_INLINE CGFloat CGCenterX(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2,CGFloat x3, CGFloat y3)
119 | {
120 | CGFloat x = ((x1 * x1 + y1 * y1) * (y2 - y3) - (x2 * x2 + y2 * y2) * (y2 - y3)
121 | - (x2 * x2 + y2 * y2) * (y1 - y2) + (x3 * x3 + y3 * y3) * (y1 - y2))
122 | / (2 * ((x1 - x2) * (y2 - y3) - (x2 - x3) * (y1 - y2)));
123 |
124 | return x;
125 | }
126 |
127 | CG_INLINE CGFloat CGCenterY(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2,CGFloat x3, CGFloat y3)
128 | {
129 | CGFloat x = CGCenterX(x1, y1, x2, y2, x3, y3);
130 | CGFloat y = ((x2 * x2 + y2 * y2) - (x3 * x3 + y3 * y3) - 2 * x * (x2 - x3))
131 | / (2 * (y2 - y3));
132 |
133 | return y;
134 | }
135 |
136 | CG_INLINE CGPoint CGCenterPoint(CGPoint p1, CGPoint p2, CGPoint p3)
137 | {
138 | CGFloat x = CGCenterX(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
139 | CGFloat y = CGCenterY(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
140 |
141 | return CGPointMake(x, y);
142 | }
143 |
144 | /**
145 | * 计算圆的半径
146 | **/
147 | CG_INLINE CGFloat CGRadius(CGPoint centerPoint,CGPoint edgePoint)
148 | {
149 | return sqrtf((edgePoint.x - centerPoint.x) * (edgePoint.x - centerPoint.x) +
150 | (edgePoint.y - centerPoint.y) * (edgePoint.y - centerPoint.y));
151 | }
152 |
153 | /**
154 | * 求三点构成的角的弧度,其中中间那点(x2,y2)是角度的顶点
155 | **/
156 | CG_INLINE CGFloat CGAngleRadianS(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2, CGFloat x3, CGFloat y3)
157 | {
158 | CGFloat a1 = atan2f(y1 - y2, x1 - x2);
159 | CGFloat a2 = atan2f(y3 - y2, x3 - x2);
160 |
161 | return a2 - a1;
162 | }
163 |
164 | CG_INLINE CGFloat CGAngleRadian(CGPoint p1, CGPoint p2, CGPoint p3)
165 | {
166 | return CGAngleRadianS(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
167 | }
168 |
169 | /**
170 | * 求三点构成的角度,其中中间那点(x2,y2)是角度的顶点
171 | **/
172 | CG_INLINE CGFloat CGAngleDegreeS(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2, CGFloat x3, CGFloat y3)
173 | {
174 | CGFloat radian = CGAngleRadianS(x1, y1, x2, y2, x3, y3);
175 | CGFloat degree = radian / M_PI * 180;
176 | if (degree < 0) {
177 | return 360 + degree;
178 | }
179 | else {
180 | return degree;
181 | }
182 | }
183 |
184 | /**
185 | * 求三点构成的角的角度,其中中间那点p2是角的顶点
186 | **/
187 | CG_INLINE CGFloat CGAngleDegree(CGPoint p1, CGPoint p2, CGPoint p3)
188 | {
189 | CGFloat radian = CGAngleRadian(p1, p2, p3);
190 | CGFloat degree = radian / M_PI * 180;
191 | if (degree < 0) {
192 | return 360 + degree;
193 | }
194 | else {
195 | return degree;
196 | }
197 | }
198 |
199 | /**
200 | * 求向量的弧度
201 | * p1 为原点
202 | **/
203 | CG_INLINE CGFloat CGVectorRadian(CGPoint p1, CGPoint p2)
204 | {
205 | return atan2f(p2.y - p1.y, p2.x - p1.x);
206 | }
207 |
208 | ///
209 | /// 求角度所对应的弧上的一点
210 | ///
211 | /// 中间点的X坐标
212 | /// 中间点的Y坐标
213 | ///
214 | ///
215 | /// 这个弧的长度,一般是固定的
216 | ///
217 | CG_INLINE CGPoint CGAngleArcPointS(CGFloat xCenter, CGFloat yCenter, CGFloat x,CGFloat y, CGFloat arcLength)
218 | {
219 | CGFloat angle = atan2(y - yCenter, x - xCenter);
220 | CGFloat height = sin(angle) * arcLength;
221 | CGFloat width = cos(angle) * arcLength;
222 |
223 | return CGPointMake(xCenter + width, yCenter +height);
224 | }
225 |
226 | CG_INLINE BOOL IsLargeArc(CGFloat radian)
227 | {
228 | //如果弧度小余0,用2π - 弧度来计算
229 | CGFloat absR = radian < 0 ? 2 * M_PI + radian : radian;
230 |
231 | return absR < 0.5 * M_PI || absR > 1.5 * M_PI;
232 | }
233 |
234 | /**
235 | * 是否是逆时针
236 | **/
237 | CG_INLINE BOOL IsCounterClockwise(CGFloat radian)
238 | {
239 | //如果弧度小余0,用2π - 弧度来计算
240 | CGFloat absR = radian < 0 ? 2 * M_PI + radian : radian;
241 | return absR > 0 && absR < M_PI;
242 | }
243 |
244 |
245 | /**
246 | * 多边形的面积
247 | **/
248 | CG_INLINE CGFloat CGPolygonArea(NSArray *points)
249 | {
250 | int count = points.count;
251 | int i, j;
252 | CGFloat area = 0;
253 |
254 | for (i = 0; i < count; i++) {
255 | j = (i + 1) % count;
256 |
257 | CGPoint pi = [points[i] CGPointValue];
258 | CGPoint pj = [points[j] CGPointValue];
259 |
260 | area += pi.x * pj.y;
261 | area -= pi.y * pj.x;
262 | }
263 |
264 | area /= 2.0;
265 |
266 | return abs(area);
267 |
268 | }
269 |
270 | /**
271 | * 多边形的周长
272 | **/
273 | CG_INLINE CGFloat CGPolygonLength(NSArray *points)
274 | {
275 | if(points.count < 2)
276 | {
277 | return 0;
278 | }
279 |
280 | NSInteger count = points.count;
281 | CGFloat length = 0.0;
282 | for (int i = 1; i < count; i++)
283 | {
284 | length += CGPointDistance([points[i - 1] CGPointValue], [points[i] CGPointValue]);
285 | }
286 |
287 | return length;
288 | }
289 |
290 | /**
291 | * 闭合多边形的周长
292 | **/
293 | CG_INLINE CGFloat CGPolygonLengthClosed(NSArray *points)
294 | {
295 | if(points.count < 2)
296 | {
297 | return 0;
298 | }
299 |
300 | CGFloat length = CGPolygonLength(points);
301 | // Add last line length
302 | length += CGPointDistance([points[0] CGPointValue], [points[points.count -1] CGPointValue]);
303 |
304 | return length;
305 | }
306 |
307 | CG_INLINE CGPoint CGArcPointParameter(CGPoint p1, CGPoint p2, CGPoint p3, float u)
308 | {
309 | CGFloat x = (powf(1 - u, 2) * p1.x) +
310 | (2 * u * (1 - u) * p2.x ) +
311 | (powf(u, 2) * p3.x);
312 |
313 | CGFloat y = (powf(1 - u, 2) * p1.y) +
314 | (2 * u * (1 - u) * p2.y ) +
315 | (powf(u, 2) * p3.y);
316 |
317 | return CGPointMake(x, y);
318 | }
319 |
320 | CG_INLINE float CGArcLength(CGPoint p1, CGPoint p2, CGPoint p3)
321 | {
322 | float u = 0;
323 | float length = 0;
324 | CGPoint pt1 = CGArcPointParameter(p1, p2, p3, u);
325 | for (int i = 0; i < 10; i++) {
326 | u += 0.1;
327 | if ( u > 1 ) {
328 | u = 1;
329 | }
330 | CGPoint pt2 = CGArcPointParameter(p1, p2, p3, u);
331 | length += CGPointDistance(pt1, pt2);
332 | pt1 = pt2;
333 | }
334 | return length;
335 | }
336 |
337 |
338 |
339 |
340 |
341 | #endif
342 |
--------------------------------------------------------------------------------
/MDraw/MDrawView.m:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2013 xmkevin
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | // this software and associated documentation files (the "Software"), to deal in
7 | // the Software without restriction, including without limitation the rights to
8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | // the Software, and to permit persons to whom the Software is furnished to do so,
10 | // 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, FITNESS
17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #import "MDrawView.h"
23 | #import "MUndoManager.h"
24 |
25 | @implementation MDrawView
26 | {
27 | NSMutableArray *_tools;
28 | Class _drawToolClass;
29 | MUndoManager *_undoManager;
30 | BOOL _isMoved; // Is mouse or figure moved
31 | CGFloat _lineWidth;
32 | BOOL _enableGesture;
33 | BOOL _showMeasurement;
34 | NSString *_unit;
35 | }
36 |
37 | @synthesize color;
38 | @synthesize calibration = _calibration;
39 | @synthesize isDirty = _isDirty;
40 |
41 |
42 | -(id)initWithCoder:(NSCoder *)aDecoder
43 | {
44 | if(self = [super initWithCoder:aDecoder])
45 | {
46 | // Initialization code
47 | _tools = [[NSMutableArray alloc] init];
48 | _undoManager = [[MUndoManager alloc] initWithTools:_tools];
49 |
50 | self.color = [UIColor colorWithRed:0 green:255 blue:0 alpha:0.6];
51 | _lineWidth = 3;
52 | _calibration = 0;
53 |
54 | _enableGesture = YES;
55 | [self initGestures];
56 | }
57 |
58 | return self;
59 | }
60 |
61 | - (id)initWithFrame:(CGRect)frame
62 | {
63 | self = [super initWithFrame:frame];
64 | if (self) {
65 | // Initialization code
66 | _tools = [[NSMutableArray alloc] init];
67 | [self initGestures];
68 | }
69 | return self;
70 | }
71 |
72 | - (void)refreshCalibrations
73 | {
74 | for (MDrawTool *tool in _tools)
75 | {
76 | tool.calibration = self.calibration;
77 | tool.unit = self.unit;
78 | tool.showMeasurement = self.showMeasurement;
79 | }
80 |
81 | [self setNeedsDisplay];
82 | }
83 |
84 | -(BOOL)hasTools
85 | {
86 | return _tools.count > 0;
87 | }
88 |
89 | -(NSArray *)tools
90 | {
91 | return _tools;
92 | }
93 |
94 | -(CGFloat)lineWidth
95 | {
96 | return _lineWidth;
97 | }
98 |
99 | -(void)setLineWidth:(CGFloat)lineWidth
100 | {
101 | if(_activeTool)
102 | {
103 | _activeTool.lineWidth = lineWidth;
104 |
105 | [self setNeedsDisplay];
106 | }
107 |
108 | _lineWidth = lineWidth;
109 | }
110 |
111 | -(BOOL)enableGesture
112 | {
113 | return _enableGesture;
114 | }
115 |
116 | -(void)setEnableGesture:(BOOL)enableGesture
117 | {
118 | _enableGesture = enableGesture;
119 |
120 | for (UIGestureRecognizer *g in self.gestureRecognizers) {
121 | g.enabled = _enableGesture;
122 | }
123 |
124 | self.multipleTouchEnabled = _enableGesture;
125 | }
126 |
127 | -(BOOL)showMeasurement
128 | {
129 | return _showMeasurement;
130 | }
131 |
132 | -(void)setShowMeasurement:(BOOL)showMeasurement
133 | {
134 | _showMeasurement = showMeasurement;
135 |
136 | for (MDrawTool *tool in _tools) {
137 | tool.showMeasurement = showMeasurement;
138 | }
139 |
140 | [self setNeedsDisplay];
141 |
142 | }
143 |
144 | - (CGFloat)calibration
145 | {
146 | return _calibration;
147 | }
148 |
149 | - (void)setCalibration:(CGFloat)calibration
150 | {
151 | _calibration = calibration;
152 |
153 | [self refreshCalibrations];
154 | }
155 |
156 | -(NSString *)unit
157 | {
158 | if(_unit == Nil)
159 | {
160 | _unit = @"px";
161 | }
162 |
163 | return _unit;
164 | }
165 |
166 | -(void)setUnit:(NSString *)unit
167 | {
168 | _unit = unit;
169 |
170 | [self refreshCalibrations];
171 | }
172 |
173 |
174 | -(BOOL)undo
175 | {
176 | if([_undoManager undo])
177 | {
178 | [self setNeedsDisplay];
179 | return YES;
180 | }
181 |
182 | return NO;
183 | }
184 |
185 | -(BOOL)redo
186 | {
187 | if([_undoManager redo])
188 | {
189 | [self setNeedsDisplay];
190 | return YES;
191 | }
192 |
193 | return NO;
194 | }
195 |
196 | - (void)drawRect:(CGRect)rect
197 | {
198 | if (_tools && _tools.count > 0) {
199 | // Drawing code
200 | CGContextRef ctx = UIGraphicsGetCurrentContext();
201 | //CGContextClearRect(ctx,self.frame);
202 | for (MDrawTool *tool in _tools)
203 | {
204 | [tool draw:ctx];
205 | [tool drawMeasurement:ctx];
206 | }
207 | }
208 | }
209 |
210 | -(void)beginDrawingForType:(Class)toolType
211 | {
212 | if(toolType == Nil)
213 | {
214 | _drawToolClass = Nil;
215 | _drawing = NO;
216 |
217 | return;
218 | }
219 |
220 | if(_activeTool)
221 | {
222 | _activeTool.selected = NO;
223 | _activeTool = Nil;
224 | [self setNeedsDisplay];
225 | }
226 |
227 | _drawToolClass = toolType;
228 | _drawing = YES;
229 | }
230 |
231 | -(void)finalizeDrawing
232 | {
233 | [_activeTool finalize];
234 | _drawing = NO;
235 | [self setNeedsDisplay];
236 | }
237 |
238 | -(void)deleteCurrentTool
239 | {
240 | if(_activeTool)
241 | {
242 | [_undoManager removeTool:_activeTool];
243 | _activeTool = Nil;
244 |
245 | _isDirty = YES;
246 |
247 | [self setNeedsDisplay];
248 | }
249 | }
250 |
251 | -(void)clearTools
252 | {
253 | [_tools removeAllObjects];
254 | [_undoManager reset];
255 | [self setNeedsDisplay];
256 | }
257 |
258 | -(void)selectNone
259 | {
260 | if(_activeTool)
261 | {
262 | _activeTool.selected = NO;
263 | [self setNeedsDisplay];
264 | }
265 | }
266 |
267 | #pragma mark - private methods
268 |
269 | -(void)initGestures
270 | {
271 | UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
272 | tapGesture.numberOfTouchesRequired = 1;
273 | tapGesture.delegate = self;
274 | [self addGestureRecognizer:tapGesture];
275 | }
276 |
277 | -(void)handleTapGesture:(UITapGestureRecognizer *)gesture
278 | {
279 | CGPoint point = [gesture locationInView:self];
280 | if(_drawing)
281 | {
282 | [self drawUp:point];
283 | [self setNeedsDisplay];
284 | }
285 | else
286 | {
287 | [self selectTool:point];
288 | }
289 | }
290 |
291 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
292 | {
293 | UITouch *touch = [[event allTouches] anyObject];
294 | CGPoint point = [touch locationInView:self];
295 |
296 | [self drawDown:point];
297 |
298 |
299 | [self.nextResponder touchesBegan:touches withEvent:event];
300 | }
301 |
302 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
303 | {
304 | UITouch *touch = [[event allTouches] anyObject];
305 | CGPoint prePoint = [touch previousLocationInView:self];
306 | CGPoint point = [touch locationInView:self];
307 |
308 | [self drawMoveFromPoint:prePoint toPoint:point];
309 |
310 | [self.nextResponder touchesMoved:touches withEvent:event];
311 | }
312 |
313 | -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
314 | {
315 | UITouch *touch = [[event allTouches] anyObject];
316 | CGPoint point = [touch locationInView:self];
317 |
318 | [self drawUp:point];
319 |
320 | [self.nextResponder touchesEnded:touches withEvent:event];
321 | }
322 |
323 | #pragma mark - draw
324 |
325 | -(void)drawDown:(CGPoint)point
326 | {
327 | _isMoved = NO;
328 |
329 | if(self.drawing)
330 | {
331 | if(_activeTool && !_activeTool.finalized && _drawing)
332 | {
333 | [_activeTool drawDown:point];
334 | }
335 | else
336 | {
337 | _activeTool = [[_drawToolClass alloc] initWithStartPoint:point];
338 | _activeTool.color = self.color;
339 | _activeTool.lineWidth = self.lineWidth;
340 | _activeTool.showMeasurement = self.showMeasurement;
341 | _activeTool.unit = self.unit;
342 | _activeTool.calibration = self.calibration;
343 | //Comment tool is special, it should interate with alert views.
344 | if([_activeTool isKindOfClass:[MDrawComment class]])
345 | {
346 | MDrawComment *comment = (MDrawComment *)_activeTool;
347 | comment.delegate = self;
348 | }
349 |
350 | [_undoManager addTool:_activeTool];
351 |
352 | _isDirty = YES;
353 | }
354 |
355 | [self setNeedsDisplay];
356 | }
357 | else
358 | {
359 | [self.activeTool hitOnHandle:point];
360 | }
361 | }
362 |
363 | -(void)drawMoveFromPoint:(CGPoint)srcPoint toPoint:(CGPoint)point
364 | {
365 | _isMoved = YES;
366 | _isDirty = YES;
367 |
368 | if(self.drawing)
369 | {
370 | [self.activeTool drawMove:point];
371 | }
372 | else
373 | {
374 | CGSize offset = CGPointOffset(srcPoint, point);
375 | [self.activeTool moveByOffset:offset];
376 | }
377 |
378 | [self setNeedsDisplay];
379 | }
380 |
381 | -(void)drawUp:(CGPoint)point
382 | {
383 | if(self.drawing)
384 | {
385 | [self.activeTool drawUp:point];
386 |
387 | if(self.activeTool.finalized)
388 | {
389 | _drawing = NO;
390 | }
391 | }
392 | else
393 | {
394 | if(_isMoved)
395 | {
396 | [self.activeTool stopMoveHandle];
397 | }
398 | else
399 | {
400 | //Click or tap
401 | [self selectTool:point];
402 | }
403 |
404 | }
405 |
406 | [self setNeedsDisplay];
407 |
408 | _isMoved = NO;
409 | }
410 |
411 | #pragma mark - hit tests
412 |
413 | -(void)selectTool:(CGPoint)point
414 | {
415 | BOOL hasSelected = NO;
416 | _activeTool = Nil;
417 |
418 | for (int i = _tools.count -1; i >= 0; i--)
419 | {
420 | MDrawTool *tool = [_tools objectAtIndex:i];
421 |
422 | if([tool hitTest:point] && !hasSelected)
423 | {
424 | hasSelected = YES;
425 |
426 | tool.selected = YES;
427 | _activeTool = tool;
428 | }
429 | else
430 | {
431 | tool.selected = NO;
432 | }
433 | }
434 |
435 | [self setNeedsDisplay];
436 | }
437 |
438 | #pragma mark - draw comment protocol
439 |
440 | -(void)drawTool:(MDrawTool *)tool isAdded:(BOOL)added
441 | {
442 | if(added)
443 | {
444 | [self setNeedsDisplay];
445 | }
446 | else
447 | {
448 | [self deleteCurrentTool];
449 | }
450 | }
451 |
452 |
453 | @end
454 |
--------------------------------------------------------------------------------
/MDraw.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 330B58CA19B98CFD0078C2FF /* MDrawAngle.m in Sources */ = {isa = PBXBuildFile; fileRef = 330B58BF19B98CFD0078C2FF /* MDrawAngle.m */; };
11 | 330B58CB19B98CFD0078C2FF /* MDrawArc.m in Sources */ = {isa = PBXBuildFile; fileRef = 330B58C119B98CFD0078C2FF /* MDrawArc.m */; };
12 | 330B58CC19B98CFD0078C2FF /* MDrawComment.m in Sources */ = {isa = PBXBuildFile; fileRef = 330B58C319B98CFD0078C2FF /* MDrawComment.m */; };
13 | 330B58CD19B98CFD0078C2FF /* MDrawFatArrow.m in Sources */ = {isa = PBXBuildFile; fileRef = 330B58C519B98CFD0078C2FF /* MDrawFatArrow.m */; };
14 | 330B58CE19B98CFD0078C2FF /* MDrawText.m in Sources */ = {isa = PBXBuildFile; fileRef = 330B58C819B98CFD0078C2FF /* MDrawText.m */; };
15 | 330B58D119B9B00E0078C2FF /* MDrawMeasurementInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 330B58D019B9B00E0078C2FF /* MDrawMeasurementInfo.m */; };
16 | 3317D07B17C6F40D008443C6 /* MDrawRect.m in Sources */ = {isa = PBXBuildFile; fileRef = 3317D07A17C6F40D008443C6 /* MDrawRect.m */; };
17 | 3317D07E17C74AF3008443C6 /* MDrawEllipse.m in Sources */ = {isa = PBXBuildFile; fileRef = 3317D07D17C74AF3008443C6 /* MDrawEllipse.m */; };
18 | 33AEF08417D07B21003C376A /* MDrawArrow.m in Sources */ = {isa = PBXBuildFile; fileRef = 33AEF08317D07B21003C376A /* MDrawArrow.m */; };
19 | 33C0988317CD8DB400C3EC1B /* MUndoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C0988217CD8DB400C3EC1B /* MUndoManager.m */; };
20 | 33D7940A17CADB97007E2E94 /* MDrawFreeline.m in Sources */ = {isa = PBXBuildFile; fileRef = 33D7940917CADB97007E2E94 /* MDrawFreeline.m */; };
21 | 33D7940D17CAFA76007E2E94 /* MDrawPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 33D7940C17CAFA76007E2E94 /* MDrawPolyline.m */; };
22 | 33DE966017C466B600A6F222 /* MDrawLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 33DE965F17C466B600A6F222 /* MDrawLine.m */; };
23 | 33E28B7817C20DA200EFC071 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33E28B7717C20DA200EFC071 /* Foundation.framework */; };
24 | 33E28B7A17C20DA200EFC071 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33E28B7917C20DA200EFC071 /* CoreGraphics.framework */; };
25 | 33E28B7C17C20DA200EFC071 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33E28B7B17C20DA200EFC071 /* UIKit.framework */; };
26 | 33E28B8217C20DA200EFC071 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 33E28B8017C20DA200EFC071 /* InfoPlist.strings */; };
27 | 33E28B8417C20DA200EFC071 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E28B8317C20DA200EFC071 /* main.m */; };
28 | 33E28B8817C20DA200EFC071 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E28B8717C20DA200EFC071 /* AppDelegate.m */; };
29 | 33E28B8B17C20DA200EFC071 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 33E28B8917C20DA200EFC071 /* Main.storyboard */; };
30 | 33E28B8E17C20DA200EFC071 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E28B8D17C20DA200EFC071 /* ViewController.m */; };
31 | 33E28B9017C20DA200EFC071 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33E28B8F17C20DA200EFC071 /* Images.xcassets */; };
32 | 33E28B9717C20DA200EFC071 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33E28B9617C20DA200EFC071 /* XCTest.framework */; };
33 | 33E28B9817C20DA200EFC071 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33E28B7717C20DA200EFC071 /* Foundation.framework */; };
34 | 33E28B9917C20DA200EFC071 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33E28B7B17C20DA200EFC071 /* UIKit.framework */; };
35 | 33E28BA117C20DA200EFC071 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 33E28B9F17C20DA200EFC071 /* InfoPlist.strings */; };
36 | 33E28BA317C20DA200EFC071 /* MDrawTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E28BA217C20DA200EFC071 /* MDrawTests.m */; };
37 | 33E28BAF17C20E6D00EFC071 /* MDrawTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E28BAE17C20E6D00EFC071 /* MDrawTool.m */; };
38 | 33E28BB217C2140B00EFC071 /* MDrawView.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E28BB117C2140B00EFC071 /* MDrawView.m */; };
39 | /* End PBXBuildFile section */
40 |
41 | /* Begin PBXContainerItemProxy section */
42 | 33E28B9A17C20DA200EFC071 /* PBXContainerItemProxy */ = {
43 | isa = PBXContainerItemProxy;
44 | containerPortal = 33E28B6C17C20DA200EFC071 /* Project object */;
45 | proxyType = 1;
46 | remoteGlobalIDString = 33E28B7317C20DA200EFC071;
47 | remoteInfo = MDraw;
48 | };
49 | /* End PBXContainerItemProxy section */
50 |
51 | /* Begin PBXFileReference section */
52 | 330B58BE19B98CFD0078C2FF /* MDrawAngle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawAngle.h; sourceTree = ""; };
53 | 330B58BF19B98CFD0078C2FF /* MDrawAngle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawAngle.m; sourceTree = ""; };
54 | 330B58C019B98CFD0078C2FF /* MDrawArc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawArc.h; sourceTree = ""; };
55 | 330B58C119B98CFD0078C2FF /* MDrawArc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawArc.m; sourceTree = ""; };
56 | 330B58C219B98CFD0078C2FF /* MDrawComment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawComment.h; sourceTree = ""; };
57 | 330B58C319B98CFD0078C2FF /* MDrawComment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawComment.m; sourceTree = ""; };
58 | 330B58C419B98CFD0078C2FF /* MDrawFatArrow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawFatArrow.h; sourceTree = ""; };
59 | 330B58C519B98CFD0078C2FF /* MDrawFatArrow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawFatArrow.m; sourceTree = ""; };
60 | 330B58C619B98CFD0078C2FF /* MDrawMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawMath.h; sourceTree = ""; };
61 | 330B58C719B98CFD0078C2FF /* MDrawText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawText.h; sourceTree = ""; };
62 | 330B58C819B98CFD0078C2FF /* MDrawText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawText.m; sourceTree = ""; };
63 | 330B58C919B98CFD0078C2FF /* MDrawTool_Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawTool_Subclass.h; sourceTree = ""; };
64 | 330B58CF19B9B00E0078C2FF /* MDrawMeasurementInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawMeasurementInfo.h; sourceTree = ""; };
65 | 330B58D019B9B00E0078C2FF /* MDrawMeasurementInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawMeasurementInfo.m; sourceTree = ""; };
66 | 3317D07917C6F40D008443C6 /* MDrawRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawRect.h; sourceTree = ""; };
67 | 3317D07A17C6F40D008443C6 /* MDrawRect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawRect.m; sourceTree = ""; };
68 | 3317D07C17C74AF3008443C6 /* MDrawEllipse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawEllipse.h; sourceTree = ""; };
69 | 3317D07D17C74AF3008443C6 /* MDrawEllipse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawEllipse.m; sourceTree = ""; };
70 | 33AEF08217D07B21003C376A /* MDrawArrow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawArrow.h; sourceTree = ""; };
71 | 33AEF08317D07B21003C376A /* MDrawArrow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawArrow.m; sourceTree = ""; };
72 | 33C0988117CD8DB400C3EC1B /* MUndoManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MUndoManager.h; sourceTree = ""; };
73 | 33C0988217CD8DB400C3EC1B /* MUndoManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MUndoManager.m; sourceTree = ""; };
74 | 33D7940817CADB97007E2E94 /* MDrawFreeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawFreeline.h; sourceTree = ""; };
75 | 33D7940917CADB97007E2E94 /* MDrawFreeline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawFreeline.m; sourceTree = ""; };
76 | 33D7940B17CAFA76007E2E94 /* MDrawPolyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawPolyline.h; sourceTree = ""; };
77 | 33D7940C17CAFA76007E2E94 /* MDrawPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawPolyline.m; sourceTree = ""; };
78 | 33DE965E17C466B600A6F222 /* MDrawLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawLine.h; sourceTree = ""; };
79 | 33DE965F17C466B600A6F222 /* MDrawLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawLine.m; sourceTree = ""; };
80 | 33E28B7417C20DA200EFC071 /* MDraw.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MDraw.app; sourceTree = BUILT_PRODUCTS_DIR; };
81 | 33E28B7717C20DA200EFC071 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
82 | 33E28B7917C20DA200EFC071 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
83 | 33E28B7B17C20DA200EFC071 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
84 | 33E28B7F17C20DA200EFC071 /* MDraw-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MDraw-Info.plist"; sourceTree = ""; };
85 | 33E28B8117C20DA200EFC071 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
86 | 33E28B8317C20DA200EFC071 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
87 | 33E28B8517C20DA200EFC071 /* MDraw-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MDraw-Prefix.pch"; sourceTree = ""; };
88 | 33E28B8617C20DA200EFC071 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
89 | 33E28B8717C20DA200EFC071 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
90 | 33E28B8A17C20DA200EFC071 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
91 | 33E28B8C17C20DA200EFC071 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
92 | 33E28B8D17C20DA200EFC071 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
93 | 33E28B8F17C20DA200EFC071 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
94 | 33E28B9517C20DA200EFC071 /* MDrawTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MDrawTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
95 | 33E28B9617C20DA200EFC071 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
96 | 33E28B9E17C20DA200EFC071 /* MDrawTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MDrawTests-Info.plist"; sourceTree = ""; };
97 | 33E28BA017C20DA200EFC071 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
98 | 33E28BA217C20DA200EFC071 /* MDrawTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MDrawTests.m; sourceTree = ""; };
99 | 33E28BAD17C20E6D00EFC071 /* MDrawTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawTool.h; sourceTree = ""; };
100 | 33E28BAE17C20E6D00EFC071 /* MDrawTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawTool.m; sourceTree = ""; };
101 | 33E28BB017C2140B00EFC071 /* MDrawView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDrawView.h; sourceTree = ""; };
102 | 33E28BB117C2140B00EFC071 /* MDrawView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDrawView.m; sourceTree = ""; };
103 | /* End PBXFileReference section */
104 |
105 | /* Begin PBXFrameworksBuildPhase section */
106 | 33E28B7117C20DA200EFC071 /* Frameworks */ = {
107 | isa = PBXFrameworksBuildPhase;
108 | buildActionMask = 2147483647;
109 | files = (
110 | 33E28B7A17C20DA200EFC071 /* CoreGraphics.framework in Frameworks */,
111 | 33E28B7C17C20DA200EFC071 /* UIKit.framework in Frameworks */,
112 | 33E28B7817C20DA200EFC071 /* Foundation.framework in Frameworks */,
113 | );
114 | runOnlyForDeploymentPostprocessing = 0;
115 | };
116 | 33E28B9217C20DA200EFC071 /* Frameworks */ = {
117 | isa = PBXFrameworksBuildPhase;
118 | buildActionMask = 2147483647;
119 | files = (
120 | 33E28B9717C20DA200EFC071 /* XCTest.framework in Frameworks */,
121 | 33E28B9917C20DA200EFC071 /* UIKit.framework in Frameworks */,
122 | 33E28B9817C20DA200EFC071 /* Foundation.framework in Frameworks */,
123 | );
124 | runOnlyForDeploymentPostprocessing = 0;
125 | };
126 | /* End PBXFrameworksBuildPhase section */
127 |
128 | /* Begin PBXGroup section */
129 | 33E28B6B17C20DA200EFC071 = {
130 | isa = PBXGroup;
131 | children = (
132 | 33E28B7D17C20DA200EFC071 /* MDraw */,
133 | 33E28B9C17C20DA200EFC071 /* MDrawTests */,
134 | 33E28B7617C20DA200EFC071 /* Frameworks */,
135 | 33E28B7517C20DA200EFC071 /* Products */,
136 | );
137 | sourceTree = "";
138 | };
139 | 33E28B7517C20DA200EFC071 /* Products */ = {
140 | isa = PBXGroup;
141 | children = (
142 | 33E28B7417C20DA200EFC071 /* MDraw.app */,
143 | 33E28B9517C20DA200EFC071 /* MDrawTests.xctest */,
144 | );
145 | name = Products;
146 | sourceTree = "";
147 | };
148 | 33E28B7617C20DA200EFC071 /* Frameworks */ = {
149 | isa = PBXGroup;
150 | children = (
151 | 33E28B7717C20DA200EFC071 /* Foundation.framework */,
152 | 33E28B7917C20DA200EFC071 /* CoreGraphics.framework */,
153 | 33E28B7B17C20DA200EFC071 /* UIKit.framework */,
154 | 33E28B9617C20DA200EFC071 /* XCTest.framework */,
155 | );
156 | name = Frameworks;
157 | sourceTree = "";
158 | };
159 | 33E28B7D17C20DA200EFC071 /* MDraw */ = {
160 | isa = PBXGroup;
161 | children = (
162 | 33E28BAC17C20DB500EFC071 /* DrawTool */,
163 | 33E28B8617C20DA200EFC071 /* AppDelegate.h */,
164 | 33E28B8717C20DA200EFC071 /* AppDelegate.m */,
165 | 33E28B8917C20DA200EFC071 /* Main.storyboard */,
166 | 33E28B8C17C20DA200EFC071 /* ViewController.h */,
167 | 33E28B8D17C20DA200EFC071 /* ViewController.m */,
168 | 33E28B8F17C20DA200EFC071 /* Images.xcassets */,
169 | 33E28B7E17C20DA200EFC071 /* Supporting Files */,
170 | );
171 | path = MDraw;
172 | sourceTree = "";
173 | };
174 | 33E28B7E17C20DA200EFC071 /* Supporting Files */ = {
175 | isa = PBXGroup;
176 | children = (
177 | 33E28B7F17C20DA200EFC071 /* MDraw-Info.plist */,
178 | 33E28B8017C20DA200EFC071 /* InfoPlist.strings */,
179 | 33E28B8317C20DA200EFC071 /* main.m */,
180 | 33E28B8517C20DA200EFC071 /* MDraw-Prefix.pch */,
181 | );
182 | name = "Supporting Files";
183 | sourceTree = "";
184 | };
185 | 33E28B9C17C20DA200EFC071 /* MDrawTests */ = {
186 | isa = PBXGroup;
187 | children = (
188 | 33E28BA217C20DA200EFC071 /* MDrawTests.m */,
189 | 33E28B9D17C20DA200EFC071 /* Supporting Files */,
190 | );
191 | path = MDrawTests;
192 | sourceTree = "";
193 | };
194 | 33E28B9D17C20DA200EFC071 /* Supporting Files */ = {
195 | isa = PBXGroup;
196 | children = (
197 | 33E28B9E17C20DA200EFC071 /* MDrawTests-Info.plist */,
198 | 33E28B9F17C20DA200EFC071 /* InfoPlist.strings */,
199 | );
200 | name = "Supporting Files";
201 | sourceTree = "";
202 | };
203 | 33E28BAC17C20DB500EFC071 /* DrawTool */ = {
204 | isa = PBXGroup;
205 | children = (
206 | 330B58BE19B98CFD0078C2FF /* MDrawAngle.h */,
207 | 330B58BF19B98CFD0078C2FF /* MDrawAngle.m */,
208 | 330B58C019B98CFD0078C2FF /* MDrawArc.h */,
209 | 330B58C119B98CFD0078C2FF /* MDrawArc.m */,
210 | 330B58C219B98CFD0078C2FF /* MDrawComment.h */,
211 | 330B58C319B98CFD0078C2FF /* MDrawComment.m */,
212 | 330B58C419B98CFD0078C2FF /* MDrawFatArrow.h */,
213 | 330B58C519B98CFD0078C2FF /* MDrawFatArrow.m */,
214 | 330B58C619B98CFD0078C2FF /* MDrawMath.h */,
215 | 330B58C719B98CFD0078C2FF /* MDrawText.h */,
216 | 330B58C819B98CFD0078C2FF /* MDrawText.m */,
217 | 330B58C919B98CFD0078C2FF /* MDrawTool_Subclass.h */,
218 | 33E28BAD17C20E6D00EFC071 /* MDrawTool.h */,
219 | 33E28BAE17C20E6D00EFC071 /* MDrawTool.m */,
220 | 33E28BB017C2140B00EFC071 /* MDrawView.h */,
221 | 33E28BB117C2140B00EFC071 /* MDrawView.m */,
222 | 33DE965E17C466B600A6F222 /* MDrawLine.h */,
223 | 33DE965F17C466B600A6F222 /* MDrawLine.m */,
224 | 3317D07917C6F40D008443C6 /* MDrawRect.h */,
225 | 3317D07A17C6F40D008443C6 /* MDrawRect.m */,
226 | 3317D07C17C74AF3008443C6 /* MDrawEllipse.h */,
227 | 3317D07D17C74AF3008443C6 /* MDrawEllipse.m */,
228 | 33D7940817CADB97007E2E94 /* MDrawFreeline.h */,
229 | 33D7940917CADB97007E2E94 /* MDrawFreeline.m */,
230 | 33D7940B17CAFA76007E2E94 /* MDrawPolyline.h */,
231 | 33D7940C17CAFA76007E2E94 /* MDrawPolyline.m */,
232 | 33C0988117CD8DB400C3EC1B /* MUndoManager.h */,
233 | 33C0988217CD8DB400C3EC1B /* MUndoManager.m */,
234 | 33AEF08217D07B21003C376A /* MDrawArrow.h */,
235 | 33AEF08317D07B21003C376A /* MDrawArrow.m */,
236 | 330B58CF19B9B00E0078C2FF /* MDrawMeasurementInfo.h */,
237 | 330B58D019B9B00E0078C2FF /* MDrawMeasurementInfo.m */,
238 | );
239 | name = DrawTool;
240 | sourceTree = "";
241 | };
242 | /* End PBXGroup section */
243 |
244 | /* Begin PBXNativeTarget section */
245 | 33E28B7317C20DA200EFC071 /* MDraw */ = {
246 | isa = PBXNativeTarget;
247 | buildConfigurationList = 33E28BA617C20DA200EFC071 /* Build configuration list for PBXNativeTarget "MDraw" */;
248 | buildPhases = (
249 | 33E28B7017C20DA200EFC071 /* Sources */,
250 | 33E28B7117C20DA200EFC071 /* Frameworks */,
251 | 33E28B7217C20DA200EFC071 /* Resources */,
252 | );
253 | buildRules = (
254 | );
255 | dependencies = (
256 | );
257 | name = MDraw;
258 | productName = MDraw;
259 | productReference = 33E28B7417C20DA200EFC071 /* MDraw.app */;
260 | productType = "com.apple.product-type.application";
261 | };
262 | 33E28B9417C20DA200EFC071 /* MDrawTests */ = {
263 | isa = PBXNativeTarget;
264 | buildConfigurationList = 33E28BA917C20DA200EFC071 /* Build configuration list for PBXNativeTarget "MDrawTests" */;
265 | buildPhases = (
266 | 33E28B9117C20DA200EFC071 /* Sources */,
267 | 33E28B9217C20DA200EFC071 /* Frameworks */,
268 | 33E28B9317C20DA200EFC071 /* Resources */,
269 | );
270 | buildRules = (
271 | );
272 | dependencies = (
273 | 33E28B9B17C20DA200EFC071 /* PBXTargetDependency */,
274 | );
275 | name = MDrawTests;
276 | productName = MDrawTests;
277 | productReference = 33E28B9517C20DA200EFC071 /* MDrawTests.xctest */;
278 | productType = "com.apple.product-type.bundle.unit-test";
279 | };
280 | /* End PBXNativeTarget section */
281 |
282 | /* Begin PBXProject section */
283 | 33E28B6C17C20DA200EFC071 /* Project object */ = {
284 | isa = PBXProject;
285 | attributes = {
286 | LastUpgradeCheck = 0500;
287 | ORGANIZATIONNAME = "Motic China Group Co., Ltd";
288 | TargetAttributes = {
289 | 33E28B9417C20DA200EFC071 = {
290 | TestTargetID = 33E28B7317C20DA200EFC071;
291 | };
292 | };
293 | };
294 | buildConfigurationList = 33E28B6F17C20DA200EFC071 /* Build configuration list for PBXProject "MDraw" */;
295 | compatibilityVersion = "Xcode 3.2";
296 | developmentRegion = English;
297 | hasScannedForEncodings = 0;
298 | knownRegions = (
299 | en,
300 | Base,
301 | );
302 | mainGroup = 33E28B6B17C20DA200EFC071;
303 | productRefGroup = 33E28B7517C20DA200EFC071 /* Products */;
304 | projectDirPath = "";
305 | projectRoot = "";
306 | targets = (
307 | 33E28B7317C20DA200EFC071 /* MDraw */,
308 | 33E28B9417C20DA200EFC071 /* MDrawTests */,
309 | );
310 | };
311 | /* End PBXProject section */
312 |
313 | /* Begin PBXResourcesBuildPhase section */
314 | 33E28B7217C20DA200EFC071 /* Resources */ = {
315 | isa = PBXResourcesBuildPhase;
316 | buildActionMask = 2147483647;
317 | files = (
318 | 33E28B9017C20DA200EFC071 /* Images.xcassets in Resources */,
319 | 33E28B8217C20DA200EFC071 /* InfoPlist.strings in Resources */,
320 | 33E28B8B17C20DA200EFC071 /* Main.storyboard in Resources */,
321 | );
322 | runOnlyForDeploymentPostprocessing = 0;
323 | };
324 | 33E28B9317C20DA200EFC071 /* Resources */ = {
325 | isa = PBXResourcesBuildPhase;
326 | buildActionMask = 2147483647;
327 | files = (
328 | 33E28BA117C20DA200EFC071 /* InfoPlist.strings in Resources */,
329 | );
330 | runOnlyForDeploymentPostprocessing = 0;
331 | };
332 | /* End PBXResourcesBuildPhase section */
333 |
334 | /* Begin PBXSourcesBuildPhase section */
335 | 33E28B7017C20DA200EFC071 /* Sources */ = {
336 | isa = PBXSourcesBuildPhase;
337 | buildActionMask = 2147483647;
338 | files = (
339 | 330B58CB19B98CFD0078C2FF /* MDrawArc.m in Sources */,
340 | 330B58CE19B98CFD0078C2FF /* MDrawText.m in Sources */,
341 | 33E28B8E17C20DA200EFC071 /* ViewController.m in Sources */,
342 | 33E28B8817C20DA200EFC071 /* AppDelegate.m in Sources */,
343 | 330B58CA19B98CFD0078C2FF /* MDrawAngle.m in Sources */,
344 | 3317D07E17C74AF3008443C6 /* MDrawEllipse.m in Sources */,
345 | 33D7940D17CAFA76007E2E94 /* MDrawPolyline.m in Sources */,
346 | 33E28BB217C2140B00EFC071 /* MDrawView.m in Sources */,
347 | 330B58D119B9B00E0078C2FF /* MDrawMeasurementInfo.m in Sources */,
348 | 33E28B8417C20DA200EFC071 /* main.m in Sources */,
349 | 3317D07B17C6F40D008443C6 /* MDrawRect.m in Sources */,
350 | 33D7940A17CADB97007E2E94 /* MDrawFreeline.m in Sources */,
351 | 33C0988317CD8DB400C3EC1B /* MUndoManager.m in Sources */,
352 | 330B58CD19B98CFD0078C2FF /* MDrawFatArrow.m in Sources */,
353 | 33AEF08417D07B21003C376A /* MDrawArrow.m in Sources */,
354 | 33E28BAF17C20E6D00EFC071 /* MDrawTool.m in Sources */,
355 | 33DE966017C466B600A6F222 /* MDrawLine.m in Sources */,
356 | 330B58CC19B98CFD0078C2FF /* MDrawComment.m in Sources */,
357 | );
358 | runOnlyForDeploymentPostprocessing = 0;
359 | };
360 | 33E28B9117C20DA200EFC071 /* Sources */ = {
361 | isa = PBXSourcesBuildPhase;
362 | buildActionMask = 2147483647;
363 | files = (
364 | 33E28BA317C20DA200EFC071 /* MDrawTests.m in Sources */,
365 | );
366 | runOnlyForDeploymentPostprocessing = 0;
367 | };
368 | /* End PBXSourcesBuildPhase section */
369 |
370 | /* Begin PBXTargetDependency section */
371 | 33E28B9B17C20DA200EFC071 /* PBXTargetDependency */ = {
372 | isa = PBXTargetDependency;
373 | target = 33E28B7317C20DA200EFC071 /* MDraw */;
374 | targetProxy = 33E28B9A17C20DA200EFC071 /* PBXContainerItemProxy */;
375 | };
376 | /* End PBXTargetDependency section */
377 |
378 | /* Begin PBXVariantGroup section */
379 | 33E28B8017C20DA200EFC071 /* InfoPlist.strings */ = {
380 | isa = PBXVariantGroup;
381 | children = (
382 | 33E28B8117C20DA200EFC071 /* en */,
383 | );
384 | name = InfoPlist.strings;
385 | sourceTree = "";
386 | };
387 | 33E28B8917C20DA200EFC071 /* Main.storyboard */ = {
388 | isa = PBXVariantGroup;
389 | children = (
390 | 33E28B8A17C20DA200EFC071 /* Base */,
391 | );
392 | name = Main.storyboard;
393 | sourceTree = "";
394 | };
395 | 33E28B9F17C20DA200EFC071 /* InfoPlist.strings */ = {
396 | isa = PBXVariantGroup;
397 | children = (
398 | 33E28BA017C20DA200EFC071 /* en */,
399 | );
400 | name = InfoPlist.strings;
401 | sourceTree = "";
402 | };
403 | /* End PBXVariantGroup section */
404 |
405 | /* Begin XCBuildConfiguration section */
406 | 33E28BA417C20DA200EFC071 /* Debug */ = {
407 | isa = XCBuildConfiguration;
408 | buildSettings = {
409 | ALWAYS_SEARCH_USER_PATHS = NO;
410 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
411 | CLANG_CXX_LIBRARY = "libc++";
412 | CLANG_ENABLE_MODULES = YES;
413 | CLANG_ENABLE_OBJC_ARC = YES;
414 | CLANG_WARN_BOOL_CONVERSION = YES;
415 | CLANG_WARN_CONSTANT_CONVERSION = YES;
416 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
417 | CLANG_WARN_EMPTY_BODY = YES;
418 | CLANG_WARN_ENUM_CONVERSION = YES;
419 | CLANG_WARN_INT_CONVERSION = YES;
420 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
421 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
422 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
423 | COPY_PHASE_STRIP = NO;
424 | GCC_C_LANGUAGE_STANDARD = gnu99;
425 | GCC_DYNAMIC_NO_PIC = NO;
426 | GCC_OPTIMIZATION_LEVEL = 0;
427 | GCC_PREPROCESSOR_DEFINITIONS = (
428 | "DEBUG=1",
429 | "$(inherited)",
430 | );
431 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
432 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
433 | GCC_WARN_UNDECLARED_SELECTOR = YES;
434 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
435 | GCC_WARN_UNUSED_FUNCTION = YES;
436 | GCC_WARN_UNUSED_VARIABLE = YES;
437 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
438 | ONLY_ACTIVE_ARCH = YES;
439 | SDKROOT = iphoneos;
440 | TARGETED_DEVICE_FAMILY = 2;
441 | };
442 | name = Debug;
443 | };
444 | 33E28BA517C20DA200EFC071 /* Release */ = {
445 | isa = XCBuildConfiguration;
446 | buildSettings = {
447 | ALWAYS_SEARCH_USER_PATHS = NO;
448 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
449 | CLANG_CXX_LIBRARY = "libc++";
450 | CLANG_ENABLE_MODULES = YES;
451 | CLANG_ENABLE_OBJC_ARC = YES;
452 | CLANG_WARN_BOOL_CONVERSION = YES;
453 | CLANG_WARN_CONSTANT_CONVERSION = YES;
454 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
455 | CLANG_WARN_EMPTY_BODY = YES;
456 | CLANG_WARN_ENUM_CONVERSION = YES;
457 | CLANG_WARN_INT_CONVERSION = YES;
458 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
459 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
460 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
461 | COPY_PHASE_STRIP = YES;
462 | ENABLE_NS_ASSERTIONS = NO;
463 | GCC_C_LANGUAGE_STANDARD = gnu99;
464 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
465 | GCC_WARN_UNDECLARED_SELECTOR = YES;
466 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
467 | GCC_WARN_UNUSED_FUNCTION = YES;
468 | GCC_WARN_UNUSED_VARIABLE = YES;
469 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
470 | SDKROOT = iphoneos;
471 | TARGETED_DEVICE_FAMILY = 2;
472 | VALIDATE_PRODUCT = YES;
473 | };
474 | name = Release;
475 | };
476 | 33E28BA717C20DA200EFC071 /* Debug */ = {
477 | isa = XCBuildConfiguration;
478 | buildSettings = {
479 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
480 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
481 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
482 | GCC_PREFIX_HEADER = "MDraw/MDraw-Prefix.pch";
483 | INFOPLIST_FILE = "MDraw/MDraw-Info.plist";
484 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
485 | PRODUCT_NAME = "$(TARGET_NAME)";
486 | WRAPPER_EXTENSION = app;
487 | };
488 | name = Debug;
489 | };
490 | 33E28BA817C20DA200EFC071 /* Release */ = {
491 | isa = XCBuildConfiguration;
492 | buildSettings = {
493 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
494 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
495 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
496 | GCC_PREFIX_HEADER = "MDraw/MDraw-Prefix.pch";
497 | INFOPLIST_FILE = "MDraw/MDraw-Info.plist";
498 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
499 | PRODUCT_NAME = "$(TARGET_NAME)";
500 | WRAPPER_EXTENSION = app;
501 | };
502 | name = Release;
503 | };
504 | 33E28BAA17C20DA200EFC071 /* Debug */ = {
505 | isa = XCBuildConfiguration;
506 | buildSettings = {
507 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/MDraw.app/MDraw";
508 | FRAMEWORK_SEARCH_PATHS = (
509 | "$(SDKROOT)/Developer/Library/Frameworks",
510 | "$(inherited)",
511 | "$(DEVELOPER_FRAMEWORKS_DIR)",
512 | );
513 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
514 | GCC_PREFIX_HEADER = "MDraw/MDraw-Prefix.pch";
515 | GCC_PREPROCESSOR_DEFINITIONS = (
516 | "DEBUG=1",
517 | "$(inherited)",
518 | );
519 | INFOPLIST_FILE = "MDrawTests/MDrawTests-Info.plist";
520 | PRODUCT_NAME = "$(TARGET_NAME)";
521 | TEST_HOST = "$(BUNDLE_LOADER)";
522 | WRAPPER_EXTENSION = xctest;
523 | };
524 | name = Debug;
525 | };
526 | 33E28BAB17C20DA200EFC071 /* Release */ = {
527 | isa = XCBuildConfiguration;
528 | buildSettings = {
529 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/MDraw.app/MDraw";
530 | FRAMEWORK_SEARCH_PATHS = (
531 | "$(SDKROOT)/Developer/Library/Frameworks",
532 | "$(inherited)",
533 | "$(DEVELOPER_FRAMEWORKS_DIR)",
534 | );
535 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
536 | GCC_PREFIX_HEADER = "MDraw/MDraw-Prefix.pch";
537 | INFOPLIST_FILE = "MDrawTests/MDrawTests-Info.plist";
538 | PRODUCT_NAME = "$(TARGET_NAME)";
539 | TEST_HOST = "$(BUNDLE_LOADER)";
540 | WRAPPER_EXTENSION = xctest;
541 | };
542 | name = Release;
543 | };
544 | /* End XCBuildConfiguration section */
545 |
546 | /* Begin XCConfigurationList section */
547 | 33E28B6F17C20DA200EFC071 /* Build configuration list for PBXProject "MDraw" */ = {
548 | isa = XCConfigurationList;
549 | buildConfigurations = (
550 | 33E28BA417C20DA200EFC071 /* Debug */,
551 | 33E28BA517C20DA200EFC071 /* Release */,
552 | );
553 | defaultConfigurationIsVisible = 0;
554 | defaultConfigurationName = Release;
555 | };
556 | 33E28BA617C20DA200EFC071 /* Build configuration list for PBXNativeTarget "MDraw" */ = {
557 | isa = XCConfigurationList;
558 | buildConfigurations = (
559 | 33E28BA717C20DA200EFC071 /* Debug */,
560 | 33E28BA817C20DA200EFC071 /* Release */,
561 | );
562 | defaultConfigurationIsVisible = 0;
563 | defaultConfigurationName = Release;
564 | };
565 | 33E28BA917C20DA200EFC071 /* Build configuration list for PBXNativeTarget "MDrawTests" */ = {
566 | isa = XCConfigurationList;
567 | buildConfigurations = (
568 | 33E28BAA17C20DA200EFC071 /* Debug */,
569 | 33E28BAB17C20DA200EFC071 /* Release */,
570 | );
571 | defaultConfigurationIsVisible = 0;
572 | defaultConfigurationName = Release;
573 | };
574 | /* End XCConfigurationList section */
575 | };
576 | rootObject = 33E28B6C17C20DA200EFC071 /* Project object */;
577 | }
578 |
--------------------------------------------------------------------------------