Merge pull request #288 from fatihergin/feature/viewbinding-and-sdk-34-migration

Feature/viewbinding and sdk 34 migration
This commit is contained in:
Tibor Kaputa 2023-08-21 20:55:32 +02:00 committed by GitHub
commit d09b75d4b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 205 additions and 152 deletions

View File

@ -1,6 +1,5 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
def keystorePropertiesFile = rootProject.file("keystore.properties") def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties() def keystoreProperties = new Properties()
@ -9,12 +8,13 @@ if (keystorePropertiesFile.exists()) {
} }
android { android {
compileSdkVersion 33 namespace "com.simplemobiletools.draw.pro"
compileSdk 34
defaultConfig { defaultConfig {
applicationId "com.simplemobiletools.draw.pro" applicationId "com.simplemobiletools.draw.pro"
minSdkVersion 23 minSdk 23
targetSdkVersion 33 targetSdk 34
versionCode 79 versionCode 79
versionName "6.9.3" versionName "6.9.3"
setProperty("archivesBaseName", "draw") setProperty("archivesBaseName", "draw")
@ -32,6 +32,11 @@ android {
} }
} }
buildFeatures {
buildConfig true
viewBinding true
}
buildTypes { buildTypes {
debug { debug {
applicationIdSuffix ".debug" applicationIdSuffix ".debug"
@ -45,7 +50,16 @@ android {
} }
} }
flavorDimensions "variants" compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
flavorDimensions = ["variants"]
productFlavors { productFlavors {
core {} core {}
fdroid {} fdroid {}
@ -63,6 +77,6 @@ android {
} }
dependencies { dependencies {
implementation 'com.github.SimpleMobileTools:Simple-Commons:4c83ec8740' implementation 'com.github.SimpleMobileTools:Simple-Commons:0e173dc5ad'
implementation "androidx.print:print:1.0.0" implementation "androidx.print:print:1.0.0"
} }

View File

@ -28,6 +28,7 @@ import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.commons.models.Release import com.simplemobiletools.commons.models.Release
import com.simplemobiletools.draw.pro.BuildConfig import com.simplemobiletools.draw.pro.BuildConfig
import com.simplemobiletools.draw.pro.R import com.simplemobiletools.draw.pro.R
import com.simplemobiletools.draw.pro.databinding.ActivityMainBinding
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.EyeDropper
@ -36,19 +37,22 @@ import com.simplemobiletools.draw.pro.helpers.PNG
import com.simplemobiletools.draw.pro.helpers.SVG import com.simplemobiletools.draw.pro.helpers.SVG
import com.simplemobiletools.draw.pro.interfaces.CanvasListener import com.simplemobiletools.draw.pro.interfaces.CanvasListener
import com.simplemobiletools.draw.pro.models.Svg import com.simplemobiletools.draw.pro.models.Svg
import kotlinx.android.synthetic.main.activity_main.*
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
import java.io.OutputStream import java.io.OutputStream
class MainActivity : SimpleActivity(), CanvasListener { class MainActivity : SimpleActivity(), CanvasListener {
private val PICK_IMAGE_INTENT = 1 companion object {
private val SAVE_IMAGE_INTENT = 2 private const val PICK_IMAGE_INTENT = 1
private const val SAVE_IMAGE_INTENT = 2
private val FOLDER_NAME = "images" private const val FOLDER_NAME = "images"
private val FILE_NAME = "simple-draw.png" private const val FILE_NAME = "simple-draw.png"
private val BITMAP_PATH = "bitmap_path" private const val BITMAP_PATH = "bitmap_path"
private val URI_TO_LOAD = "uri_to_load" private const val URI_TO_LOAD = "uri_to_load"
}
private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivityMainBinding.inflate(layoutInflater) }
private lateinit var eyeDropper: EyeDropper private lateinit var eyeDropper: EyeDropper
@ -71,17 +75,17 @@ class MainActivity : SimpleActivity(), CanvasListener {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(binding.root)
appLaunched(BuildConfig.APPLICATION_ID) appLaunched(BuildConfig.APPLICATION_ID)
setupOptionsMenu() setupOptionsMenu()
refreshMenuItems() refreshMenuItems()
eyeDropper = EyeDropper(my_canvas) { selectedColor -> eyeDropper = EyeDropper(binding.myCanvas) { selectedColor ->
setColor(selectedColor) setColor(selectedColor)
} }
my_canvas.mListener = this binding.myCanvas.mListener = this
stroke_width_bar.onSeekBarChangeListener { progress -> binding.strokeWidthBar.onSeekBarChangeListener { progress ->
brushSize = Math.max(progress.toFloat(), 5f) brushSize = Math.max(progress.toFloat(), 5f)
updateBrushSize() updateBrushSize()
} }
@ -93,37 +97,39 @@ class MainActivity : SimpleActivity(), CanvasListener {
brushSize = config.brushSize brushSize = config.brushSize
updateBrushSize() updateBrushSize()
stroke_width_bar.progress = brushSize.toInt() binding.strokeWidthBar.progress = brushSize.toInt()
color_picker.setOnClickListener { pickColor() } binding.apply {
undo.setOnClickListener { my_canvas.undo() } colorPicker.setOnClickListener { pickColor() }
undo.setOnLongClickListener { undo.setOnClickListener { myCanvas.undo() }
toast(R.string.undo) undo.setOnLongClickListener {
true toast(R.string.undo)
} true
}
eraser.setOnClickListener { eraserClicked() } eraser.setOnClickListener { eraserClicked() }
eraser.setOnLongClickListener { eraser.setOnLongClickListener {
toast(R.string.eraser) toast(R.string.eraser)
true true
} }
redo.setOnClickListener { my_canvas.redo() } redo.setOnClickListener { myCanvas.redo() }
redo.setOnLongClickListener { redo.setOnLongClickListener {
toast(R.string.redo) toast(R.string.redo)
true true
} }
eye_dropper.setOnClickListener { eyeDropperClicked() } eyeDropper.setOnClickListener { eyeDropperClicked() }
eye_dropper.setOnLongClickListener { eyeDropper.setOnLongClickListener {
toast(R.string.eyedropper) toast(R.string.eyedropper)
true true
} }
bucket_fill.setOnClickListener { bucketFillClicked() } bucketFill.setOnClickListener { bucketFillClicked() }
bucket_fill.setOnLongClickListener { bucketFill.setOnLongClickListener {
toast(R.string.bucket_fill) toast(R.string.bucket_fill)
true true
}
} }
checkIntents() checkIntents()
@ -138,15 +144,17 @@ class MainActivity : SimpleActivity(), CanvasListener {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
setupToolbar(main_toolbar, statusBarColor = getProperBackgroundColor()) setupToolbar(binding.mainToolbar, statusBarColor = getProperBackgroundColor())
val isShowBrushSizeEnabled = config.showBrushSize binding.apply {
stroke_width_bar.beVisibleIf(isShowBrushSizeEnabled) val isShowBrushSizeEnabled = config.showBrushSize
stroke_width_preview.beVisibleIf(isShowBrushSizeEnabled) strokeWidthBar.beVisibleIf(isShowBrushSizeEnabled)
my_canvas.setAllowZooming(config.allowZoomingCanvas) strokeWidthPreview.beVisibleIf(isShowBrushSizeEnabled)
updateTextColors(main_holder) myCanvas.setAllowZooming(config.allowZoomingCanvas)
if (isBlackAndWhiteTheme()) { updateTextColors(mainHolder)
stroke_width_bar.setColors(0, config.canvasBackgroundColor.getContrastColor(), 0) if (isBlackAndWhiteTheme()) {
strokeWidthBar.setColors(0, config.canvasBackgroundColor.getContrastColor(), 0)
}
} }
if (config.preventPhoneFromSleeping) { if (config.preventPhoneFromSleeping) {
@ -169,11 +177,11 @@ class MainActivity : SimpleActivity(), CanvasListener {
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
my_canvas.mListener = null binding.myCanvas.mListener = null
} }
private fun refreshMenuItems() { private fun refreshMenuItems() {
main_toolbar.menu.apply { binding.mainToolbar.menu.apply {
findItem(R.id.menu_confirm).isVisible = isImageCaptureIntent || isEditIntent findItem(R.id.menu_confirm).isVisible = isImageCaptureIntent || isEditIntent
findItem(R.id.menu_save).isVisible = !isImageCaptureIntent && !isEditIntent findItem(R.id.menu_save).isVisible = !isImageCaptureIntent && !isEditIntent
findItem(R.id.menu_share).isVisible = !isImageCaptureIntent && !isEditIntent findItem(R.id.menu_share).isVisible = !isImageCaptureIntent && !isEditIntent
@ -183,7 +191,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
} }
private fun setupOptionsMenu() { private fun setupOptionsMenu() {
main_toolbar.setOnMenuItemClickListener { menuItem -> binding.mainToolbar.setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) { when (menuItem.itemId) {
R.id.menu_confirm -> confirmImage() R.id.menu_confirm -> confirmImage()
R.id.menu_save -> trySaveImage() R.id.menu_save -> trySaveImage()
@ -202,7 +210,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
} }
override fun onBackPressed() { override fun onBackPressed() {
val hasUnsavedChanges = savedPathsHash != my_canvas.getDrawingHashCode() val hasUnsavedChanges = savedPathsHash != binding.myCanvas.getDrawingHashCode()
if (hasUnsavedChanges && System.currentTimeMillis() - lastSavePromptTS > SAVE_DISCARD_PROMPT_INTERVAL) { if (hasUnsavedChanges && System.currentTimeMillis() - lastSavePromptTS > SAVE_DISCARD_PROMPT_INTERVAL) {
lastSavePromptTS = System.currentTimeMillis() lastSavePromptTS = System.currentTimeMillis()
ConfirmationAdvancedDialog(this, "", R.string.save_before_closing, R.string.save, R.string.discard) { ConfirmationAdvancedDialog(this, "", R.string.save_before_closing, R.string.save, R.string.discard) {
@ -244,11 +252,11 @@ class MainActivity : SimpleActivity(), CanvasListener {
} else if (requestCode == SAVE_IMAGE_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) { } else if (requestCode == SAVE_IMAGE_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
val outputStream = contentResolver.openOutputStream(resultData.data!!) val outputStream = contentResolver.openOutputStream(resultData.data!!)
if (defaultExtension == SVG) { if (defaultExtension == SVG) {
Svg.saveToOutputStream(this, outputStream, my_canvas) Svg.saveToOutputStream(this, outputStream, binding.myCanvas)
} else { } else {
saveToOutputStream(outputStream, defaultExtension.getCompressionFormat(), false) saveToOutputStream(outputStream, defaultExtension.getCompressionFormat(), false)
} }
savedPathsHash = my_canvas.getDrawingHashCode() savedPathsHash = binding.myCanvas.getDrawingHashCode()
} }
} }
@ -318,26 +326,30 @@ class MainActivity : SimpleActivity(), CanvasListener {
uriToLoad = uri uriToLoad = uri
openPath(uri.path!!) openPath(uri.path!!)
} }
uri.scheme == "content" -> { uri.scheme == "content" -> {
uriToLoad = uri uriToLoad = uri
openUri(uri, intent) openUri(uri, intent)
} }
else -> false else -> false
} }
private fun openPath(path: String) = when { private fun openPath(path: String) = when {
path.endsWith(".svg") -> { path.endsWith(".svg") -> {
my_canvas.mBackgroundBitmap = null binding.myCanvas.mBackgroundBitmap = null
Svg.loadSvg(this, File(path), my_canvas) Svg.loadSvg(this, File(path), binding.myCanvas)
defaultExtension = SVG defaultExtension = SVG
true true
} }
File(path).isImageSlow() -> { File(path).isImageSlow() -> {
lastBitmapPath = path lastBitmapPath = path
my_canvas.drawBitmap(this, path) binding.myCanvas.drawBitmap(this, path)
defaultExtension = JPG defaultExtension = JPG
true true
} }
else -> { else -> {
toast(R.string.invalid_file_format) toast(R.string.invalid_file_format)
false false
@ -349,16 +361,18 @@ class MainActivity : SimpleActivity(), CanvasListener {
val type = mime.getExtensionFromMimeType(contentResolver.getType(uri)) ?: intent.type ?: contentResolver.getType(uri) val type = mime.getExtensionFromMimeType(contentResolver.getType(uri)) ?: intent.type ?: contentResolver.getType(uri)
return when (type) { return when (type) {
"svg", "image/svg+xml" -> { "svg", "image/svg+xml" -> {
my_canvas.mBackgroundBitmap = null binding.myCanvas.mBackgroundBitmap = null
Svg.loadSvg(this, uri, my_canvas) Svg.loadSvg(this, uri, binding.myCanvas)
defaultExtension = SVG defaultExtension = SVG
true true
} }
"jpg", "jpeg", "png", "gif", "image/jpg", "image/png", "image/gif", "webp" -> { "jpg", "jpeg", "png", "gif", "image/jpg", "image/png", "image/gif", "webp" -> {
my_canvas.drawBitmap(this, uri) binding.myCanvas.drawBitmap(this, uri)
defaultExtension = JPG defaultExtension = JPG
true true
} }
else -> { else -> {
toast(R.string.invalid_file_format) toast(R.string.invalid_file_format)
false false
@ -379,11 +393,11 @@ class MainActivity : SimpleActivity(), CanvasListener {
private fun updateEraserState() { private fun updateEraserState() {
updateButtonStates() updateButtonStates()
my_canvas.toggleEraser(isEraserOn) binding.myCanvas.toggleEraser(isEraserOn)
} }
private fun changeBackgroundClicked() { private fun changeBackgroundClicked() {
val oldColor = (my_canvas.background as ColorDrawable).color val oldColor = (binding.myCanvas.background as ColorDrawable).color
ColorPickerDialog(this, oldColor) { wasPositivePressed, color -> ColorPickerDialog(this, oldColor) { wasPositivePressed, color ->
if (wasPositivePressed) { if (wasPositivePressed) {
config.canvasBackgroundColor = color config.canvasBackgroundColor = color
@ -423,7 +437,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
isBucketFillOn = !isBucketFillOn isBucketFillOn = !isBucketFillOn
updateButtonStates() updateButtonStates()
my_canvas.toggleBucketFill(isBucketFillOn) binding.myCanvas.toggleBucketFill(isBucketFillOn)
} }
private fun updateButtonStates() { private fun updateButtonStates() {
@ -431,9 +445,11 @@ class MainActivity : SimpleActivity(), CanvasListener {
hideBrushSettings(isEyeDropperOn || isBucketFillOn) hideBrushSettings(isEyeDropperOn || isBucketFillOn)
} }
updateButtonColor(eraser, isEraserOn) binding.apply {
updateButtonColor(eye_dropper, isEyeDropperOn) updateButtonColor(eraser, isEraserOn)
updateButtonColor(bucket_fill, isBucketFillOn) updateButtonColor(eyeDropper, isEyeDropperOn)
updateButtonColor(bucketFill, isBucketFillOn)
}
} }
private fun updateButtonColor(view: ImageView, enabled: Boolean) { private fun updateButtonColor(view: ImageView, enabled: Boolean) {
@ -447,7 +463,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
} }
private fun hideBrushSettings(hide: Boolean) { private fun hideBrushSettings(hide: Boolean) {
arrayOf(stroke_width_bar, stroke_width_preview).forEach { arrayOf(binding.strokeWidthBar, binding.strokeWidthPreview).forEach {
it.beGoneIf(hide) it.beGoneIf(hide)
} }
} }
@ -462,10 +478,12 @@ class MainActivity : SimpleActivity(), CanvasListener {
showErrorToast(e) showErrorToast(e)
} }
} }
intentUri?.scheme == "content" -> { intentUri?.scheme == "content" -> {
val outputStream = contentResolver.openOutputStream(intentUri!!) val outputStream = contentResolver.openOutputStream(intentUri!!)
saveToOutputStream(outputStream, defaultPath.getCompressionFormat(), true) saveToOutputStream(outputStream, defaultPath.getCompressionFormat(), true)
} }
else -> handlePermission(PERMISSION_WRITE_STORAGE) { else -> handlePermission(PERMISSION_WRITE_STORAGE) {
val fileDirItem = FileDirItem(defaultPath, defaultPath.getFilenameFromPath()) val fileDirItem = FileDirItem(defaultPath, defaultPath.getFilenameFromPath())
getFileOutputStream(fileDirItem, true) { getFileOutputStream(fileDirItem, true) {
@ -488,7 +506,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
} }
outputStream.use { outputStream.use {
my_canvas.getBitmap().compress(format, quality, it) binding.myCanvas.getBitmap().compress(format, quality, it)
} }
if (finishAfterSaving) { if (finishAfterSaving) {
@ -529,7 +547,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
private fun saveImage() { private fun saveImage() {
SaveImageDialog(this, defaultPath, defaultFilename, defaultExtension, false) { fullPath, filename, extension -> SaveImageDialog(this, defaultPath, defaultFilename, defaultExtension, false) { fullPath, filename, extension ->
savedPathsHash = my_canvas.getDrawingHashCode() savedPathsHash = binding.myCanvas.getDrawingHashCode()
saveFile(fullPath) saveFile(fullPath)
defaultPath = fullPath.getParentPath() defaultPath = fullPath.getParentPath()
defaultFilename = filename defaultFilename = filename
@ -541,7 +559,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
private fun saveFile(path: String) { private fun saveFile(path: String) {
when (path.getFilenameExtension()) { when (path.getFilenameExtension()) {
SVG -> Svg.saveSvg(this, path, my_canvas) SVG -> Svg.saveSvg(this, path, binding.myCanvas)
else -> saveImageFile(path) else -> saveImageFile(path)
} }
rescanPaths(arrayListOf(path)) {} rescanPaths(arrayListOf(path)) {}
@ -561,12 +579,12 @@ class MainActivity : SimpleActivity(), CanvasListener {
private fun writeToOutputStream(path: String, out: OutputStream) { private fun writeToOutputStream(path: String, out: OutputStream) {
out.use { out.use {
my_canvas.getBitmap().compress(path.getCompressionFormat(), 70, out) binding.myCanvas.getBitmap().compress(path.getCompressionFormat(), 70, out)
} }
} }
private fun shareImage() { private fun shareImage() {
getImagePath(my_canvas.getBitmap()) { getImagePath(binding.myCanvas.getBitmap()) {
if (it != null) { if (it != null) {
sharePathIntent(it, BuildConfig.APPLICATION_ID) sharePathIntent(it, BuildConfig.APPLICATION_ID)
} else { } else {
@ -606,7 +624,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
private fun clearCanvas() { private fun clearCanvas() {
uriToLoad = null uriToLoad = null
my_canvas.clearCanvas() binding.myCanvas.clearCanvas()
defaultExtension = PNG defaultExtension = PNG
defaultPath = "" defaultPath = ""
lastBitmapPath = "" lastBitmapPath = ""
@ -629,40 +647,42 @@ class MainActivity : SimpleActivity(), CanvasListener {
eyeDropperClicked() eyeDropperClicked()
} }
val contrastColor = pickedColor.getContrastColor() binding.apply {
undo.applyColorFilter(contrastColor) val contrastColor = pickedColor.getContrastColor()
eraser.applyColorFilter(contrastColor) undo.applyColorFilter(contrastColor)
redo.applyColorFilter(contrastColor) eraser.applyColorFilter(contrastColor)
eye_dropper.applyColorFilter(contrastColor) redo.applyColorFilter(contrastColor)
bucket_fill.applyColorFilter(contrastColor) eyeDropper.applyColorFilter(contrastColor)
if (isBlackAndWhiteTheme()) { bucketFill.applyColorFilter(contrastColor)
stroke_width_bar.setColors(0, contrastColor, 0) if (isBlackAndWhiteTheme()) {
} strokeWidthBar.setColors(0, contrastColor, 0)
}
my_canvas.updateBackgroundColor(pickedColor) myCanvas.updateBackgroundColor(pickedColor)
defaultExtension = PNG defaultExtension = PNG
getBrushPreviewView().setStroke(getBrushStrokeSize(), contrastColor) getBrushPreviewView().setStroke(getBrushStrokeSize(), contrastColor)
}
} }
private fun setColor(pickedColor: Int) { private fun setColor(pickedColor: Int) {
color = pickedColor color = pickedColor
color_picker.setFillWithStroke(color, config.canvasBackgroundColor, true) binding.colorPicker.setFillWithStroke(color, config.canvasBackgroundColor, true)
my_canvas.setColor(color) binding.myCanvas.setColor(color)
isEraserOn = false isEraserOn = false
updateEraserState() updateEraserState()
getBrushPreviewView().setColor(color) getBrushPreviewView().setColor(color)
} }
private fun getBrushPreviewView() = stroke_width_preview.background as GradientDrawable private fun getBrushPreviewView() = binding.strokeWidthPreview.background as GradientDrawable
private fun getBrushStrokeSize() = resources.getDimension(R.dimen.preview_dot_stroke_size).toInt() private fun getBrushStrokeSize() = resources.getDimension(R.dimen.preview_dot_stroke_size).toInt()
override fun toggleUndoVisibility(visible: Boolean) { override fun toggleUndoVisibility(visible: Boolean) {
undo.beVisibleIf(visible) binding.undo.beVisibleIf(visible)
} }
override fun toggleRedoVisibility(visible: Boolean) { override fun toggleRedoVisibility(visible: Boolean) {
redo.beVisibleIf(visible) binding.redo.beVisibleIf(visible)
} }
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
@ -686,17 +706,19 @@ class MainActivity : SimpleActivity(), CanvasListener {
} }
private fun updateBrushSize() { private fun updateBrushSize() {
my_canvas.setBrushSize(brushSize) binding.apply {
val scale = Math.max(0.03f, brushSize / 100f) myCanvas.setBrushSize(brushSize)
stroke_width_preview.scaleX = scale val scale = Math.max(0.03f, brushSize / 100f)
stroke_width_preview.scaleY = scale strokeWidthPreview.scaleX = scale
strokeWidthPreview.scaleY = scale
}
} }
private fun printImage() { private fun printImage() {
val printHelper = PrintHelper(this) val printHelper = PrintHelper(this)
printHelper.scaleMode = PrintHelper.SCALE_MODE_FIT printHelper.scaleMode = PrintHelper.SCALE_MODE_FIT
try { try {
printHelper.printBitmap(getString(R.string.app_name), my_canvas.getBitmap()) printHelper.printBitmap(getString(R.string.app_name), binding.myCanvas.getBitmap())
} catch (e: Exception) { } catch (e: Exception) {
showErrorToast(e) showErrorToast(e)
} }

View File

@ -6,24 +6,27 @@ import com.simplemobiletools.commons.extensions.getProperPrimaryColor
import com.simplemobiletools.commons.extensions.updateTextColors import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.commons.helpers.NavigationIcon import com.simplemobiletools.commons.helpers.NavigationIcon
import com.simplemobiletools.commons.helpers.isTiramisuPlus import com.simplemobiletools.commons.helpers.isTiramisuPlus
import com.simplemobiletools.draw.pro.R import com.simplemobiletools.draw.pro.databinding.ActivitySettingsBinding
import com.simplemobiletools.draw.pro.extensions.config import com.simplemobiletools.draw.pro.extensions.config
import kotlinx.android.synthetic.main.activity_settings.* import java.util.Locale
import java.util.*
class SettingsActivity : SimpleActivity() { class SettingsActivity : SimpleActivity() {
private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivitySettingsBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true isMaterialActivity = true
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings) setContentView(binding.root)
updateMaterialActivityViews(settings_coordinator, settings_holder, useTransparentNavigation = true, useTopSearchMenu = false) binding.apply {
setupMaterialScrollListener(settings_nested_scrollview, settings_toolbar) updateMaterialActivityViews(settingsCoordinator, settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false)
setupMaterialScrollListener(settingsNestedScrollview, settingsToolbar)
}
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
setupToolbar(settings_toolbar, NavigationIcon.Arrow) setupToolbar(binding.settingsToolbar, NavigationIcon.Arrow)
setupCustomizeColors() setupCustomizeColors()
setupUseEnglish() setupUseEnglish()
@ -32,66 +35,78 @@ class SettingsActivity : SimpleActivity() {
setupBrushSize() setupBrushSize()
setupAllowZoomingCanvas() setupAllowZoomingCanvas()
setupForcePortraitMode() setupForcePortraitMode()
updateTextColors(settings_holder) updateTextColors(binding.settingsHolder)
arrayOf(settings_color_customization_section_label, settings_general_settings_label).forEach { arrayOf(binding.settingsColorCustomizationSectionLabel, binding.settingsGeneralSettingsLabel).forEach {
it.setTextColor(getProperPrimaryColor()) it.setTextColor(getProperPrimaryColor())
} }
} }
private fun setupCustomizeColors() { private fun setupCustomizeColors() {
settings_color_customization_holder.setOnClickListener { binding.settingsColorCustomizationHolder.setOnClickListener {
startCustomizationActivity() startCustomizationActivity()
} }
} }
private fun setupUseEnglish() { private fun setupUseEnglish() {
settings_use_english_holder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) binding.apply {
settings_use_english.isChecked = config.useEnglish settingsUseEnglishHolder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus())
settings_use_english_holder.setOnClickListener { settingsUseEnglish.isChecked = config.useEnglish
settings_use_english.toggle() settingsUseEnglishHolder.setOnClickListener {
config.useEnglish = settings_use_english.isChecked settingsUseEnglish.toggle()
System.exit(0) config.useEnglish = settingsUseEnglish.isChecked
System.exit(0)
}
} }
} }
private fun setupLanguage() { private fun setupLanguage() {
settings_language.text = Locale.getDefault().displayLanguage binding.apply {
settings_language_holder.beVisibleIf(isTiramisuPlus()) settingsLanguage.text = Locale.getDefault().displayLanguage
settings_language_holder.setOnClickListener { settingsLanguageHolder.beVisibleIf(isTiramisuPlus())
launchChangeAppLanguageIntent() settingsLanguageHolder.setOnClickListener {
launchChangeAppLanguageIntent()
}
} }
} }
private fun setupPreventPhoneFromSleeping() { private fun setupPreventPhoneFromSleeping() {
settings_prevent_phone_from_sleeping.isChecked = config.preventPhoneFromSleeping binding.apply {
settings_prevent_phone_from_sleeping_holder.setOnClickListener { settingsPreventPhoneFromSleeping.isChecked = config.preventPhoneFromSleeping
settings_prevent_phone_from_sleeping.toggle() settingsPreventPhoneFromSleepingHolder.setOnClickListener {
config.preventPhoneFromSleeping = settings_prevent_phone_from_sleeping.isChecked settingsPreventPhoneFromSleeping.toggle()
config.preventPhoneFromSleeping = settingsPreventPhoneFromSleeping.isChecked
}
} }
} }
private fun setupBrushSize() { private fun setupBrushSize() {
settings_show_brush_size.isChecked = config.showBrushSize binding.apply {
settings_show_brush_size_holder.setOnClickListener { settingsShowBrushSize.isChecked = config.showBrushSize
settings_show_brush_size.toggle() settingsShowBrushSizeHolder.setOnClickListener {
config.showBrushSize = settings_show_brush_size.isChecked settingsShowBrushSize.toggle()
config.showBrushSize = settingsShowBrushSize.isChecked
}
} }
} }
private fun setupAllowZoomingCanvas() { private fun setupAllowZoomingCanvas() {
settings_allow_zooming_canvas.isChecked = config.allowZoomingCanvas binding.apply {
settings_allow_zooming_canvas_holder.setOnClickListener { settingsAllowZoomingCanvas.isChecked = config.allowZoomingCanvas
settings_allow_zooming_canvas.toggle() settingsAllowZoomingCanvasHolder.setOnClickListener {
config.allowZoomingCanvas = settings_allow_zooming_canvas.isChecked settingsAllowZoomingCanvas.toggle()
config.allowZoomingCanvas = settingsAllowZoomingCanvas.isChecked
}
} }
} }
private fun setupForcePortraitMode() { private fun setupForcePortraitMode() {
settings_force_portrait.isChecked = config.forcePortraitMode binding.apply {
settings_force_portrait_holder.setOnClickListener { settingsForcePortrait.isChecked = config.forcePortraitMode
settings_force_portrait.toggle() settingsForcePortraitHolder.setOnClickListener {
config.forcePortraitMode = settings_force_portrait.isChecked settingsForcePortrait.toggle()
config.forcePortraitMode = settingsForcePortrait.isChecked
}
} }
} }
} }

View File

@ -6,10 +6,10 @@ import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.draw.pro.R import com.simplemobiletools.draw.pro.R
import com.simplemobiletools.draw.pro.activities.SimpleActivity import com.simplemobiletools.draw.pro.activities.SimpleActivity
import com.simplemobiletools.draw.pro.databinding.DialogSaveImageBinding
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
import kotlinx.android.synthetic.main.dialog_save_image.view.*
import java.io.File import java.io.File
class SaveImageDialog( class SaveImageDialog(
@ -21,9 +21,9 @@ class SaveImageDialog(
init { init {
val initialFilename = getInitialFilename() val initialFilename = getInitialFilename()
var folder = if (defaultPath.isEmpty()) "${activity.internalStoragePath}/$SIMPLE_DRAW" else defaultPath var folder = if (defaultPath.isEmpty()) "${activity.internalStoragePath}/$SIMPLE_DRAW" else defaultPath
val view = activity.layoutInflater.inflate(R.layout.dialog_save_image, null).apply { val binding = DialogSaveImageBinding.inflate(activity.layoutInflater).apply {
save_image_filename.setText(initialFilename) saveImageFilename.setText(initialFilename)
save_image_radio_group.check( saveImageRadioGroup.check(
when (defaultExtension) { when (defaultExtension) {
JPG -> R.id.save_image_radio_jpg JPG -> R.id.save_image_radio_jpg
SVG -> R.id.save_image_radio_svg SVG -> R.id.save_image_radio_svg
@ -32,12 +32,12 @@ class SaveImageDialog(
) )
if (hidePath) { if (hidePath) {
folder_hint.beGone() folderHint.beGone()
} else { } else {
folder_value.setText(activity.humanizePath(folder)) folderValue.setText(activity.humanizePath(folder))
folder_value.setOnClickListener { folderValue.setOnClickListener {
FilePickerDialog(activity, folder, false, showFAB = true) { FilePickerDialog(activity, folder, false, showFAB = true) {
folder_value.setText(activity.humanizePath(it)) folderValue.setText(activity.humanizePath(it))
folder = it folder = it
} }
} }
@ -48,16 +48,16 @@ class SaveImageDialog(
.setPositiveButton(R.string.ok, null) .setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.apply { .apply {
activity.setupDialogStuff(view, this, R.string.save_as) { alertDialog -> activity.setupDialogStuff(binding.root, this, R.string.save_as) { alertDialog ->
alertDialog.showKeyboard(view.save_image_filename) alertDialog.showKeyboard(binding.saveImageFilename)
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
val filename = view.save_image_filename.value val filename = binding.saveImageFilename.value
if (filename.isEmpty()) { if (filename.isEmpty()) {
activity.toast(R.string.filename_cannot_be_empty) activity.toast(R.string.filename_cannot_be_empty)
return@setOnClickListener return@setOnClickListener
} }
val extension = when (view.save_image_radio_group.checkedRadioButtonId) { val extension = when (binding.saveImageRadioGroup.checkedRadioButtonId) {
R.id.save_image_radio_png -> PNG R.id.save_image_radio_png -> PNG
R.id.save_image_radio_svg -> SVG R.id.save_image_radio_svg -> SVG
else -> JPG else -> JPG

View File

@ -3,7 +3,8 @@ package com.simplemobiletools.draw.pro.helpers
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import com.simplemobiletools.draw.pro.models.MyPath import com.simplemobiletools.draw.pro.models.MyPath
import java.util.* import java.util.LinkedList
import java.util.Queue
// Original algorithm by J. Dunlap http:// www.codeproject.com/KB/GDI-plus/queuelinearflood-fill.aspx // Original algorithm by J. Dunlap http:// www.codeproject.com/KB/GDI-plus/queuelinearflood-fill.aspx
// Java port by Owen Kaluza // Java port by Owen Kaluza
@ -28,7 +29,7 @@ class VectorFloodFiller(image: Bitmap) {
width = image.width width = image.width
height = image.height height = image.height
pixels = IntArray(width * height) pixels = IntArray(width * height)
image.getPixels(pixels, 0, width, 0, 0, width, height) image.getPixels(pixels!!, 0, width, 0, 0, width, height)
} }
private fun prepare() { private fun prepare() {

View File

@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.7.10' ext.kotlin_version = '1.9.0'
repositories { repositories {
google() google()
@ -9,7 +9,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.3.0' classpath 'com.android.tools.build:gradle:8.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View File

@ -1,3 +1,4 @@
android.enableJetifier=true android.enableJetifier=true
android.nonTransitiveRClass=false
android.useAndroidX=true android.useAndroidX=true
org.gradle.jvmargs=-Xmx4g

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip