From fdbce47c12e4abb25cb61da66f552b0c70648fa4 Mon Sep 17 00:00:00 2001 From: Alain Dumesny Date: Sat, 29 May 2021 06:48:35 -0700 Subject: [PATCH] `locked` item can be moved/resized * fix #1767 * `locked` item can be user moved/resized just not pushed by other nodes (broke in 1.1.1) * had incorrectly assume locked = noMove + noSize (user driven) but it's for layout only, so now you have complete choice. --- demo/float.html | 5 +++-- doc/CHANGES.md | 1 + spec/gridstack-engine-spec.ts | 35 ++++++++++++++++++++--------------- src/gridstack-dd.ts | 7 +++---- src/gridstack-engine.ts | 4 ++-- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/demo/float.html b/demo/float.html index 2821f94ea..988bdd5da 100644 --- a/demo/float.html +++ b/demo/float.html @@ -29,7 +29,7 @@

Float grid demo

addEvents(grid); let items = [ - {x: 1, y: 1}, + {x: 1, y: 1}, //, locked:true, content:"locked"}, {x: 2, y: 2, w: 3}, {x: 4, y: 2}, {x: 3, y: 1, h: 2}, @@ -44,8 +44,9 @@

Float grid demo

w: Math.round(1 + 3 * Math.random()), h: Math.round(1 + 3 * Math.random()) }; - n.content = String(count++); + n.content = n.content || String(count); grid.addWidget(n); + count++; }; toggleFloat = function() { diff --git a/doc/CHANGES.md b/doc/CHANGES.md index afd102072..c7585d803 100644 --- a/doc/CHANGES.md +++ b/doc/CHANGES.md @@ -61,6 +61,7 @@ Change log * fix [#1760](https://github.com/gridstack/gridstack.js/issues/1760) `removable:true` working again (broke in 4.x) * fix [#1761](https://github.com/gridstack/gridstack.js/issues/1761) `staticGrid(false)` will now enable drag in behavior (if set) +* fix [#1767](https://github.com/gridstack/gridstack.js/issues/1767) `locked` item can be user moved/resized again, just not pushed by other nodes (broke in 1.1.1) ## 4.2.3 (2021-5-8) diff --git a/spec/gridstack-engine-spec.ts b/spec/gridstack-engine-spec.ts index 8574dd398..478f8b78d 100644 --- a/spec/gridstack-engine-spec.ts +++ b/spec/gridstack-engine-spec.ts @@ -359,27 +359,32 @@ describe('gridstack engine', function() { }); it('should add widgets around locked one', function() { let nodes: GridStackNode[] = [ - {x: 0, y: 1, w: 12, h: 1, locked: true, noMove: true, noResize: true, id: 1}, - {x: 1, y: 0, w: 2, h: 3, id: 2} + {x: 0, y: 1, w: 12, h: 1, locked: true, noMove: true, noResize: true, id: 0}, + {x: 1, y: 0, w: 2, h: 3, id: 1} ]; // add locked item engine.addNode(nodes[0]) - expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, w: 12, h: 1, locked: true})); - engine.addNode(nodes[1]) + expect(findNode(engine, 0)).toEqual(jasmine.objectContaining({x: 0, y: 1, w: 12, h: 1, locked: true})); // add item that moves past locked one - expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 0, y: 1, w: 12, h: 1, locked: true})); - expect(findNode(engine, 2)).toEqual(jasmine.objectContaining({x: 1, y: 2, h: 3, id: 2})); - // prevents moving locked item + engine.addNode(nodes[1]) + expect(findNode(engine, 0)).toEqual(jasmine.objectContaining({x: 0, y: 1, w: 12, h: 1, locked: true})); + expect(findNode(engine, 1)).toEqual(jasmine.objectContaining({x: 1, y: 2, h: 3})); + // locked item can still be moved directly (what user does) + let node0 = findNode(engine, 0); + expect(engine.moveNode(node0, {y:6})).toEqual(true); + expect(findNode(engine, 0)).toEqual(jasmine.objectContaining({x: 0, y: 6, h: 1, locked: true})); + // but moves regular one past it let node1 = findNode(engine, 1); - expect(engine.moveNode(node1, {x:6, y:6})).toEqual(false); - // but moves regular one (gravity ON) - let node2 = findNode(engine, 2); - expect(engine.moveNode(node2, {x:6, y:6})).toEqual(true); - expect(node2).toEqual(jasmine.objectContaining({x: 6, y: 2, w: 2, h: 3})); - // but moves regular one (gravity OFF) + expect(engine.moveNode(node1, {x:6, y:6})).toEqual(true); + expect(node1).toEqual(jasmine.objectContaining({x: 6, y: 7, w: 2, h: 3})); + // but moves regular one before (gravity ON) + engine.float = false; + expect(engine.moveNode(node1, {x:7, y:3})).toEqual(true); + expect(node1).toEqual(jasmine.objectContaining({x: 7, y: 0, w: 2, h: 3})); + // but moves regular one before (gravity OFF) engine.float = true; - expect(engine.moveNode(node2, {x:7, y:6})).toEqual(true); - expect(node2).toEqual(jasmine.objectContaining({x: 7, y: 6, w: 2, h: 3})); + expect(engine.moveNode(node1, {x:7, y:3})).toEqual(true); + expect(node1).toEqual(jasmine.objectContaining({x: 7, y: 3, w: 2, h: 3})); }); }); diff --git a/src/gridstack-dd.ts b/src/gridstack-dd.ts index ecff600ff..fa4283ee3 100644 --- a/src/gridstack-dd.ts +++ b/src/gridstack-dd.ts @@ -353,8 +353,7 @@ GridStack.prototype._prepareDragDropByNode = function(node: GridStackNode): Grid let dd = GridStackDD.get(); // check for disabled grid first - if (this.opts.staticGrid || node.locked || - ((node.noMove || this.opts.disableDrag) && (node.noResize || this.opts.disableResize))) { + if (this.opts.staticGrid || ((node.noMove || this.opts.disableDrag) && (node.noResize || this.opts.disableResize))) { if (node._initDD) { dd.remove(el); // nukes everything instead of just disable, will add some styles back next delete node._initDD; @@ -616,7 +615,7 @@ GridStack.prototype.movable = function(els: GridStackElement, val: boolean): Gri if (this.opts.staticGrid) return this; // can't move a static grid! GridStack.getElements(els).forEach(el => { let node = el.gridstackNode; - if (!node || node.locked) return; + if (!node) return; if (val) delete node.noMove; else node.noMove = true; this._prepareDragDropByNode(node); // init DD if need be, and adjust }); @@ -632,7 +631,7 @@ GridStack.prototype.resizable = function(els: GridStackElement, val: boolean): G if (this.opts.staticGrid) return this; // can't resize a static grid! GridStack.getElements(els).forEach(el => { let node = el.gridstackNode; - if (!node || node.locked) return; + if (!node) return; if (val) delete node.noResize; else node.noResize = true; this._prepareDragDropByNode(node); // init DD if need be, and adjust }); diff --git a/src/gridstack-engine.ts b/src/gridstack-engine.ts index 47e8f1dcd..334783ea4 100644 --- a/src/gridstack-engine.ts +++ b/src/gridstack-engine.ts @@ -506,7 +506,7 @@ export class GridStackEngine { * In more complicated cases (maxRow) it will attempt at moving the item and fixing * others in a clone first, then apply those changes if still within specs. */ public moveNodeCheck(node: GridStackNode, o: GridStackMoveOpts): boolean { - if (node.locked) return false; + // if (node.locked) return false; if (!this.changedPosConstrain(node, o)) return false; o.pack = true; @@ -594,7 +594,7 @@ export class GridStackEngine { /** return true if the passed in node was actually moved (checks for no-op and locked) */ public moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean { - if (!node || node.locked || !o) return false; + if (!node || /*node.locked ||*/ !o) return false; if (o.pack === undefined) o.pack = true; // constrain the passed in values and check if we're still changing our node