support animated thumbnails of webp files and allow settings for files/folders separately

This commit is contained in:
gmasil 2023-09-19 15:29:09 +02:00
parent 83a916bcc6
commit 1edbfd6264
No known key found for this signature in database
GPG Key ID: 135FC0B941F3ECC7
11 changed files with 112 additions and 114 deletions

View File

@ -124,6 +124,7 @@ dependencies {
compileOnly(libs.okhttp) compileOnly(libs.okhttp)
ksp(libs.glide.compiler) ksp(libs.glide.compiler)
implementation(libs.zjupure.webpdecoder)
implementation(libs.bundles.room) implementation(libs.bundles.room)
ksp(libs.androidx.room.compiler) ksp(libs.androidx.room.compiler)

View File

@ -77,7 +77,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private var mDirs = ArrayList<Directory>() private var mDirs = ArrayList<Directory>()
private var mDirsIgnoringSearch = ArrayList<Directory>() private var mDirsIgnoringSearch = ArrayList<Directory>()
private var mStoredAnimateGifs = true private var mStoredAnimateGifsInFolders = true
private var mStoredCropThumbnails = true private var mStoredCropThumbnails = true
private var mStoredScrollHorizontally = true private var mStoredScrollHorizontally = true
private var mStoredTextColor = 0 private var mStoredTextColor = 0
@ -198,8 +198,8 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
refreshMenuItems() refreshMenuItems()
if (mStoredAnimateGifs != config.animateGifs) { if (mStoredAnimateGifsInFolders != config.animateGifsInFolders) {
getRecyclerAdapter()?.updateAnimateGifs(config.animateGifs) getRecyclerAdapter()?.updateAnimateGifs(config.animateGifsInFolders)
} }
if (mStoredCropThumbnails != config.cropThumbnails) { if (mStoredCropThumbnails != config.cropThumbnails) {
@ -438,7 +438,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
mStoredTextColor = getProperTextColor() mStoredTextColor = getProperTextColor()
mStoredPrimaryColor = getProperPrimaryColor() mStoredPrimaryColor = getProperPrimaryColor()
config.apply { config.apply {
mStoredAnimateGifs = animateGifs mStoredAnimateGifsInFolders = animateGifsInFolders
mStoredCropThumbnails = cropThumbnails mStoredCropThumbnails = cropThumbnails
mStoredScrollHorizontally = scrollHorizontally mStoredScrollHorizontally = scrollHorizontally
mStoredStyleString = "$folderStyle$showFolderMediaCount$limitFolderTitle" mStoredStyleString = "$folderStyle$showFolderMediaCount$limitFolderTitle"

View File

@ -178,7 +178,7 @@ class WidgetConfigureActivity : SimpleActivity() {
if (path != null) { if (path != null) {
runOnUiThread { runOnUiThread {
val signature = ObjectKey(System.currentTimeMillis().toString()) val signature = ObjectKey(System.currentTimeMillis().toString())
loadJpg(path, binding.configImage, config.cropThumbnails, ROUNDED_CORNERS_NONE, signature) loadImageBase(path, binding.configImage, config.cropThumbnails, ROUNDED_CORNERS_NONE, signature)
} }
} }
} }

View File

@ -55,7 +55,7 @@ class DirectoryAdapter(
private val isListViewType = config.viewTypeFolders == VIEW_TYPE_LIST private val isListViewType = config.viewTypeFolders == VIEW_TYPE_LIST
private var pinnedFolders = config.pinnedFolders private var pinnedFolders = config.pinnedFolders
private var scrollHorizontally = config.scrollHorizontally private var scrollHorizontally = config.scrollHorizontally
private var animateGifs = config.animateGifs private var animateGifs = config.animateGifsInFolders
private var cropThumbnails = config.cropThumbnails private var cropThumbnails = config.cropThumbnails
private var groupDirectSubfolders = config.groupDirectSubfolders private var groupDirectSubfolders = config.groupDirectSubfolders
private var currentDirectoriesHash = dirs.hashCode() private var currentDirectoriesHash = dirs.hashCode()

View File

@ -1,11 +1,14 @@
package com.simplemobiletools.gallery.pro.dialogs package com.simplemobiletools.gallery.pro.dialogs
import android.content.DialogInterface import android.content.DialogInterface
import android.widget.Toast
import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.databinding.DialogChangeFileThumbnailStyleBinding import com.simplemobiletools.gallery.pro.databinding.DialogChangeFileThumbnailStyleBinding
import com.simplemobiletools.gallery.pro.extensions.config import com.simplemobiletools.gallery.pro.extensions.config
@ -22,7 +25,10 @@ class ChangeFileThumbnailStyleDialog(val activity: BaseSimpleActivity) : DialogI
dialogFileStyleShowThumbnailFileTypes.isChecked = config.showThumbnailFileTypes dialogFileStyleShowThumbnailFileTypes.isChecked = config.showThumbnailFileTypes
dialogFileStyleMarkFavoriteItems.isChecked = config.markFavoriteItems dialogFileStyleMarkFavoriteItems.isChecked = config.markFavoriteItems
dialogFileStyleRoundedCornersHolder.setOnClickListener { dialogFileStyleRoundedCorners.toggle() } dialogFileStyleRoundedCornersHolder.setOnClickListener {
dialogFileStyleRoundedCorners.toggle()
updateAnimateGifsCheckbox()
}
dialogFileStyleAnimateGifsHolder.setOnClickListener { dialogFileStyleAnimateGifs.toggle() } dialogFileStyleAnimateGifsHolder.setOnClickListener { dialogFileStyleAnimateGifs.toggle() }
dialogFileStyleShowThumbnailVideoDurationHolder.setOnClickListener { dialogFileStyleShowThumbnailVideoDuration.toggle() } dialogFileStyleShowThumbnailVideoDurationHolder.setOnClickListener { dialogFileStyleShowThumbnailVideoDuration.toggle() }
dialogFileStyleShowThumbnailFileTypesHolder.setOnClickListener { dialogFileStyleShowThumbnailFileTypes.toggle() } dialogFileStyleShowThumbnailFileTypesHolder.setOnClickListener { dialogFileStyleShowThumbnailFileTypes.toggle() }
@ -48,6 +54,7 @@ class ChangeFileThumbnailStyleDialog(val activity: BaseSimpleActivity) : DialogI
} }
updateThumbnailSpacingText() updateThumbnailSpacingText()
updateAnimateGifsCheckbox()
activity.getAlertDialogBuilder() activity.getAlertDialogBuilder()
.setPositiveButton(com.simplemobiletools.commons.R.string.ok, this) .setPositiveButton(com.simplemobiletools.commons.R.string.ok, this)
@ -59,13 +66,21 @@ class ChangeFileThumbnailStyleDialog(val activity: BaseSimpleActivity) : DialogI
override fun onClick(dialog: DialogInterface, which: Int) { override fun onClick(dialog: DialogInterface, which: Int) {
config.fileRoundedCorners = binding.dialogFileStyleRoundedCorners.isChecked config.fileRoundedCorners = binding.dialogFileStyleRoundedCorners.isChecked
config.animateGifs = binding.dialogFileStyleAnimateGifs.isChecked if (binding.dialogFileStyleRoundedCorners.isChecked) {
config.animateGifs = false
} else {
config.animateGifs = binding.dialogFileStyleAnimateGifs.isChecked
}
config.showThumbnailVideoDuration = binding.dialogFileStyleShowThumbnailVideoDuration.isChecked config.showThumbnailVideoDuration = binding.dialogFileStyleShowThumbnailVideoDuration.isChecked
config.showThumbnailFileTypes = binding.dialogFileStyleShowThumbnailFileTypes.isChecked config.showThumbnailFileTypes = binding.dialogFileStyleShowThumbnailFileTypes.isChecked
config.markFavoriteItems = binding.dialogFileStyleMarkFavoriteItems.isChecked config.markFavoriteItems = binding.dialogFileStyleMarkFavoriteItems.isChecked
config.thumbnailSpacing = thumbnailSpacing config.thumbnailSpacing = thumbnailSpacing
} }
private fun updateAnimateGifsCheckbox() {
binding.dialogFileStyleAnimateGifs.beVisibleIf(!binding.dialogFileStyleRoundedCorners.isChecked)
}
private fun updateThumbnailSpacingText() { private fun updateThumbnailSpacingText() {
binding.dialogFileStyleSpacing.text = "${thumbnailSpacing}x" binding.dialogFileStyleSpacing.text = "${thumbnailSpacing}x"
} }

View File

@ -2,6 +2,7 @@ package com.simplemobiletools.gallery.pro.dialogs
import android.content.DialogInterface import android.content.DialogInterface
import android.widget.RelativeLayout import android.widget.RelativeLayout
import android.widget.Toast
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CenterCrop import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners import com.bumptech.glide.load.resource.bitmap.RoundedCorners
@ -20,6 +21,7 @@ class ChangeFolderThumbnailStyleDialog(val activity: BaseSimpleActivity, val cal
private var config = activity.config private var config = activity.config
private val binding = DialogChangeFolderThumbnailStyleBinding.inflate(activity.layoutInflater).apply { private val binding = DialogChangeFolderThumbnailStyleBinding.inflate(activity.layoutInflater).apply {
dialogFolderLimitTitle.isChecked = config.limitFolderTitle dialogFolderLimitTitle.isChecked = config.limitFolderTitle
dialogAnimateGifsInFolders.isChecked = config.animateGifsInFolders
} }
init { init {
@ -31,6 +33,7 @@ class ChangeFolderThumbnailStyleDialog(val activity: BaseSimpleActivity, val cal
setupStyle() setupStyle()
setupMediaCount() setupMediaCount()
updateSample() updateSample()
updateAnimateGifsCheckbox()
} }
} }
} }
@ -39,6 +42,7 @@ class ChangeFolderThumbnailStyleDialog(val activity: BaseSimpleActivity, val cal
val styleRadio = binding.dialogRadioFolderStyle val styleRadio = binding.dialogRadioFolderStyle
styleRadio.setOnCheckedChangeListener { group, checkedId -> styleRadio.setOnCheckedChangeListener { group, checkedId ->
updateSample() updateSample()
updateAnimateGifsCheckbox()
} }
val styleBtn = when (config.folderStyle) { val styleBtn = when (config.folderStyle) {
@ -117,10 +121,7 @@ class ChangeFolderThumbnailStyleDialog(val activity: BaseSimpleActivity, val cal
} }
override fun onClick(dialog: DialogInterface, which: Int) { override fun onClick(dialog: DialogInterface, which: Int) {
val style = when (binding.dialogRadioFolderStyle.checkedRadioButtonId) { val style = getStyle()
R.id.dialog_radio_folder_square -> FOLDER_STYLE_SQUARE
else -> FOLDER_STYLE_ROUNDED_CORNERS
}
val count = when (binding.dialogRadioFolderCountHolder.checkedRadioButtonId) { val count = when (binding.dialogRadioFolderCountHolder.checkedRadioButtonId) {
R.id.dialog_radio_folder_count_line -> FOLDER_MEDIA_CNT_LINE R.id.dialog_radio_folder_count_line -> FOLDER_MEDIA_CNT_LINE
@ -131,6 +132,25 @@ class ChangeFolderThumbnailStyleDialog(val activity: BaseSimpleActivity, val cal
config.folderStyle = style config.folderStyle = style
config.showFolderMediaCount = count config.showFolderMediaCount = count
config.limitFolderTitle = binding.dialogFolderLimitTitle.isChecked config.limitFolderTitle = binding.dialogFolderLimitTitle.isChecked
if (style == FOLDER_STYLE_ROUNDED_CORNERS) {
config.animateGifsInFolders = false
} else {
config.animateGifsInFolders = binding.dialogAnimateGifsInFolders.isChecked
}
callback() callback()
} }
private fun getStyle(): Int {
return when (binding.dialogRadioFolderStyle.checkedRadioButtonId) {
R.id.dialog_radio_folder_square -> FOLDER_STYLE_SQUARE
else -> FOLDER_STYLE_ROUNDED_CORNERS
}
}
private fun updateAnimateGifsCheckbox() {
val style = getStyle()
binding.dialogAnimateGifsInFolders.beVisibleIf(style != FOLDER_STYLE_ROUNDED_CORNERS)
}
} }

View File

@ -6,6 +6,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.database.Cursor import android.database.Cursor
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.graphics.drawable.PictureDrawable import android.graphics.drawable.PictureDrawable
import android.media.AudioManager import android.media.AudioManager
import android.os.Process import android.os.Process
@ -14,12 +15,15 @@ import android.provider.MediaStore.Images
import android.widget.ImageView import android.widget.ImageView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.Priority import com.bumptech.glide.Priority
import com.bumptech.glide.integration.webp.decoder.WebpDrawable
import com.bumptech.glide.integration.webp.decoder.WebpDrawableTransformation
import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.DecodeFormat import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.bitmap.BitmapTransitionOptions
import com.bumptech.glide.load.resource.bitmap.CenterCrop import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.FitCenter
import com.bumptech.glide.load.resource.bitmap.RoundedCorners import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.RequestListener
@ -37,7 +41,6 @@ import com.simplemobiletools.gallery.pro.interfaces.*
import com.simplemobiletools.gallery.pro.models.* import com.simplemobiletools.gallery.pro.models.*
import com.simplemobiletools.gallery.pro.svg.SvgSoftwareLayerSetter import com.simplemobiletools.gallery.pro.svg.SvgSoftwareLayerSetter
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import pl.droidsonroids.gif.GifDrawable
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.nio.ByteBuffer import java.nio.ByteBuffer
@ -45,6 +48,7 @@ import java.nio.channels.FileChannel
import kotlin.collections.set import kotlin.collections.set
import kotlin.math.max import kotlin.math.max
val Context.audioManager get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager val Context.audioManager get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager
fun Context.getHumanizedFilename(path: String): String { fun Context.getHumanizedFilename(path: String): String {
@ -463,31 +467,11 @@ fun Context.loadImage(
roundCorners: Int, signature: ObjectKey, skipMemoryCacheAtPaths: ArrayList<String>? = null roundCorners: Int, signature: ObjectKey, skipMemoryCacheAtPaths: ArrayList<String>? = null
) { ) {
target.isHorizontalScrolling = horizontalScroll target.isHorizontalScrolling = horizontalScroll
if (type == TYPE_IMAGES || type == TYPE_VIDEOS || type == TYPE_RAWS || type == TYPE_PORTRAITS) { if (type == TYPE_SVGS) {
if (type == TYPE_IMAGES && path.isPng()) {
loadPng(path, target, cropThumbnails, roundCorners, signature, skipMemoryCacheAtPaths)
} else {
loadJpg(path, target, cropThumbnails, roundCorners, signature, skipMemoryCacheAtPaths)
}
} else if (type == TYPE_GIFS) {
if (!animateGifs) {
loadStaticGIF(path, target, cropThumbnails, roundCorners, signature, skipMemoryCacheAtPaths)
return
}
try {
val gifDrawable = GifDrawable(path)
target.setImageDrawable(gifDrawable)
gifDrawable.start()
target.scaleType = if (cropThumbnails) ImageView.ScaleType.CENTER_CROP else ImageView.ScaleType.FIT_CENTER
} catch (e: Exception) {
loadStaticGIF(path, target, cropThumbnails, roundCorners, signature, skipMemoryCacheAtPaths)
} catch (e: OutOfMemoryError) {
loadStaticGIF(path, target, cropThumbnails, roundCorners, signature, skipMemoryCacheAtPaths)
}
} else if (type == TYPE_SVGS) {
loadSVG(path, target, cropThumbnails, roundCorners, signature) loadSVG(path, target, cropThumbnails, roundCorners, signature)
} else {
val tryLoadingWithPicasso = type == TYPE_IMAGES && path.isPng()
loadImageBase(path, target, cropThumbnails, roundCorners, signature, skipMemoryCacheAtPaths, animateGifs, tryLoadingWithPicasso)
} }
} }
@ -512,109 +496,72 @@ fun Context.getPathLocation(path: String): Int {
} }
} }
fun Context.loadPng( fun Context.loadImageBase(
path: String, path: String,
target: MySquareImageView, target: MySquareImageView,
cropThumbnails: Boolean, cropThumbnails: Boolean,
roundCorners: Int, roundCorners: Int,
signature: ObjectKey, signature: ObjectKey,
skipMemoryCacheAtPaths: ArrayList<String>? = null skipMemoryCacheAtPaths: ArrayList<String>? = null,
animate: Boolean = false,
tryLoadingWithPicasso: Boolean = false,
crossFadeDuration: Int = 300
) { ) {
val options = RequestOptions() val options = RequestOptions()
.signature(signature) .signature(signature)
.skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true) .skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.priority(Priority.LOW) .priority(Priority.LOW)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.format(DecodeFormat.PREFER_ARGB_8888) .format(DecodeFormat.PREFER_ARGB_8888)
if (cropThumbnails) options.centerCrop() else options.fitCenter() if (cropThumbnails) {
options.optionalTransform(CenterCrop())
options.optionalTransform(WebpDrawable::class.java, WebpDrawableTransformation(CenterCrop()))
} else {
options.optionalTransform(FitCenter())
options.optionalTransform(WebpDrawable::class.java, WebpDrawableTransformation(FitCenter()))
}
// animation is only supported without rounded corners
if (animate && roundCorners == ROUNDED_CORNERS_NONE) {
// this is required to make glide cache aware of changes
options.decode(Drawable::class.java)
} else {
options.dontAnimate()
// don't animate is not enough for webp files, decode as bitmap forces first frame use in animated webps
options.decode(Bitmap::class.java)
}
if (roundCorners != ROUNDED_CORNERS_NONE) {
val cornerSize = if (roundCorners == ROUNDED_CORNERS_SMALL) com.simplemobiletools.commons.R.dimen.rounded_corner_radius_small else com.simplemobiletools.commons.R.dimen.rounded_corner_radius_big
val cornerRadius = resources.getDimension(cornerSize).toInt()
val roundedCornersTransform = RoundedCorners(cornerRadius)
options.optionalTransform(MultiTransformation(CenterCrop(), roundedCornersTransform))
options.optionalTransform(WebpDrawable::class.java, MultiTransformation(WebpDrawableTransformation(CenterCrop()), WebpDrawableTransformation(roundedCornersTransform)))
}
var builder = Glide.with(applicationContext) var builder = Glide.with(applicationContext)
.asBitmap()
.load(path) .load(path)
.apply(options) .apply(options)
.listener(object : RequestListener<Bitmap> { .transition(DrawableTransitionOptions.withCrossFade(crossFadeDuration))
override fun onLoadFailed(e: GlideException?, model: Any?, targetBitmap: Target<Bitmap>, isFirstResource: Boolean): Boolean {
if (tryLoadingWithPicasso) {
builder = builder.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, targetBitmap: Target<Drawable>, isFirstResource: Boolean): Boolean {
tryLoadingWithPicasso(path, target, cropThumbnails, roundCorners, signature) tryLoadingWithPicasso(path, target, cropThumbnails, roundCorners, signature)
return true return true
} }
override fun onResourceReady( override fun onResourceReady(
resource: Bitmap, resource: Drawable,
model: Any, model: Any,
targetBitmap: Target<Bitmap>, targetBitmap: Target<Drawable>,
dataSource: DataSource, dataSource: DataSource,
isFirstResource: Boolean isFirstResource: Boolean
): Boolean { ): Boolean {
return false return false
} }
}) })
if (roundCorners != ROUNDED_CORNERS_NONE) {
val cornerSize =
if (roundCorners == ROUNDED_CORNERS_SMALL) com.simplemobiletools.commons.R.dimen.rounded_corner_radius_small else com.simplemobiletools.commons.R.dimen.rounded_corner_radius_big
val cornerRadius = resources.getDimension(cornerSize).toInt()
builder = builder.transform(CenterCrop(), RoundedCorners(cornerRadius))
}
builder.into(target)
}
fun Context.loadJpg(
path: String,
target: MySquareImageView,
cropThumbnails: Boolean,
roundCorners: Int,
signature: ObjectKey,
skipMemoryCacheAtPaths: ArrayList<String>? = null
) {
val options = RequestOptions()
.signature(signature)
.skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true)
.priority(Priority.LOW)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
if (cropThumbnails) options.centerCrop() else options.fitCenter()
var builder = Glide.with(applicationContext)
.asBitmap()
.load(path)
.apply(options)
.transition(BitmapTransitionOptions.withCrossFade())
if (roundCorners != ROUNDED_CORNERS_NONE) {
val cornerSize =
if (roundCorners == ROUNDED_CORNERS_SMALL) com.simplemobiletools.commons.R.dimen.rounded_corner_radius_small else com.simplemobiletools.commons.R.dimen.rounded_corner_radius_big
val cornerRadius = resources.getDimension(cornerSize).toInt()
builder = builder.transform(CenterCrop(), RoundedCorners(cornerRadius))
}
builder.into(target)
}
fun Context.loadStaticGIF(
path: String,
target: MySquareImageView,
cropThumbnails: Boolean,
roundCorners: Int,
signature: ObjectKey,
skipMemoryCacheAtPaths: ArrayList<String>? = null
) {
val options = RequestOptions()
.signature(signature)
.skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true)
.priority(Priority.LOW)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
if (cropThumbnails) options.centerCrop() else options.fitCenter()
var builder = Glide.with(applicationContext)
.asBitmap() // make sure the GIF wont animate
.load(path)
.apply(options)
if (roundCorners != ROUNDED_CORNERS_NONE) {
val cornerSize =
if (roundCorners == ROUNDED_CORNERS_SMALL) com.simplemobiletools.commons.R.dimen.rounded_corner_radius_small else com.simplemobiletools.commons.R.dimen.rounded_corner_radius_big
val cornerRadius = resources.getDimension(cornerSize).toInt()
builder = builder.transform(CenterCrop(), RoundedCorners(cornerRadius))
} }
builder.into(target) builder.into(target)

