From 6e943df7c4459ab3be91f83668957f7fe6fb715e Mon Sep 17 00:00:00 2001
From: Julian Leucker <leuckerj@gmail.com>
Date: Tue, 7 Feb 2023 12:30:10 +0100
Subject: [PATCH] Don't allow items inside each other

---
 src/Grid.vue | 46 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/Grid.vue b/src/Grid.vue
index e52fdf8..8b9d4cd 100644
--- a/src/Grid.vue
+++ b/src/Grid.vue
@@ -37,13 +37,43 @@ export default {
       type: Number,
       required: true,
     },
+    posValidation: {
+      type: Function,
+      required: false,
+    },
   },
   methods: {
+    positionAllowed(x, y, key) {
+      for (let item of this.items) {
+        if (key === item.key) continue;
+        if (x >= item.x && x < item.x + item.w) {
+          if (y >= item.y && y < item.y + item.h) {
+            return false;
+          }
+        }
+      }
+      if (this.posValidation) return this.posValidation(x, y);
+      return true;
+    },
     handleDragOver(event) {
       let data = event.dataTransfer.getData("vueDrag/gridItem");
       let element = JSON.parse(data);
       let coords = this.getCoords(event.layerX, event.layerY);
 
+      let newPositionValid = true;
+
+      for (let x = coords.x; x < coords.x + element.w; x++) {
+        for (let y = coords.y; y < coords.y + element.h; y++) {
+          newPositionValid = this.positionAllowed(x, y, element.key);
+          if (!newPositionValid) break;
+        }
+      }
+
+      if (!newPositionValid) {
+        this.$refs.highlight.style.display = "none";
+        return;
+      }
+
       this.$refs.highlight.style.display = "block";
       this.$refs.highlight.style.gridColumnStart = coords.x + "";
       this.$refs.highlight.style.gridRowStart = coords.y + "";
@@ -55,13 +85,27 @@ export default {
       let data = event.dataTransfer.getData("vueDrag/gridItem");
       let element = JSON.parse(data);
       console.log(element);
+
+      let coords = this.getCoords(event.layerX, event.layerY);
+
+      let newPositionValid = true;
+
+      for (let x = coords.x; x < coords.x + element.w; x++) {
+        for (let y = coords.y; y < coords.y + element.h; y++) {
+          newPositionValid = this.positionAllowed(x, y, element.key);
+          if (!newPositionValid) break;
+        }
+      }
+
+      if (!newPositionValid) return;
+
       this.items.splice(
         this.items.findIndex((i) => {
           return i.key === element.key;
         }),
         1
       );
-      let coords = this.getCoords(event.layerX, event.layerY);
+
       element.x = coords.x;
       element.y = coords.y;
       this.items.push(element);
-- 
GitLab