Skip to content

Commit

Permalink
Merge pull request #20 from MohamedRejeb/0.2.x
Browse files Browse the repository at this point in the history
Refactor dropTarget
  • Loading branch information
MohamedRejeb authored Sep 16, 2024
2 parents 814d714 + 0198667 commit 75eff07
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ class DragAndDropState<T>(
* Add or update [DropTargetState] in [dropTargetMap]
*/
internal fun addDropTarget(dropTargetState: DropTargetState<T>) {
if (dropTargetMap[dropTargetState.key] == dropTargetState) {
return
}

dropTargetMap[dropTargetState.key] = dropTargetState
}

Expand Down Expand Up @@ -119,40 +123,16 @@ class DragAndDropState<T>(
*
* @param state - new state
*/
internal fun addOrUpdateDraggableItem(
internal fun addDraggableItem(
state: DraggableItemState<T>
) {
val key = state.key
val oldState = draggableItemMap[key]

if (oldState != null) {
updateDraggableItem(oldState, state)
} else {
draggableItemMap[key] = state
}
draggableItemMap[state.key] = state
}

internal fun removeDraggableItem(key: Any) {
draggableItemMap.remove(key)
}

/**
* Update [DraggableItemState]
*
* @param oldState - old state
* @param newState - new state
*/
private fun updateDraggableItem(
oldState: DraggableItemState<T>,
newState: DraggableItemState<T>
) {
oldState.size = newState.size
oldState.positionInRoot = newState.positionInRoot
oldState.dropTargets = newState.dropTargets
oldState.data = newState.data
oldState.key = newState.key
}

private var dragStartPositionInRoot: Offset = Offset.Zero
private var dragStartOffset: Offset = Offset.Zero

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.key
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
Expand Down Expand Up @@ -104,7 +103,7 @@ internal fun <T> CoreDraggableItem(
}

DisposableEffect(key, state, draggableItemState) {
state.addOrUpdateDraggableItem(draggableItemState)
state.addDraggableItem(draggableItemState)

onDispose {
state.removeDraggableItem(key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,6 @@ interface DropStrategy {
): DropTargetState<T>? =
dropTargets
.minByOrNull {
println("it.key: ${it.key}")
println("draggedItemTopLeft: $draggedItemTopLeft")
println("draggedItemSize: $draggedItemSize")
println("it.topLeft: ${it.topLeft}")
println("it.size: ${it.size}")
val p1 = Offset(
x = draggedItemTopLeft.x + draggedItemSize.width / 2f,
y = draggedItemTopLeft.y + draggedItemSize.height / 2f,
Expand All @@ -88,12 +83,7 @@ interface DropStrategy {
y = it.topLeft.y + it.size.height / 2f,
)

println("p1: $p1")
println("p2: $p2")

MathUtils.distance2(p1 = p1, p2 = p2).also {
println("distance2: $it")
}
MathUtils.distance2(p1 = p1, p2 = p2)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ package com.mohamedrejeb.compose.dnd.drop
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.node.LayoutAwareModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.toSize
import com.mohamedrejeb.compose.dnd.DragAndDropState
import com.mohamedrejeb.compose.dnd.drag.DraggedItemState
Expand Down Expand Up @@ -75,67 +77,82 @@ private data class DropTargetNodeElement<T>(
val onDragEnter: (state: DraggedItemState<T>) -> Unit,
val onDragExit: (state: DraggedItemState<T>) -> Unit,
) : ModifierNodeElement<DropTargetNode<T>>() {
override fun create(): DropTargetNode<T> = DropTargetNode(
key = key,
state = state,
zIndex = zIndex,
dropAlignment = dropAlignment,
dropOffset = dropOffset,
dropAnimationEnabled = dropAnimationEnabled,
onDrop = onDrop,
onDragEnter = onDragEnter,
onDragExit = onDragExit,
)
override fun create(): DropTargetNode<T> =
DropTargetNode(
dropTargetState = DropTargetState(
key = key,
zIndex = zIndex,
size = Size.Zero,
topLeft = Offset.Zero,
dropAlignment = dropAlignment,
dropOffset = dropOffset,
dropAnimationEnabled = dropAnimationEnabled,
onDrop = onDrop,
onDragEnter = onDragEnter,
onDragExit = onDragExit,
),
state = state,
)

override fun update(node: DropTargetNode<T>) {
node.key = key
node.state = state
node.zIndex = zIndex
node.dropAlignment = dropAlignment
node.dropOffset = dropOffset
node.dropAnimationEnabled = dropAnimationEnabled
node.onDrop = onDrop
node.onDragEnter = onDragEnter
node.onDragExit = onDragExit
node.apply {
this.state = state

val isKeyChanged = dropTargetState.key != key

dropTargetState.key = key
dropTargetState.zIndex = zIndex
dropTargetState.dropAlignment = dropAlignment
dropTargetState.dropOffset = dropOffset
dropTargetState.dropAnimationEnabled = dropAnimationEnabled
dropTargetState.onDrop = onDrop
dropTargetState.onDragEnter = onDragEnter
dropTargetState.onDragExit = onDragExit

if (isKeyChanged) {
onDetach()
onAttach()
}
}
}

override fun InspectorInfo.inspectableProperties() {
name = "DropTarget"
properties["key"] = key
properties["state"] = state
properties["zIndex"] = zIndex
properties["dropAlignment"] = dropAlignment
properties["dropOffset"] = dropOffset
properties["dropAnimationEnabled"] = dropAnimationEnabled
properties["onDrop"] = onDrop
properties["onDragEnter"] = onDragEnter
properties["onDragExit"] = onDragExit
}
}

private data class DropTargetNode<T>(
var key: Any,
val dropTargetState: DropTargetState<T>,
var state: DragAndDropState<T>,
var zIndex: Float,
var dropAlignment: Alignment,
var dropOffset: Offset,
var dropAnimationEnabled: Boolean,
var onDrop: (state: DraggedItemState<T>) -> Unit,
var onDragEnter: (state: DraggedItemState<T>) -> Unit,
var onDragExit: (state: DraggedItemState<T>) -> Unit,
) : Modifier.Node(), LayoutAwareModifierNode {

private val key get() = dropTargetState.key

override fun onAttach() {
state.addDropTarget(dropTargetState)
}

override fun onPlaced(coordinates: LayoutCoordinates) {
state.addDropTarget(dropTargetState)

val size = coordinates.size.toSize()
val topLeft = coordinates.positionInRoot()
val dropTargetState = DropTargetState(
key = key,
zIndex = zIndex,
size = size,
topLeft = topLeft,
dropAlignment = dropAlignment,
dropOffset = dropOffset,
dropAnimationEnabled = dropAnimationEnabled,
onDrop = onDrop,
onDragEnter = onDragEnter,
onDragExit = onDragExit,
)
state.addDropTarget(dropTargetState)

dropTargetState.size = size
dropTargetState.topLeft = topLeft
}

override fun onRemeasured(size: IntSize) {
dropTargetState.size = size.toSize()
}

override fun onReset() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import androidx.compose.ui.geometry.Size
import com.mohamedrejeb.compose.dnd.drag.DraggedItemState

class DropTargetState<T> internal constructor(
val key: Any,
val zIndex: Float,
key: Any,
zIndex: Float,

size: Size,
topLeft: Offset,
Expand All @@ -31,10 +31,16 @@ class DropTargetState<T> internal constructor(
internal var dropOffset: Offset,
internal var dropAnimationEnabled: Boolean,

internal val onDrop: (state: DraggedItemState<T>) -> Unit,
internal val onDragEnter: (state: DraggedItemState<T>) -> Unit,
internal val onDragExit: (state: DraggedItemState<T>) -> Unit,
internal var onDrop: (state: DraggedItemState<T>) -> Unit,
internal var onDragEnter: (state: DraggedItemState<T>) -> Unit,
internal var onDragExit: (state: DraggedItemState<T>) -> Unit,
) {
var key: Any = key
internal set

var zIndex: Float = zIndex
internal set

var size: Size = size
internal set

Expand Down

0 comments on commit 75eff07

Please sign in to comment.