commit
ed678be33c
|
@ -13,8 +13,8 @@ import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.print.PrintHelper
|
import androidx.print.PrintHelper
|
||||||
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
|
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
|
||||||
import com.simplemobiletools.commons.dialogs.ConfirmationAdvancedDialog
|
import com.simplemobiletools.commons.dialogs.ConfirmationAdvancedDialog
|
||||||
|
@ -30,6 +30,7 @@ import com.simplemobiletools.draw.pro.BuildConfig
|
||||||
import com.simplemobiletools.draw.pro.R
|
import com.simplemobiletools.draw.pro.R
|
||||||
import com.simplemobiletools.draw.pro.dialogs.SaveImageDialog
|
import com.simplemobiletools.draw.pro.dialogs.SaveImageDialog
|
||||||
import com.simplemobiletools.draw.pro.extensions.config
|
import com.simplemobiletools.draw.pro.extensions.config
|
||||||
|
import com.simplemobiletools.draw.pro.helpers.EyeDropper
|
||||||
import com.simplemobiletools.draw.pro.helpers.JPG
|
import com.simplemobiletools.draw.pro.helpers.JPG
|
||||||
import com.simplemobiletools.draw.pro.helpers.PNG
|
import com.simplemobiletools.draw.pro.helpers.PNG
|
||||||
import com.simplemobiletools.draw.pro.helpers.SVG
|
import com.simplemobiletools.draw.pro.helpers.SVG
|
||||||
|
@ -49,10 +50,12 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
||||||
private val BITMAP_PATH = "bitmap_path"
|
private val BITMAP_PATH = "bitmap_path"
|
||||||
private val URI_TO_LOAD = "uri_to_load"
|
private val URI_TO_LOAD = "uri_to_load"
|
||||||
|
|
||||||
|
private lateinit var eyeDropper: EyeDropper
|
||||||
|
|
||||||
private var defaultPath = ""
|
private var defaultPath = ""
|
||||||
private var defaultFilename = ""
|
private var defaultFilename = ""
|
||||||
private var defaultExtension = PNG
|
|
||||||
|
|
||||||
|
private var defaultExtension = PNG
|
||||||
private var intentUri: Uri? = null
|
private var intentUri: Uri? = null
|
||||||
private var uriToLoad: Uri? = null
|
private var uriToLoad: Uri? = null
|
||||||
private var color = 0
|
private var color = 0
|
||||||
|
@ -60,6 +63,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
||||||
private var savedPathsHash = 0L
|
private var savedPathsHash = 0L
|
||||||
private var lastSavePromptTS = 0L
|
private var lastSavePromptTS = 0L
|
||||||
private var isEraserOn = false
|
private var isEraserOn = false
|
||||||
|
private var isEyeDropperOn = false
|
||||||
private var isImageCaptureIntent = false
|
private var isImageCaptureIntent = false
|
||||||
private var isEditIntent = false
|
private var isEditIntent = false
|
||||||
private var lastBitmapPath = ""
|
private var lastBitmapPath = ""
|
||||||
|
@ -68,6 +72,11 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
appLaunched(BuildConfig.APPLICATION_ID)
|
appLaunched(BuildConfig.APPLICATION_ID)
|
||||||
|
|
||||||
|
eyeDropper = EyeDropper(my_canvas) { selectedColor ->
|
||||||
|
setColor(selectedColor)
|
||||||
|
}
|
||||||
|
|
||||||
my_canvas.mListener = this
|
my_canvas.mListener = this
|
||||||
stroke_width_bar.setOnSeekBarChangeListener(onStrokeWidthBarChangeListener)
|
stroke_width_bar.setOnSeekBarChangeListener(onStrokeWidthBarChangeListener)
|
||||||
|
|
||||||
|
@ -87,7 +96,13 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
||||||
toast(R.string.eraser)
|
toast(R.string.eraser)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
redo.setOnClickListener { my_canvas.redo() }
|
redo.setOnClickListener { my_canvas.redo() }
|
||||||
|
eye_dropper.setOnClickListener { eyeDropperClicked() }
|
||||||
|
eye_dropper.setOnLongClickListener {
|
||||||
|
toast(R.string.eyedropper)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
checkIntents()
|
checkIntents()
|
||||||
if (!isImageCaptureIntent) {
|
if (!isImageCaptureIntent) {
|
||||||
|
@ -184,7 +199,8 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
||||||
val faqItems = arrayListOf(
|
val faqItems = arrayListOf(
|
||||||
FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons),
|
FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons),
|
||||||
FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons),
|
FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons),
|
||||||
FAQItem(R.string.faq_7_title_commons, R.string.faq_7_text_commons))
|
FAQItem(R.string.faq_7_title_commons, R.string.faq_7_text_commons)
|
||||||
|
)
|
||||||
|
|
||||||
startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, false)
|
startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, false)
|
||||||
}
|
}
|
||||||
|
@ -317,7 +333,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateEraserState() {
|
private fun updateEraserState() {
|
||||||
eraser.setImageDrawable(resources.getDrawable(if (isEraserOn) R.drawable.ic_eraser_on else R.drawable.ic_eraser_off))
|
eraser.setImageDrawable(ContextCompat.getDrawable(this, if (isEraserOn) R.drawable.ic_eraser_on else R.drawable.ic_eraser_off))
|
||||||
my_canvas.toggleEraser(isEraserOn)
|
my_canvas.toggleEraser(isEraserOn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,6 +351,23 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun eyeDropperClicked() {
|
||||||
|
isEyeDropperOn = !isEyeDropperOn
|
||||||
|
if (isEyeDropperOn) {
|
||||||
|
eyeDropper.start()
|
||||||
|
} else {
|
||||||
|
eyeDropper.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
val iconId = if (isEyeDropperOn) {
|
||||||
|
R.drawable.ic_colorize_off_vector
|
||||||
|
} else {
|
||||||
|
R.drawable.ic_colorize_on_vector
|
||||||
|
}
|
||||||
|
|
||||||
|
eye_dropper.setImageResource(iconId)
|
||||||
|
}
|
||||||
|
|
||||||
private fun confirmImage() {
|
private fun confirmImage() {
|
||||||
when {
|
when {
|
||||||
isEditIntent -> {
|
isEditIntent -> {
|
||||||
|
@ -496,6 +529,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
||||||
undo.applyColorFilter(contrastColor)
|
undo.applyColorFilter(contrastColor)
|
||||||
eraser.applyColorFilter(contrastColor)
|
eraser.applyColorFilter(contrastColor)
|
||||||
redo.applyColorFilter(contrastColor)
|
redo.applyColorFilter(contrastColor)
|
||||||
|
eye_dropper.applyColorFilter(contrastColor)
|
||||||
if (isBlackAndWhiteTheme()) {
|
if (isBlackAndWhiteTheme()) {
|
||||||
stroke_width_bar.setColors(0, contrastColor, 0)
|
stroke_width_bar.setColors(0, contrastColor, 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.simplemobiletools.draw.pro.helpers
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.Matrix
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.view.View
|
||||||
|
import android.view.View.DRAWING_CACHE_QUALITY_LOW
|
||||||
|
import android.widget.ImageView
|
||||||
|
|
||||||
|
// forked from https://github.com/Madrapps/EyeDropper
|
||||||
|
class EyeDropper(private val view: View, private val onColorSelected: ((Int) -> Unit)) {
|
||||||
|
companion object {
|
||||||
|
private const val NO_COLOR = Color.TRANSPARENT
|
||||||
|
private val INVERT_MATRIX = Matrix()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var viewTouchListener = View.OnTouchListener { _, event ->
|
||||||
|
notifyColorSelection(event.x.toInt(), event.y.toInt())
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start() {
|
||||||
|
enableDrawingCache()
|
||||||
|
view.setOnTouchListener(viewTouchListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop() {
|
||||||
|
disableDrawingCache()
|
||||||
|
view.setOnTouchListener(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun enableDrawingCache() {
|
||||||
|
if (view.shouldDrawingCacheBeEnabled()) {
|
||||||
|
view.isDrawingCacheEnabled = true
|
||||||
|
view.drawingCacheQuality = DRAWING_CACHE_QUALITY_LOW
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun disableDrawingCache() {
|
||||||
|
if (view.shouldDrawingCacheBeEnabled()) {
|
||||||
|
view.isDrawingCacheEnabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notifyColorSelection(x: Int, y: Int) {
|
||||||
|
val colorAtPoint = getColorAtPoint(x, y)
|
||||||
|
onColorSelected.invoke(colorAtPoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getColorAtPoint(x: Int, y: Int): Int {
|
||||||
|
return when (view) {
|
||||||
|
is ImageView -> handleIfImageView(view, x, y)
|
||||||
|
else -> getPixelAtPoint(view.drawingCache, x, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleIfImageView(view: ImageView, x: Int, y: Int): Int {
|
||||||
|
return when (val drawable = view.drawable) {
|
||||||
|
is BitmapDrawable -> {
|
||||||
|
view.imageMatrix.invert(INVERT_MATRIX)
|
||||||
|
val mappedPoints = floatArrayOf(x.toFloat(), y.toFloat())
|
||||||
|
INVERT_MATRIX.mapPoints(mappedPoints)
|
||||||
|
getPixelAtPoint(drawable.bitmap, mappedPoints[0].toInt(), mappedPoints[1].toInt())
|
||||||
|
}
|
||||||
|
else -> NO_COLOR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getPixelAtPoint(bitmap: Bitmap, x: Int, y: Int): Int {
|
||||||
|
if (bitmap.isValidCoordinate(x, y)) {
|
||||||
|
return bitmap.getPixel(x, y)
|
||||||
|
}
|
||||||
|
return NO_COLOR
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Bitmap.isValidCoordinate(x: Int, y: Int): Boolean {
|
||||||
|
val isValidXCoordinate = x >= 1 && x < width
|
||||||
|
val isValidYCoordinate = y >= 1 && y < height
|
||||||
|
return isValidXCoordinate && isValidYCoordinate
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun View.shouldDrawingCacheBeEnabled(): Boolean = (this !is ImageView) && !isDrawingCacheEnabled
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M10.266 8.976L3 16.25V21h4.75l7.27-7.27zM6.92 19L5 17.08l6.665-6.673c3.355 3.323 1.973 1.946 1.973 1.946zM17.664 5.413l0.92 0.92L16.2 8.78l-0.983-0.973 2.447-2.394m0.43 8.09l1.41-1.41-1.92-1.92 3.12-3.12c0.4-0.4 0.4-1.03 0.01-1.42l-2.34-2.34c-0.2-0.19-0.45-0.29-0.7-0.29-0.26 0-0.51 0.1-0.71 0.29l-3.12 3.12-1.93-1.91-1.41 1.41"/>
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M3.186 3.03c-0.39 0.39-0.39 1.02 0 1.41l16.32 16.33c0.39 0.39 1.02 0.39 1.41 0 0.39-0.39 0.39-1.02 0-1.41L4.606 3.03c-0.39-0.39-1.03-0.39-1.42 0z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M17.66 5.41l0.92 0.92-2.384 2.447-0.983-0.974L17.66 5.41M17.67 3c-0.26 0-0.51 0.1-0.71 0.29l-3.12 3.12-1.93-1.91-1.41 1.41 1.42 1.42L3 16.25V21h4.75l8.92-8.92 1.42 1.42 1.41-1.41-1.92-1.92 3.12-3.12c0.4-0.4 0.4-1.03 0.01-1.42l-2.34-2.34C18.17 3.1 17.92 3 17.67 3zM6.92 19L5 17.08l8.339-8.348 1.938 1.938z"/>
|
||||||
|
</vector>
|
|
@ -23,10 +23,19 @@
|
||||||
android:id="@+id/eraser"
|
android:id="@+id/eraser"
|
||||||
android:layout_width="@dimen/normal_icon_size"
|
android:layout_width="@dimen/normal_icon_size"
|
||||||
android:layout_height="@dimen/normal_icon_size"
|
android:layout_height="@dimen/normal_icon_size"
|
||||||
android:layout_toStartOf="@+id/color_picker"
|
android:layout_toStartOf="@+id/eye_dropper"
|
||||||
android:padding="@dimen/normal_margin"
|
android:padding="@dimen/normal_margin"
|
||||||
android:src="@drawable/ic_eraser_off" />
|
android:src="@drawable/ic_eraser_off" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/eye_dropper"
|
||||||
|
android:layout_width="@dimen/normal_icon_size"
|
||||||
|
android:layout_height="@dimen/normal_icon_size"
|
||||||
|
android:layout_toStartOf="@+id/color_picker"
|
||||||
|
android:padding="@dimen/medium_margin"
|
||||||
|
android:src="@drawable/ic_colorize_vector"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/color_picker"
|
android:id="@+id/color_picker"
|
||||||
android:layout_width="@dimen/normal_icon_size"
|
android:layout_width="@dimen/normal_icon_size"
|
||||||
|
|
Loading…
Reference in New Issue