removing the unused parts of the old editor, use it only for crop intents

This commit is contained in:
tibbi 2019-12-17 18:44:46 +01:00
parent 68f9ceeea3
commit 552dc97aa6
14 changed files with 43 additions and 831 deletions

View file

@ -73,7 +73,6 @@ dependencies {
implementation 'com.google.vr:sdk-panowidget:1.180.0'
implementation 'com.google.vr:sdk-videowidget:1.180.0'
implementation 'org.apache.sanselan:sanselan:0.97-incubator'
implementation 'info.androidhive:imagefilters:1.0.7'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.caverock:androidsvg-aar:1.3'
implementation 'com.github.tibbi:gestureviews:a2208ce9d9'

View file

@ -6,7 +6,6 @@ import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.graphics.Color
import android.graphics.Point
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
@ -15,16 +14,6 @@ import android.provider.MediaStore
import android.view.Menu
import android.view.MenuItem
import android.widget.RelativeLayout
import androidx.recyclerview.widget.LinearLayoutManager
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
@ -34,62 +23,29 @@ import com.simplemobiletools.commons.helpers.isNougatPlus
import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.gallery.pro.BuildConfig
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.adapters.FiltersAdapter
import com.simplemobiletools.gallery.pro.dialogs.OtherAspectRatioDialog
import com.simplemobiletools.gallery.pro.dialogs.ResizeDialog
import com.simplemobiletools.gallery.pro.dialogs.SaveAsDialog
import com.simplemobiletools.gallery.pro.extensions.config
import com.simplemobiletools.gallery.pro.extensions.fixDateTaken
import com.simplemobiletools.gallery.pro.extensions.openEditor
import com.simplemobiletools.gallery.pro.helpers.*
import com.simplemobiletools.gallery.pro.models.FilterItem
import com.theartofdev.edmodo.cropper.CropImageView
import com.zomato.photofilters.FilterPack
import com.zomato.photofilters.imageprocessors.Filter
import kotlinx.android.synthetic.main.activity_edit.*
import kotlinx.android.synthetic.main.bottom_actions_aspect_ratio.*
import kotlinx.android.synthetic.main.bottom_editor_actions_filter.*
import kotlinx.android.synthetic.main.bottom_editor_crop_rotate_actions.*
import kotlinx.android.synthetic.main.bottom_editor_draw_actions.*
import kotlinx.android.synthetic.main.bottom_editor_primary_actions.*
import java.io.*
class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener {
companion object {
init {
System.loadLibrary("NativeImageProcessor")
}
}
private val TEMP_FOLDER_NAME = "images"
private val ASPECT_X = "aspectX"
private val ASPECT_Y = "aspectY"
private val CROP = "crop"
// constants for bottom primary action groups
private val PRIMARY_ACTION_NONE = 0
private val PRIMARY_ACTION_FILTER = 1
private val PRIMARY_ACTION_CROP_ROTATE = 2
private val PRIMARY_ACTION_DRAW = 3
private val CROP_ROTATE_NONE = 0
private val CROP_ROTATE_ASPECT_RATIO = 1
private lateinit var uri: Uri
private lateinit var saveUri: Uri
private var resizeWidth = 0
private var resizeHeight = 0
private var drawColor = 0
private var lastOtherAspectRatio: Pair<Float, Float>? = null
private var currPrimaryAction = PRIMARY_ACTION_NONE
private var currCropRotateAction = CROP_ROTATE_ASPECT_RATIO
private var currAspectRatio = ASPECT_RATIO_FREE
private var isCropIntent = false
private var isEditingWithThirdParty = false
private var isSharingBitmap = false
private var wasDrawCanvasPositioned = false
private var oldExif: ExifInterface? = null
private var filterInitialBitmap: Bitmap? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -109,19 +65,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
}
}
override fun onResume() {
super.onResume()
isEditingWithThirdParty = false
bottom_draw_width.setColors(config.textColor, getAdjustedPrimaryColor(), config.backgroundColor)
}
override fun onStop() {
super.onStop()
if (isEditingWithThirdParty) {
finish()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_editor, menu)
updateMenuItemColors(menu)
@ -131,7 +74,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.save_as -> saveImage()
R.id.edit -> editWith()
R.id.share -> shareImage()
else -> return super.onOptionsItemSelected(item)
}
@ -170,14 +112,10 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
else -> uri
}
isCropIntent = intent.extras?.get(CROP) == "true"
if (isCropIntent) {
bottom_editor_primary_actions.beGone()
(bottom_editor_crop_rotate_actions.layoutParams as RelativeLayout.LayoutParams).addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1)
}
loadDefaultImageView()
setupBottomActions()
loadCropImageView()
setupCropRotateActionButtons()
setupAspectRatioButtons()
if (config.lastEditorCropAspectRatio == ASPECT_RATIO_OTHER) {
if (config.lastEditorCropOtherAspectRatioX == 0f) {
@ -195,57 +133,14 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
bottom_aspect_ratios.beVisible()
}
private fun loadDefaultImageView() {
default_image_view.beVisible()
crop_image_view.beGone()
editor_draw_canvas.beGone()
val options = RequestOptions()
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
Glide.with(this)
.asBitmap()
.load(uri)
.apply(options)
.listener(object : RequestListener<Bitmap> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean) = false
override fun onResourceReady(bitmap: Bitmap?, model: Any?, target: Target<Bitmap>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
val currentFilter = getFiltersAdapter()?.getCurrentFilter()
if (filterInitialBitmap == null) {
loadCropImageView()
bottomCropRotateClicked()
}
if (filterInitialBitmap != null && currentFilter != null && currentFilter.filter.name != getString(R.string.none)) {
default_image_view.onGlobalLayout {
applyFilter(currentFilter)
}
} else {
filterInitialBitmap = bitmap
}
if (isCropIntent) {
bottom_primary_filter.beGone()
bottom_primary_draw.beGone()
}
return false
}
}).into(default_image_view)
}
private fun loadCropImageView() {
default_image_view.beGone()
editor_draw_canvas.beGone()
crop_image_view.apply {
beVisible()
setOnCropImageCompleteListener(this@EditActivity)
setImageUriAsync(uri)
guidelines = CropImageView.Guidelines.ON
if (isCropIntent && shouldCropSquare()) {
if (shouldCropSquare()) {
currAspectRatio = ASPECT_RATIO_ONE_ONE
setFixedAspectRatio(true)
bottom_aspect_ratio.beGone()
@ -253,52 +148,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
}
}
private fun loadDrawCanvas() {
default_image_view.beGone()
crop_image_view.beGone()
editor_draw_canvas.beVisible()
if (!wasDrawCanvasPositioned) {
wasDrawCanvasPositioned = true
editor_draw_canvas.onGlobalLayout {
ensureBackgroundThread {
fillCanvasBackground()
}
}
}
}
private fun fillCanvasBackground() {
val size = Point()
windowManager.defaultDisplay.getSize(size)
val options = RequestOptions()
.format(DecodeFormat.PREFER_ARGB_8888)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.fitCenter()
try {
val builder = Glide.with(applicationContext)
.asBitmap()
.load(uri)
.apply(options)
.into(editor_draw_canvas.width, editor_draw_canvas.height)
val bitmap = builder.get()
runOnUiThread {
editor_draw_canvas.apply {
updateBackgroundBitmap(bitmap)
layoutParams.width = bitmap.width
layoutParams.height = bitmap.height
y = (height - bitmap.height) / 2f
requestLayout()
}
}
} catch (e: Exception) {
showErrorToast(e)
}
}
@TargetApi(Build.VERSION_CODES.N)
private fun saveImage() {
var inputStream: InputStream? = null
@ -312,68 +161,16 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
inputStream?.close()
}
if (crop_image_view.isVisible()) {
crop_image_view.getCroppedImageAsync()
} else if (editor_draw_canvas.isVisible()) {
val bitmap = editor_draw_canvas.getBitmap()
if (saveUri.scheme == "file") {
SaveAsDialog(this, saveUri.path!!, true) {
saveBitmapToFile(bitmap, it, true)
}
} else if (saveUri.scheme == "content") {
val filePathGetter = getNewFilePath()
SaveAsDialog(this, filePathGetter.first, filePathGetter.second) {
saveBitmapToFile(bitmap, it, true)
}
}
} else {
val currentFilter = getFiltersAdapter()?.getCurrentFilter() ?: return
val filePathGetter = getNewFilePath()
SaveAsDialog(this, filePathGetter.first, filePathGetter.second) {
toast(R.string.saving)
// clean up everything to free as much memory as possible
default_image_view.setImageResource(0)
crop_image_view.setImageBitmap(null)
bottom_actions_filter_list.adapter = null
bottom_actions_filter_list.beGone()
ensureBackgroundThread {
try {
val originalBitmap = Glide.with(applicationContext).asBitmap().load(uri).submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get()
currentFilter.filter.processFilter(originalBitmap)
saveBitmapToFile(originalBitmap, it, false)
} catch (e: OutOfMemoryError) {
toast(R.string.out_of_memory_error)
}
}
}
}
}
private fun shareImage() {
ensureBackgroundThread {
when {
default_image_view.isVisible() -> {
val currentFilter = getFiltersAdapter()?.getCurrentFilter()
if (currentFilter == null) {
toast(R.string.unknown_error_occurred)
return@ensureBackgroundThread
}
val originalBitmap = Glide.with(applicationContext).asBitmap().load(uri).submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get()
currentFilter.filter.processFilter(originalBitmap)
shareBitmap(originalBitmap)
}
crop_image_view.isVisible() -> {
isSharingBitmap = true
runOnUiThread {
crop_image_view.getCroppedImageAsync()
}
}
editor_draw_canvas.isVisible() -> shareBitmap(editor_draw_canvas.getBitmap())
}
}
}
private fun getTempImagePath(bitmap: Bitmap, callback: (path: String?) -> Unit) {
@ -416,66 +213,11 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
}
}
private fun getFiltersAdapter() = bottom_actions_filter_list.adapter as? FiltersAdapter
private fun setupBottomActions() {
setupPrimaryActionButtons()
setupCropRotateActionButtons()
setupAspectRatioButtons()
setupDrawButtons()
}
private fun setupPrimaryActionButtons() {
bottom_primary_filter.setOnClickListener {
bottomFilterClicked()
}
bottom_primary_crop_rotate.setOnClickListener {
bottomCropRotateClicked()
}
bottom_primary_draw.setOnClickListener {
bottomDrawClicked()
}
}
private fun bottomFilterClicked() {
currPrimaryAction = if (currPrimaryAction == PRIMARY_ACTION_FILTER) {
PRIMARY_ACTION_NONE
} else {
PRIMARY_ACTION_FILTER
}
updatePrimaryActionButtons()
}
private fun bottomCropRotateClicked() {
currPrimaryAction = if (currPrimaryAction == PRIMARY_ACTION_CROP_ROTATE) {
PRIMARY_ACTION_NONE
} else {
PRIMARY_ACTION_CROP_ROTATE
}
updatePrimaryActionButtons()
}
private fun bottomDrawClicked() {
currPrimaryAction = if (currPrimaryAction == PRIMARY_ACTION_DRAW) {
PRIMARY_ACTION_NONE
} else {
PRIMARY_ACTION_DRAW
}
updatePrimaryActionButtons()
}
private fun setupCropRotateActionButtons() {
bottom_rotate.setOnClickListener {
crop_image_view.rotateImage(90)
}
bottom_resize.beGoneIf(isCropIntent)
bottom_resize.setOnClickListener {
resizeImage()
}
bottom_flip_horizontally.setOnClickListener {
crop_image_view.flipImageHorizontally()
}
@ -483,19 +225,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
bottom_flip_vertically.setOnClickListener {
crop_image_view.flipImageVertically()
}
bottom_aspect_ratio.setOnClickListener {
currCropRotateAction = if (currCropRotateAction == CROP_ROTATE_ASPECT_RATIO) {
crop_image_view.guidelines = CropImageView.Guidelines.OFF
bottom_aspect_ratios.beGone()
CROP_ROTATE_NONE
} else {
crop_image_view.guidelines = CropImageView.Guidelines.ON
bottom_aspect_ratios.beVisible()
CROP_ROTATE_ASPECT_RATIO
}
updateCropRotateActionButtons()
}
}
private fun setupAspectRatioButtons() {
@ -527,126 +256,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
updateAspectRatioButtons()
}
private fun setupDrawButtons() {
updateDrawColor(config.lastEditorDrawColor)
bottom_draw_width.progress = config.lastEditorBrushSize
updateBrushSize(config.lastEditorBrushSize)
bottom_draw_color_clickable.setOnClickListener {
ColorPickerDialog(this, drawColor) { wasPositivePressed, color ->
if (wasPositivePressed) {
updateDrawColor(color)
}
}
}
bottom_draw_width.onSeekBarChangeListener {
config.lastEditorBrushSize = it
updateBrushSize(it)
}
bottom_draw_undo.setOnClickListener {
editor_draw_canvas.undo()
}
}
private fun updateBrushSize(percent: Int) {
editor_draw_canvas.updateBrushSize(percent)
val scale = Math.max(0.03f, percent / 100f)
bottom_draw_color.scaleX = scale
bottom_draw_color.scaleY = scale
}
private fun updatePrimaryActionButtons() {
if (crop_image_view.isGone() && currPrimaryAction == PRIMARY_ACTION_CROP_ROTATE) {
loadCropImageView()
} else if (default_image_view.isGone() && currPrimaryAction == PRIMARY_ACTION_FILTER) {
loadDefaultImageView()
} else if (editor_draw_canvas.isGone() && currPrimaryAction == PRIMARY_ACTION_DRAW) {
loadDrawCanvas()
}
arrayOf(bottom_primary_filter, bottom_primary_crop_rotate, bottom_primary_draw).forEach {
it.applyColorFilter(Color.WHITE)
}
val currentPrimaryActionButton = when (currPrimaryAction) {
PRIMARY_ACTION_FILTER -> bottom_primary_filter
PRIMARY_ACTION_CROP_ROTATE -> bottom_primary_crop_rotate
PRIMARY_ACTION_DRAW -> bottom_primary_draw
else -> null
}
currentPrimaryActionButton?.applyColorFilter(getAdjustedPrimaryColor())
bottom_editor_filter_actions.beVisibleIf(currPrimaryAction == PRIMARY_ACTION_FILTER)
bottom_editor_crop_rotate_actions.beVisibleIf(currPrimaryAction == PRIMARY_ACTION_CROP_ROTATE)
bottom_editor_draw_actions.beVisibleIf(currPrimaryAction == PRIMARY_ACTION_DRAW)
if (currPrimaryAction == PRIMARY_ACTION_FILTER && bottom_actions_filter_list.adapter == null) {
ensureBackgroundThread {
val thumbnailSize = resources.getDimension(R.dimen.bottom_filters_thumbnail_size).toInt()
val bitmap = try {
Glide.with(this)
.asBitmap()
.load(uri).listener(object : RequestListener<Bitmap> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
showErrorToast(e.toString())
return false
}
override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target<Bitmap>?, dataSource: DataSource?, isFirstResource: Boolean) = false
})
.submit(thumbnailSize, thumbnailSize)
.get()
} catch (e: GlideException) {
showErrorToast(e)
finish()
return@ensureBackgroundThread
}
runOnUiThread {
val filterThumbnailsManager = FilterThumbnailsManager()
filterThumbnailsManager.clearThumbs()
val noFilter = Filter(getString(R.string.none))
filterThumbnailsManager.addThumb(FilterItem(bitmap, noFilter))
FilterPack.getFilterPack(this).forEach {
val filterItem = FilterItem(bitmap, it)
filterThumbnailsManager.addThumb(filterItem)
}
val filterItems = filterThumbnailsManager.processThumbs()
val adapter = FiltersAdapter(applicationContext, filterItems) {
val layoutManager = bottom_actions_filter_list.layoutManager as LinearLayoutManager
applyFilter(filterItems[it])
if (it == layoutManager.findLastCompletelyVisibleItemPosition() || it == layoutManager.findLastVisibleItemPosition()) {
bottom_actions_filter_list.smoothScrollBy(thumbnailSize, 0)
} else if (it == layoutManager.findFirstCompletelyVisibleItemPosition() || it == layoutManager.findFirstVisibleItemPosition()) {
bottom_actions_filter_list.smoothScrollBy(-thumbnailSize, 0)
}
}
bottom_actions_filter_list.adapter = adapter
adapter.notifyDataSetChanged()
}
}
}
if (currPrimaryAction != PRIMARY_ACTION_CROP_ROTATE) {
bottom_aspect_ratios.beGone()
currCropRotateAction = CROP_ROTATE_NONE
}
updateCropRotateActionButtons()
}
private fun applyFilter(filterItem: FilterItem) {
val newBitmap = Bitmap.createBitmap(filterInitialBitmap!!)
default_image_view.setImageBitmap(filterItem.filter.processFilter(newBitmap))
}
private fun updateAspectRatio(aspectRatio: Int) {
currAspectRatio = aspectRatio
config.lastEditorCropAspectRatio = aspectRatio
@ -684,40 +293,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
currentAspectRatioButton.setTextColor(getAdjustedPrimaryColor())
}
private fun updateCropRotateActionButtons() {
arrayOf(bottom_aspect_ratio).forEach {
it.applyColorFilter(Color.WHITE)
}
val primaryActionView = when (currCropRotateAction) {
CROP_ROTATE_ASPECT_RATIO -> bottom_aspect_ratio
else -> null
}
primaryActionView?.applyColorFilter(getAdjustedPrimaryColor())
}
private fun updateDrawColor(color: Int) {
drawColor = color
bottom_draw_color.applyColorFilter(color)
config.lastEditorDrawColor = color
editor_draw_canvas.updateColor(color)
}
private fun resizeImage() {
val point = getAreaSize()
if (point == null) {
toast(R.string.unknown_error_occurred)
return
}
ResizeDialog(this, point) {
resizeWidth = it.x
resizeHeight = it.y
crop_image_view.getCroppedImageAsync()
}
}
private fun shouldCropSquare(): Boolean {
val extras = intent.extras
return if (extras != null && extras.containsKey(ASPECT_X) && extras.containsKey(ASPECT_Y)) {
@ -727,16 +302,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
}
}
private fun getAreaSize(): Point? {
val rect = crop_image_view.cropRect ?: return null
val rotation = crop_image_view.rotatedDegrees
return if (rotation == 0 || rotation == 180) {
Point(rect.width(), rect.height())
} else {
Point(rect.height(), rect.width())
}
}
override fun onCropImageComplete(view: CropImageView, result: CropImageView.CropResult) {
if (result.error == null) {
val bitmap = result.bitmap
@ -746,7 +311,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
return
}
if (isCropIntent) {
if (saveUri.scheme == "file") {
saveBitmapToFile(bitmap, saveUri.path!!, true)
} else {
@ -770,47 +334,11 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
}
finish()
}
} else if (saveUri.scheme == "file") {
SaveAsDialog(this, saveUri.path!!, true) {
saveBitmapToFile(bitmap, it, true)
}
} else if (saveUri.scheme == "content") {
val filePathGetter = getNewFilePath()
SaveAsDialog(this, filePathGetter.first, filePathGetter.second) {
saveBitmapToFile(bitmap, it, true)
}
} else {
toast(R.string.unknown_file_location)
}
} else {
toast("${getString(R.string.image_editing_failed)}: ${result.error.message}")
}
}
private fun getNewFilePath(): Pair<String, Boolean> {
var newPath = applicationContext.getRealPathFromURI(saveUri) ?: ""
if (newPath.startsWith("/mnt/")) {
newPath = ""
}
var shouldAppendFilename = true
if (newPath.isEmpty()) {
val filename = applicationContext.getFilenameFromContentUri(saveUri) ?: ""
if (filename.isNotEmpty()) {
val path = if (intent.extras?.containsKey(REAL_FILE_PATH) == true) intent.getStringExtra(REAL_FILE_PATH).getParentPath() else internalStoragePath
newPath = "$path/$filename"
shouldAppendFilename = false
}
}
if (newPath.isEmpty()) {
newPath = "$internalStoragePath/${getCurrentFormattedDateTime()}.${saveUri.toString().getFilenameExtension()}"
shouldAppendFilename = false
}
return Pair(newPath, shouldAppendFilename)
}
private fun saveBitmapToFile(bitmap: Bitmap, path: String, showSavingToast: Boolean) {
if (!packageName.contains("slootelibomelpmis".reversed(), true)) {
if (baseConfig.appRunCount > 100) {
@ -869,11 +397,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
out.close()
}
private fun editWith() {
openEditor(uri.toString(), true)
isEditingWithThirdParty = true
}
private fun scanFinalPath(path: String) {
val paths = arrayListOf(path)
rescanPaths(paths) {

View file

@ -1,58 +0,0 @@
package com.simplemobiletools.gallery.pro.adapters
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.models.FilterItem
import kotlinx.android.synthetic.main.editor_filter_item.view.*
import java.util.*
class FiltersAdapter(val context: Context, val filterItems: ArrayList<FilterItem>, val itemClick: (Int) -> Unit) : RecyclerView.Adapter<FiltersAdapter.ViewHolder>() {
private var currentSelection = filterItems.first()
private var strokeBackground = context.resources.getDrawable(R.drawable.stroke_background)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindView(filterItems[position])
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.editor_filter_item, parent, false)
return ViewHolder(view)
}
override fun getItemCount() = filterItems.size
fun getCurrentFilter() = currentSelection
private fun setCurrentFilter(position: Int) {
val filterItem = filterItems.getOrNull(position) ?: return
if (currentSelection != filterItem) {
currentSelection = filterItem
notifyDataSetChanged()
itemClick.invoke(position)
}
}
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bindView(filterItem: FilterItem): View {
itemView.apply {
editor_filter_item_label.text = filterItem.filter.name
editor_filter_item_thumbnail.setImageBitmap(filterItem.bitmap)
editor_filter_item_thumbnail.background = if (getCurrentFilter() == filterItem) {
strokeBackground
} else {
null
}
setOnClickListener {
setCurrentFilter(adapterPosition)
}
}
return itemView
}
}
}

View file

@ -80,7 +80,7 @@ fun Activity.launchCamera() {
fun SimpleActivity.launchAbout() {
val licenses = LICENSE_GLIDE or LICENSE_CROPPER or LICENSE_RTL or LICENSE_SUBSAMPLING or LICENSE_PATTERN or LICENSE_REPRINT or LICENSE_GIF_DRAWABLE or
LICENSE_PICASSO or LICENSE_EXOPLAYER or LICENSE_PANORAMA_VIEW or LICENSE_SANSELAN or LICENSE_FILTERS or LICENSE_GESTURE_VIEWS
LICENSE_PICASSO or LICENSE_EXOPLAYER or LICENSE_PANORAMA_VIEW or LICENSE_SANSELAN or LICENSE_GESTURE_VIEWS
val faqItems = arrayListOf(
FAQItem(R.string.faq_5_title_commons, R.string.faq_5_text_commons),

View file

@ -1,27 +0,0 @@
package com.simplemobiletools.gallery.pro.helpers
import android.graphics.Bitmap
import com.simplemobiletools.gallery.pro.models.FilterItem
import java.util.*
class FilterThumbnailsManager {
private var filterThumbnails = ArrayList<FilterItem>(10)
private var processedThumbnails = ArrayList<FilterItem>(10)
fun addThumb(filterItem: FilterItem) {
filterThumbnails.add(filterItem)
}
fun processThumbs(): ArrayList<FilterItem> {
for (filterItem in filterThumbnails) {
filterItem.bitmap = filterItem.filter.processFilter(Bitmap.createBitmap(filterItem.bitmap))
processedThumbnails.add(filterItem)
}
return processedThumbnails
}
fun clearThumbs() {
filterThumbnails = ArrayList()
processedThumbnails = ArrayList()
}
}

View file

@ -1,6 +0,0 @@
package com.simplemobiletools.gallery.pro.models
import android.graphics.Bitmap
import com.zomato.photofilters.imageprocessors.Filter
data class FilterItem(var bitmap: Bitmap, val filter: Filter)

View file

@ -1,77 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_edit_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/default_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/bottom_editor_crop_rotate_actions"
android:layout_marginBottom="@dimen/bottom_filters_height_with_margin"/>
<com.theartofdev.edmodo.cropper.CropImageView
android:id="@+id/crop_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/bottom_actions_height_bigger"
android:visibility="gone"
app:cropBackgroundColor="@color/crop_image_view_background"
app:cropInitialCropWindowPaddingRatio="0"/>
<com.simplemobiletools.gallery.pro.views.EditorDrawCanvas
android:id="@+id/editor_draw_canvas"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/bottom_actions_height_double"
android:background="@android:color/transparent"
android:visibility="gone"/>
app:cropInitialCropWindowPaddingRatio="0" />
<RelativeLayout
android:id="@+id/bottom_editor_actions_background"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_editor_actions_shadow_height"
android:layout_alignParentBottom="true"
android:background="@drawable/gradient_background"/>
<include
android:id="@+id/bottom_editor_primary_actions"
layout="@layout/bottom_editor_primary_actions"/>
android:background="@drawable/gradient_background" />
<include
android:id="@+id/bottom_aspect_ratios"
layout="@layout/bottom_actions_aspect_ratio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/bottom_editor_crop_rotate_actions"
android:visibility="gone"/>
<include
android:id="@+id/bottom_editor_filter_actions"
layout="@layout/bottom_editor_actions_filter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/bottom_editor_primary_actions"
android:visibility="gone"/>
android:layout_above="@+id/bottom_editor_crop_rotate_actions" />
<include
android:id="@+id/bottom_editor_crop_rotate_actions"
layout="@layout/bottom_editor_crop_rotate_actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/bottom_editor_primary_actions"
android:visibility="gone"/>
<include
android:id="@+id/bottom_editor_draw_actions"
layout="@layout/bottom_editor_draw_actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/bottom_editor_primary_actions"
android:visibility="gone"/>
android:layout_alignParentBottom="true" />
</RelativeLayout>

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottom_actions_filter_wrapper"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_filters_height"
android:paddingTop="@dimen/medium_margin">
<com.simplemobiletools.commons.views.MyRecyclerView
android:id="@+id/bottom_actions_filter_list"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_filters_height"
android:background="@color/crop_image_view_background"
android:orientation="horizontal"
android:overScrollMode="never"
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager"/>
</RelativeLayout>

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottom_editor_actions_wrapper"
android:layout_width="match_parent"
@ -16,24 +15,10 @@
android:padding="@dimen/normal_margin"
android:src="@drawable/ic_rotate_right_vector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/bottom_resize"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/bottom_resize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/resize"
android:padding="@dimen/normal_margin"
android:src="@drawable/ic_minimize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/bottom_aspect_ratio"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/bottom_rotate"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/bottom_aspect_ratio"
@ -46,8 +31,8 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/bottom_flip_horizontally"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/bottom_resize"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintStart_toEndOf="@+id/bottom_rotate"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/bottom_flip_horizontally"
@ -61,7 +46,7 @@
app:layout_constraintEnd_toStartOf="@+id/bottom_flip_vertically"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/bottom_aspect_ratio"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/bottom_flip_vertically"
@ -75,6 +60,6 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/bottom_flip_horizontally"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottom_editor_draw_actions_wrapper"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_actions_height"
android:layout_alignParentBottom="true">
<com.simplemobiletools.commons.views.MySeekBar
android:id="@+id/bottom_draw_width"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginLeft="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:max="100"
android:progress="50"
app:layout_constraintBottom_toBottomOf="@id/bottom_draw_color"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/bottom_draw_color"
app:layout_constraintTop_toTopOf="@+id/bottom_draw_color"/>
<ImageView
android:id="@+id/bottom_draw_color_clickable"
android:layout_width="@dimen/bottom_editor_color_picker_size"
android:layout_height="@dimen/bottom_editor_color_picker_size"
android:layout_marginEnd="@dimen/small_margin"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/change_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/bottom_draw_undo"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/bottom_draw_color"
android:layout_width="@dimen/bottom_editor_color_picker_size"
android:layout_height="@dimen/bottom_editor_color_picker_size"
android:layout_marginEnd="@dimen/small_margin"
android:clickable="false"
android:contentDescription="@null"
android:padding="@dimen/small_margin"
android:src="@drawable/circle_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/bottom_draw_undo"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/bottom_draw_undo"
android:layout_width="@dimen/bottom_editor_color_picker_size"
android:layout_height="@dimen/bottom_editor_color_picker_size"
android:layout_marginEnd="@dimen/normal_margin"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="false"
android:contentDescription="@string/undo"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_undo_vector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottom_editor_primary_actions_wrapper"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_actions_height"
android:layout_alignParentBottom="true">
<ImageView
android:id="@+id/bottom_primary_filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/filter"
android:padding="@dimen/normal_margin"
android:src="@drawable/ic_photo_filter_vector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/bottom_primary_crop_rotate"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/bottom_primary_crop_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/normal_margin"
android:src="@drawable/ic_crop_rotate_vector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/bottom_primary_draw"
app:layout_constraintStart_toEndOf="@+id/bottom_primary_filter"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/bottom_primary_draw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/normal_margin"
android:src="@drawable/ic_draw_vector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/bottom_primary_crop_rotate"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/editor_filter_item_holder"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/editor_filter_item_thumbnail"
android:layout_width="@dimen/bottom_filters_thumbnail_size"
android:layout_height="@dimen/bottom_filters_thumbnail_size"
android:layout_above="@+id/editor_filter_item_label"
android:background="@drawable/stroke_background"
android:contentDescription="@null"
android:padding="1dp"/>
<TextView
android:id="@+id/editor_filter_item_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:textColor="@android:color/white"
android:textSize="@dimen/smaller_text_size"
tools:text="Filter"/>
</RelativeLayout>

View file

@ -6,11 +6,6 @@
android:icon="@drawable/ic_check_vector"
android:title="@string/save_as"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/edit"
android:icon="@drawable/ic_edit_vector"
android:title="@string/edit_with"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/share"
android:icon="@drawable/ic_share_vector"

View file

@ -15,9 +15,6 @@
<dimen name="bottom_actions_height_double">128dp</dimen>
<dimen name="bottom_actions_height_bigger">164dp</dimen>
<dimen name="bottom_editor_color_picker_size">48dp</dimen>
<dimen name="bottom_filters_thumbnail_size">76dp</dimen>
<dimen name="bottom_filters_height">90dp</dimen>
<dimen name="bottom_filters_height_with_margin">98dp</dimen>
<dimen name="bottom_editor_actions_shadow_height">180dp</dimen>
<dimen name="portrait_photos_stripe_height">48dp</dimen>
<dimen name="default_status_action_height">86dp</dimen>