View File

@ -164,6 +164,10 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getBoolean(ANIMATE_GIFS, false) get() = prefs.getBoolean(ANIMATE_GIFS, false)
set(animateGifs) = prefs.edit().putBoolean(ANIMATE_GIFS, animateGifs).apply() set(animateGifs) = prefs.edit().putBoolean(ANIMATE_GIFS, animateGifs).apply()
var animateGifsInFolders: Boolean
get() = prefs.getBoolean(ANIMATE_GIFS_IN_FOLDERS, false)
set(animateGifsInFolders) = prefs.edit().putBoolean(ANIMATE_GIFS_IN_FOLDERS, animateGifsInFolders).apply()
var maxBrightness: Boolean var maxBrightness: Boolean
get() = prefs.getBoolean(MAX_BRIGHTNESS, false) get() = prefs.getBoolean(MAX_BRIGHTNESS, false)
set(maxBrightness) = prefs.edit().putBoolean(MAX_BRIGHTNESS, maxBrightness).apply() set(maxBrightness) = prefs.edit().putBoolean(MAX_BRIGHTNESS, maxBrightness).apply()

View File

@ -18,6 +18,7 @@ const val REMEMBER_LAST_VIDEO_POSITION = "remember_last_video_position"
const val LOOP_VIDEOS = "loop_videos" const val LOOP_VIDEOS = "loop_videos"
const val OPEN_VIDEOS_ON_SEPARATE_SCREEN = "open_videos_on_separate_screen" const val OPEN_VIDEOS_ON_SEPARATE_SCREEN = "open_videos_on_separate_screen"
const val ANIMATE_GIFS = "animate_gifs" const val ANIMATE_GIFS = "animate_gifs"
const val ANIMATE_GIFS_IN_FOLDERS = "animate_gifs_in_folders"
const val MAX_BRIGHTNESS = "max_brightness" const val MAX_BRIGHTNESS = "max_brightness"
const val CROP_THUMBNAILS = "crop_thumbnails" const val CROP_THUMBNAILS = "crop_thumbnails"
const val SHOW_THUMBNAIL_VIDEO_DURATION = "show_thumbnail_video_duration" const val SHOW_THUMBNAIL_VIDEO_DURATION = "show_thumbnail_video_duration"

