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