Skip to content

Commit 14ad7b8

Browse files
committed
collsion: swap working on different height
swap() now handles objects taking same columns (but different height) as a simple swap (no further collision) which optimizes current flow. more #1094
1 parent 1dfda99 commit 14ad7b8

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

src/gridstack-engine.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,22 +182,38 @@ export class GridStackEngine {
182182
return this;
183183
}
184184

185-
/** called to possibly swap between 2 nodes (same size, not locked, touching), returning true if successful */
185+
/** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */
186186
public swap(a: GridStackNode, b: GridStackNode): boolean {
187187
if (!b || b.locked || !a || a.locked) return false;
188188

189-
function _doSwap(): true {
190-
let x = a.x, y = a.y;
191-
a.x = b.x; a.y = b.y;
192-
b.x = x; b.y = y;
189+
function _doSwap(): true { // assumes a is before b IFF they have different height (put after rather than exact swap)
190+
let x = b.x, y = b.y;
191+
b.x = a.x; b.y = a.y; // b -> a position
192+
if (a.h != b.h) {
193+
a.x = x; a.y = b.y + b.h; // a -> goes after b
194+
} else {
195+
a.x = x; a.y = y; // a -> old b position
196+
}
193197
a._dirty = b._dirty = true;
194198
return true;
195199
}
200+
// make sure they at least touch (including corners which will skip below as unwanted)
201+
function _touching(): boolean {
202+
return Utils.isIntercepted(a, {x: b.x-0.5, y:b.y-0.5, w: b.w+1, h: b.h+1})
203+
}
204+
let touching: boolean; // remember if we called it (vs undefined)
196205

197-
// same size and same row/column and touching
198-
if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y)
199-
&& Utils.isIntercepted(b, {x: a.x-0.5, y:a.y-0.5, w: a.w+1, h: a.h+1}))
206+
// same size and same row or column, and touching
207+
if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) && (touching = _touching()))
200208
return _doSwap();
209+
if (touching === false) return; // ran test and fail, bail out
210+
211+
// check for taking same columns (but different height) and touching
212+
if (a.w === b.w && a.x === b.x && (touching || _touching())) {
213+
if (b.y < a.y) { let t = a; a = b; b = t; } // swap a <-> b vars so a is first
214+
return _doSwap();
215+
}
216+
201217
/* different X will be weird (expect vertical swap) and different height overlap, so too complex. user regular layout instead
202218
// else check if swapping would not collide with anything else (requiring a re-layout)
203219
if (!this.collide(a, {x: a.x, y: a.y, w: b.w, h: b.h}, b) &&

0 commit comments

Comments
 (0)