├── cidrawinglib ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── mocircle │ │ │ ├── cidrawing │ │ │ ├── element │ │ │ │ ├── DiscreteElement.java │ │ │ │ ├── behavior │ │ │ │ │ ├── Recyclable.java │ │ │ │ │ ├── Skewable.java │ │ │ │ │ ├── ResizingDirection.java │ │ │ │ │ ├── Movable.java │ │ │ │ │ ├── Rotatable.java │ │ │ │ │ ├── SupportVector.java │ │ │ │ │ ├── Resizable.java │ │ │ │ │ └── Selectable.java │ │ │ │ ├── shape │ │ │ │ │ ├── CircleElement.java │ │ │ │ │ ├── OvalElement.java │ │ │ │ │ ├── SquareElement.java │ │ │ │ │ ├── RectElement.java │ │ │ │ │ ├── ArcElement.java │ │ │ │ │ ├── IsoscelesTriangleElement.java │ │ │ │ │ ├── LineElement.java │ │ │ │ │ ├── RightTriangleElement.java │ │ │ │ │ ├── ShapeElement.java │ │ │ │ │ └── BoxShapeElement.java │ │ │ │ ├── PathElement.java │ │ │ │ ├── BaseElement.java │ │ │ │ ├── BasePathElement.java │ │ │ │ ├── BoundsElement.java │ │ │ │ ├── GroupElement.java │ │ │ │ ├── VirtualElement.java │ │ │ │ ├── TextElement.java │ │ │ │ └── StrokeElement.java │ │ │ ├── mode │ │ │ │ ├── CompositeMode.java │ │ │ │ ├── InsertTextMode.java │ │ │ │ ├── InsertPhotoMode.java │ │ │ │ ├── selection │ │ │ │ │ ├── OvalSelectionMode.java │ │ │ │ │ ├── RectSelectionMode.java │ │ │ │ │ ├── ShapeSelectionMode.java │ │ │ │ │ ├── LassoSelectionMode.java │ │ │ │ │ └── SelectionMode.java │ │ │ │ ├── stroke │ │ │ │ │ ├── PlainStrokeMode.java │ │ │ │ │ ├── EraserStrokeMode.java │ │ │ │ │ ├── SmoothStrokeMode.java │ │ │ │ │ └── BaseStrokeMode.java │ │ │ │ ├── AbstractDrawingMode.java │ │ │ │ ├── DrawingMode.java │ │ │ │ ├── eraser │ │ │ │ │ └── ObjectEraserMode.java │ │ │ │ ├── AutoDetectedElementOperationMode.java │ │ │ │ ├── BasePointMode.java │ │ │ │ ├── transformation │ │ │ │ │ ├── DataTransformMode.java │ │ │ │ │ ├── DisplayTransformMode.java │ │ │ │ │ ├── MoveMode.java │ │ │ │ │ ├── RotateMode.java │ │ │ │ │ ├── SkewMode.java │ │ │ │ │ └── MoveReferencePointMode.java │ │ │ │ ├── ElementOperationMode.java │ │ │ │ ├── InsertShapeMode.java │ │ │ │ ├── InsertVectorElementMode.java │ │ │ │ └── PointerMode.java │ │ │ ├── operation │ │ │ │ ├── DrawingOperation.java │ │ │ │ ├── OperationManager.java │ │ │ │ ├── AbstractOperation.java │ │ │ │ ├── ReshapeOperation.java │ │ │ │ ├── SingleSelectedElementOperation.java │ │ │ │ ├── MovePointOperation.java │ │ │ │ ├── SelectedElementsOperation.java │ │ │ │ ├── DisplayTransformOperation.java │ │ │ │ ├── DataTransformOperation.java │ │ │ │ ├── InsertElementOperation.java │ │ │ │ ├── RemoveElementOperation.java │ │ │ │ ├── GroupElementOperation.java │ │ │ │ ├── FlipOperation.java │ │ │ │ ├── UngroupElementOperation.java │ │ │ │ ├── OperationManagerImpl.java │ │ │ │ ├── PathOperation.java │ │ │ │ └── ArrangeOperation.java │ │ │ ├── persistence │ │ │ │ ├── Persistable.java │ │ │ │ ├── PersistenceException.java │ │ │ │ ├── ExportData.java │ │ │ │ └── PersistenceManager.java │ │ │ ├── utils │ │ │ │ ├── ElementUtils.java │ │ │ │ ├── MatrixUtils.java │ │ │ │ ├── VectorUtils.java │ │ │ │ ├── ShapeUtils.java │ │ │ │ └── DrawUtils.java │ │ │ ├── exception │ │ │ │ └── DrawingBoardNotFoundException.java │ │ │ ├── view │ │ │ │ ├── DrawingView.java │ │ │ │ ├── DrawingViewProxy.java │ │ │ │ ├── DrawingViewProxyImpl.java │ │ │ │ └── CiDrawingView.java │ │ │ ├── ConfigManagerImpl.java │ │ │ ├── board │ │ │ │ ├── LayerManager.java │ │ │ │ ├── ArrangeStrategy.java │ │ │ │ ├── ElementManager.java │ │ │ │ └── Selection.java │ │ │ ├── ConfigManager.java │ │ │ ├── PaintingBehavior.java │ │ │ ├── core │ │ │ │ ├── Vector2.java │ │ │ │ └── CiPaint.java │ │ │ ├── DrawingContext.java │ │ │ ├── PaintBuilder.java │ │ │ ├── DrawingBoardManager.java │ │ │ ├── DrawingBoard.java │ │ │ └── DefaultPaintBuilder.java │ │ │ └── android │ │ │ └── logging │ │ │ └── CircleLog.java │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── mocircle │ │ │ └── cidrawing │ │ │ ├── ApplicationTest.java │ │ │ └── ExampleInstrumentedTest.java │ └── test │ │ └── java │ │ └── com │ │ └── mocircle │ │ └── cidrawing │ │ ├── ExampleUnitTest.java │ │ └── utils │ │ ├── ShapeUtilsTest.java │ │ ├── VectorUtilsTest.java │ │ └── ListUtilsTest.java ├── proguard-rules.pro └── build.gradle ├── cidrawingsample ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── dimens.xml │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── menu │ │ │ │ ├── menu_eraser.xml │ │ │ │ ├── menu_color.xml │ │ │ │ ├── menu_width.xml │ │ │ │ ├── menu_style.xml │ │ │ │ ├── menu_stroke.xml │ │ │ │ ├── menu_select.xml │ │ │ │ ├── menu_color2.xml │ │ │ │ ├── menu_transform.xml │ │ │ │ ├── menu_arrange.xml │ │ │ │ ├── menu_insert_shape.xml │ │ │ │ └── menu_more.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── layout │ │ │ │ ├── layer_item_layout.xml │ │ │ │ ├── drawer_layout.xml │ │ │ │ ├── activity_main.xml │ │ │ │ └── right_drawer_layout.xml │ │ │ └── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ ├── assets │ │ │ └── sample.jpg │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── mocircle │ │ │ └── cidrawingsample │ │ │ └── LayerAdapter.java │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── mocircle │ │ │ └── cidrawingsample │ │ │ ├── ApplicationTest.java │ │ │ └── ExampleInstrumentedTest.java │ └── test │ │ └── java │ │ └── com │ │ └── mocircle │ │ └── cidrawingsample │ │ └── ExampleUnitTest.java ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── docs ├── sample1.png ├── sample2.png └── sample3.png ├── .gitignore ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── .travis.yml ├── gradlew.bat └── README.md /cidrawinglib/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /cidrawingsample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':cidrawinglib', ':cidrawingsample' 2 | -------------------------------------------------------------------------------- /docs/sample1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/docs/sample1.png -------------------------------------------------------------------------------- /docs/sample2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/docs/sample2.png -------------------------------------------------------------------------------- /docs/sample3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/docs/sample3.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /cidrawinglib/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | CiDrawing 3 | 4 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16dp 3 | 4 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/assets/sample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/assets/sample.jpg -------------------------------------------------------------------------------- /cidrawinglib/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruochao/cidrawing/HEAD/cidrawingsample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/DiscreteElement.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element; 2 | 3 | public abstract class DiscreteElement extends DrawElement { 4 | } 5 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/CompositeMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode; 2 | 3 | public abstract class CompositeMode extends AbstractDrawingMode { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Jun 11 22:52:04 PDT 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/behavior/Recyclable.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.behavior; 2 | 3 | /** 4 | * A interface indicates the element can be recycled. 5 | */ 6 | public interface Recyclable { 7 | 8 | void recycleElement(); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_eraser.xml: -------------------------------------------------------------------------------- 1 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/behavior/Skewable.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.behavior; 2 | 3 | public interface Skewable { 4 | 5 | boolean isSkewEnabled(); 6 | 7 | void setSkewEnabled(boolean skewEnabled); 8 | 9 | void skew(float kx, float ky, float px, float py); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | CiDrawing Sample 3 | Settings 4 | 5 | Open navigation drawer 6 | Close navigation drawer 7 | 8 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/InsertTextMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode; 2 | 3 | import com.mocircle.cidrawing.element.TextElement; 4 | 5 | public class InsertTextMode extends InsertVectorElementMode { 6 | 7 | public InsertTextMode() { 8 | } 9 | 10 | public void setTextElement(TextElement element) { 11 | setVectorElement(element); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/behavior/ResizingDirection.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.behavior; 2 | 3 | public enum ResizingDirection { 4 | 5 | NONE, 6 | 7 | CENTER, 8 | 9 | NORTH, 10 | 11 | SOUTH, 12 | 13 | WEST, 14 | 15 | EAST, 16 | 17 | NORTH_WEST, 18 | 19 | NORTH_EAST, 20 | 21 | SOUTH_WEST, 22 | 23 | SOUTH_EAST 24 | 25 | } 26 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/InsertPhotoMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode; 2 | 3 | import com.mocircle.cidrawing.element.PhotoElement; 4 | 5 | public class InsertPhotoMode extends InsertVectorElementMode { 6 | 7 | public InsertPhotoMode() { 8 | } 9 | 10 | public void setPhotoElement(PhotoElement element) { 11 | setVectorElement(element); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/DrawingOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | /** 4 | * The operation to support undo/redo. 5 | */ 6 | public interface DrawingOperation { 7 | 8 | void setDrawingBoardId(String boardId); 9 | 10 | boolean isExecutable(); 11 | 12 | boolean doOperation(); 13 | 14 | void undo(); 15 | 16 | void redo(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/behavior/Movable.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.behavior; 2 | 3 | public interface Movable { 4 | 5 | boolean isMovementEnabled(); 6 | 7 | void setMovementEnabled(boolean movementEnabled); 8 | 9 | void move(float dx, float dy); 10 | 11 | void moveTo(float locX, float locY); 12 | 13 | float getLocX(); 14 | 15 | float getLocY(); 16 | } 17 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_width.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/persistence/Persistable.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.persistence; 2 | 3 | import org.json.JSONObject; 4 | 5 | import java.util.Map; 6 | 7 | public interface Persistable { 8 | 9 | JSONObject generateJson(); 10 | 11 | Map generateResources(); 12 | 13 | void loadFromJson(JSONObject object, Map resources); 14 | 15 | void afterLoaded(); 16 | } 17 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_style.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /cidrawinglib/src/androidTest/java/com/mocircle/cidrawing/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_stroke.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /cidrawingsample/src/androidTest/java/com/mocircle/cidrawingsample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawingsample; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/behavior/Rotatable.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.behavior; 2 | 3 | import android.graphics.Canvas; 4 | 5 | public interface Rotatable { 6 | 7 | boolean isRotationEnabled(); 8 | 9 | void setRotationEnabled(boolean rotationEnabled); 10 | 11 | void rotate(float degree, float px, float py); 12 | 13 | void drawRotationHandle(Canvas canvas); 14 | 15 | boolean hitTestForRotationHandle(float x, float y); 16 | } 17 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/selection/OvalSelectionMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode.selection; 2 | 3 | import com.mocircle.cidrawing.element.DrawElement; 4 | import com.mocircle.cidrawing.element.shape.OvalElement; 5 | 6 | public class OvalSelectionMode extends ShapeSelectionMode { 7 | 8 | public OvalSelectionMode() { 9 | } 10 | 11 | @Override 12 | protected DrawElement createSelectionElement() { 13 | return new OvalElement(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/selection/RectSelectionMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode.selection; 2 | 3 | import com.mocircle.cidrawing.element.DrawElement; 4 | import com.mocircle.cidrawing.element.shape.RectElement; 5 | 6 | public class RectSelectionMode extends ShapeSelectionMode { 7 | 8 | public RectSelectionMode() { 9 | } 10 | 11 | @Override 12 | protected DrawElement createSelectionElement() { 13 | return new RectElement(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/OperationManager.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import java.util.List; 4 | 5 | public interface OperationManager { 6 | 7 | void executeOperation(DrawingOperation operation); 8 | 9 | List getOperationHistory(); 10 | 11 | void undo(); 12 | 13 | void undoToOperation(DrawingOperation operation); 14 | 15 | void redo(); 16 | 17 | void redoToOperation(DrawingOperation operation); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /cidrawinglib/src/test/java/com/mocircle/cidrawing/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_select.xml: -------------------------------------------------------------------------------- 1 | 4 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_color2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_transform.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /cidrawingsample/src/test/java/com/mocircle/cidrawingsample/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawingsample; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/behavior/SupportVector.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.behavior; 2 | 3 | import com.mocircle.cidrawing.core.Vector2; 4 | 5 | /** 6 | * Indicates the element is able to be created by vector. 7 | */ 8 | public interface SupportVector { 9 | 10 | /** 11 | * To create the element or extract the details from a given vector. 12 | * 13 | * @param vector vector in the coordinate 14 | */ 15 | void setupElementByVector(Vector2 vector); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/stroke/PlainStrokeMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode.stroke; 2 | 3 | import android.graphics.CornerPathEffect; 4 | import android.graphics.Paint; 5 | 6 | import com.mocircle.cidrawing.core.CiPaint; 7 | 8 | public class PlainStrokeMode extends BaseStrokeMode { 9 | 10 | public PlainStrokeMode() { 11 | } 12 | 13 | protected CiPaint assignPaint() { 14 | CiPaint paint = new CiPaint(drawingContext.getPaint()); 15 | paint.setStyle(Paint.Style.STROKE); 16 | return paint; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/persistence/PersistenceException.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.persistence; 2 | 3 | public class PersistenceException extends RuntimeException { 4 | 5 | public PersistenceException() { 6 | super(); 7 | } 8 | 9 | public PersistenceException(String message) { 10 | super(message); 11 | } 12 | 13 | public PersistenceException(String message, Throwable cause) { 14 | super(message, cause); 15 | } 16 | 17 | public PersistenceException(Throwable cause) { 18 | super(cause); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/shape/CircleElement.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.shape; 2 | 3 | import com.mocircle.cidrawing.core.Vector2; 4 | import com.mocircle.cidrawing.utils.VectorUtils; 5 | 6 | public class CircleElement extends OvalElement { 7 | 8 | @Override 9 | public void setupElementByVector(Vector2 vector) { 10 | VectorUtils.shiftVectorAsSquare(vector, true); 11 | super.setupElementByVector(vector); 12 | } 13 | 14 | @Override 15 | public boolean isLockAspectRatio() { 16 | return true; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/shape/OvalElement.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.shape; 2 | 3 | import android.graphics.Path; 4 | 5 | public class OvalElement extends BoxShapeElement { 6 | 7 | @Override 8 | public Object clone() { 9 | OvalElement element = new OvalElement(); 10 | cloneTo(element); 11 | return element; 12 | } 13 | 14 | @Override 15 | protected Path createShapePath() { 16 | Path path = new Path(); 17 | path.addOval(shapeBox, Path.Direction.CW); 18 | return path; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/shape/SquareElement.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.shape; 2 | 3 | import com.mocircle.cidrawing.core.Vector2; 4 | import com.mocircle.cidrawing.utils.VectorUtils; 5 | 6 | public class SquareElement extends RectElement { 7 | 8 | @Override 9 | public void setupElementByVector(Vector2 vector) { 10 | VectorUtils.shiftVectorAsSquare(vector, true); 11 | super.setupElementByVector(vector); 12 | } 13 | 14 | @Override 15 | public boolean isLockAspectRatio() { 16 | return true; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/AbstractOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import com.mocircle.cidrawing.DrawingBoard; 4 | import com.mocircle.cidrawing.DrawingBoardManager; 5 | 6 | public abstract class AbstractOperation implements DrawingOperation { 7 | 8 | protected DrawingBoard drawingBoard; 9 | 10 | @Override 11 | public void setDrawingBoardId(String boardId) { 12 | this.drawingBoard = DrawingBoardManager.getInstance().findDrawingBoard(boardId); 13 | } 14 | 15 | @Override 16 | public void redo() { 17 | doOperation(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/shape/RectElement.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.shape; 2 | 3 | import android.graphics.Path; 4 | 5 | public class RectElement extends BoxShapeElement { 6 | 7 | public RectElement() { 8 | } 9 | 10 | @Override 11 | public Object clone() { 12 | RectElement element = new RectElement(); 13 | cloneTo(element); 14 | return element; 15 | } 16 | 17 | @Override 18 | protected Path createShapePath() { 19 | Path path = new Path(); 20 | path.addRect(shapeBox, Path.Direction.CW); 21 | return path; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/stroke/EraserStrokeMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode.stroke; 2 | 3 | import android.graphics.Paint; 4 | import android.graphics.PorterDuff; 5 | import android.graphics.PorterDuffXfermode; 6 | 7 | import com.mocircle.cidrawing.core.CiPaint; 8 | 9 | public class EraserStrokeMode extends BaseStrokeMode { 10 | 11 | @Override 12 | protected CiPaint assignPaint() { 13 | CiPaint paint = new CiPaint(drawingContext.getPaint()); 14 | paint.setStyle(Paint.Style.STROKE); 15 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 16 | return paint; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/utils/ElementUtils.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.utils; 2 | 3 | import com.mocircle.cidrawing.element.DrawElement; 4 | 5 | import java.util.Collections; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | 9 | public class ElementUtils { 10 | 11 | public static void sortElementsInLayer(List elements) { 12 | Collections.sort(elements, new Comparator() { 13 | @Override 14 | public int compare(DrawElement o1, DrawElement o2) { 15 | return o1.getOrderIndex() - o2.getOrderIndex(); 16 | } 17 | }); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/exception/DrawingBoardNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.exception; 2 | 3 | public class DrawingBoardNotFoundException extends RuntimeException { 4 | 5 | public DrawingBoardNotFoundException() { 6 | super(); 7 | } 8 | 9 | public DrawingBoardNotFoundException(String detailMessage) { 10 | super(detailMessage); 11 | } 12 | 13 | public DrawingBoardNotFoundException(String detailMessage, Throwable throwable) { 14 | super(detailMessage, throwable); 15 | } 16 | 17 | public DrawingBoardNotFoundException(Throwable throwable) { 18 | super(throwable); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/view/DrawingView.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.view; 2 | 3 | import android.content.Context; 4 | 5 | /** 6 | * Drawing view interface 7 | */ 8 | public interface DrawingView { 9 | 10 | /** 11 | * Sets the proxy object to delegate view behaviors. 12 | * 13 | * @param viewProxy proxy object 14 | */ 15 | void setViewProxy(DrawingViewProxy viewProxy); 16 | 17 | /** 18 | * Notifies to redraw the view 19 | */ 20 | void notifyViewUpdated(); 21 | 22 | /** 23 | * Gets android context 24 | * 25 | * @return android context 26 | */ 27 | Context getContext(); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/AbstractDrawingMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode; 2 | 3 | import com.mocircle.cidrawing.DrawingBoard; 4 | import com.mocircle.cidrawing.DrawingBoardManager; 5 | 6 | public abstract class AbstractDrawingMode implements DrawingMode { 7 | 8 | protected DrawingBoard drawingBoard; 9 | 10 | public AbstractDrawingMode() { 11 | } 12 | 13 | @Override 14 | public void setDrawingBoardId(String boardId) { 15 | drawingBoard = DrawingBoardManager.getInstance().findDrawingBoard(boardId); 16 | } 17 | 18 | @Override 19 | public void onEnterMode() { 20 | } 21 | 22 | @Override 23 | public void onLeaveMode() { 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/persistence/ExportData.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.persistence; 2 | 3 | import org.json.JSONObject; 4 | 5 | import java.util.Map; 6 | 7 | public class ExportData { 8 | 9 | private JSONObject metaData; 10 | private Map resources; 11 | 12 | public JSONObject getMetaData() { 13 | return metaData; 14 | } 15 | 16 | public void setMetaData(JSONObject metaData) { 17 | this.metaData = metaData; 18 | } 19 | 20 | public Map getResources() { 21 | return resources; 22 | } 23 | 24 | public void setResources(Map resources) { 25 | this.resources = resources; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/shape/ArcElement.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.shape; 2 | 3 | import android.graphics.Path; 4 | 5 | public class ArcElement extends BoxShapeElement { 6 | 7 | @Override 8 | public Object clone() { 9 | ArcElement element = new ArcElement(); 10 | cloneTo(element); 11 | return element; 12 | } 13 | 14 | @Override 15 | protected Path createShapePath() { 16 | Path path = new Path(); 17 | path.moveTo(shapeVector.getPoint1().x, shapeVector.getPoint1().y); 18 | path.quadTo(shapeVector.getPoint1().x, shapeVector.getPoint2().y, shapeVector.getPoint2().x, shapeVector.getPoint2().y); 19 | return path; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_arrange.xml: -------------------------------------------------------------------------------- 1 | 4 | 7 | 10 | 13 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | 16 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/PathElement.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element; 2 | 3 | import android.graphics.Matrix; 4 | import android.graphics.Path; 5 | 6 | public class PathElement extends BasePathElement { 7 | 8 | public PathElement() { 9 | } 10 | 11 | public void setElementPath(Path elementPath) { 12 | this.elementPath = elementPath; 13 | updateBoundingBox(); 14 | } 15 | 16 | @Override 17 | public void applyMatrixForData(Matrix matrix) { 18 | super.applyMatrixForData(matrix); 19 | 20 | elementPath.transform(matrix); 21 | } 22 | 23 | @Override 24 | public Object clone() { 25 | PathElement element = new PathElement(); 26 | cloneTo(element); 27 | return element; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/view/DrawingViewProxy.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.view; 2 | 3 | import android.graphics.Canvas; 4 | import android.view.MotionEvent; 5 | import android.view.View; 6 | 7 | /** 8 | * A interface delegates the view behavior. 9 | */ 10 | public interface DrawingViewProxy { 11 | 12 | /** 13 | * Delegates method: {@link View#onDraw(Canvas)} 14 | * 15 | * @param canvas the canvas on which the background will be drawn 16 | */ 17 | void onDraw(Canvas canvas); 18 | 19 | /** 20 | * Delegates method: {@link View#onTouchEvent(MotionEvent)} 21 | * 22 | * @param event the motion event 23 | * @return True if the event was handled, false otherwise. 24 | */ 25 | boolean onTouchEvent(MotionEvent event); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/shape/IsoscelesTriangleElement.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.shape; 2 | 3 | import android.graphics.Path; 4 | 5 | public class IsoscelesTriangleElement extends BoxShapeElement { 6 | 7 | @Override 8 | public Object clone() { 9 | IsoscelesTriangleElement element = new IsoscelesTriangleElement(); 10 | cloneTo(element); 11 | return element; 12 | } 13 | 14 | @Override 15 | protected Path createShapePath() { 16 | Path path = new Path(); 17 | path.moveTo(shapeBox.left, shapeBox.bottom); 18 | path.lineTo(shapeBox.centerX(), shapeBox.top); 19 | path.lineTo(shapeBox.right, shapeBox.bottom); 20 | path.lineTo(shapeBox.left, shapeBox.bottom); 21 | return path; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/ConfigManagerImpl.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing; 2 | 3 | /** 4 | * The default implementation of {@link ConfigManager}. 5 | */ 6 | public class ConfigManagerImpl implements ConfigManager { 7 | 8 | private boolean debugMode = false; 9 | private DrawingType drawingType = DrawingType.Vector; 10 | 11 | @Override 12 | public boolean isDebugMode() { 13 | return debugMode; 14 | } 15 | 16 | @Override 17 | public void setDebugMode(boolean debugMode) { 18 | this.debugMode = debugMode; 19 | } 20 | 21 | @Override 22 | public DrawingType getDrawingType() { 23 | return drawingType; 24 | } 25 | 26 | @Override 27 | public void setDrawingType(DrawingType type) { 28 | this.drawingType = type; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/ReshapeOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import android.graphics.Matrix; 4 | 5 | public class ReshapeOperation extends SingleSelectedElementOperation { 6 | 7 | private Matrix displayMatrix; 8 | 9 | @Override 10 | public boolean doOperation() { 11 | displayMatrix = selectedElement.applyDisplayMatrixToData(); 12 | selectedElement.resetReferencePoint(); 13 | drawingBoard.getDrawingView().notifyViewUpdated(); 14 | return true; 15 | } 16 | 17 | @Override 18 | public void undo() { 19 | if (selectedElement != null) { 20 | selectedElement.restoreDisplayMatrixFromData(displayMatrix); 21 | drawingBoard.getDrawingView().notifyViewUpdated(); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /cidrawinglib/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /cidrawingsample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/DrawingMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode; 2 | 3 | import android.view.MotionEvent; 4 | 5 | /** 6 | * A drawing mode defines the behavior when interacting with the view. 7 | */ 8 | public interface DrawingMode { 9 | 10 | /** 11 | * Sets drawing board id 12 | * 13 | * @param boardId board id 14 | */ 15 | void setDrawingBoardId(String boardId); 16 | 17 | /** 18 | * Called when switch to this mode. 19 | */ 20 | void onEnterMode(); 21 | 22 | /** 23 | * Called when switch to other mode. 24 | */ 25 | void onLeaveMode(); 26 | 27 | /** 28 | * Delegates the view touch event. 29 | * 30 | * @param event the motion event 31 | * @return True if the event was handled, false otherwise. 32 | */ 33 | boolean onTouchEvent(MotionEvent event); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/SingleSelectedElementOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import com.mocircle.cidrawing.board.ElementManager; 4 | import com.mocircle.cidrawing.element.DrawElement; 5 | 6 | public abstract class SingleSelectedElementOperation extends AbstractOperation { 7 | 8 | protected ElementManager elementManager; 9 | protected DrawElement selectedElement; 10 | 11 | @Override 12 | public void setDrawingBoardId(String boardId) { 13 | super.setDrawingBoardId(boardId); 14 | elementManager = drawingBoard.getElementManager(); 15 | } 16 | 17 | @Override 18 | public boolean isExecutable() { 19 | if (selectedElement == null) { 20 | selectedElement = elementManager.getSelection().getSingleElement(); 21 | } 22 | return selectedElement != null; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /cidrawinglib/src/androidTest/java/com/mocircle/cidrawing/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.mocircle.cidrawing.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/behavior/Resizable.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.behavior; 2 | 3 | import android.graphics.Canvas; 4 | 5 | public interface Resizable { 6 | 7 | enum AspectRatioResetMethod { 8 | WIDTH_FIRST, 9 | HEIGHT_FIRST, 10 | SMALL_FIRST, 11 | LARGE_FIRST 12 | } 13 | 14 | boolean isResizingEnabled(); 15 | 16 | void setResizingEnabled(boolean resizingEnabled); 17 | 18 | boolean isLockAspectRatio(); 19 | 20 | void setLockAspectRatio(boolean lockAspectRatio); 21 | 22 | void resetAspectRatio(AspectRatioResetMethod method); 23 | 24 | void resize(float sx, float sy, float px, float py); 25 | 26 | void resizeTo(float width, float height, float px, float py); 27 | 28 | void drawResizingHandle(Canvas canvas); 29 | 30 | ResizingDirection hitTestForResizingHandle(float x, float y); 31 | } 32 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /cidrawingsample/src/androidTest/java/com/mocircle/cidrawingsample/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawingsample; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.mocircle.cidrawingsample", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/board/LayerManager.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.board; 2 | 3 | public interface LayerManager { 4 | 5 | interface LayerChangeListener { 6 | void onLayerChanged(); 7 | } 8 | 9 | Layer[] getLayers(); 10 | 11 | Layer getCurrentLayer(); 12 | 13 | void selectLayer(Layer selectedLayer); 14 | 15 | Layer selectFirstVisibleLayer(); 16 | 17 | Layer createNewLayer(); 18 | 19 | Layer createNewLayer(String name); 20 | 21 | void addLayer(Layer layer); 22 | 23 | void removeLayer(Layer layer); 24 | 25 | void removeAllLayers(); 26 | 27 | void showLayer(Layer layer); 28 | 29 | void showAllLayers(); 30 | 31 | void hideLayer(Layer layer); 32 | 33 | void hideAllLayers(); 34 | 35 | void addLayerChangeListener(LayerChangeListener listener); 36 | 37 | void removeLayerChangeListener(LayerChangeListener listener); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/board/ArrangeStrategy.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.board; 2 | 3 | /** 4 | * Indicate how to handle multiple elements arrangement. 5 | */ 6 | public enum ArrangeStrategy { 7 | 8 | /** 9 | * If elements shift out of the list, this strategy will try to shift each element to the furthest 10 | * distance but still keep the same order between elements. 11 | * For example: 12 | *
13 |      * Before arrange: [A,B,C,D,E]
14 |      * Move: A,C -> 5 steps
15 |      * After arrange: [B,D,E,A,C]
16 |      * 
17 | */ 18 | AS_MUCH_AS_POSSIBLE, 19 | 20 | /** 21 | * If elements shift out of the list, this strategy will keep the same distance and order between elements. 22 | * For example: 23 | *
24 |      * Before arrange: [A,B,C,D,E]
25 |      * Move: A,C -> 5 steps
26 |      * After arrange: [B,D,A,E,C]
27 |      * 
28 | */ 29 | WITH_FIXED_DISTANCE 30 | 31 | } 32 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_insert_shape.xml: -------------------------------------------------------------------------------- 1 | 4 | 7 | 10 | 13 | 16 | 19 | 22 | 25 | 28 | 29 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/MovePointOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import android.graphics.PointF; 4 | 5 | public class MovePointOperation extends AbstractOperation { 6 | 7 | private PointF point; 8 | private float deltaX; 9 | private float deltaY; 10 | 11 | public MovePointOperation(PointF point, float deltaX, float deltaY) { 12 | this.point = point; 13 | this.deltaX = deltaX; 14 | this.deltaY = deltaY; 15 | } 16 | 17 | @Override 18 | public boolean isExecutable() { 19 | return point != null; 20 | } 21 | 22 | @Override 23 | public boolean doOperation() { 24 | point.offset(deltaX, deltaY); 25 | drawingBoard.getDrawingView().notifyViewUpdated(); 26 | return true; 27 | } 28 | 29 | @Override 30 | public void undo() { 31 | point.offset(-deltaX, -deltaY); 32 | drawingBoard.getDrawingView().notifyViewUpdated(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/SelectedElementsOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import com.mocircle.cidrawing.board.ElementManager; 4 | import com.mocircle.cidrawing.element.DrawElement; 5 | 6 | import java.util.List; 7 | 8 | public abstract class SelectedElementsOperation extends AbstractOperation { 9 | 10 | protected ElementManager elementManager; 11 | protected List elements; 12 | 13 | @Override 14 | public void setDrawingBoardId(String boardId) { 15 | super.setDrawingBoardId(boardId); 16 | elementManager = drawingBoard.getElementManager(); 17 | } 18 | 19 | @Override 20 | public boolean isExecutable() { 21 | if (elements == null) { 22 | // Get current selected elements 23 | elements = elementManager.getSelection().getElements(); 24 | } 25 | return elements.size() >= minimumSelectedElements(); 26 | } 27 | 28 | protected int minimumSelectedElements() { 29 | return 2; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/menu/menu_more.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | -------------------------------------------------------------------------------- /cidrawinglib/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 28 5 | buildToolsVersion "29.0.0" 6 | 7 | 8 | defaultConfig { 9 | minSdkVersion 15 10 | targetSdkVersion 28 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: 'libs', include: ['*.jar']) 29 | implementation 'com.android.support:appcompat-v7:28.0.0' 30 | 31 | testImplementation 'junit:junit:4.12' 32 | testImplementation 'org.robolectric:robolectric:3.1.4' 33 | 34 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 35 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 36 | } 37 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/layout/layer_item_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | 25 | 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | 3 | jdk: 4 | - oraclejdk8 5 | 6 | android: 7 | components: 8 | # Uncomment the lines below if you want to 9 | # use the latest revision of Android SDK Tools 10 | - platform-tools 11 | - tools 12 | 13 | # The BuildTools version used by your project 14 | - build-tools-29.0.0 15 | 16 | # The SDK version used to compile your project 17 | - android-28 18 | 19 | # Additional components 20 | - extra-google-m2repository 21 | - extra-android-m2repository 22 | - extra-android-support 23 | 24 | # Specify at least one system image, 25 | # if you need to run emulator(s) during your tests 26 | - sys-img-armeabi-v7a-android-28 27 | 28 | before_script: 29 | - chmod +x gradlew 30 | #- echo no | android create avd --force -n test -t android-23 --abi armeabi-v7a 31 | #- emulator -avd test -no-audio -no-window & 32 | #- android-wait-for-emulator 33 | #- adb shell input keyevent 82 & 34 | 35 | script: 36 | - ./gradlew assemble 37 | - ./gradlew test 38 | #- ./gradlew connectedAndroidTest 39 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/board/ElementManager.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.board; 2 | 3 | import com.mocircle.cidrawing.element.DrawElement; 4 | 5 | import java.util.List; 6 | 7 | public interface ElementManager extends LayerManager { 8 | 9 | DrawElement[] getVisibleObjects(); 10 | 11 | DrawElement[] getVisibleElements(); 12 | 13 | DrawElement[] getVisibleAdornments(); 14 | 15 | DrawElement[] getCurrentObjects(); 16 | 17 | DrawElement[] getCurrentElements(); 18 | 19 | DrawElement[] getCurrentAdornments(); 20 | 21 | void addElementToCurrentLayer(DrawElement element); 22 | 23 | void removeElementFromCurrentLayer(DrawElement element); 24 | 25 | void addAdornmentToCurrentLayer(DrawElement element); 26 | 27 | void removeAdornmentFromCurrentLayer(DrawElement element); 28 | 29 | void selectElement(DrawElement element); 30 | 31 | void selectElements(List elements); 32 | 33 | Selection getSelection(); 34 | 35 | void clearSelection(); 36 | 37 | DrawElement getFirstHitElement(float x, float y); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/utils/MatrixUtils.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.utils; 2 | 3 | import android.graphics.Matrix; 4 | 5 | /** 6 | * Matrix utility class. 7 | */ 8 | public final class MatrixUtils { 9 | 10 | private MatrixUtils() { 11 | } 12 | 13 | /** 14 | * Gets invert matrix. 15 | * 16 | * @param matrix original matrix 17 | * @return invert matrix 18 | */ 19 | public static Matrix getInvertMatrix(Matrix matrix) { 20 | Matrix invertMatrix = new Matrix(); 21 | matrix.invert(invertMatrix); 22 | return invertMatrix; 23 | } 24 | 25 | /** 26 | * Calculates the transformation matrix according to M(transformation) * M(source) = M(target). 27 | * 28 | * @param source source matrix 29 | * @param target target matrix 30 | * @return delta matrix 31 | */ 32 | public static Matrix getTransformationMatrix(Matrix source, Matrix target) { 33 | Matrix delta = new Matrix(); 34 | source.invert(delta); 35 | delta.postConcat(target); 36 | return delta; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/eraser/ObjectEraserMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode.eraser; 2 | 3 | import com.mocircle.cidrawing.board.ElementManager; 4 | import com.mocircle.cidrawing.element.DrawElement; 5 | import com.mocircle.cidrawing.mode.BasePointMode; 6 | import com.mocircle.cidrawing.operation.OperationManager; 7 | import com.mocircle.cidrawing.operation.RemoveElementOperation; 8 | 9 | public class ObjectEraserMode extends BasePointMode { 10 | 11 | private ElementManager elementManager; 12 | private OperationManager operationManager; 13 | 14 | @Override 15 | public void setDrawingBoardId(String boardId) { 16 | super.setDrawingBoardId(boardId); 17 | elementManager = drawingBoard.getElementManager(); 18 | operationManager = drawingBoard.getOperationManager(); 19 | } 20 | 21 | @Override 22 | protected void onOverPoint(float x, float y) { 23 | DrawElement element = elementManager.getFirstHitElement(x, y); 24 | if (element != null) { 25 | operationManager.executeOperation(new RemoveElementOperation(element)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /cidrawingsample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | buildToolsVersion "29.0.0" 6 | 7 | 8 | defaultConfig { 9 | applicationId "com.mocircle.cidrawingsample" 10 | minSdkVersion 15 11 | targetSdkVersion 28 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | implementation project(':cidrawinglib') 31 | 32 | implementation 'com.android.support:appcompat-v7:28.0.0' 33 | implementation 'com.android.support:design:28.0.0' 34 | testImplementation 'junit:junit:4.12' 35 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 36 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 37 | } 38 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/DisplayTransformOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import android.graphics.Matrix; 4 | 5 | import com.mocircle.cidrawing.element.DrawElement; 6 | import com.mocircle.cidrawing.utils.MatrixUtils; 7 | 8 | public class DisplayTransformOperation extends AbstractOperation { 9 | 10 | protected DrawElement element; 11 | protected Matrix deltaMatrix; 12 | 13 | public DisplayTransformOperation(DrawElement element, Matrix deltaMatrix) { 14 | this.element = element; 15 | this.deltaMatrix = deltaMatrix; 16 | } 17 | 18 | @Override 19 | public boolean isExecutable() { 20 | return element != null; 21 | } 22 | 23 | @Override 24 | public boolean doOperation() { 25 | element.getDisplayMatrix().postConcat(deltaMatrix); 26 | drawingBoard.getDrawingView().notifyViewUpdated(); 27 | return true; 28 | } 29 | 30 | @Override 31 | public void undo() { 32 | element.getDisplayMatrix().postConcat(MatrixUtils.getInvertMatrix(deltaMatrix)); 33 | drawingBoard.getDrawingView().notifyViewUpdated(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/DataTransformOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import android.graphics.Matrix; 4 | 5 | import com.mocircle.cidrawing.element.DrawElement; 6 | import com.mocircle.cidrawing.utils.MatrixUtils; 7 | 8 | public class DataTransformOperation extends AbstractOperation { 9 | 10 | private DrawElement element; 11 | private Matrix deltaMatrix; 12 | 13 | public DataTransformOperation(DrawElement element, Matrix deltaMatrix) { 14 | this.element = element; 15 | this.deltaMatrix = deltaMatrix; 16 | } 17 | 18 | @Override 19 | public boolean isExecutable() { 20 | return element != null; 21 | } 22 | 23 | @Override 24 | public boolean doOperation() { 25 | element.applyMatrixForData(deltaMatrix); 26 | element.updateBoundingBox(); 27 | drawingBoard.getDrawingView().notifyViewUpdated(); 28 | return true; 29 | } 30 | 31 | @Override 32 | public void undo() { 33 | element.applyMatrixForData(MatrixUtils.getInvertMatrix(deltaMatrix)); 34 | element.updateBoundingBox(); 35 | drawingBoard.getDrawingView().notifyViewUpdated(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/AutoDetectedElementOperationMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode; 2 | 3 | import android.view.MotionEvent; 4 | 5 | public class AutoDetectedElementOperationMode extends ElementOperationMode { 6 | 7 | protected boolean autoDetectMode; 8 | 9 | public AutoDetectedElementOperationMode() { 10 | } 11 | 12 | public AutoDetectedElementOperationMode(boolean autoDetectMode) { 13 | this.autoDetectMode = autoDetectMode; 14 | } 15 | 16 | public boolean isAutoDetectMode() { 17 | return autoDetectMode; 18 | } 19 | 20 | public void setAutoDetectMode(boolean autoDetectMode) { 21 | this.autoDetectMode = autoDetectMode; 22 | } 23 | 24 | @Override 25 | public boolean onTouchEvent(MotionEvent event) { 26 | switch (event.getAction()) { 27 | case MotionEvent.ACTION_DOWN: 28 | if (autoDetectMode) { 29 | detectElement(event.getX(), event.getY()); 30 | } 31 | } 32 | return super.onTouchEvent(event); 33 | } 34 | 35 | protected void detectElement(float x, float y) { 36 | setElement(elementManager.getFirstHitElement(x, y)); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/InsertElementOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import com.mocircle.cidrawing.board.ElementManager; 4 | import com.mocircle.cidrawing.element.DrawElement; 5 | 6 | public class InsertElementOperation extends AbstractOperation { 7 | 8 | private ElementManager elementManager; 9 | private DrawElement element; 10 | 11 | public InsertElementOperation(DrawElement element) { 12 | this.element = element; 13 | } 14 | 15 | @Override 16 | public void setDrawingBoardId(String boardId) { 17 | super.setDrawingBoardId(boardId); 18 | elementManager = drawingBoard.getElementManager(); 19 | } 20 | 21 | @Override 22 | public boolean isExecutable() { 23 | return element != null; 24 | } 25 | 26 | @Override 27 | public boolean doOperation() { 28 | elementManager.addElementToCurrentLayer(element); 29 | drawingBoard.getDrawingView().notifyViewUpdated(); 30 | return true; 31 | } 32 | 33 | @Override 34 | public void undo() { 35 | elementManager.removeElementFromCurrentLayer(element); 36 | drawingBoard.getDrawingView().notifyViewUpdated(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/operation/RemoveElementOperation.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.operation; 2 | 3 | import com.mocircle.cidrawing.board.ElementManager; 4 | import com.mocircle.cidrawing.element.DrawElement; 5 | 6 | public class RemoveElementOperation extends AbstractOperation { 7 | 8 | private ElementManager elementManager; 9 | private DrawElement element; 10 | 11 | public RemoveElementOperation(DrawElement element) { 12 | this.element = element; 13 | } 14 | 15 | @Override 16 | public void setDrawingBoardId(String boardId) { 17 | super.setDrawingBoardId(boardId); 18 | elementManager = drawingBoard.getElementManager(); 19 | } 20 | 21 | @Override 22 | public boolean isExecutable() { 23 | return element != null; 24 | } 25 | 26 | @Override 27 | public boolean doOperation() { 28 | elementManager.removeElementFromCurrentLayer(element); 29 | drawingBoard.getDrawingView().notifyViewUpdated(); 30 | return true; 31 | } 32 | 33 | @Override 34 | public void undo() { 35 | elementManager.addElementToCurrentLayer(element); 36 | drawingBoard.getDrawingView().notifyViewUpdated(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/behavior/Selectable.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.behavior; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Path; 5 | 6 | public interface Selectable { 7 | 8 | enum SelectionStyle { 9 | FULL, 10 | LIGHT 11 | } 12 | 13 | boolean isSelectionEnabled(); 14 | 15 | void setSelectionEnabled(boolean selectionEnabled); 16 | 17 | boolean isSelected(); 18 | 19 | void setSelected(boolean selected); 20 | 21 | void setSelected(boolean selected, SelectionStyle selectionStyle); 22 | 23 | SelectionStyle getSelectionStyle(); 24 | 25 | void drawSelection(Canvas canvas); 26 | 27 | /** 28 | * Checks if the given point is inside the element's touch area. 29 | * 30 | * @param x axis x of given point 31 | * @param y axis y of given point 32 | * @return true if hit test successful, otherwise false. 33 | */ 34 | boolean hitTestForSelection(float x, float y); 35 | 36 | /** 37 | * Checks if the given path is including the element's touch area. 38 | * 39 | * @param path given path 40 | * @return true if hit test successful, otherwise false. 41 | */ 42 | boolean hitTestForSelection(Path path); 43 | } 44 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/mode/selection/ShapeSelectionMode.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.mode.selection; 2 | 3 | import android.graphics.Path; 4 | import android.view.MotionEvent; 5 | 6 | import com.mocircle.cidrawing.core.Vector2; 7 | import com.mocircle.cidrawing.element.shape.ShapeElement; 8 | 9 | public abstract class ShapeSelectionMode extends SelectionMode { 10 | 11 | private static final String TAG = "ShapeSelectionMode"; 12 | 13 | public ShapeSelectionMode() { 14 | } 15 | 16 | @Override 17 | public boolean onTouchEvent(MotionEvent event) { 18 | switch (event.getAction()) { 19 | case MotionEvent.ACTION_MOVE: 20 | if (selectionElement instanceof ShapeElement) { 21 | ((ShapeElement) selectionElement).setupElementByVector(new Vector2(downX, downY, event.getX(), event.getY())); 22 | } 23 | return true; 24 | default: 25 | return super.onTouchEvent(event); 26 | } 27 | } 28 | 29 | @Override 30 | protected Path getSelectionPath() { 31 | if (selectionElement instanceof ShapeElement) { 32 | return ((ShapeElement) selectionElement).getElementPath(); 33 | } else { 34 | return null; 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/element/shape/LineElement.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.element.shape; 2 | 3 | import android.graphics.Path; 4 | 5 | public class LineElement extends BoxShapeElement { 6 | 7 | public LineElement() { 8 | } 9 | 10 | @Override 11 | public Path getTouchableArea() { 12 | Path path = new Path(super.getTouchableArea()); 13 | if (shapeVector != null) { 14 | // Add a noise line to make the path easy to touch 15 | final int NOISE_SIZE = 10; 16 | if (Math.abs(shapeVector.getValueX()) < Math.abs(shapeVector.getValueY())) { 17 | path.lineTo(shapeVector.getPoint2().x + NOISE_SIZE, shapeVector.getPoint2().y); 18 | } else { 19 | path.lineTo(shapeVector.getPoint2().x, shapeVector.getPoint2().y + NOISE_SIZE); 20 | } 21 | } 22 | return path; 23 | } 24 | 25 | @Override 26 | public Object clone() { 27 | LineElement element = new LineElement(); 28 | cloneTo(element); 29 | return element; 30 | } 31 | 32 | @Override 33 | protected Path createShapePath() { 34 | Path path = new Path(); 35 | path.moveTo(shapeVector.getPoint1().x, shapeVector.getPoint1().y); 36 | path.lineTo(shapeVector.getPoint2().x, shapeVector.getPoint2().y); 37 | return path; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /cidrawinglib/src/main/java/com/mocircle/cidrawing/board/Selection.java: -------------------------------------------------------------------------------- 1 | package com.mocircle.cidrawing.board; 2 | 3 | import com.mocircle.cidrawing.element.DrawElement; 4 | import com.mocircle.cidrawing.element.VirtualElement; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Element selection class. 11 | */ 12 | public class Selection { 13 | 14 | private DrawElement element; 15 | 16 | Selection(DrawElement element) { 17 | this.element = element; 18 | } 19 | 20 | public boolean isEmptySelection() { 21 | return element == null; 22 | } 23 | 24 | public boolean isMultipleSelection() { 25 | return element instanceof VirtualElement; 26 | } 27 | 28 | public DrawElement getSingleElement() { 29 | if (isMultipleSelection()) { 30 | return null; 31 | } else { 32 | return element; 33 | } 34 | } 35 | 36 | public List getElements() { 37 | if (isEmptySelection()) { 38 | return new ArrayList<>(); 39 | } 40 | if (isMultipleSelection()) { 41 | VirtualElement virtualElement = (VirtualElement) element; 42 | return virtualElement.getElements(); 43 | } else { 44 | List elements = new ArrayList<>(); 45 | elements.add(element); 46 | return elements; 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cidrawingsample/src/main/res/layout/drawer_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 |