View File

@ -87,5 +87,13 @@
android:paddingBottom="@dimen/activity_margin" android:paddingBottom="@dimen/activity_margin"
android:text="@string/limit_folder_title" /> android:text="@string/limit_folder_title" />
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id="@+id/dialog_animate_gifs_in_folders"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:text="@string/animate_gifs" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@ -22,6 +22,7 @@ androidImageCropper = "4.5.0"
apng = "2.25.0" apng = "2.25.0"
awebp = "2.25.0" awebp = "2.25.0"
glideCompiler = "4.15.1" glideCompiler = "4.15.1"
zjupureWebpdecoder = "2.3.4.15.1"
gestureviews = "a8e8fa8d27" gestureviews = "a8e8fa8d27"
androidsvgAar = "1.4" androidsvgAar = "1.4"
imagefilters = "1.0.7" imagefilters = "1.0.7"
@ -71,6 +72,7 @@ sdk-panowidget = { module = "com.google.vr:sdk-panowidget", version.ref = "sdkPa
apng = { module = "com.github.penfeizhou.android.animation:apng", version.ref = "apng" } apng = { module = "com.github.penfeizhou.android.animation:apng", version.ref = "apng" }
awebp = { module = "com.github.penfeizhou.android.animation:awebp", version.ref = "awebp" } awebp = { module = "com.github.penfeizhou.android.animation:awebp", version.ref = "awebp" }
glide-compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glideCompiler" } glide-compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glideCompiler" }
zjupure-webpdecoder = { module = "com.github.zjupure:webpdecoder", version.ref = "zjupureWebpdecoder" }
picasso = { module = "com.squareup.picasso:picasso", version.ref = "picasso" } picasso = { module = "com.squareup.picasso:picasso", version.ref = "picasso" }
[bundles] [bundles]
room = [ room = [