ImageViewer: delete button & ui behavior improvements
This commit is contained in:
parent
c82d6c0e36
commit
bad270851f
@ -42,7 +42,7 @@ dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation "androidx.core:core-ktx:1.3.1"
|
||||
implementation "androidx.appcompat:appcompat:1.2.0"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.0.0"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.0.1"
|
||||
|
||||
implementation "androidx.sqlite:sqlite:2.1.0"
|
||||
implementation "androidx.preference:preference:1.1.1"
|
||||
|
@ -15,9 +15,10 @@ import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||
import kotlinx.android.synthetic.main.activity_image_viewer.*
|
||||
import sushi.hardcore.droidfs.ConstValues
|
||||
import sushi.hardcore.droidfs.R
|
||||
import sushi.hardcore.droidfs.util.MiscUtils
|
||||
import sushi.hardcore.droidfs.explorers.ExplorerElement
|
||||
import sushi.hardcore.droidfs.util.MiscUtils
|
||||
import sushi.hardcore.droidfs.util.PathUtils
|
||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||
import sushi.hardcore.droidfs.widgets.ZoomableImageView
|
||||
import java.io.File
|
||||
import java.security.MessageDigest
|
||||
@ -28,6 +29,7 @@ class ImageViewer: FileViewerActivity() {
|
||||
private const val hideDelay: Long = 3000
|
||||
private const val MIN_SWIPE_DISTANCE = 150
|
||||
}
|
||||
private lateinit var fileName: String
|
||||
private lateinit var glideImage: RequestBuilder<Drawable>
|
||||
private var x1 = 0F
|
||||
private var x2 = 0F
|
||||
@ -43,13 +45,11 @@ class ImageViewer: FileViewerActivity() {
|
||||
action_bar.visibility = View.GONE
|
||||
}
|
||||
override fun viewFile() {
|
||||
val imageBuff = loadWholeFile(filePath)
|
||||
if (imageBuff != null){
|
||||
setContentView(R.layout.activity_image_viewer)
|
||||
image_viewer.setOnInteractionListener(object : ZoomableImageView.OnInteractionListener{
|
||||
image_viewer.setOnInteractionListener(object : ZoomableImageView.OnInteractionListener {
|
||||
override fun onSingleTap(event: MotionEvent?) {
|
||||
handler.removeCallbacks(hideUI)
|
||||
if (action_buttons.visibility == View.GONE){
|
||||
if (action_buttons.visibility == View.GONE) {
|
||||
action_buttons.visibility = View.VISIBLE
|
||||
action_bar.visibility = View.VISIBLE
|
||||
handler.postDelayed(hideUI, hideDelay)
|
||||
@ -57,16 +57,17 @@ class ImageViewer: FileViewerActivity() {
|
||||
hideUI.run()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouch(event: MotionEvent?) {
|
||||
if (!image_viewer.isZoomed){
|
||||
when(event?.action){
|
||||
if (!image_viewer.isZoomed) {
|
||||
when (event?.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
x1 = event.x
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
x2 = event.x
|
||||
val deltaX = x2 - x1
|
||||
if (abs(deltaX) > MIN_SWIPE_DISTANCE){
|
||||
if (abs(deltaX) > MIN_SWIPE_DISTANCE) {
|
||||
swipeImage(deltaX)
|
||||
}
|
||||
}
|
||||
@ -74,11 +75,24 @@ class ImageViewer: FileViewerActivity() {
|
||||
}
|
||||
}
|
||||
})
|
||||
glideImage = Glide.with(this).load(imageBuff)
|
||||
glideImage.into(image_viewer)
|
||||
text_filename.text = File(filePath).name
|
||||
loadImage()
|
||||
handler.postDelayed(hideUI, hideDelay)
|
||||
}
|
||||
|
||||
private fun loadImage(){
|
||||
loadWholeFile(filePath)?.let {
|
||||
glideImage = Glide.with(this).load(it)
|
||||
glideImage.into(image_viewer)
|
||||
fileName = File(filePath).name
|
||||
text_filename.text = fileName
|
||||
rotationAngle = 0F
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUserInteraction() {
|
||||
super.onUserInteraction()
|
||||
handler.removeCallbacks(hideUI)
|
||||
handler.postDelayed(hideUI, hideDelay)
|
||||
}
|
||||
|
||||
private fun swipeImage(deltaX: Float){
|
||||
@ -103,27 +117,62 @@ class ImageViewer: FileViewerActivity() {
|
||||
} else {
|
||||
MiscUtils.decrementIndex(currentMappedImageIndex, mappedImages)
|
||||
}
|
||||
loadWholeFile(mappedImages[currentMappedImageIndex].fullPath)?.let {
|
||||
glideImage = Glide.with(applicationContext).load(it)
|
||||
glideImage.into(image_viewer)
|
||||
text_filename.text = File(mappedImages[currentMappedImageIndex].fullPath).name
|
||||
rotationAngle = 0F
|
||||
filePath = mappedImages[currentMappedImageIndex].fullPath
|
||||
loadImage()
|
||||
}
|
||||
|
||||
fun onClickDelete(view: View) {
|
||||
ColoredAlertDialogBuilder(this)
|
||||
.keepFullScreen()
|
||||
.setTitle(R.string.warning)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
if (gocryptfsVolume.removeFile(filePath)){
|
||||
currentMappedImageIndex = MiscUtils.decrementIndex(currentMappedImageIndex, mappedImages)
|
||||
mappedImages.clear()
|
||||
wasMapped = false
|
||||
swipeImage(-1F)
|
||||
} else {
|
||||
ColoredAlertDialogBuilder(this)
|
||||
.keepFullScreen()
|
||||
.setTitle(R.string.error)
|
||||
.setMessage(getString(R.string.remove_failed, fileName))
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setMessage(getString(R.string.single_delete_confirm, fileName))
|
||||
.show()
|
||||
}
|
||||
|
||||
fun onClickSlideshow(view: View) {
|
||||
if (!slideshowActive){
|
||||
slideshowActive = true
|
||||
Thread {
|
||||
Thread.sleep(ConstValues.slideshow_delay)
|
||||
while (slideshowActive){
|
||||
runOnUiThread { swipeImage(-1F) }
|
||||
Thread.sleep(ConstValues.slideshow_delay)
|
||||
}
|
||||
}.start()
|
||||
hideUI.run()
|
||||
Toast.makeText(this, R.string.slideshow_started, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
stopSlideshow()
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopSlideshow(){
|
||||
slideshowActive = false
|
||||
Toast.makeText(this, R.string.slideshow_stopped, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (slideshowActive){
|
||||
stopSlideshow()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
class RotateTransformation(private val rotationAngle: Float): BitmapTransformation() {
|
||||
|
@ -2,10 +2,19 @@ package sushi.hardcore.droidfs.widgets
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.view.WindowManager
|
||||
|
||||
class ColoredAlertDialogBuilder: AlertDialog.Builder {
|
||||
constructor(context: Context): super(context)
|
||||
constructor(context: Context, themeResId: Int): super(context, themeResId)
|
||||
|
||||
private var keepFullScreen = false
|
||||
|
||||
fun keepFullScreen(): AlertDialog.Builder {
|
||||
keepFullScreen = true
|
||||
return this
|
||||
}
|
||||
|
||||
private fun applyColor(dialog: AlertDialog){
|
||||
dialog.setOnShowListener{
|
||||
val themeColor = ThemeColor.getThemeColor(context)
|
||||
@ -14,16 +23,19 @@ class ColoredAlertDialogBuilder: AlertDialog.Builder {
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun show(): AlertDialog? {
|
||||
val dialog = super.create()
|
||||
applyColor(dialog)
|
||||
|
||||
override fun show(): AlertDialog {
|
||||
val dialog = create()
|
||||
dialog.show()
|
||||
return null
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun create(): AlertDialog {
|
||||
val dialog = super.create()
|
||||
applyColor(dialog)
|
||||
if (keepFullScreen){
|
||||
dialog.window?.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
|
||||
}
|
||||
return dialog
|
||||
}
|
||||
}
|
@ -27,8 +27,21 @@
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:textSize="20sp"
|
||||
android:layout_marginEnd="40dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_toStartOf="@id/image_delete"
|
||||
android:layout_centerVertical="true"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/image_delete"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="#00000000"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/icon_delete"
|
||||
android:onClick="onClickDelete"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_toStartOf="@id/image_button_slideshow"
|
||||
android:layout_centerVertical="true"/>
|
||||
|
||||
<ImageButton
|
||||
|
@ -136,7 +136,7 @@
|
||||
<string name="query_cursor_null_error_msg">Unable to access this file</string>
|
||||
<string name="about">About</string>
|
||||
<string name="github">GitHub</string>
|
||||
<string name="github_summary">Want to read the documentation, request feature, report bug, read the source code… Check the DroidFS\'s repository !</string>
|
||||
<string name="github_summary">Want to read the documentation, review the source code, request feature, report bug… Check the DroidFS\'s repository !</string>
|
||||
<string name="share">Share</string>
|
||||
<string name="decrypt_files">Export/Decrypt</string>
|
||||
<string name="loading_msg_copy">Copying selected items…</string>
|
||||
@ -172,4 +172,5 @@
|
||||
<string name="change_pwd_cant_write_error_msg">DroidFS doesn\'t have write access to this path. You can try to move the volume to a writable location.</string>
|
||||
<string name="change_pwd_on_sdcard_error_msg">DroidFS can\'t write on removable SD cards, please move the volume to internal storage.</string>
|
||||
<string name="slideshow_stopped">Slideshow stopped</string>
|
||||
<string name="slideshow_started">Slideshow started</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user