Roo/bootstrap/LayoutMasonry.js
[roojs1] / Roo / bootstrap / LayoutMasonry.js
1 /**
2  *
3  * This is based on 
4  * http://masonry.desandro.com
5  *
6  * The idea is to render all the bricks based on vertical width...
7  *
8  * The original code extends 'outlayer' - we might need to use that....
9  * 
10  */
11
12
13 /**
14  * @class Roo.bootstrap.LayoutMasonry
15  * @extends Roo.bootstrap.Component
16  * Bootstrap Layout Masonry class
17  * 
18  * @constructor
19  * Create a new Element
20  * @param {Object} config The config object
21  */
22
23 Roo.bootstrap.LayoutMasonry = function(config){
24     
25     Roo.bootstrap.LayoutMasonry.superclass.constructor.call(this, config);
26     
27     this.bricks = [];
28     
29     Roo.bootstrap.LayoutMasonry.register(this);
30     
31     this.addEvents({
32         // raw events
33         /**
34          * @event layout
35          * Fire after layout the items
36          * @param {Roo.bootstrap.LayoutMasonry} this
37          * @param {Roo.EventObject} e
38          */
39         "layout" : true
40     });
41     
42 };
43
44 Roo.extend(Roo.bootstrap.LayoutMasonry, Roo.bootstrap.Component,  {
45     
46     /**
47      * @cfg {Boolean} isLayoutInstant = no animation?
48      */   
49     isLayoutInstant : false, // needed?
50    
51     /**
52      * @cfg {Number} boxWidth  width of the columns
53      */   
54     boxWidth : 450,
55     
56       /**
57      * @cfg {Number} boxHeight  - 0 for square, or fix it at a certian height
58      */   
59     boxHeight : 0,
60     
61     /**
62      * @cfg {Number} padWidth padding below box..
63      */   
64     padWidth : 10, 
65     
66     /**
67      * @cfg {Number} gutter gutter width..
68      */   
69     gutter : 10,
70     
71      /**
72      * @cfg {Number} maxCols maximum number of columns
73      */   
74     
75     maxCols: 0,
76     
77     /**
78      * @cfg {Boolean} isAutoInitial defalut true
79      */   
80     isAutoInitial : true, 
81     
82     containerWidth: 0,
83     
84     /**
85      * @cfg {Boolean} isHorizontal defalut false
86      */   
87     isHorizontal : false, 
88
89     currentSize : null,
90     
91     tag: 'div',
92     
93     cls: '',
94     
95     bricks: null, //CompositeElement
96     
97     cols : 1,
98     
99     _isLayoutInited : false,
100     
101 //    isAlternative : false, // only use for vertical layout...
102     
103     /**
104      * @cfg {Number} alternativePadWidth padding below box..
105      */   
106     alternativePadWidth : 50,
107     
108     selectedBrick : [],
109     
110     getAutoCreate : function(){
111         
112         var cfg = Roo.apply({}, Roo.bootstrap.LayoutMasonry.superclass.getAutoCreate.call(this));
113         
114         var cfg = {
115             tag: this.tag,
116             cls: 'blog-masonary-wrapper ' + this.cls,
117             cn : {
118                 cls : 'mas-boxes masonary'
119             }
120         };
121         
122         return cfg;
123     },
124     
125     getChildContainer: function( )
126     {
127         if (this.boxesEl) {
128             return this.boxesEl;
129         }
130         
131         this.boxesEl = this.el.select('.mas-boxes').first();
132         
133         return this.boxesEl;
134     },
135     
136     
137     initEvents : function()
138     {
139         var _this = this;
140         
141         if(this.isAutoInitial){
142             Roo.log('hook children rendered');
143             this.on('childrenrendered', function() {
144                 Roo.log('children rendered');
145                 _this.initial();
146             } ,this);
147         }
148     },
149     
150     initial : function()
151     {
152         this.selectedBrick = [];
153         
154         this.currentSize = this.el.getBox(true);
155         
156         Roo.EventManager.onWindowResize(this.resize, this); 
157
158         if(!this.isAutoInitial){
159             this.layout();
160             return;
161         }
162         
163         this.layout();
164         
165         return;
166         //this.layout.defer(500,this);
167         
168     },
169     
170     resize : function()
171     {
172         var cs = this.el.getBox(true);
173         
174         if (
175                 this.currentSize.width == cs.width && 
176                 this.currentSize.x == cs.x && 
177                 this.currentSize.height == cs.height && 
178                 this.currentSize.y == cs.y 
179         ) {
180             Roo.log("no change in with or X or Y");
181             return;
182         }
183         
184         this.currentSize = cs;
185         
186         this.layout();
187         
188     },
189     
190     layout : function()
191     {   
192         this._resetLayout();
193         
194         var isInstant = this.isLayoutInstant !== undefined ? this.isLayoutInstant : !this._isLayoutInited;
195         
196         this.layoutItems( isInstant );
197       
198         this._isLayoutInited = true;
199         
200         this.fireEvent('layout', this);
201         
202     },
203     
204     _resetLayout : function()
205     {
206         if(this.isHorizontal){
207             this.horizontalMeasureColumns();
208             return;
209         }
210         
211         this.verticalMeasureColumns();
212         
213     },
214     
215     verticalMeasureColumns : function()
216     {
217         this.getContainerWidth();
218         
219 //        if(Roo.lib.Dom.getViewWidth() < 768 && this.isAlternative){
220 //            this.colWidth = Math.floor(this.containerWidth * 0.8);
221 //            return;
222 //        }
223         
224         var boxWidth = this.boxWidth + this.padWidth;
225         
226         if(this.containerWidth < this.boxWidth){
227             boxWidth = this.containerWidth
228         }
229         
230         var containerWidth = this.containerWidth;
231         
232         var cols = Math.floor(containerWidth / boxWidth);
233         
234         this.cols = Math.max( cols, 1 );
235         
236         this.cols = this.maxCols > 0 ? Math.min( this.cols, this.maxCols ) : this.cols;
237         
238         var totalBoxWidth = this.cols * boxWidth - this.padWidth;
239         
240         var avail = Math.floor((containerWidth - totalBoxWidth) / this.cols);
241         
242         this.colWidth = boxWidth + avail - this.padWidth;
243         
244         this.unitWidth = Math.round((this.colWidth - (this.gutter * 2)) / 3);
245         this.unitHeight = this.boxHeight > 0 ? this.boxHeight  : this.unitWidth;
246     },
247     
248     horizontalMeasureColumns : function()
249     {
250         this.getContainerWidth();
251         
252         Roo.log('this.containerWidth : ' + this.containerWidth);
253         
254         var boxWidth = this.boxWidth;
255         
256         Roo.log('this.boxWidth : ' + this.boxWidth);
257         
258         if(this.containerWidth < boxWidth){
259             boxWidth = this.containerWidth;
260         }
261         
262         Roo.log('boxWidth : ' + boxWidth);
263         
264         this.unitWidth = Math.floor((boxWidth - (this.gutter * 2)) / 3);
265         
266         Roo.log('this.unitWidth : ' + this.unitWidth);
267         
268         this.el.setHeight(boxWidth);
269         
270     },
271     
272     getContainerWidth : function()
273     {
274         Roo.log(this.el.getBox(true));
275         this.containerWidth = this.el.getBox(true).width;  //maybe use getComputedWidth
276     },
277     
278     layoutItems : function( isInstant )
279     {
280         Roo.log(this.bricks);
281         
282         var items = Roo.apply([], this.bricks);
283         
284         if(this.isHorizontal){
285             this._horizontalLayoutItems( items , isInstant );
286             return;
287         }
288         
289 //        if(Roo.lib.Dom.getViewWidth() < 768 && this.isAlternative){
290 //            this._verticalAlternativeLayoutItems( items , isInstant );
291 //            return;
292 //        }
293         
294         this._verticalLayoutItems( items , isInstant );
295         
296     },
297     
298     _verticalLayoutItems : function ( items , isInstant)
299     {
300         if ( !items || !items.length ) {
301             return;
302         }
303         
304         var standard = [
305             ['xs', 'xs', 'xs', 'tall'],
306             ['xs', 'xs', 'tall'],
307             ['xs', 'xs', 'sm'],
308             ['xs', 'xs', 'xs'],
309             ['xs', 'tall'],
310             ['xs', 'sm'],
311             ['xs', 'xs'],
312             ['xs'],
313             
314             ['sm', 'xs', 'xs'],
315             ['sm', 'xs'],
316             ['sm'],
317             
318             ['tall', 'xs', 'xs', 'xs'],
319             ['tall', 'xs', 'xs'],
320             ['tall', 'xs'],
321             ['tall']
322             
323         ];
324         
325         var queue = [];
326         
327         var boxes = [];
328         
329         var box = [];
330         
331         Roo.each(items, function(item, k){
332             
333             switch (item.size) {
334                 // these layouts take up a full box,
335                 case 'md' :
336                 case 'md-left' :
337                 case 'md-right' :
338                 case 'wide' :
339                     
340                     if(box.length){
341                         boxes.push(box);
342                         box = [];
343                     }
344                     
345                     boxes.push([item]);
346                     
347                     break;
348                     
349                 case 'xs' :
350                 case 'sm' :
351                 case 'tall' :
352                     
353                     box.push(item);
354                     
355                     break;
356                 default :
357                     break;
358                     
359             }
360             
361         }, this);
362         
363         if(box.length){
364             boxes.push(box);
365             box = [];
366         }
367         
368         var filterPattern = function(box, length)
369         {
370             if(!box.length){
371                 return;
372             }
373             
374             var match = false;
375             
376             var pattern = box.slice(0, length);
377             
378             var format = [];
379             
380             Roo.each(pattern, function(i){
381                 format.push(i.size);
382             }, this);
383             
384             Roo.each(standard, function(s){
385                 
386                 if(String(s) != String(format)){
387                     return;
388                 }
389                 
390                 match = true;
391                 return false;
392                 
393             }, this);
394             
395             if(!match && length == 1){
396                 return;
397             }
398             
399             if(!match){
400                 filterPattern(box, length - 1);
401                 return;
402             }
403                 
404             queue.push(pattern);
405
406             box = box.slice(length, box.length);
407
408             filterPattern(box, 4);
409
410             return;
411             
412         }
413         
414         Roo.each(boxes, function(box, k){
415             
416             if(!box.length){
417                 return;
418             }
419             
420             if(box.length == 1){
421                 queue.push(box);
422                 return;
423             }
424             
425             filterPattern(box, 4);
426             
427         }, this);
428         
429         this._processVerticalLayoutQueue( queue, isInstant );
430         
431     },
432     
433 //    _verticalAlternativeLayoutItems : function( items , isInstant )
434 //    {
435 //        if ( !items || !items.length ) {
436 //            return;
437 //        }
438 //
439 //        this._processVerticalAlternativeLayoutQueue( items, isInstant );
440 //        
441 //    },
442     
443     _horizontalLayoutItems : function ( items , isInstant)
444     {
445         if ( !items || !items.length || items.length < 3) {
446             return;
447         }
448         
449         items.reverse();
450         
451         var eItems = items.slice(0, 3);
452         
453         items = items.slice(3, items.length);
454         
455         var standard = [
456             ['xs', 'xs', 'xs', 'wide'],
457             ['xs', 'xs', 'wide'],
458             ['xs', 'xs', 'sm'],
459             ['xs', 'xs', 'xs'],
460             ['xs', 'wide'],
461             ['xs', 'sm'],
462             ['xs', 'xs'],
463             ['xs'],
464             
465             ['sm', 'xs', 'xs'],
466             ['sm', 'xs'],
467             ['sm'],
468             
469             ['wide', 'xs', 'xs', 'xs'],
470             ['wide', 'xs', 'xs'],
471             ['wide', 'xs'],
472             ['wide'],
473             
474             ['wide-thin']
475         ];
476         
477         var queue = [];
478         
479         var boxes = [];
480         
481         var box = [];
482         
483         Roo.each(items, function(item, k){
484             
485             switch (item.size) {
486                 case 'md' :
487                 case 'md-left' :
488                 case 'md-right' :
489                 case 'tall' :
490                     
491                     if(box.length){
492                         boxes.push(box);
493                         box = [];
494                     }
495                     
496                     boxes.push([item]);
497                     
498                     break;
499                     
500                 case 'xs' :
501                 case 'sm' :
502                 case 'wide' :
503                 case 'wide-thin' :
504                     
505                     box.push(item);
506                     
507                     break;
508                 default :
509                     break;
510                     
511             }
512             
513         }, this);
514         
515         if(box.length){
516             boxes.push(box);
517             box = [];
518         }
519         
520         var filterPattern = function(box, length)
521         {
522             if(!box.length){
523                 return;
524             }
525             
526             var match = false;
527             
528             var pattern = box.slice(0, length);
529             
530             var format = [];
531             
532             Roo.each(pattern, function(i){
533                 format.push(i.size);
534             }, this);
535             
536             Roo.each(standard, function(s){
537                 
538                 if(String(s) != String(format)){
539                     return;
540                 }
541                 
542                 match = true;
543                 return false;
544                 
545             }, this);
546             
547             if(!match && length == 1){
548                 return;
549             }
550             
551             if(!match){
552                 filterPattern(box, length - 1);
553                 return;
554             }
555                 
556             queue.push(pattern);
557
558             box = box.slice(length, box.length);
559
560             filterPattern(box, 4);
561
562             return;
563             
564         }
565         
566         Roo.each(boxes, function(box, k){
567             
568             if(!box.length){
569                 return;
570             }
571             
572             if(box.length == 1){
573                 queue.push(box);
574                 return;
575             }
576             
577             filterPattern(box, 4);
578             
579         }, this);
580         
581         
582         var prune = [];
583         
584         var pos = this.el.getBox(true);
585         
586         var minX = pos.x;
587         
588         var maxX = pos.right - this.unitWidth * 3 - this.gutter * 2 - this.padWidth;
589         
590         var hit_end = false;
591         
592         Roo.each(queue, function(box){
593             
594             if(hit_end){
595                 
596                 Roo.each(box, function(b){
597                 
598                     b.el.setVisibilityMode(Roo.Element.DISPLAY);
599                     b.el.hide();
600
601                 }, this);
602
603                 return;
604             }
605             
606             var mx = 0;
607             
608             Roo.each(box, function(b){
609                 
610                 b.el.setVisibilityMode(Roo.Element.DISPLAY);
611                 b.el.show();
612
613                 mx = Math.max(mx, b.x);
614                 
615             }, this);
616             
617             maxX = maxX - this.unitWidth * mx - this.gutter * (mx - 1) - this.padWidth;
618             
619             if(maxX < minX){
620                 
621                 Roo.each(box, function(b){
622                 
623                     b.el.setVisibilityMode(Roo.Element.DISPLAY);
624                     b.el.hide();
625                     
626                 }, this);
627                 
628                 hit_end = true;
629                 
630                 return;
631             }
632             
633             prune.push(box);
634             
635         }, this);
636         
637         this._processHorizontalLayoutQueue( prune, eItems, isInstant );
638     },
639     
640     /** Sets position of item in DOM
641     * @param {Element} item
642     * @param {Number} x - horizontal position
643     * @param {Number} y - vertical position
644     * @param {Boolean} isInstant - disables transitions
645     */
646     _processVerticalLayoutQueue : function( queue, isInstant )
647     {
648         var pos = this.el.getBox(true);
649         var x = pos.x;
650         var y = pos.y;
651         var maxY = [];
652         
653         for (var i = 0; i < this.cols; i++){
654             maxY[i] = pos.y;
655         }
656         
657         Roo.each(queue, function(box, k){
658             
659             var col = k % this.cols;
660             
661             Roo.each(box, function(b,kk){
662                 
663                 b.el.position('absolute');
664                 
665                 var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
666                 var height = Math.floor(this.unitHeight * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
667                 
668                 if(b.size == 'md-left' || b.size == 'md-right'){
669                     width = Math.floor(this.unitWidth * (b.x - 1) + (this.gutter * (b.x - 2)) + b.el.getPadding('lr'));
670                     height = Math.floor(this.unitHeight * (b.y - 1) + (this.gutter * (b.y - 2)) + b.el.getPadding('tb'));
671                 }
672                 
673                 b.el.setWidth(width);
674                 b.el.setHeight(height);
675                 // iframe?
676                 b.el.select('iframe',true).setSize(width,height);
677                 
678             }, this);
679             
680             for (var i = 0; i < this.cols; i++){
681                 
682                 if(maxY[i] < maxY[col]){
683                     col = i;
684                     continue;
685                 }
686                 
687                 col = Math.min(col, i);
688                 
689             }
690             
691             x = pos.x + col * (this.colWidth + this.padWidth);
692             
693             y = maxY[col];
694             
695             var positions = [];
696             
697             switch (box.length){
698                 case 1 :
699                     positions = this.getVerticalOneBoxColPositions(x, y, box);
700                     break;
701                 case 2 :
702                     positions = this.getVerticalTwoBoxColPositions(x, y, box);
703                     break;
704                 case 3 :
705                     positions = this.getVerticalThreeBoxColPositions(x, y, box);
706                     break;
707                 case 4 :
708                     positions = this.getVerticalFourBoxColPositions(x, y, box);
709                     break;
710                 default :
711                     break;
712             }
713             
714             Roo.each(box, function(b,kk){
715                 
716                 b.el.setXY([positions[kk].x, positions[kk].y], isInstant ? false : true);
717                 
718                 var sz = b.el.getSize();
719                 
720                 maxY[col] = Math.max(maxY[col], positions[kk].y + sz.height + this.padWidth);
721                 
722             }, this);
723             
724         }, this);
725         
726         var mY = 0;
727         
728         for (var i = 0; i < this.cols; i++){
729             mY = Math.max(mY, maxY[i]);
730         }
731         
732         this.el.setHeight(mY - pos.y);
733         
734     },
735     
736 //    _processVerticalAlternativeLayoutQueue : function( items, isInstant )
737 //    {
738 //        var pos = this.el.getBox(true);
739 //        var x = pos.x;
740 //        var y = pos.y;
741 //        var maxX = pos.right;
742 //        
743 //        var maxHeight = 0;
744 //        
745 //        Roo.each(items, function(item, k){
746 //            
747 //            var c = k % 2;
748 //            
749 //            item.el.position('absolute');
750 //                
751 //            var width = Math.floor(this.colWidth + item.el.getPadding('lr'));
752 //
753 //            item.el.setWidth(width);
754 //
755 //            var height = Math.floor(this.colWidth * item.y / item.x + item.el.getPadding('tb'));
756 //
757 //            item.el.setHeight(height);
758 //            
759 //            if(c == 0){
760 //                item.el.setXY([x, y], isInstant ? false : true);
761 //            } else {
762 //                item.el.setXY([maxX - width, y], isInstant ? false : true);
763 //            }
764 //            
765 //            y = y + height + this.alternativePadWidth;
766 //            
767 //            maxHeight = maxHeight + height + this.alternativePadWidth;
768 //            
769 //        }, this);
770 //        
771 //        this.el.setHeight(maxHeight);
772 //        
773 //    },
774     
775     _processHorizontalLayoutQueue : function( queue, eItems, isInstant )
776     {
777         var pos = this.el.getBox(true);
778         
779         var minX = pos.x;
780         var minY = pos.y;
781         
782         var maxX = pos.right;
783         
784         this._processHorizontalEndItem(eItems, maxX, minX, minY, isInstant);
785         
786         var maxX = maxX - this.unitWidth * 3 - this.gutter * 2 - this.padWidth;
787         
788         Roo.each(queue, function(box, k){
789             
790             Roo.each(box, function(b, kk){
791                 
792                 b.el.position('absolute');
793                 
794                 var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
795                 var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
796                 
797                 if(b.size == 'md-left' || b.size == 'md-right'){
798                     width = Math.floor(this.unitWidth * (b.x - 1) + (this.gutter * (b.x - 2)) + b.el.getPadding('lr'));
799                     height = Math.floor(this.unitWidth * (b.y - 1) + (this.gutter * (b.y - 2)) + b.el.getPadding('tb'));
800                 }
801                 
802                 b.el.setWidth(width);
803                 b.el.setHeight(height);
804                 
805             }, this);
806             
807             if(!box.length){
808                 return;
809             }
810             
811             var positions = [];
812             
813             switch (box.length){
814                 case 1 :
815                     positions = this.getHorizontalOneBoxColPositions(maxX, minY, box);
816                     break;
817                 case 2 :
818                     positions = this.getHorizontalTwoBoxColPositions(maxX, minY, box);
819                     break;
820                 case 3 :
821                     positions = this.getHorizontalThreeBoxColPositions(maxX, minY, box);
822                     break;
823                 case 4 :
824                     positions = this.getHorizontalFourBoxColPositions(maxX, minY, box);
825                     break;
826                 default :
827                     break;
828             }
829             
830             Roo.each(box, function(b,kk){
831                 
832                 b.el.setXY([positions[kk].x, positions[kk].y], isInstant ? false : true);
833                 
834                 maxX = Math.min(maxX, positions[kk].x - this.padWidth);
835                 
836             }, this);
837             
838         }, this);
839         
840     },
841     
842     _processHorizontalEndItem : function(eItems, maxX, minX, minY, isInstant)
843     {
844         Roo.each(eItems, function(b,k){
845             
846             b.size = (k == 0) ? 'sm' : 'xs';
847             b.x = (k == 0) ? 2 : 1;
848             b.y = (k == 0) ? 2 : 1;
849             
850             b.el.position('absolute');
851             
852             var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
853                 
854             b.el.setWidth(width);
855             
856             var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
857             
858             b.el.setHeight(height);
859             
860         }, this);
861
862         var positions = [];
863         
864         positions.push({
865             x : maxX - this.unitWidth * 2 - this.gutter,
866             y : minY
867         });
868         
869         positions.push({
870             x : maxX - this.unitWidth,
871             y : minY + (this.unitWidth + this.gutter) * 2
872         });
873         
874         positions.push({
875             x : maxX - this.unitWidth * 3 - this.gutter * 2,
876             y : minY
877         });
878         
879         Roo.each(eItems, function(b,k){
880             
881             b.el.setXY([positions[k].x, positions[k].y], isInstant ? false : true);
882
883         }, this);
884         
885     },
886     
887     getVerticalOneBoxColPositions : function(x, y, box)
888     {
889         var pos = [];
890         
891         var rand = Math.floor(Math.random() * ((4 - box[0].x)));
892         
893         if(box[0].size == 'md-left'){
894             rand = 0;
895         }
896         
897         if(box[0].size == 'md-right'){
898             rand = 1;
899         }
900         
901         pos.push({
902             x : x + (this.unitWidth + this.gutter) * rand,
903             y : y
904         });
905         
906         return pos;
907     },
908     
909     getVerticalTwoBoxColPositions : function(x, y, box)
910     {
911         var pos = [];
912         
913         if(box[0].size == 'xs'){
914             
915             pos.push({
916                 x : x,
917                 y : y + ((this.unitHeight + this.gutter) * Math.floor(Math.random() * box[1].y))
918             });
919
920             pos.push({
921                 x : x + (this.unitWidth + this.gutter) * (3 - box[1].x),
922                 y : y
923             });
924             
925             return pos;
926             
927         }
928         
929         pos.push({
930             x : x,
931             y : y
932         });
933
934         pos.push({
935             x : x + (this.unitWidth + this.gutter) * 2,
936             y : y + ((this.unitHeight + this.gutter) * Math.floor(Math.random() * box[0].y))
937         });
938         
939         return pos;
940         
941     },
942     
943     getVerticalThreeBoxColPositions : function(x, y, box)
944     {
945         var pos = [];
946         
947         if(box[0].size == 'xs' && box[1].size == 'xs' && box[2].size == 'xs'){
948             
949             pos.push({
950                 x : x,
951                 y : y
952             });
953
954             pos.push({
955                 x : x + (this.unitWidth + this.gutter) * 1,
956                 y : y
957             });
958             
959             pos.push({
960                 x : x + (this.unitWidth + this.gutter) * 2,
961                 y : y
962             });
963             
964             return pos;
965             
966         }
967         
968         if(box[0].size == 'xs' && box[1].size == 'xs'){
969             
970             pos.push({
971                 x : x,
972                 y : y
973             });
974
975             pos.push({
976                 x : x,
977                 y : y + ((this.unitHeight + this.gutter) * (box[2].y - 1))
978             });
979             
980             pos.push({
981                 x : x + (this.unitWidth + this.gutter) * 1,
982                 y : y
983             });
984             
985             return pos;
986             
987         }
988         
989         pos.push({
990             x : x,
991             y : y
992         });
993
994         pos.push({
995             x : x + (this.unitWidth + this.gutter) * 2,
996             y : y
997         });
998
999         pos.push({
1000             x : x + (this.unitWidth + this.gutter) * 2,
1001             y : y + (this.unitHeight + this.gutter) * (box[0].y - 1)
1002         });
1003             
1004         return pos;
1005         
1006     },
1007     
1008     getVerticalFourBoxColPositions : function(x, y, box)
1009     {
1010         var pos = [];
1011         
1012         if(box[0].size == 'xs'){
1013             
1014             pos.push({
1015                 x : x,
1016                 y : y
1017             });
1018
1019             pos.push({
1020                 x : x,
1021                 y : y + (this.unitHeight + this.gutter) * 1
1022             });
1023             
1024             pos.push({
1025                 x : x,
1026                 y : y + (this.unitHeight + this.gutter) * 2
1027             });
1028             
1029             pos.push({
1030                 x : x + (this.unitWidth + this.gutter) * 1,
1031                 y : y
1032             });
1033             
1034             return pos;
1035             
1036         }
1037         
1038         pos.push({
1039             x : x,
1040             y : y
1041         });
1042
1043         pos.push({
1044             x : x + (this.unitWidth + this.gutter) * 2,
1045             y : y
1046         });
1047
1048         pos.push({
1049             x : x + (this.unitHeightunitWidth + this.gutter) * 2,
1050             y : y + (this.unitHeight + this.gutter) * 1
1051         });
1052
1053         pos.push({
1054             x : x + (this.unitWidth + this.gutter) * 2,
1055             y : y + (this.unitWidth + this.gutter) * 2
1056         });
1057
1058         return pos;
1059         
1060     },
1061     
1062     getHorizontalOneBoxColPositions : function(maxX, minY, box)
1063     {
1064         var pos = [];
1065         
1066         if(box[0].size == 'md-left'){
1067             pos.push({
1068                 x : maxX - this.unitWidth * (box[0].x - 1) - this.gutter * (box[0].x - 2),
1069                 y : minY
1070             });
1071             
1072             return pos;
1073         }
1074         
1075         if(box[0].size == 'md-right'){
1076             pos.push({
1077                 x : maxX - this.unitWidth * (box[0].x - 1) - this.gutter * (box[0].x - 2),
1078                 y : minY + (this.unitWidth + this.gutter) * 1
1079             });
1080             
1081             return pos;
1082         }
1083         
1084         var rand = Math.floor(Math.random() * (4 - box[0].y));
1085         
1086         pos.push({
1087             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1088             y : minY + (this.unitWidth + this.gutter) * rand
1089         });
1090         
1091         return pos;
1092         
1093     },
1094     
1095     getHorizontalTwoBoxColPositions : function(maxX, minY, box)
1096     {
1097         var pos = [];
1098         
1099         if(box[0].size == 'xs'){
1100             
1101             pos.push({
1102                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1103                 y : minY
1104             });
1105
1106             pos.push({
1107                 x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1108                 y : minY + (this.unitWidth + this.gutter) * (3 - box[1].y)
1109             });
1110             
1111             return pos;
1112             
1113         }
1114         
1115         pos.push({
1116             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1117             y : minY
1118         });
1119
1120         pos.push({
1121             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1122             y : minY + (this.unitWidth + this.gutter) * 2
1123         });
1124         
1125         return pos;
1126         
1127     },
1128     
1129     getHorizontalThreeBoxColPositions : function(maxX, minY, box)
1130     {
1131         var pos = [];
1132         
1133         if(box[0].size == 'xs' && box[1].size == 'xs' && box[2].size == 'xs'){
1134             
1135             pos.push({
1136                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1137                 y : minY
1138             });
1139
1140             pos.push({
1141                 x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1142                 y : minY + (this.unitWidth + this.gutter) * 1
1143             });
1144             
1145             pos.push({
1146                 x : maxX - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1),
1147                 y : minY + (this.unitWidth + this.gutter) * 2
1148             });
1149             
1150             return pos;
1151             
1152         }
1153         
1154         if(box[0].size == 'xs' && box[1].size == 'xs'){
1155             
1156             pos.push({
1157                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1158                 y : minY
1159             });
1160
1161             pos.push({
1162                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1) - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1163                 y : minY
1164             });
1165             
1166             pos.push({
1167                 x : maxX - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1),
1168                 y : minY + (this.unitWidth + this.gutter) * 1
1169             });
1170             
1171             return pos;
1172             
1173         }
1174         
1175         pos.push({
1176             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1177             y : minY
1178         });
1179
1180         pos.push({
1181             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1182             y : minY + (this.unitWidth + this.gutter) * 2
1183         });
1184
1185         pos.push({
1186             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1) - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1),
1187             y : minY + (this.unitWidth + this.gutter) * 2
1188         });
1189             
1190         return pos;
1191         
1192     },
1193     
1194     getHorizontalFourBoxColPositions : function(maxX, minY, box)
1195     {
1196         var pos = [];
1197         
1198         if(box[0].size == 'xs'){
1199             
1200             pos.push({
1201                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1202                 y : minY
1203             });
1204
1205             pos.push({
1206                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1) - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1207                 y : minY
1208             });
1209             
1210             pos.push({
1211                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1) - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1) - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1),
1212                 y : minY
1213             });
1214             
1215             pos.push({
1216                 x : maxX - this.unitWidth * box[3].x - this.gutter * (box[3].x - 1),
1217                 y : minY + (this.unitWidth + this.gutter) * 1
1218             });
1219             
1220             return pos;
1221             
1222         }
1223         
1224         pos.push({
1225             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1226             y : minY
1227         });
1228         
1229         pos.push({
1230             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1231             y : minY + (this.unitWidth + this.gutter) * 2
1232         });
1233         
1234         pos.push({
1235             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1) - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1),
1236             y : minY + (this.unitWidth + this.gutter) * 2
1237         });
1238         
1239         pos.push({
1240             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1) - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1) - this.unitWidth * box[3].x - this.gutter * (box[3].x - 1),
1241             y : minY + (this.unitWidth + this.gutter) * 2
1242         });
1243
1244         return pos;
1245         
1246     },
1247     
1248     /**
1249     * remove a Masonry Brick
1250     * @param {Roo.bootstrap.MasonryBrick} the masonry brick to remove
1251     */
1252     removeBrick : function(brick_id)
1253     {
1254         if (!brick_id) {
1255             return;
1256         }
1257         
1258         for (var i = 0; i<this.bricks.length; i++) {
1259             if (this.bricks[i].id == brick_id) {
1260                 this.bricks.splice(i,1);
1261                 this.selectedBrick = [];
1262                 this.el.dom.removeChild(Roo.get(brick_id).dom);
1263                 this.initial();
1264             }
1265         }
1266     },
1267     
1268     /**
1269     * adds a Masonry Brick
1270     * @param {Roo.bootstrap.MasonryBrick} the masonry brick to add
1271     */
1272     addBrick : function(cfg)
1273     {
1274         var cn = new Roo.bootstrap.MasonryBrick(cfg);
1275         //this.register(cn);
1276         cn.parentId = this.id;
1277         cn.onRender(this.el, null);
1278         return cn;
1279     },
1280     
1281     /**
1282     * register a Masonry Brick
1283     * @param {Roo.bootstrap.MasonryBrick} the masonry brick to add
1284     */
1285     
1286     register : function(brick)
1287     {
1288         this.bricks.push(brick);
1289         brick.masonryId = this.id;
1290     },
1291     
1292     /**
1293     * clear all the Masonry Brick
1294     */
1295     clearAll : function()
1296     {
1297         this.bricks = [];
1298         //this.getChildContainer().dom.innerHTML = "";
1299         this.el.dom.innerHTML = '';
1300     },
1301     
1302     getSelected : function()
1303     {
1304         if (!this.selectedBrick) {
1305             return false;
1306         }
1307         
1308         return this.selectedBrick;
1309     }
1310 });
1311
1312 Roo.apply(Roo.bootstrap.LayoutMasonry, {
1313     
1314     groups: {},
1315      /**
1316     * register a Masonry Layout
1317     * @param {Roo.bootstrap.LayoutMasonry} the masonry layout to add
1318     */
1319     
1320     register : function(layout)
1321     {
1322         this.groups[layout.id] = layout;
1323     },
1324     /**
1325     * fetch a  Masonry Layout based on the masonry layout ID
1326     * @param {string} the masonry layout to add
1327     * @returns {Roo.bootstrap.LayoutMasonry} the masonry layout
1328     */
1329     
1330     get: function(layout_id) {
1331         if (typeof(this.groups[layout_id]) == 'undefined') {
1332             return false;
1333         }
1334         return this.groups[layout_id] ;
1335     }
1336     
1337     
1338     
1339 });
1340
1341  
1342
1343