From c174b7d39597e7619f7d757f3657a8493964f842 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sat, 13 May 2017 21:10:13 +0200 Subject: [PATCH] add Drag selection to directories --- .../gallery/activities/MainActivity.kt | 8 + .../gallery/adapters/DirectoryAdapter.kt | 4 + .../gallery/views/MyScalableRecyclerView.kt | 157 +++++++++++++++++- app/src/main/res/values/dimens.xml | 2 + 4 files changed, 163 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt index b5fdd60bf..59807e256 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt @@ -124,6 +124,10 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { override fun onStop() { super.onStop() config.temporarilyShowHidden = false + } + + override fun onDestroy() { + super.onDestroy() DirectoryAdapter.cleanup() } @@ -211,6 +215,10 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { } } + override fun itemLongClicked(position: Int) { + directories_grid.setDragSelectActive(position) + } + private fun handleZooming() { val layoutManager = directories_grid.layoutManager as GridLayoutManager layoutManager.spanCount = config.dirColumnCnt diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt index 35ce4a8d1..ee6224582 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt @@ -321,6 +321,10 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList -1) { + hotspotTopBoundStart = hotspotOffsetTop + hotspotTopBoundEnd = hotspotOffsetTop + hotspotHeight + hotspotBottomBoundStart = measuredHeight - hotspotHeight - hotspotOffsetBottom + hotspotBottomBoundEnd = measuredHeight - hotspotOffsetBottom } + } + private var autoScrollHandler = Handler() + private val autoScrollRunnable = object : Runnable { + override fun run() { + if (inTopHotspot) { + scrollBy(0, -autoScrollVelocity) + autoScrollHandler.postDelayed(this, AUTO_SCROLL_DELAY) + } else if (inBottomHotspot) { + scrollBy(0, autoScrollVelocity) + autoScrollHandler.postDelayed(this, AUTO_SCROLL_DELAY) + } + } + } + + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + if (!dragSelectActive) + super.dispatchTouchEvent(ev) + + when (ev.action) { + MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { + dragSelectActive = false + mCurrScaleFactor = 1.0f + mLastUp = System.currentTimeMillis() + return true + } + + MotionEvent.ACTION_MOVE -> { + if (dragSelectActive) { + val itemPosition = getItemPosition(ev) + if (hotspotHeight > -1) { + if (ev.y in hotspotTopBoundStart..hotspotTopBoundEnd) { + inBottomHotspot = false + if (!inTopHotspot) { + inTopHotspot = true + autoScrollHandler.removeCallbacks(autoScrollRunnable) + autoScrollHandler.postDelayed(autoScrollRunnable, AUTO_SCROLL_DELAY.toLong()) + } + + val simulatedFactor = (hotspotTopBoundEnd - hotspotTopBoundStart).toFloat() + val simulatedY = ev.y - hotspotTopBoundStart + autoScrollVelocity = (simulatedFactor - simulatedY).toInt() / 2 + } else if (ev.y in hotspotBottomBoundStart..hotspotBottomBoundEnd) { + inTopHotspot = false + if (!inBottomHotspot) { + inBottomHotspot = true + autoScrollHandler.removeCallbacks(autoScrollRunnable) + autoScrollHandler.postDelayed(autoScrollRunnable, AUTO_SCROLL_DELAY.toLong()) + } + + val simulatedY = ev.y + hotspotBottomBoundEnd + val simulatedFactor = (hotspotBottomBoundStart + hotspotBottomBoundEnd).toFloat() + autoScrollVelocity = (simulatedY - simulatedFactor).toInt() / 2 + } else if (inTopHotspot || inBottomHotspot) { + autoScrollHandler.removeCallbacks(autoScrollRunnable) + inTopHotspot = false + inBottomHotspot = false + } + } + + if (itemPosition != RecyclerView.NO_POSITION && lastDraggedIndex != itemPosition) { + lastDraggedIndex = itemPosition + if (minReached == -1) { + minReached = lastDraggedIndex + } + + if (maxReached == -1) { + maxReached = lastDraggedIndex + } + + if (lastDraggedIndex > maxReached) { + maxReached = lastDraggedIndex + } + + if (lastDraggedIndex < minReached) { + minReached = lastDraggedIndex + } + + (adapter as DirectoryAdapter).selectRange(initialSelection, lastDraggedIndex, minReached, maxReached) + + if (initialSelection == lastDraggedIndex) { + minReached = lastDraggedIndex + maxReached = lastDraggedIndex + } + } + + return true + } + } + } return mScaleDetector.onTouchEvent(ev) } + fun setDragSelectActive(initialSelection: Int) { + if (dragSelectActive) + return + + lastDraggedIndex = -1 + minReached = -1 + maxReached = -1 + this.initialSelection = initialSelection + dragSelectActive = true + (adapter as DirectoryAdapter).selectItem(initialSelection) + } + + private fun getItemPosition(e: MotionEvent): Int { + val v = findChildViewUnder(e.x, e.y) ?: return RecyclerView.NO_POSITION + + if (v.tag == null || v.tag !is RecyclerView.ViewHolder) { + throw IllegalStateException("Make sure your adapter makes a call to super.onBindViewHolder(), and doesn't override itemView tags.") + } + + val holder = v.tag as RecyclerView.ViewHolder + return holder.adapterPosition + } + + class GestureListener : ScaleGestureDetector.SimpleOnScaleGestureListener() { - val ZOOM_IN_THRESHOLD = -0.6f - val ZOOM_OUT_THRESHOLD = 0.25f + private val ZOOM_IN_THRESHOLD = -0.4f + private val ZOOM_OUT_THRESHOLD = 0.15f override fun onScale(detector: ScaleGestureDetector): Boolean { if (System.currentTimeMillis() - mLastUp < 1000) diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 7e8edefbe..4944170eb 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -7,4 +7,6 @@ 150dp 24dp 50dp + + 56dp