New UI: Select a tab and then, while holding down, start dragging

drag-tabs
Steven Knipe 3 years ago
parent f3bfca7218
commit ae79fc327f

@ -4,6 +4,8 @@
package org.mozilla.fenix.tabstray.browser
import android.annotation.SuppressLint
import android.view.MotionEvent
import android.view.View
import android.widget.ImageButton
import android.widget.ImageView
@ -31,6 +33,7 @@ import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.ext.removeAndDisable
import org.mozilla.fenix.ext.removeTouchDelegate
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showAndEnable
import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.selection.SelectionHolder
@ -201,6 +204,7 @@ abstract class AbstractBrowserTabViewHolder(
imageLoader.loadIntoView(thumbnailView, ImageLoadRequest(id, thumbnailSize))
}
@SuppressLint("ClickableViewAccessibility")
private fun setSelectionInteractor(
item: TabSessionState,
holder: SelectionHolder<TabSessionState>,
@ -222,22 +226,36 @@ abstract class AbstractBrowserTabViewHolder(
metrics.track(Event.CollectionTabLongPressed)
interactor.select(item)
true
} else if (holder.selectedItems.contains(item)) {
val parent = itemView.parent as? AbstractBrowserTrayList
if (parent?.context?.settings()?.searchTermTabGroupsAreEnabled == false) {
val shadow = View.DragShadowBuilder(itemView)
@Suppress("DEPRECATION")
itemView.startDrag(null, shadow, item, 0)
// startDragAndDrop is the non-deprecated version, but requires API 24
true
} else false
} else {
false
}
}
// Since I immediately pass the event to onTouchEvent if it's not a move
// The ClickableViewAccessibility warning isn't useful
itemView.setOnTouchListener { view, motionEvent ->
when (motionEvent.actionMasked) {
MotionEvent.ACTION_MOVE -> if (holder.selectedItems.contains(item)) {
val parent = itemView.parent as? AbstractBrowserTrayList
if (parent?.context?.settings()?.searchTermTabGroupsAreEnabled == false) {
for (tabSelected in holder.selectedItems) {
// Exit selection mode by deselecting everything
interactor.deselect(tabSelected)
}
val shadow = View.DragShadowBuilder(itemView)
// startDragAndDrop is the non-deprecated version, but requires API 24
@Suppress("DEPRECATION")
itemView.startDrag(null, shadow, item, 0)
view.alpha = DRAG_TRANSPARENCY // Make the dragged tab mostly invisible
}
}
else -> view.onTouchEvent(motionEvent)
}
true
}
}
companion object {
internal const val DRAG_TRANSPARENCY = 0.2f
internal const val PLAY_PAUSE_BUTTON_EXTRA_DPS = 24
internal const val GRID_ITEM_CLOSE_BUTTON_EXTRA_DPS = 24
}

@ -8,6 +8,7 @@ import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.view.DragEvent
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.tabstray.TabViewHolder
@ -76,8 +77,6 @@ abstract class AbstractBrowserTrayList @JvmOverloads constructor(
// Find the closest item to the x/y position of the drop.
private fun getDropPosition(x: Float, y: Float): String? {
if (childCount < 2) return null // If there's 0 or 1 tabs visible, can't reorder
if (layoutManager == null) return null
val lm = layoutManager!!
var bestDist = Float.MAX_VALUE
var bestId: String? = null
for (i in 0 until childCount) {
@ -85,7 +84,7 @@ abstract class AbstractBrowserTrayList @JvmOverloads constructor(
val targetHolder = findContainingViewHolder(proposedTarget)
if (targetHolder is TabViewHolder) {
var rect = Rect() // Use layoutManager to get post-animation positioning
lm.getDecoratedBoundsWithMargins(proposedTarget, rect)
getDecoratedBoundsWithMargins(proposedTarget, rect)
val targetX = (rect.left + rect.right) / 2
val targetY = (rect.top + rect.bottom) / 2
val xDiff = x - targetX
@ -99,6 +98,16 @@ abstract class AbstractBrowserTrayList @JvmOverloads constructor(
}
return bestId
}
private fun findSourceView(id: String): View? {
for (i in 0 until childCount) {
val proposed = getChildAt(i)
val targetHolder = findContainingViewHolder(proposed)
if (targetHolder is TabViewHolder && targetHolder.tab?.id == id) {
return proposed
}
}
return null
}
private val dragListen = OnDragListener { _, event ->
when (event.action) {
DragEvent.ACTION_DRAG_STARTED -> {
@ -127,6 +136,12 @@ abstract class AbstractBrowserTrayList @JvmOverloads constructor(
true
}
DragEvent.ACTION_DRAG_ENDED -> {
// Revert the invisibility
val id = (event.localState as TabSessionState).id
val sourceView = findSourceView(id)
if (sourceView != null) {
sourceView.alpha = 1.0f
}
true
}
else -> { // Unknown action

Loading…
Cancel
Save