From 25f880f8d31c1167e2dea3fae63062955e14bdf1 Mon Sep 17 00:00:00 2001 From: Alain Dumesny Date: Fri, 26 Feb 2021 21:25:46 -0800 Subject: [PATCH] collision: more fixes more for #1094 * dragging larger size items will now correctly recursively push items down one afater another * also fixed swap to check for touching items --- demo/column.html | 5 ++--- spec/e2e/html/141_1534_swap.html | 29 +++++++++++++++++++++++------ src/gridstack-engine.ts | 11 +++++++---- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/demo/column.html b/demo/column.html index 84a5d8ecb..479f6bf99 100644 --- a/demo/column.html +++ b/demo/column.html @@ -72,9 +72,8 @@

column() grid demo (fix cellHeight)

{x: 0, y: 4, w: 12} ]; let count = 0; - grid.batchUpdate(); - addWidget(); addWidget(); addWidget(); addWidget(); - grid.commit(); + items.forEach(n => n.content = '
' + count++ + (n.text ? n.text : '')); + grid.load(items); function addWidget() { let n = items[count] || { diff --git a/spec/e2e/html/141_1534_swap.html b/spec/e2e/html/141_1534_swap.html index 8c83e232b..91e979a8e 100644 --- a/spec/e2e/html/141_1534_swap.html +++ b/spec/e2e/html/141_1534_swap.html @@ -18,6 +18,9 @@

Swap collision demo

+ with layouts: + load 0 + load 1

@@ -28,19 +31,28 @@

Swap collision demo

let maxButton = document.getElementById('max'); let bigButton = document.getElementById('big'); let size = 1; + let layout = 0; let grid = GridStack.init({float: false, cellHeight: 70, maxRow: 0}); addEvents(grid); - let count = 0; - let items = [ + let items = [[ {x:0, y:0}, {x:0, y:1}, {x:0, y:2},{x:1, y:0}, {x:1, y:1}, {x:1, y:2, h:2, w:2}, {x:5, y:0}, {x:4, y:1, w:3, locked: false, _content: 'locked'}, {x:5, y:2}, {x:7, y:0}, {x:8, y:0}, {x:9, y:0}, {x:7, y:1, w:3}, {x:8, y:2}, {x:11, y:0}, {x:11, y:1, h:2}, - ]; - items.forEach(n => {n.id = count; n.content = n.content || String(count); count++}) - grid.load(items); + ], [ + {x: 1, y: 0}, + {x: 1, y: 1}, + {x: 1, y: 2, w: 2}, + {x: 0, y: 3, w: 3}, + {x: 1, y: 4, h: 2}, + ]]; + items.forEach(layout => { + let count = 0; + layout.forEach(n => {n.id = count; n.content = n.content || String(count); count++}) + }); + grid.load(items[layout]); addNewWidget = function() { let n = { @@ -48,11 +60,16 @@

Swap collision demo

y: Math.round(5 * Math.random()), w: Math.round(1 + 3 * Math.random()), h: Math.round(1 + 3 * Math.random()), - content: String(count++) + content: String(grid.engine.nodes.length+1) }; grid.addWidget(n); }; + load = function(i) { + grid.removeAll(); + grid.load(items[i]); + } + toggleFloat = function() { grid.float(! grid.getFloat()); floatButton.innerHTML = 'float: ' + grid.getFloat(); diff --git a/src/gridstack-engine.ts b/src/gridstack-engine.ts index bf2c4b4ac..6ec2685c5 100644 --- a/src/gridstack-engine.ts +++ b/src/gridstack-engine.ts @@ -83,6 +83,7 @@ export class GridStackEngine { } let didMove = false; + let yOffset = 0; let newOpt: GridStackMoveOpts = {nested: true, pack: false, sanitize: false}; while (collide = collide || this.collide(node, nn)) { // could collide with more than 1 item... so repeat for each let moved: boolean; @@ -103,8 +104,9 @@ export class GridStackEngine { } didMove = didMove || moved; } else { - // move collide down *after* us - moved = this.moveNode(collide, {...collide, y: nn.y + nn.h, ...newOpt}); + // move collide down *after* where we will be + moved = this.moveNode(collide, {...collide, y: nn.y + nn.h + yOffset, ...newOpt}); + if (moved) yOffset += collide.h; // during while loop put next one after this one } if (!moved) { return didMove; } // break inf loop if we couldn't move after all (ex: maxRow, fixed) collide = undefined; @@ -192,8 +194,9 @@ export class GridStackEngine { return true; } - // same size and same row or column - if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) /*&& Utils.isIntercepted(b, {x: a.x-0.5, y:a.y-0.5, w: a.w+1, h: a.h+1})*/) + // same size and same row/column and touching + if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) + && Utils.isIntercepted(b, {x: a.x-0.5, y:a.y-0.5, w: a.w+1, h: a.h+1})) return _doSwap(); /* different X will be weird (expect vertical swap) and different height overlap, so too complex. user regular layout instead // else check if swapping would not collide with anything else (requiring a re-layout)