Skip to content

Commit

Permalink
Merge pull request #31 from MohamedRejeb/0.2.x
Browse files Browse the repository at this point in the history
Add new requireFirstDownUnconsumed param
  • Loading branch information
MohamedRejeb authored Oct 10, 2024
2 parents 0e92c44 + 51f9db0 commit 6bc8f46
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,20 @@ import kotlinx.coroutines.launch
* Remember [DragAndDropState]
* @param dragAfterLongPress if true, drag will start after long press, otherwise drag will start after simple press
* This parameter is applied to all [DraggableItem]s. If you want to change it for a specific item, use [DraggableItem] parameter.
* @param requireFirstDownUnconsumed if true, the first down event should be unconsumed
* @param T type of the data that is dragged
* @return [DragAndDropState]
* @see DragAndDropState
*/
@Composable
fun <T> rememberDragAndDropState(
dragAfterLongPress: Boolean = false,
requireFirstDownUnconsumed: Boolean = false,
): DragAndDropState<T> {
return remember {
DragAndDropState(
dragAfterLongPress = dragAfterLongPress,
requireFirstDownUnconsumed = requireFirstDownUnconsumed,
)
}
}
Expand All @@ -59,11 +62,13 @@ fun <T> rememberDragAndDropState(
* State of the drag and drop
* @param dragAfterLongPress if true, drag will start after long press, otherwise drag will start after simple press
* This parameter is applied to all [DraggableItem]s. If you want to change it for a specific item, use [DraggableItem] parameter.
* @param requireFirstDownUnconsumed if true, the first down event should be unconsumed
* @param T type of the data that is dragged
*/
@Stable
class DragAndDropState<T>(
internal val dragAfterLongPress: Boolean = false,
internal val requireFirstDownUnconsumed: Boolean = false,
) {
/**
* If true, drag and drop is enabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ internal fun <T> CoreDraggableItem(
key: Any,
data: T,
state: DragAndDropState<T>,
enabled: Boolean = true,
dragAfterLongPress: Boolean = state.dragAfterLongPress,
dropTargets: List<Any> = emptyList(),
dropStrategy: DropStrategy = DropStrategy.SurfacePercentage,
dropAnimationSpec: AnimationSpec<Offset> = SpringSpec(),
sizeDropAnimationSpec: AnimationSpec<Size> = SpringSpec(),
enabled: Boolean,
dragAfterLongPress: Boolean,
requireFirstDownUnconsumed: Boolean,
dropTargets: List<Any>,
dropStrategy: DropStrategy,
dropAnimationSpec: AnimationSpec<Offset>,
sizeDropAnimationSpec: AnimationSpec<Size>,
draggableContent: @Composable () -> Unit,
content: @Composable () -> Unit,
) {
Expand Down Expand Up @@ -118,12 +119,20 @@ internal fun <T> CoreDraggableItem(
.onSizeChanged {
draggableItemState.size = it.toSize()
}
.pointerInput(key, enabled, state, state.enabled, dragAfterLongPress) {
.pointerInput(
key,
enabled,
state,
state.enabled,
dragAfterLongPress,
requireFirstDownUnconsumed,
) {
detectDragStartGesture(
key = key,
state = state,
enabled = enabled && state.enabled,
dragAfterLongPress = dragAfterLongPress,
requireFirstDownUnconsumed = requireFirstDownUnconsumed,
)
},
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.mohamedrejeb.compose.dnd.DragAndDropState
* @param state - state of the drag and drop
* @param enabled - whether the drag and drop is enabled
* @param dragAfterLongPress if true, drag will start after long press, otherwise drag will start after simple press
* @param requireFirstDownUnconsumed if true, the first down event must be unconsumed to start the drag
* @param dropTargets - list of drop targets ids to which this item can be dropped, if empty, item can be dropped to any drop target
* @param dropStrategy - strategy to determine the drop target
* @param dropAnimationSpec - animation spec for the position drop animation
Expand All @@ -49,6 +50,7 @@ fun <T> DraggableItem(
state: DragAndDropState<T>,
enabled: Boolean = true,
dragAfterLongPress: Boolean = state.dragAfterLongPress,
requireFirstDownUnconsumed: Boolean = state.requireFirstDownUnconsumed,
dropTargets: List<Any> = emptyList(),
dropStrategy: DropStrategy = DropStrategy.SurfacePercentage,
dropAnimationSpec: AnimationSpec<Offset> = SpringSpec(),
Expand Down Expand Up @@ -76,6 +78,7 @@ fun <T> DraggableItem(
state = state,
enabled = enabled,
dragAfterLongPress = dragAfterLongPress,
requireFirstDownUnconsumed = requireFirstDownUnconsumed,
dropTargets = dropTargets,
dropStrategy = dropStrategy,
dropAnimationSpec = dropAnimationSpec,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ internal suspend fun <T> PointerInputScope.detectDragStartGesture(
state: DragAndDropState<T>,
enabled: Boolean,
dragAfterLongPress: Boolean,
requireFirstDownUnconsumed: Boolean,
) = coroutineScope {
if (!enabled) return@coroutineScope

awaitEachGesture {
val down = awaitFirstDown(requireUnconsumed = true, pass = PointerEventPass.Main)
val down = awaitFirstDown(requireUnconsumed = requireFirstDownUnconsumed, pass = PointerEventPass.Main)
var drag: PointerInputChange?
if (dragAfterLongPress) {
drag = awaitLongPressOrCancellation(down.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,21 @@ fun <T> rememberReorderState(
* State of the reorder
*
* @param dragAfterLongPress if true, drag will start after long press, otherwise drag will start after simple press
* @param requireFirstDownUnconsumed if true, the first down event must be unconsumed to start the drag
* This parameter is applied to all [ReorderableItem]s. If you want to change it for a specific item, use [ReorderableItem] parameter.
*/
@Stable
class ReorderState<T>(
dragAfterLongPress: Boolean = false,
requireFirstDownUnconsumed: Boolean = false,
) {
/**
* State of the drag and drop
*/
@ExperimentalDndApi
val dndState = DragAndDropState<T>(
dragAfterLongPress = dragAfterLongPress,
requireFirstDownUnconsumed = requireFirstDownUnconsumed,
)

@OptIn(ExperimentalDndApi::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.mohamedrejeb.compose.dnd.drop.dropTarget
* @param zIndex The z-index of the item.
* @param enabled Whether the reorder is enabled.
* @param dragAfterLongPress if true, drag will start after long press, otherwise drag will start after simple press
* @param requireFirstDownUnconsumed if true, the first down event must be unconsumed to start the drag
* @param dropTargets - list of drop targets ids to which this item can be dropped, if empty, item can be dropped to any drop target
* @param dropStrategy - strategy to determine the drop target
* @param onDrop The action to perform when an item is dropped onto the target.
Expand All @@ -61,6 +62,7 @@ fun <T> ReorderableItem(
zIndex: Float = 0f,
enabled: Boolean = true,
dragAfterLongPress: Boolean = state.dndState.dragAfterLongPress,
requireFirstDownUnconsumed: Boolean = state.dndState.requireFirstDownUnconsumed,
dropTargets: List<Any> = emptyList(),
dropStrategy: DropStrategy = DropStrategy.SurfacePercentage,
onDrop: (state: DraggedItemState<T>) -> Unit = {},
Expand Down Expand Up @@ -99,6 +101,7 @@ fun <T> ReorderableItem(
state = state.dndState,
enabled = enabled,
dragAfterLongPress = dragAfterLongPress,
requireFirstDownUnconsumed = requireFirstDownUnconsumed,
dropTargets = dropTargets,
dropStrategy = dropStrategy,
dropAnimationSpec = dropAnimationSpec,
Expand Down

0 comments on commit 6bc8f46

Please sign in to comment.