11/**
22 * gridstack-engine.ts 5.0.0-dev
3- * Copyright (c) 2021 Alain Dumesny - see GridStack root license
3+ * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license
44 */
55
66import { Utils } from './utils' ;
77import { GridStackNode , ColumnOptions , GridStackPosition , GridStackMoveOpts } from './types' ;
88
9- export type onChangeCB = ( nodes : GridStackNode [ ] , removeDOM ?: boolean ) => void ;
10- /** options used for creations - similar to GridStackOptions */
9+ /** callback to update the DOM attributes since this class is generic (no HTML or other info) for items that changed - see _notify() */
10+ type OnChangeCB = ( nodes : GridStackNode [ ] ) => void ;
11+
12+ /** options used during creation - similar to GridStackOptions */
1113export interface GridStackEngineOptions {
1214 column ?: number ;
1315 maxRow ?: number ;
1416 float ?: boolean ;
1517 nodes ?: GridStackNode [ ] ;
16- onChange ?: onChangeCB ;
18+ onChange ?: OnChangeCB ;
1719}
1820
1921/**
@@ -26,38 +28,38 @@ export class GridStackEngine {
2628 public column : number ;
2729 public maxRow : number ;
2830 public nodes : GridStackNode [ ] ;
29- public onChange : onChangeCB ;
3031 public addedNodes : GridStackNode [ ] = [ ] ;
3132 public removedNodes : GridStackNode [ ] = [ ] ;
3233 public batchMode : boolean ;
34+ /** @internal callback to update the DOM attributes */
35+ protected onChange : OnChangeCB ;
3336 /** @internal */
34- private _float : boolean ;
37+ protected _float : boolean ;
3538 /** @internal */
36- private _prevFloat : boolean ;
39+ protected _prevFloat : boolean ;
3740 /** @internal cached layouts of difference column count so we can restore ack (eg 12 -> 1 -> 12) */
38- private _layouts ?: Layout [ ] [ ] ; // maps column # to array of values nodes
41+ protected _layouts ?: GridStackNode [ ] [ ] ; // maps column # to array of values nodes
3942 /** @internal true while we are resizing widgets during column resize to skip certain parts */
40- private _inColumnResize : boolean ;
43+ protected _inColumnResize : boolean ;
4144 /** @internal true if we have some items locked */
42- private _hasLocked : boolean ;
45+ protected _hasLocked : boolean ;
4346 /** @internal unique global internal _id counter NOT starting at 0 */
44- private static _idSeq = 1 ;
47+ protected static _idSeq = 1 ;
4548
4649 public constructor ( opts : GridStackEngineOptions = { } ) {
4750 this . column = opts . column || 12 ;
48- this . onChange = opts . onChange ;
49- this . _float = opts . float ;
5051 this . maxRow = opts . maxRow ;
52+ this . _float = opts . float ;
5153 this . nodes = opts . nodes || [ ] ;
54+ this . onChange = opts . onChange ;
5255 }
5356
5457 public batchUpdate ( ) : GridStackEngine {
5558 if ( this . batchMode ) return this ;
5659 this . batchMode = true ;
5760 this . _prevFloat = this . _float ;
5861 this . _float = true ; // let things go anywhere for now... commit() will restore and possibly reposition
59- this . saveInitial ( ) ; // since begin update (which is called multiple times) won't do this
60- return this ;
62+ return this . saveInitial ( ) ; // since begin update (which is called multiple times) won't do this
6163 }
6264
6365 public commit ( ) : GridStackEngine {
@@ -70,14 +72,14 @@ export class GridStackEngine {
7072 }
7173
7274 // use entire row for hitting area (will use bottom reverse sorted first) if we not actively moving DOWN and didn't already skip
73- private _useEntireRowArea ( node : GridStackNode , nn : GridStackPosition ) : boolean {
75+ protected _useEntireRowArea ( node : GridStackNode , nn : GridStackPosition ) : boolean {
7476 return ! this . float && ! this . _hasLocked && ( ! node . _moving || node . _skipDown || nn . y <= node . y ) ;
7577 }
7678
7779 /** @internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found.
7880 * return true if we moved. */
79- private _fixCollisions ( node : GridStackNode , nn = node , collide ?: GridStackNode , opt : GridStackMoveOpts = { } ) : boolean {
80- this . _sortNodes ( - 1 ) ; // from last to first, so recursive collision move items in the right order
81+ protected _fixCollisions ( node : GridStackNode , nn = node , collide ?: GridStackNode , opt : GridStackMoveOpts = { } ) : boolean {
82+ this . sortNodes ( - 1 ) ; // from last to first, so recursive collision move items in the right order
8183
8284 collide = collide || this . collide ( node , nn ) ; // REAL area collide for swap and skip if none...
8385 if ( ! collide ) return false ;
@@ -240,7 +242,7 @@ export class GridStackEngine {
240242 public compact ( ) : GridStackEngine {
241243 if ( this . nodes . length === 0 ) return this ;
242244 this . batchUpdate ( )
243- . _sortNodes ( ) ;
245+ . sortNodes ( ) ;
244246 let copyNodes = this . nodes ;
245247 this . nodes = [ ] ; // pretend we have no nodes to conflict layout to start with...
246248 copyNodes . forEach ( node => {
@@ -265,16 +267,16 @@ export class GridStackEngine {
265267 /** float getter method */
266268 public get float ( ) : boolean { return this . _float || false ; }
267269
268- /** @internal */
269- private _sortNodes ( dir ?: - 1 | 1 ) : GridStackEngine {
270+ /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */
271+ public sortNodes ( dir ?: - 1 | 1 ) : GridStackEngine {
270272 this . nodes = Utils . sort ( this . nodes , dir , this . column ) ;
271273 return this ;
272274 }
273275
274276 /** @internal called to top gravity pack the items back OR revert back to original Y positions when floating */
275- private _packNodes ( ) : GridStackEngine {
277+ protected _packNodes ( ) : GridStackEngine {
276278 if ( this . batchMode ) { return this ; }
277- this . _sortNodes ( ) ; // first to last
279+ this . sortNodes ( ) ; // first to last
278280
279281 if ( this . float ) {
280282 // restore original Y pos
@@ -402,6 +404,7 @@ export class GridStackEngine {
402404 return node ;
403405 }
404406
407+ /** returns a list of modified nodes from their original values */
405408 public getDirtyNodes ( verify ?: boolean ) : GridStackNode [ ] {
406409 // compare original x,y,w,h instead as _dirty can be a temporary state
407410 if ( verify ) {
@@ -410,12 +413,11 @@ export class GridStackEngine {
410413 return this . nodes . filter ( n => n . _dirty ) ;
411414 }
412415
413- /** @internal call this to call onChange CB with dirty nodes */
414- private _notify ( nodes ?: GridStackNode | GridStackNode [ ] , removeDOM = true ) : GridStackEngine {
415- if ( this . batchMode ) return this ;
416- nodes = ( nodes === undefined ? [ ] : ( Array . isArray ( nodes ) ? nodes : [ nodes ] ) ) ;
417- let dirtyNodes = nodes . concat ( this . getDirtyNodes ( ) ) ;
418- this . onChange && this . onChange ( dirtyNodes , removeDOM ) ;
416+ /** @internal call this to call onChange callback with dirty nodes so DOM can be updated */
417+ protected _notify ( removedNodes ?: GridStackNode [ ] ) : GridStackEngine {
418+ if ( this . batchMode || ! this . onChange ) return this ;
419+ let dirtyNodes = ( removedNodes || [ ] ) . concat ( this . getDirtyNodes ( ) ) ;
420+ this . onChange ( dirtyNodes ) ;
419421 return this ;
420422 }
421423
@@ -463,7 +465,7 @@ export class GridStackEngine {
463465 delete node . _removeDOM ;
464466
465467 if ( node . autoPosition ) {
466- this . _sortNodes ( ) ;
468+ this . sortNodes ( ) ;
467469
468470 for ( let i = 0 ; ; ++ i ) {
469471 let x = i % this . column ;
@@ -501,7 +503,7 @@ export class GridStackEngine {
501503 // don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times.
502504 this . nodes = this . nodes . filter ( n => n !== node ) ;
503505 return this . _packNodes ( )
504- . _notify ( node ) ;
506+ . _notify ( [ node ] ) ;
505507 }
506508
507509 public removeAll ( removeDOM = true ) : GridStackEngine {
@@ -676,7 +678,7 @@ export class GridStackEngine {
676678 let len = this . _layouts ?. length ;
677679 let layout = len && this . column !== ( len - 1 ) ? this . _layouts [ len - 1 ] : null ;
678680 let list : GridStackNode [ ] = [ ] ;
679- this . _sortNodes ( ) ;
681+ this . sortNodes ( ) ;
680682 this . nodes . forEach ( n => {
681683 let wl = layout ?. find ( l => l . _id === n . _id ) ;
682684 let w : GridStackNode = { ...n } ;
@@ -771,7 +773,7 @@ export class GridStackEngine {
771773
772774 // see if we have cached previous layout IFF we are going up in size (restore) otherwise always
773775 // generate next size down from where we are (looks more natural as you gradually size down).
774- let cacheNodes : Layout [ ] = [ ] ;
776+ let cacheNodes : GridStackNode [ ] = [ ] ;
775777 if ( column > prevColumn ) {
776778 cacheNodes = this . _layouts [ column ] || [ ] ;
777779 // ...if not, start with the largest layout (if not already there) as down-scaling is more accurate
@@ -842,7 +844,7 @@ export class GridStackEngine {
842844 * @param clear if true, will force other caches to be removed (default false)
843845 */
844846 public cacheLayout ( nodes : GridStackNode [ ] , column : number , clear = false ) : GridStackEngine {
845- let copy : Layout [ ] = [ ] ;
847+ let copy : GridStackNode [ ] = [ ] ;
846848 nodes . forEach ( ( n , i ) => {
847849 n . _id = n . _id || GridStackEngine . _idSeq ++ ; // make sure we have an id in case this is new layout, else re-use id already set
848850 copy [ i ] = { x : n . x , y : n . y , w : n . w , _id : n . _id } // only thing we change is x,y,w and id to find it back
@@ -859,7 +861,7 @@ export class GridStackEngine {
859861 */
860862 public cacheOneLayout ( n : GridStackNode , column : number ) : GridStackEngine {
861863 n . _id = n . _id || GridStackEngine . _idSeq ++ ;
862- let layout : Layout = { x : n . x , y : n . y , w : n . w , _id : n . _id }
864+ let layout : GridStackNode = { x : n . x , y : n . y , w : n . w , _id : n . _id }
863865 this . _layouts = this . _layouts || [ ] ;
864866 this . _layouts [ column ] = this . _layouts [ column ] || [ ] ;
865867 let index = this . _layouts [ column ] . findIndex ( l => l . _id === n . _id ) ;
@@ -876,11 +878,3 @@ export class GridStackEngine {
876878 return this ;
877879 }
878880}
879-
880- /** @internal class to store per column layout bare minimal info (subset of GridStackWidget) */
881- interface Layout {
882- x : number ;
883- y : number ;
884- w : number ;
885- _id : number ; // so we can find full node back
886- }
0 commit comments