From f1c1222e1bb45ce6effcec34292b4da835b63c2a Mon Sep 17 00:00:00 2001 From: m1ga Date: Wed, 30 Nov 2022 20:07:54 +0100 Subject: [PATCH 1/5] android: bugfixes --- .../titanium/paint/PaintViewProxy.java | 18 ++++--- .../ti/modules/titanium/paint/PathPaint.java | 5 +- .../modules/titanium/paint/UIPaintView.java | 35 ++++++++++---- example/app.js | 48 +++++++++++++------ 4 files changed, 73 insertions(+), 33 deletions(-) diff --git a/android/src/ti/modules/titanium/paint/PaintViewProxy.java b/android/src/ti/modules/titanium/paint/PaintViewProxy.java index 59e3558..41143ec 100644 --- a/android/src/ti/modules/titanium/paint/PaintViewProxy.java +++ b/android/src/ti/modules/titanium/paint/PaintViewProxy.java @@ -34,33 +34,32 @@ public TiUIView createView(Activity activity) { } @Kroll.setProperty - @Kroll.method public void setStrokeWidth(Object width) { paintView.setStrokeWidth(TiConvert.toFloat(width)); } @Kroll.setProperty - @Kroll.method public void setStrokeColor(String color) { paintView.setStrokeColor(color); } @Kroll.setProperty - @Kroll.method public void setEraseMode(Boolean toggle) { paintView.setEraseMode(toggle); } @Kroll.setProperty - @Kroll.method public void setStrokeAlpha(int alpha) { paintView.setStrokeAlpha(alpha); } @Kroll.setProperty - @Kroll.method public void setImage(String imagePath) { - paintView.setImage(imagePath); + if (!TiApplication.isUIThread()) { + TiMessenger.sendBlockingMainMessage(handler.obtainMessage(MSG_LOAD)); + } else { + paintView.setImage(imagePath); + } } @Kroll.method @@ -100,6 +99,7 @@ public void clear() { } private static final int MSG_CLEAR = 60000; + private static final int MSG_LOAD = 60001; private final Handler handler = new Handler(TiMessenger.getMainMessenger().getLooper(), new Handler.Callback() { public boolean handleMessage(@NotNull Message msg) { switch (msg.what) { @@ -109,6 +109,12 @@ public boolean handleMessage(@NotNull Message msg) { result.setResult(null); return true; } + case MSG_LOAD: { + AsyncResult result = (AsyncResult) msg.obj; + paintView.setImage(result.getResult().toString()); + result.setResult(null); + return true; + } } return false; } diff --git a/android/src/ti/modules/titanium/paint/PathPaint.java b/android/src/ti/modules/titanium/paint/PathPaint.java index 1239c1a..d8f4799 100644 --- a/android/src/ti/modules/titanium/paint/PathPaint.java +++ b/android/src/ti/modules/titanium/paint/PathPaint.java @@ -6,6 +6,7 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; +import org.appcelerator.titanium.TiApplication; import org.appcelerator.titanium.util.TiConvert; public class PathPaint { @@ -20,7 +21,7 @@ public void setPaint(Paint p) { public Paint getPaint() { if (isErease) { - myPaint.setColor(TiConvert.toColor("black")); + myPaint.setColor(TiConvert.toColor("black", TiApplication.getAppCurrentActivity())); myPaint.setAlpha(0xFF); myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); myPaint.setColor(Color.TRANSPARENT); @@ -51,7 +52,7 @@ public PathPaint() { myPaint = new Paint(); myPaint.setAntiAlias(true); myPaint.setDither(true); - myPaint.setColor(TiConvert.toColor("black")); + myPaint.setColor(TiConvert.toColor("black", TiApplication.getAppCurrentActivity())); myPaint.setStyle(Paint.Style.STROKE); myPaint.setStrokeJoin(Paint.Join.ROUND); myPaint.setStrokeCap(Paint.Cap.ROUND); diff --git a/android/src/ti/modules/titanium/paint/UIPaintView.java b/android/src/ti/modules/titanium/paint/UIPaintView.java index e904e83..2a9d680 100644 --- a/android/src/ti/modules/titanium/paint/UIPaintView.java +++ b/android/src/ti/modules/titanium/paint/UIPaintView.java @@ -9,7 +9,10 @@ import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.common.Log; +import org.appcelerator.titanium.TiApplication; import org.appcelerator.titanium.TiC; +import org.appcelerator.titanium.io.TiBaseFile; +import org.appcelerator.titanium.io.TiFileFactory; import org.appcelerator.titanium.proxy.TiViewProxy; import org.appcelerator.titanium.util.TiConvert; import org.appcelerator.titanium.view.TiDrawableReference; @@ -20,6 +23,8 @@ import android.view.MotionEvent; import android.view.View; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; public class UIPaintView extends TiUIView { @@ -48,7 +53,7 @@ public UIPaintView(TiViewProxy proxy) { private void setPaintOptions() { if (currentColor == -999999999) { - currentColor = (props.containsKeyAndNotNull("strokeColor")) ? TiConvert.toColor(props, "strokeColor") : TiConvert.toColor("black"); + currentColor = (props.containsKeyAndNotNull("strokeColor")) ? TiConvert.toColor(props, "strokeColor", TiApplication.getAppCurrentActivity()) : TiConvert.toColor("black",TiApplication.getAppCurrentActivity()); } if (oldWidth == -1.0f) { @@ -82,7 +87,7 @@ public void setStrokeWidth(Float width) { public void setEraseMode(Boolean toggle) { eraseState = toggle; if (eraseState) { - tiPaint.setColor(TiConvert.toColor("black")); + tiPaint.setColor(TiConvert.toColor("black", TiApplication.getAppCurrentActivity())); tiPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); } else { tiPaint.setXfermode(null); @@ -92,7 +97,7 @@ public void setEraseMode(Boolean toggle) { public void setStrokeColor(String color) { Log.d(LCAT, "Changing stroke color."); - currentColor = TiConvert.toColor(color); + currentColor = TiConvert.toColor(color, TiApplication.getAppCurrentActivity()); tiPaint.setColor(currentColor); tiPaint.setAlpha(alphaState); } @@ -171,8 +176,12 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { if(tiBitmap == null){ if (tiImage != null) { - TiDrawableReference ref = TiDrawableReference.fromUrl(proxy, tiImage); - tiBitmap = Bitmap.createScaledBitmap(ref.getBitmap(), w, h, true); + TiDrawableReference ref = TiDrawableReference.fromUrl(proxy, proxy.resolveUrl(null, tiImage)); + if (ref.getBitmap() != null) { + tiBitmap = Bitmap.createScaledBitmap(ref.getBitmap(), w, h, true); + } else { + tiBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + } } else { tiBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); } @@ -188,9 +197,13 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { @Override protected void onDraw(Canvas canvas) { + if (tiBitmap != null) { + canvas.drawBitmap(tiBitmap, 0, 0, null); + } for (PathPaint p : tiPaths) { canvas.drawPath(p.getPath(), p.getPaint()); } + canvas.drawPath(mPath, tiPaint); } @@ -279,15 +292,17 @@ public boolean onTouchEvent(MotionEvent mainEvent) { public void setImage(String imagePath) { - Log.i(LCAT, "setImage called"); + Log.d(LCAT, "setImage called"); tiImage = imagePath; if (tiImage == null) { clear(); } else { - TiDrawableReference ref = TiDrawableReference.fromUrl(proxy, tiImage); - tiBitmap = ref.getBitmap().copy(Bitmap.Config.ARGB_8888, true); - tiCanvas = new Canvas(tiBitmap); - invalidate(); + TiDrawableReference ref = TiDrawableReference.fromUrl(proxy, proxy.resolveUrl(null, tiImage)); + if (ref.getBitmap() != null) { + tiBitmap = ref.getBitmap().copy(Bitmap.Config.ARGB_8888, true); + tiCanvas = new Canvas(tiBitmap); + invalidate(); + } } } diff --git a/example/app.js b/example/app.js index 7fc91ee..a964329 100644 --- a/example/app.js +++ b/example/app.js @@ -17,6 +17,7 @@ var paintView = Paint.createPaintView({ win.add(paintView); var buttonStrokeWidth = Ti.UI.createButton({ + height: 40, left: 10, bottom: 10, right: 10, @@ -29,6 +30,7 @@ buttonStrokeWidth.addEventListener('click', function(e) { win.add(buttonStrokeWidth); var buttonStrokeColorRed = Ti.UI.createButton({ + height: 40, bottom: 100, left: 10, title: 'Red' @@ -37,6 +39,7 @@ buttonStrokeColorRed.addEventListener('click', function() { paintView.strokeColor = 'red'; }); var buttonStrokeColorGreen = Ti.UI.createButton({ + height: 40, bottom: 70, left: 10, title: 'Green' @@ -45,6 +48,7 @@ buttonStrokeColorGreen.addEventListener('click', function() { paintView.strokeColor = '#0f0'; }); var buttonStrokeColorBlue = Ti.UI.createButton({ + height: 40, bottom: 40, left: 10, title: 'Blue' @@ -57,6 +61,7 @@ win.add(buttonStrokeColorGreen); win.add(buttonStrokeColorBlue); var clear = Ti.UI.createButton({ + height: 40, bottom: 40, left: 100, title: 'Clear' @@ -68,6 +73,7 @@ win.add(clear); if (OS_ANDROID) { var undo = Ti.UI.createButton({ + height: 40, bottom: 70, left: 100, title: 'undo' @@ -77,6 +83,7 @@ if (OS_ANDROID) { }); win.add(undo); var redo = Ti.UI.createButton({ + height: 40, bottom: 100, left: 100, title: 'redo' @@ -87,7 +94,27 @@ if (OS_ANDROID) { win.add(redo); } +var isSaved = false; +var buttonLoadSave = Ti.UI.createButton({ + height: 40, + bottom: 100, + right: 10, + title: 'Save/Load' +}); +buttonLoadSave.addEventListener('click', function(e) { + var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, "tmp.jpg"); + if (!isSaved) { + paintView.toImage(function(blob) { + file.write(blob); + alert("done"); + }) + } else { + paintView.image = file.nativePath + } + isSaved = !isSaved; +}); var buttonStrokeAlpha = Ti.UI.createButton({ + height: 40, bottom: 70, right: 10, title: 'Alpha : 100%' @@ -99,6 +126,7 @@ buttonStrokeAlpha.addEventListener('click', function(e) { win.add(buttonStrokeAlpha); var buttonStrokeColorEraser = Ti.UI.createButton({ + height: 40, bottom: 40, right: 10, title: 'Erase : Off' @@ -108,21 +136,11 @@ buttonStrokeColorEraser.addEventListener('click', function(e) { e.source.title = (paintView.eraseMode) ? 'Erase : On' : 'Erase : Off'; }); win.add(buttonStrokeColorEraser); +win.add(buttonLoadSave); -paintView.addEventListener('touchcancel', function(e) { - console.log('touchcancel event fired.'); -}); - -paintView.addEventListener('touchend', function(e) { - console.log('touchend event fired.'); -}); - -paintView.addEventListener('touchmove', function(e) { - console.log('touchmove event fired.'); -}); - -paintView.addEventListener('touchstart', function(e) { - console.log('touchstart event fired.'); -}); +paintView.addEventListener('touchcancel', function(e) {}); +paintView.addEventListener('touchend', function(e) {}); +paintView.addEventListener('touchmove', function(e) {}); +paintView.addEventListener('touchstart', function(e) {}); win.open(); From 2b8e3471a0dbd32ba77d3645cbef89dd7231a7ac Mon Sep 17 00:00:00 2001 From: m1ga Date: Wed, 30 Nov 2022 20:08:13 +0100 Subject: [PATCH 2/5] version --- android/manifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/manifest b/android/manifest index 817a8c5..c0790e0 100644 --- a/android/manifest +++ b/android/manifest @@ -2,7 +2,7 @@ # this is your module manifest and used by Titanium # during compilation, packaging, distribution, etc. # -version: 5.0.1 +version: 5.1.0 apiversion: 4 architectures: arm64-v8a armeabi-v7a x86 x86_64 description: Provides a paint surface user interface view. From faef84bca7d070d48f92e3cf59c8456a94c74412 Mon Sep 17 00:00:00 2001 From: m1ga Date: Wed, 30 Nov 2022 21:05:45 +0100 Subject: [PATCH 3/5] don't draw path in tiBitmap --- android/src/ti/modules/titanium/paint/UIPaintView.java | 1 - 1 file changed, 1 deletion(-) diff --git a/android/src/ti/modules/titanium/paint/UIPaintView.java b/android/src/ti/modules/titanium/paint/UIPaintView.java index 2a9d680..0198bb2 100644 --- a/android/src/ti/modules/titanium/paint/UIPaintView.java +++ b/android/src/ti/modules/titanium/paint/UIPaintView.java @@ -229,7 +229,6 @@ public void touch_move(float x, float y) { public void touch_up() { mPath.lineTo(mX, mY); - tiCanvas.drawPath(mPath, tiPaint); tiPaths.add(pp); mPath = new Path(); From 332026db071ba037c60d37cb404f8cf9a27acbf6 Mon Sep 17 00:00:00 2001 From: m1ga Date: Fri, 22 Mar 2024 22:07:00 +0100 Subject: [PATCH 4/5] add fill method --- .../modules/titanium/paint/PaintModule.java | 6 +- .../titanium/paint/PaintViewProxy.java | 208 +++--- .../ti/modules/titanium/paint/PathPaint.java | 92 +-- .../modules/titanium/paint/UIPaintView.java | 597 +++++++++--------- 4 files changed, 458 insertions(+), 445 deletions(-) diff --git a/android/src/ti/modules/titanium/paint/PaintModule.java b/android/src/ti/modules/titanium/paint/PaintModule.java index 777adde..f44e629 100644 --- a/android/src/ti/modules/titanium/paint/PaintModule.java +++ b/android/src/ti/modules/titanium/paint/PaintModule.java @@ -11,7 +11,7 @@ @Kroll.module(name = "Paint", id = "ti.paint") public class PaintModule extends KrollModule { - public PaintModule() { - super(); - } + public PaintModule() { + super(); + } } diff --git a/android/src/ti/modules/titanium/paint/PaintViewProxy.java b/android/src/ti/modules/titanium/paint/PaintViewProxy.java index 41143ec..f969946 100644 --- a/android/src/ti/modules/titanium/paint/PaintViewProxy.java +++ b/android/src/ti/modules/titanium/paint/PaintViewProxy.java @@ -6,6 +6,10 @@ package ti.modules.titanium.paint; +import android.app.Activity; +import android.os.Handler; +import android.os.Message; + import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.kroll.common.AsyncResult; import org.appcelerator.kroll.common.TiMessenger; @@ -15,108 +19,108 @@ import org.appcelerator.titanium.view.TiUIView; import org.jetbrains.annotations.NotNull; -import android.app.Activity; -import android.os.Handler; -import android.os.Message; - @Kroll.proxy(creatableInModule = PaintModule.class) public class PaintViewProxy extends TiViewProxy { - private UIPaintView paintView; - - public PaintViewProxy() { - super(); - } - - @Override - public TiUIView createView(Activity activity) { - paintView = new UIPaintView(this); - return paintView; - } - - @Kroll.setProperty - public void setStrokeWidth(Object width) { - paintView.setStrokeWidth(TiConvert.toFloat(width)); - } - - @Kroll.setProperty - public void setStrokeColor(String color) { - paintView.setStrokeColor(color); - } - - @Kroll.setProperty - public void setEraseMode(Boolean toggle) { - paintView.setEraseMode(toggle); - } - - @Kroll.setProperty - public void setStrokeAlpha(int alpha) { - paintView.setStrokeAlpha(alpha); - } - - @Kroll.setProperty - public void setImage(String imagePath) { - if (!TiApplication.isUIThread()) { - TiMessenger.sendBlockingMainMessage(handler.obtainMessage(MSG_LOAD)); - } else { - paintView.setImage(imagePath); - } - } - - @Kroll.method - public void lineTo(int x, int y) { - paintView.lineTo(x, y); - } - - @Kroll.method - public void moveTo(int x, int y) { - paintView.moveTo(x, y); - } - - @Kroll.method - public void undo() { - paintView.undo(); - } - - @Kroll.method - public void redo() { - paintView.redo(); - } - - @Kroll.method - public void enable(boolean enable) { - paintView.enable(enable); - } - - @Kroll.method - public void clear() { - if (paintView != null) { - if (!TiApplication.isUIThread()) { - TiMessenger.sendBlockingMainMessage(handler.obtainMessage(MSG_CLEAR)); - } else { - paintView.clear(); - } - } - } - - private static final int MSG_CLEAR = 60000; - private static final int MSG_LOAD = 60001; - private final Handler handler = new Handler(TiMessenger.getMainMessenger().getLooper(), new Handler.Callback() { - public boolean handleMessage(@NotNull Message msg) { - switch (msg.what) { - case MSG_CLEAR: { - AsyncResult result = (AsyncResult) msg.obj; - paintView.clear(); - result.setResult(null); - return true; - } - case MSG_LOAD: { - AsyncResult result = (AsyncResult) msg.obj; - paintView.setImage(result.getResult().toString()); - result.setResult(null); - return true; - } - } - return false; - } - }); + private static final int MSG_CLEAR = 60000; + private static final int MSG_LOAD = 60001; + private UIPaintView paintView; + private final Handler handler = new Handler(TiMessenger.getMainMessenger().getLooper(), new Handler.Callback() { + public boolean handleMessage(@NotNull Message msg) { + switch (msg.what) { + case MSG_CLEAR: { + AsyncResult result = (AsyncResult) msg.obj; + paintView.clear(); + result.setResult(null); + return true; + } + case MSG_LOAD: { + AsyncResult result = (AsyncResult) msg.obj; + paintView.setImage(result.getResult().toString()); + result.setResult(null); + return true; + } + } + return false; + } + }); + + public PaintViewProxy() { + super(); + } + + @Override + public TiUIView createView(Activity activity) { + paintView = new UIPaintView(this); + return paintView; + } + + @Kroll.setProperty + public void setStrokeWidth(Object width) { + paintView.setStrokeWidth(TiConvert.toFloat(width)); + } + + @Kroll.setProperty + public void setStrokeColor(String color) { + paintView.setStrokeColor(color); + } + + @Kroll.setProperty + public void setEraseMode(Boolean toggle) { + paintView.setEraseMode(toggle); + } + + @Kroll.setProperty + public void setStrokeAlpha(int alpha) { + paintView.setStrokeAlpha(alpha); + } + + @Kroll.setProperty + public void setImage(String imagePath) { + if (!TiApplication.isUIThread()) { + TiMessenger.sendBlockingMainMessage(handler.obtainMessage(MSG_LOAD)); + } else { + paintView.setImage(imagePath); + } + } + + @Kroll.method + public void fill(String color) { + paintView.fill(TiConvert.toColor(color, TiApplication.getAppCurrentActivity())); + } + + @Kroll.method + public void lineTo(int x, int y) { + paintView.lineTo(x, y); + } + + @Kroll.method + public void moveTo(int x, int y) { + paintView.moveTo(x, y); + } + + @Kroll.method + public void undo() { + paintView.undo(); + } + + @Kroll.method + public void redo() { + paintView.redo(); + } + + @Kroll.method + public void enable(boolean enable) { + paintView.enable(enable); + } + + @Kroll.method + public void clear() { + if (paintView != null) { + if (!TiApplication.isUIThread()) { + TiMessenger.sendBlockingMainMessage(handler.obtainMessage(MSG_CLEAR)); + } else { + paintView.clear(); + } + } + } } diff --git a/android/src/ti/modules/titanium/paint/PathPaint.java b/android/src/ti/modules/titanium/paint/PathPaint.java index d8f4799..47d08ec 100644 --- a/android/src/ti/modules/titanium/paint/PathPaint.java +++ b/android/src/ti/modules/titanium/paint/PathPaint.java @@ -11,50 +11,50 @@ public class PathPaint { - private Path myPath; - private Paint myPaint; - private Boolean isErease = false; - - public void setPaint(Paint p) { - myPaint = p; - } - - public Paint getPaint() { - if (isErease) { - myPaint.setColor(TiConvert.toColor("black", TiApplication.getAppCurrentActivity())); - myPaint.setAlpha(0xFF); - myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); - myPaint.setColor(Color.TRANSPARENT); - } - return myPaint; - } - - public Path getPath() { - return myPath; - } - - public void setPath(Path p) { - myPath = p; - } - - public Boolean getEarase() { - return isErease; - } - - public void setEarase(Boolean p) { - isErease = p; - } - - public PathPaint() { - myPath = new Path(); - myPaint = new Paint(); - - myPaint = new Paint(); - myPaint.setAntiAlias(true); - myPaint.setDither(true); - myPaint.setColor(TiConvert.toColor("black", TiApplication.getAppCurrentActivity())); - myPaint.setStyle(Paint.Style.STROKE); - myPaint.setStrokeJoin(Paint.Join.ROUND); - myPaint.setStrokeCap(Paint.Cap.ROUND); - } + private Path myPath; + private Paint myPaint; + private Boolean isErease = false; + + public PathPaint() { + myPath = new Path(); + myPaint = new Paint(); + + myPaint = new Paint(); + myPaint.setAntiAlias(true); + myPaint.setDither(true); + myPaint.setColor(TiConvert.toColor("black", TiApplication.getAppCurrentActivity())); + myPaint.setStyle(Paint.Style.STROKE); + myPaint.setStrokeJoin(Paint.Join.ROUND); + myPaint.setStrokeCap(Paint.Cap.ROUND); + } + + public Paint getPaint() { + if (isErease) { + myPaint.setColor(TiConvert.toColor("black", TiApplication.getAppCurrentActivity())); + myPaint.setAlpha(0xFF); + myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); + myPaint.setColor(Color.TRANSPARENT); + } + return myPaint; + } + + public void setPaint(Paint p) { + myPaint = p; + } + + public Path getPath() { + return myPath; + } + + public void setPath(Path p) { + myPath = p; + } + + public Boolean getEarase() { + return isErease; + } + + public void setEarase(Boolean p) { + isErease = p; + } } diff --git a/android/src/ti/modules/titanium/paint/UIPaintView.java b/android/src/ti/modules/titanium/paint/UIPaintView.java index 0198bb2..8042af3 100644 --- a/android/src/ti/modules/titanium/paint/UIPaintView.java +++ b/android/src/ti/modules/titanium/paint/UIPaintView.java @@ -6,310 +6,319 @@ package ti.modules.titanium.paint; -import org.appcelerator.kroll.KrollDict; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.view.MotionEvent; +import android.view.View; +import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.common.Log; import org.appcelerator.titanium.TiApplication; -import org.appcelerator.titanium.TiC; -import org.appcelerator.titanium.io.TiBaseFile; -import org.appcelerator.titanium.io.TiFileFactory; import org.appcelerator.titanium.proxy.TiViewProxy; import org.appcelerator.titanium.util.TiConvert; import org.appcelerator.titanium.view.TiDrawableReference; import org.appcelerator.titanium.view.TiUIView; -import android.content.Context; -import android.graphics.*; -import android.view.MotionEvent; -import android.view.View; - -import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; public class UIPaintView extends TiUIView { - private static final String LCAT = "UIPaintView"; - - public Paint tiPaint; - public PaintView tiPaintView; - private KrollDict props; - private Boolean eraseState = false; - private int currentColor = -999999999; - private int alphaState = -1; - private Float oldWidth = -1.0f; - - public UIPaintView(TiViewProxy proxy) { - super(proxy); - - props = proxy.getProperties(); - setPaintOptions(); // set initial paint options - - setNativeView(tiPaintView = new PaintView(proxy.getActivity())); - - if (props.containsKeyAndNotNull("image")) { - tiPaintView.setImage(props.getString("image")); - } - } - - private void setPaintOptions() { - if (currentColor == -999999999) { - currentColor = (props.containsKeyAndNotNull("strokeColor")) ? TiConvert.toColor(props, "strokeColor", TiApplication.getAppCurrentActivity()) : TiConvert.toColor("black",TiApplication.getAppCurrentActivity()); - } - - if (oldWidth == -1.0f) { - oldWidth = (props.containsKeyAndNotNull("strokeWidth")) ? TiConvert.toFloat(props.get("strokeWidth")) : 12.0f; - } - - if (alphaState == -1 ){ - alphaState = (props.containsKeyAndNotNull("strokeAlpha")) ? TiConvert.toInt(props.get("strokeAlpha")) : 255; - } - tiPaint = new Paint(); - tiPaint.setAntiAlias(true); - tiPaint.setDither(true); - tiPaint.setColor(currentColor); - tiPaint.setStyle(Paint.Style.STROKE); - tiPaint.setStrokeJoin(Paint.Join.ROUND); - tiPaint.setStrokeCap(Paint.Cap.ROUND); - - tiPaint.setStrokeWidth(oldWidth); - tiPaint.setAlpha(alphaState); - - } - - public void setStrokeWidth(Float width) { - Log.d(LCAT, "Changing stroke width."); - tiPaint.setStrokeWidth(width); - tiPaint.setAlpha(alphaState); - oldWidth = width; - } - - - public void setEraseMode(Boolean toggle) { - eraseState = toggle; - if (eraseState) { - tiPaint.setColor(TiConvert.toColor("black", TiApplication.getAppCurrentActivity())); - tiPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); - } else { - tiPaint.setXfermode(null); - } - tiPaintView.newPath(); - } - - public void setStrokeColor(String color) { - Log.d(LCAT, "Changing stroke color."); - currentColor = TiConvert.toColor(color, TiApplication.getAppCurrentActivity()); - tiPaint.setColor(currentColor); - tiPaint.setAlpha(alphaState); - } - - public void setStrokeAlpha(int alpha) { - Log.d(LCAT, "Changing stroke alpha."); - tiPaint.setAlpha(alpha); - alphaState = alpha; - } - - public void setImage(String imagePath) { - Log.d(LCAT, "Changing image."); - tiPaintView.setImage(imagePath); - } - - public void clear() { - Log.d(LCAT, "Clearing."); - tiPaintView.clear(); - } - - public void moveTo(int x, int y) { - tiPaintView.touch_up(); - tiPaintView.touch_start( x, y); - tiPaintView.invalidate(); - } - - public void lineTo(int x, int y) { - tiPaintView.touch_move( x, y); - tiPaintView.invalidate(); - } - - public void enable(boolean enable) { - tiPaintView.enable(enable); - } - - public void undo() { - tiPaintView.undo(); - } - - public void redo() { - tiPaintView.redo(); - } - - public class PaintView extends View { - - private static final int maxTouchPoints = 20; - - private float mX, mY; - - private ArrayList tiPaths = new ArrayList(); - private ArrayList undoPaths = new ArrayList(); - private Path mPath; - private Bitmap tiBitmap; - private String tiImage; - private Canvas tiCanvas; - private Paint tiBitmapPaint; - private boolean enabled = true; - private PathPaint pp; - - public PaintView(Context c) { - super(c); - tiBitmapPaint = new Paint(Paint.DITHER_FLAG); - mPath = new Path(); - - pp = new PathPaint(); - pp.setPath(mPath); - pp.setPaint(tiPaint); - pp.setEarase(eraseState); - - setLayerType(View.LAYER_TYPE_SOFTWARE, null); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - - if(tiBitmap == null){ - if (tiImage != null) { - TiDrawableReference ref = TiDrawableReference.fromUrl(proxy, proxy.resolveUrl(null, tiImage)); - if (ref.getBitmap() != null) { - tiBitmap = Bitmap.createScaledBitmap(ref.getBitmap(), w, h, true); - } else { - tiBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); - } - } else { - tiBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); - } - tiCanvas = new Canvas(tiBitmap); - } - else { - tiBitmap = Bitmap.createScaledBitmap(tiBitmap, w, h, true); - tiCanvas = new Canvas(tiBitmap); - } - - } - - - @Override - protected void onDraw(Canvas canvas) { - if (tiBitmap != null) { - canvas.drawBitmap(tiBitmap, 0, 0, null); - } - for (PathPaint p : tiPaths) { - canvas.drawPath(p.getPath(), p.getPaint()); - } - - canvas.drawPath(mPath, tiPaint); - } - - public void touch_start(float x, float y) { - setPaintOptions(); - undoPaths.clear(); - mPath.reset(); - mPath.moveTo(x, y); - mX = x; - mY = y; - } - - public void enable(boolean enable) { - enabled = enable; - } - - public void touch_move(float x, float y) { - mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); - - mX = x; - mY = y; - } - - public void touch_up() { - mPath.lineTo(mX, mY); - tiPaths.add(pp); - - mPath = new Path(); - pp = new PathPaint(); - pp.setPath(mPath); - pp.setPaint(tiPaint); - pp.setEarase(eraseState); - } - - public void newPath(){ - mPath = new Path(); - pp = new PathPaint(); - pp.setPath(mPath); - pp.setPaint(tiPaint); - pp.setEarase(eraseState); - } - - public void undo() { - if (tiPaths.size()>0) { - undoPaths.add(tiPaths.remove(tiPaths.size()-1)); - invalidate(); - } - } - - public void redo() { - if (undoPaths.size()>0) { - tiPaths.add(undoPaths.remove(undoPaths.size()-1)); - invalidate(); - } - } - - @Override - public boolean onTouchEvent(MotionEvent mainEvent) { - if (enabled) { - for (int i = 0; i < mainEvent.getPointerCount(); i++) { - float x = mainEvent.getX(i); - float y = mainEvent.getY(i); - int action = mainEvent.getAction(); - if (action > 6) { - action = (action % 256) - 5; - } - switch (action) { - case MotionEvent.ACTION_DOWN: - touch_start(x, y); - invalidate(); - break; - case MotionEvent.ACTION_MOVE: - touch_move(x, y); - invalidate(); - break; - case MotionEvent.ACTION_UP: - touch_up(); - invalidate(); - break; - } - } - } - return true; - } - - - public void setImage(String imagePath) { - Log.d(LCAT, "setImage called"); - tiImage = imagePath; - if (tiImage == null) { - clear(); - } else { - TiDrawableReference ref = TiDrawableReference.fromUrl(proxy, proxy.resolveUrl(null, tiImage)); - if (ref.getBitmap() != null) { - tiBitmap = ref.getBitmap().copy(Bitmap.Config.ARGB_8888, true); - tiCanvas = new Canvas(tiBitmap); - invalidate(); - } - } - } - - public void clear() { - tiBitmap.eraseColor(Color.TRANSPARENT); - tiPaths.clear(); - invalidate(); - } - } + private static final String LCAT = "UIPaintView"; + + public Paint tiPaint; + public PaintView tiPaintView; + private final KrollDict props; + private Boolean eraseState = false; + private int currentColor = -999999999; + private int alphaState = -1; + private Float oldWidth = -1.0f; + + public UIPaintView(TiViewProxy proxy) { + super(proxy); + + props = proxy.getProperties(); + setPaintOptions(); // set initial paint options + + setNativeView(tiPaintView = new PaintView(proxy.getActivity())); + + if (props.containsKeyAndNotNull("image")) { + tiPaintView.setImage(props.getString("image")); + } + } + + private void setPaintOptions() { + if (currentColor == -999999999) { + currentColor = (props.containsKeyAndNotNull("strokeColor")) ? TiConvert.toColor(props, "strokeColor", TiApplication.getAppCurrentActivity()) : TiConvert.toColor("black", TiApplication.getAppCurrentActivity()); + } + + if (oldWidth == -1.0f) { + oldWidth = (props.containsKeyAndNotNull("strokeWidth")) ? TiConvert.toFloat(props.get("strokeWidth")) : 12.0f; + } + + if (alphaState == -1) { + alphaState = (props.containsKeyAndNotNull("strokeAlpha")) ? TiConvert.toInt(props.get("strokeAlpha")) : 255; + } + tiPaint = new Paint(); + tiPaint.setAntiAlias(true); + tiPaint.setDither(true); + tiPaint.setColor(currentColor); + tiPaint.setStyle(Paint.Style.STROKE); + tiPaint.setStrokeJoin(Paint.Join.ROUND); + tiPaint.setStrokeCap(Paint.Cap.ROUND); + + tiPaint.setStrokeWidth(oldWidth); + tiPaint.setAlpha(alphaState); + + } + + public void setStrokeWidth(Float width) { + Log.d(LCAT, "Changing stroke width."); + tiPaint.setStrokeWidth(width); + tiPaint.setAlpha(alphaState); + oldWidth = width; + } + + + public void setEraseMode(Boolean toggle) { + eraseState = toggle; + if (eraseState) { + tiPaint.setColor(TiConvert.toColor("black", TiApplication.getAppCurrentActivity())); + tiPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); + } else { + tiPaint.setXfermode(null); + } + tiPaintView.newPath(); + } + + public void setStrokeColor(String color) { + Log.d(LCAT, "Changing stroke color."); + currentColor = TiConvert.toColor(color, TiApplication.getAppCurrentActivity()); + tiPaint.setColor(currentColor); + tiPaint.setAlpha(alphaState); + } + + public void setStrokeAlpha(int alpha) { + Log.d(LCAT, "Changing stroke alpha."); + tiPaint.setAlpha(alpha); + alphaState = alpha; + } + + public void setImage(String imagePath) { + Log.d(LCAT, "Changing image."); + tiPaintView.setImage(imagePath); + } + + public void clear() { + Log.d(LCAT, "Clearing."); + tiPaintView.clear(); + } + + public void moveTo(int x, int y) { + tiPaintView.touch_up(); + tiPaintView.touch_start(x, y); + tiPaintView.invalidate(); + } + + public void lineTo(int x, int y) { + tiPaintView.touch_move(x, y); + tiPaintView.invalidate(); + } + + public void fill(int color) { + tiPaintView.fill(color); + } + + public void enable(boolean enable) { + tiPaintView.enable(enable); + } + + public void undo() { + tiPaintView.undo(); + } + + public void redo() { + tiPaintView.redo(); + } + + public class PaintView extends View { + + private static final int maxTouchPoints = 20; + + private float mX, mY; + + private final ArrayList tiPaths = new ArrayList(); + private final ArrayList undoPaths = new ArrayList(); + private Path mPath; + private Bitmap tiBitmap; + private String tiImage; + private Canvas tiCanvas; + private final Paint tiBitmapPaint; + private boolean enabled = true; + private PathPaint pp; + + public PaintView(Context c) { + super(c); + tiBitmapPaint = new Paint(Paint.DITHER_FLAG); + mPath = new Path(); + + pp = new PathPaint(); + pp.setPath(mPath); + pp.setPaint(tiPaint); + pp.setEarase(eraseState); + + setLayerType(View.LAYER_TYPE_SOFTWARE, null); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + if (tiBitmap == null) { + if (tiImage != null) { + TiDrawableReference ref = TiDrawableReference.fromUrl(proxy, proxy.resolveUrl(null, tiImage)); + if (ref.getBitmap() != null) { + tiBitmap = Bitmap.createScaledBitmap(ref.getBitmap(), w, h, true); + } else { + tiBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + } + } else { + tiBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + } + tiCanvas = new Canvas(tiBitmap); + } else { + tiBitmap = Bitmap.createScaledBitmap(tiBitmap, w, h, true); + tiCanvas = new Canvas(tiBitmap); + } + + } + + + @Override + protected void onDraw(Canvas canvas) { + if (tiBitmap != null) { + canvas.drawBitmap(tiBitmap, 0, 0, null); + } + for (PathPaint p : tiPaths) { + canvas.drawPath(p.getPath(), p.getPaint()); + } + + canvas.drawPath(mPath, tiPaint); + } + + public void touch_start(float x, float y) { + setPaintOptions(); + undoPaths.clear(); + mPath.reset(); + mPath.moveTo(x, y); + mX = x; + mY = y; + } + + public void enable(boolean enable) { + enabled = enable; + } + + public void touch_move(float x, float y) { + mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); + + mX = x; + mY = y; + } + + public void touch_up() { + mPath.lineTo(mX, mY); + tiPaths.add(pp); + + mPath = new Path(); + pp = new PathPaint(); + pp.setPath(mPath); + pp.setPaint(tiPaint); + pp.setEarase(eraseState); + } + + public void newPath() { + mPath = new Path(); + pp = new PathPaint(); + pp.setPath(mPath); + pp.setPaint(tiPaint); + pp.setEarase(eraseState); + } + + public void undo() { + if (tiPaths.size() > 0) { + undoPaths.add(tiPaths.remove(tiPaths.size() - 1)); + invalidate(); + } + } + + public void redo() { + if (undoPaths.size() > 0) { + tiPaths.add(undoPaths.remove(undoPaths.size() - 1)); + invalidate(); + } + } + + public void fill(int color) { + tiBitmap.eraseColor(color); + tiPaths.clear(); + invalidate(); + } + + @Override + public boolean onTouchEvent(MotionEvent mainEvent) { + if (enabled) { + for (int i = 0; i < mainEvent.getPointerCount(); i++) { + float x = mainEvent.getX(i); + float y = mainEvent.getY(i); + int action = mainEvent.getAction(); + if (action > 6) { + action = (action % 256) - 5; + } + switch (action) { + case MotionEvent.ACTION_DOWN: + touch_start(x, y); + invalidate(); + break; + case MotionEvent.ACTION_MOVE: + touch_move(x, y); + invalidate(); + break; + case MotionEvent.ACTION_UP: + touch_up(); + invalidate(); + break; + } + } + } + return true; + } + + + public void setImage(String imagePath) { + Log.d(LCAT, "setImage called"); + tiImage = imagePath; + if (tiImage == null) { + clear(); + } else { + TiDrawableReference ref = TiDrawableReference.fromUrl(proxy, proxy.resolveUrl(null, tiImage)); + if (ref.getBitmap() != null) { + tiBitmap = ref.getBitmap().copy(Bitmap.Config.ARGB_8888, true); + tiCanvas = new Canvas(tiBitmap); + invalidate(); + } + } + } + + public void clear() { + tiBitmap.eraseColor(Color.TRANSPARENT); + tiPaths.clear(); + invalidate(); + } + } } From 62af511524add628bf935287563dfc88965aef6a Mon Sep 17 00:00:00 2001 From: m1ga Date: Fri, 22 Mar 2024 22:07:36 +0100 Subject: [PATCH 5/5] add fill method --- README.md | 3 +++ example/app.js | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 178f7ba..5c4ee16 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,9 @@ Disable drawing * undo()/redo() [Android only] Undo or redo last action +* fill(color) [Android only] +Fills the whole paint view with a solid color + ### Properties diff --git a/example/app.js b/example/app.js index a964329..10e55b5 100644 --- a/example/app.js +++ b/example/app.js @@ -88,10 +88,16 @@ if (OS_ANDROID) { left: 100, title: 'redo' }); - redo.addEventListener('click', function() { - paintView.redo(); + var fill = Ti.UI.createButton({ + height: 40, + bottom: 130, + left: 10, + title: 'fill' + }); + fill.addEventListener('click', function() { + paintView.fill("#ff0000"); }); - win.add(redo); + win.add(fill); } var isSaved = false;