getItemsCollision function

int? getItemsCollision({
  1. required int id,
  2. required Offset position,
  3. required Map<int, GridItemEntity> childrenIdMap,
  4. required List<int> lockedChildren,
  5. required double scrollPixelsY,
})

Checks collision of item with given id with another one in childrenIdMap.

Expects that the id is existing in childrenIdMap and is not locked inside of lockedChildren.

Depending of the current position of the item, it's possible that there is a collision with another one in childrenIdMap. That happens if the dragged item lays above another one. It's also possible that the item has a collision with itself. In that case you should check if the returned id is equal to the given id because most of the cases you don't want to update sth if nothing changes.

If there was no collision or the collision item is found in lockedChildren, then null will be returned. Otherwise the id of the collision item in childrenIdMap.

Implementation

int? getItemsCollision({
  required int id,
  required Offset position,
  required Map<int, GridItemEntity> childrenIdMap,
  required List<int> lockedChildren,
  required double scrollPixelsY,
}) {
  int? collisionId;

  // child does not exist or is locked
  if (childrenIdMap[id] == null || lockedChildren.contains(id)) {
    return null;
  }

  for (final entry in childrenIdMap.entries) {
    final item = entry.value;
    final itemDx = item.globalPosition.dx;
    final itemDy = item.globalPosition.dy;
    final itemWidth = item.size.width;
    final itemHeight = item.size.height;
    final detailsDx = position.dx;
    final detailsDy = position.dy + scrollPixelsY;

    // checking collision with full item size and global position
    if (detailsDx >= itemDx &&
        detailsDy >= itemDy &&
        detailsDx <= itemDx + itemWidth &&
        detailsDy <= itemDy + itemHeight) {
      collisionId = entry.key;
      break;
    }
  }

  if (lockedChildren.contains(collisionId)) {
    return null;
  }

  return collisionId;
}