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);
275         Roo.log(this.el.getBox(true));
276         this.containerWidth = this.el.getBox(true).width;  //maybe use getComputedWidth
277     },
278     
279     layoutItems : function( isInstant )
280     {
281         Roo.log(this.bricks);
282         
283         var items = Roo.apply([], this.bricks);
284         
285         if(this.isHorizontal){
286             this._horizontalLayoutItems( items , isInstant );
287             return;
288         }
289         
290 //        if(Roo.lib.Dom.getViewWidth() < 768 && this.isAlternative){
291 //            this._verticalAlternativeLayoutItems( items , isInstant );
292 //            return;
293 //        }
294         
295         this._verticalLayoutItems( items , isInstant );
296         
297     },
298     
299     _verticalLayoutItems : function ( items , isInstant)
300     {
301         if ( !items || !items.length ) {
302             return;
303         }
304         
305         var standard = [
306             ['xs', 'xs', 'xs', 'tall'],
307             ['xs', 'xs', 'tall'],
308             ['xs', 'xs', 'sm'],
309             ['xs', 'xs', 'xs'],
310             ['xs', 'tall'],
311             ['xs', 'sm'],
312             ['xs', 'xs'],
313             ['xs'],
314             
315             ['sm', 'xs', 'xs'],
316             ['sm', 'xs'],
317             ['sm'],
318             
319             ['tall', 'xs', 'xs', 'xs'],
320             ['tall', 'xs', 'xs'],
321             ['tall', 'xs'],
322             ['tall']
323             
324         ];
325         
326         var queue = [];
327         
328         var boxes = [];
329         
330         var box = [];
331         
332         Roo.each(items, function(item, k){
333             
334             switch (item.size) {
335                 // these layouts take up a full box,
336                 case 'md' :
337                 case 'md-left' :
338                 case 'md-right' :
339                 case 'wide' :
340                     
341                     if(box.length){
342                         boxes.push(box);
343                         box = [];
344                     }
345                     
346                     boxes.push([item]);
347                     
348                     break;
349                     
350                 case 'xs' :
351                 case 'sm' :
352                 case 'tall' :
353                     
354                     box.push(item);
355                     
356                     break;
357                 default :
358                     break;
359                     
360             }
361             
362         }, this);
363         
364         if(box.length){
365             boxes.push(box);
366             box = [];
367         }
368         
369         var filterPattern = function(box, length)
370         {
371             if(!box.length){
372                 return;
373             }
374             
375             var match = false;
376             
377             var pattern = box.slice(0, length);
378             
379             var format = [];
380             
381             Roo.each(pattern, function(i){
382                 format.push(i.size);
383             }, this);
384             
385             Roo.each(standard, function(s){
386                 
387                 if(String(s) != String(format)){
388                     return;
389                 }
390                 
391                 match = true;
392                 return false;
393                 
394             }, this);
395             
396             if(!match && length == 1){
397                 return;
398             }
399             
400             if(!match){
401                 filterPattern(box, length - 1);
402                 return;
403             }
404                 
405             queue.push(pattern);
406
407             box = box.slice(length, box.length);
408
409             filterPattern(box, 4);
410
411             return;
412             
413         }
414         
415         Roo.each(boxes, function(box, k){
416             
417             if(!box.length){
418                 return;
419             }
420             
421             if(box.length == 1){
422                 queue.push(box);
423                 return;
424             }
425             
426             filterPattern(box, 4);
427             
428         }, this);
429         
430         this._processVerticalLayoutQueue( queue, isInstant );
431         
432     },
433     
434 //    _verticalAlternativeLayoutItems : function( items , isInstant )
435 //    {
436 //        if ( !items || !items.length ) {
437 //            return;
438 //        }
439 //
440 //        this._processVerticalAlternativeLayoutQueue( items, isInstant );
441 //        
442 //    },
443     
444     _horizontalLayoutItems : function ( items , isInstant)
445     {
446         if ( !items || !items.length || items.length < 3) {
447             return;
448         }
449         
450         items.reverse();
451         
452         var eItems = items.slice(0, 3);
453         
454         items = items.slice(3, items.length);
455         
456         var standard = [
457             ['xs', 'xs', 'xs', 'wide'],
458             ['xs', 'xs', 'wide'],
459             ['xs', 'xs', 'sm'],
460             ['xs', 'xs', 'xs'],
461             ['xs', 'wide'],
462             ['xs', 'sm'],
463             ['xs', 'xs'],
464             ['xs'],
465             
466             ['sm', 'xs', 'xs'],
467             ['sm', 'xs'],
468             ['sm'],
469             
470             ['wide', 'xs', 'xs', 'xs'],
471             ['wide', 'xs', 'xs'],
472             ['wide', 'xs'],
473             ['wide'],
474             
475             ['wide-thin']
476         ];
477         
478         var queue = [];
479         
480         var boxes = [];
481         
482         var box = [];
483         
484         Roo.each(items, function(item, k){
485             
486             switch (item.size) {
487                 case 'md' :
488                 case 'md-left' :
489                 case 'md-right' :
490                 case 'tall' :
491                     
492                     if(box.length){
493                         boxes.push(box);
494                         box = [];
495                     }
496                     
497                     boxes.push([item]);
498                     
499                     break;
500                     
501                 case 'xs' :
502                 case 'sm' :
503                 case 'wide' :
504                 case 'wide-thin' :
505                     
506                     box.push(item);
507                     
508                     break;
509                 default :
510                     break;
511                     
512             }
513             
514         }, this);
515         
516         if(box.length){
517             boxes.push(box);
518             box = [];
519         }
520         
521         var filterPattern = function(box, length)
522         {
523             if(!box.length){
524                 return;
525             }
526             
527             var match = false;
528             
529             var pattern = box.slice(0, length);
530             
531             var format = [];
532             
533             Roo.each(pattern, function(i){
534                 format.push(i.size);
535             }, this);
536             
537             Roo.each(standard, function(s){
538                 
539                 if(String(s) != String(format)){
540                     return;
541                 }
542                 
543                 match = true;
544                 return false;
545                 
546             }, this);
547             
548             if(!match && length == 1){
549                 return;
550             }
551             
552             if(!match){
553                 filterPattern(box, length - 1);
554                 return;
555             }
556                 
557             queue.push(pattern);
558
559             box = box.slice(length, box.length);
560
561             filterPattern(box, 4);
562
563             return;
564             
565         }
566         
567         Roo.each(boxes, function(box, k){
568             
569             if(!box.length){
570                 return;
571             }
572             
573             if(box.length == 1){
574                 queue.push(box);
575                 return;
576             }
577             
578             filterPattern(box, 4);
579             
580         }, this);
581         
582         
583         var prune = [];
584         
585         var pos = this.el.getBox(true);
586         
587         var minX = pos.x;
588         
589         var maxX = pos.right - this.unitWidth * 3 - this.gutter * 2 - this.padWidth;
590         
591         var hit_end = false;
592         
593         Roo.each(queue, function(box){
594             
595             if(hit_end){
596                 
597                 Roo.each(box, function(b){
598                 
599                     b.el.setVisibilityMode(Roo.Element.DISPLAY);
600                     b.el.hide();
601
602                 }, this);
603
604                 return;
605             }
606             
607             var mx = 0;
608             
609             Roo.each(box, function(b){
610                 
611                 b.el.setVisibilityMode(Roo.Element.DISPLAY);
612                 b.el.show();
613
614                 mx = Math.max(mx, b.x);
615                 
616             }, this);
617             
618             maxX = maxX - this.unitWidth * mx - this.gutter * (mx - 1) - this.padWidth;
619             
620             if(maxX < minX){
621                 
622                 Roo.each(box, function(b){
623                 
624                     b.el.setVisibilityMode(Roo.Element.DISPLAY);
625                     b.el.hide();
626                     
627                 }, this);
628                 
629                 hit_end = true;
630                 
631                 return;
632             }
633             
634             prune.push(box);
635             
636         }, this);
637         
638         this._processHorizontalLayoutQueue( prune, eItems, isInstant );
639     },
640     
641     /** Sets position of item in DOM
642     * @param {Element} item
643     * @param {Number} x - horizontal position
644     * @param {Number} y - vertical position
645     * @param {Boolean} isInstant - disables transitions
646     */
647     _processVerticalLayoutQueue : function( queue, isInstant )
648     {
649         var pos = this.el.getBox(true);
650         var x = pos.x;
651         var y = pos.y;
652         var maxY = [];
653         
654         for (var i = 0; i < this.cols; i++){
655             maxY[i] = pos.y;
656         }
657         
658         Roo.each(queue, function(box, k){
659             
660             var col = k % this.cols;
661             
662             Roo.each(box, function(b,kk){
663                 
664                 b.el.position('absolute');
665                 
666                 var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
667                 var height = Math.floor(this.unitHeight * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
668                 
669                 if(b.size == 'md-left' || b.size == 'md-right'){
670                     width = Math.floor(this.unitWidth * (b.x - 1) + (this.gutter * (b.x - 2)) + b.el.getPadding('lr'));
671                     height = Math.floor(this.unitHeight * (b.y - 1) + (this.gutter * (b.y - 2)) + b.el.getPadding('tb'));
672                 }
673                 
674                 b.el.setWidth(width);
675                 b.el.setHeight(height);
676                 // iframe?
677                 b.el.select('iframe',true).setSize(width,height);
678                 
679             }, this);
680             
681             for (var i = 0; i < this.cols; i++){
682                 
683                 if(maxY[i] < maxY[col]){
684                     col = i;
685                     continue;
686                 }
687                 
688                 col = Math.min(col, i);
689                 
690             }
691             
692             x = pos.x + col * (this.colWidth + this.padWidth);
693             
694             y = maxY[col];
695             
696             var positions = [];
697             
698             switch (box.length){
699                 case 1 :
700                     positions = this.getVerticalOneBoxColPositions(x, y, box);
701                     break;
702                 case 2 :
703                     positions = this.getVerticalTwoBoxColPositions(x, y, box);
704                     break;
705                 case 3 :
706                     positions = this.getVerticalThreeBoxColPositions(x, y, box);
707                     break;
708                 case 4 :
709                     positions = this.getVerticalFourBoxColPositions(x, y, box);
710                     break;
711                 default :
712                     break;
713             }
714             
715             Roo.each(box, function(b,kk){
716                 
717                 b.el.setXY([positions[kk].x, positions[kk].y], isInstant ? false : true);
718                 
719                 var sz = b.el.getSize();
720                 
721                 maxY[col] = Math.max(maxY[col], positions[kk].y + sz.height + this.padWidth);
722                 
723             }, this);
724             
725         }, this);
726         
727         var mY = 0;
728         
729         for (var i = 0; i < this.cols; i++){
730             mY = Math.max(mY, maxY[i]);
731         }
732         
733         this.el.setHeight(mY - pos.y);
734         
735     },
736     
737 //    _processVerticalAlternativeLayoutQueue : function( items, isInstant )
738 //    {
739 //        var pos = this.el.getBox(true);
740 //        var x = pos.x;
741 //        var y = pos.y;
742 //        var maxX = pos.right;
743 //        
744 //        var maxHeight = 0;
745 //        
746 //        Roo.each(items, function(item, k){
747 //            
748 //            var c = k % 2;
749 //            
750 //            item.el.position('absolute');
751 //                
752 //            var width = Math.floor(this.colWidth + item.el.getPadding('lr'));
753 //
754 //            item.el.setWidth(width);
755 //
756 //            var height = Math.floor(this.colWidth * item.y / item.x + item.el.getPadding('tb'));
757 //
758 //            item.el.setHeight(height);
759 //            
760 //            if(c == 0){
761 //                item.el.setXY([x, y], isInstant ? false : true);
762 //            } else {
763 //                item.el.setXY([maxX - width, y], isInstant ? false : true);
764 //            }
765 //            
766 //            y = y + height + this.alternativePadWidth;
767 //            
768 //            maxHeight = maxHeight + height + this.alternativePadWidth;
769 //            
770 //        }, this);
771 //        
772 //        this.el.setHeight(maxHeight);
773 //        
774 //    },
775     
776     _processHorizontalLayoutQueue : function( queue, eItems, isInstant )
777     {
778         var pos = this.el.getBox(true);
779         
780         var minX = pos.x;
781         var minY = pos.y;
782         
783         var maxX = pos.right;
784         
785         this._processHorizontalEndItem(eItems, maxX, minX, minY, isInstant);
786         
787         var maxX = maxX - this.unitWidth * 3 - this.gutter * 2 - this.padWidth;
788         
789         Roo.each(queue, function(box, k){
790             
791             Roo.each(box, function(b, kk){
792                 
793                 b.el.position('absolute');
794                 
795                 var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
796                 var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
797                 
798                 if(b.size == 'md-left' || b.size == 'md-right'){
799                     width = Math.floor(this.unitWidth * (b.x - 1) + (this.gutter * (b.x - 2)) + b.el.getPadding('lr'));
800                     height = Math.floor(this.unitWidth * (b.y - 1) + (this.gutter * (b.y - 2)) + b.el.getPadding('tb'));
801                 }
802                 
803                 b.el.setWidth(width);
804                 b.el.setHeight(height);
805                 
806             }, this);
807             
808             if(!box.length){
809                 return;
810             }
811             
812             var positions = [];
813             
814             switch (box.length){
815                 case 1 :
816                     positions = this.getHorizontalOneBoxColPositions(maxX, minY, box);
817                     break;
818                 case 2 :
819                     positions = this.getHorizontalTwoBoxColPositions(maxX, minY, box);
820                     break;
821                 case 3 :
822                     positions = this.getHorizontalThreeBoxColPositions(maxX, minY, box);
823                     break;
824                 case 4 :
825                     positions = this.getHorizontalFourBoxColPositions(maxX, minY, box);
826                     break;
827                 default :
828                     break;
829             }
830             
831             Roo.each(box, function(b,kk){
832                 
833                 b.el.setXY([positions[kk].x, positions[kk].y], isInstant ? false : true);
834                 
835                 maxX = Math.min(maxX, positions[kk].x - this.padWidth);
836                 
837             }, this);
838             
839         }, this);
840         
841     },
842     
843     _processHorizontalEndItem : function(eItems, maxX, minX, minY, isInstant)
844     {
845         Roo.each(eItems, function(b,k){
846             
847             b.size = (k == 0) ? 'sm' : 'xs';
848             b.x = (k == 0) ? 2 : 1;
849             b.y = (k == 0) ? 2 : 1;
850             
851             b.el.position('absolute');
852             
853             var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
854                 
855             b.el.setWidth(width);
856             
857             var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
858             
859             b.el.setHeight(height);
860             
861         }, this);
862
863         var positions = [];
864         
865         positions.push({
866             x : maxX - this.unitWidth * 2 - this.gutter,
867             y : minY
868         });
869         
870         positions.push({
871             x : maxX - this.unitWidth,
872             y : minY + (this.unitWidth + this.gutter) * 2
873         });
874         
875         positions.push({
876             x : maxX - this.unitWidth * 3 - this.gutter * 2,
877             y : minY
878         });
879         
880         Roo.each(eItems, function(b,k){
881             
882             b.el.setXY([positions[k].x, positions[k].y], isInstant ? false : true);
883
884         }, this);
885         
886     },
887     
888     getVerticalOneBoxColPositions : function(x, y, box)
889     {
890         var pos = [];
891         
892         var rand = Math.floor(Math.random() * ((4 - box[0].x)));
893         
894         if(box[0].size == 'md-left'){
895             rand = 0;
896         }
897         
898         if(box[0].size == 'md-right'){
899             rand = 1;
900         }
901         
902         pos.push({
903             x : x + (this.unitWidth + this.gutter) * rand,
904             y : y
905         });
906         
907         return pos;
908     },
909     
910     getVerticalTwoBoxColPositions : function(x, y, box)
911     {
912         var pos = [];
913         
914         if(box[0].size == 'xs'){
915             
916             pos.push({
917                 x : x,
918                 y : y + ((this.unitHeight + this.gutter) * Math.floor(Math.random() * box[1].y))
919             });
920
921             pos.push({
922                 x : x + (this.unitWidth + this.gutter) * (3 - box[1].x),
923                 y : y
924             });
925             
926             return pos;
927             
928         }
929         
930         pos.push({
931             x : x,
932             y : y
933         });
934
935         pos.push({
936             x : x + (this.unitWidth + this.gutter) * 2,
937             y : y + ((this.unitHeight + this.gutter) * Math.floor(Math.random() * box[0].y))
938         });
939         
940         return pos;
941         
942     },
943     
944     getVerticalThreeBoxColPositions : function(x, y, box)
945     {
946         var pos = [];
947         
948         if(box[0].size == 'xs' && box[1].size == 'xs' && box[2].size == 'xs'){
949             
950             pos.push({
951                 x : x,
952                 y : y
953             });
954
955             pos.push({
956                 x : x + (this.unitWidth + this.gutter) * 1,
957                 y : y
958             });
959             
960             pos.push({
961                 x : x + (this.unitWidth + this.gutter) * 2,
962                 y : y
963             });
964             
965             return pos;
966             
967         }
968         
969         if(box[0].size == 'xs' && box[1].size == 'xs'){
970             
971             pos.push({
972                 x : x,
973                 y : y
974             });
975
976             pos.push({
977                 x : x,
978                 y : y + ((this.unitHeight + this.gutter) * (box[2].y - 1))
979             });
980             
981             pos.push({
982                 x : x + (this.unitWidth + this.gutter) * 1,
983                 y : y
984             });
985             
986             return pos;
987             
988         }
989         
990         pos.push({
991             x : x,
992             y : y
993         });
994
995         pos.push({
996             x : x + (this.unitWidth + this.gutter) * 2,
997             y : y
998         });
999
1000         pos.push({
1001             x : x + (this.unitWidth + this.gutter) * 2,
1002             y : y + (this.unitHeight + this.gutter) * (box[0].y - 1)
1003         });
1004             
1005         return pos;
1006         
1007     },
1008     
1009     getVerticalFourBoxColPositions : function(x, y, box)
1010     {
1011         var pos = [];
1012         
1013         if(box[0].size == 'xs'){
1014             
1015             pos.push({
1016                 x : x,
1017                 y : y
1018             });
1019
1020             pos.push({
1021                 x : x,
1022                 y : y + (this.unitHeight + this.gutter) * 1
1023             });
1024             
1025             pos.push({
1026                 x : x,
1027                 y : y + (this.unitHeight + this.gutter) * 2
1028             });
1029             
1030             pos.push({
1031                 x : x + (this.unitWidth + this.gutter) * 1,
1032                 y : y
1033             });
1034             
1035             return pos;
1036             
1037         }
1038         
1039         pos.push({
1040             x : x,
1041             y : y
1042         });
1043
1044         pos.push({
1045             x : x + (this.unitWidth + this.gutter) * 2,
1046             y : y
1047         });
1048
1049         pos.push({
1050             x : x + (this.unitHeightunitWidth + this.gutter) * 2,
1051             y : y + (this.unitHeight + this.gutter) * 1
1052         });
1053
1054         pos.push({
1055             x : x + (this.unitWidth + this.gutter) * 2,
1056             y : y + (this.unitWidth + this.gutter) * 2
1057         });
1058
1059         return pos;
1060         
1061     },
1062     
1063     getHorizontalOneBoxColPositions : function(maxX, minY, box)
1064     {
1065         var pos = [];
1066         
1067         if(box[0].size == 'md-left'){
1068             pos.push({
1069                 x : maxX - this.unitWidth * (box[0].x - 1) - this.gutter * (box[0].x - 2),
1070                 y : minY
1071             });
1072             
1073             return pos;
1074         }
1075         
1076         if(box[0].size == 'md-right'){
1077             pos.push({
1078                 x : maxX - this.unitWidth * (box[0].x - 1) - this.gutter * (box[0].x - 2),
1079                 y : minY + (this.unitWidth + this.gutter) * 1
1080             });
1081             
1082             return pos;
1083         }
1084         
1085         var rand = Math.floor(Math.random() * (4 - box[0].y));
1086         
1087         pos.push({
1088             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1089             y : minY + (this.unitWidth + this.gutter) * rand
1090         });
1091         
1092         return pos;
1093         
1094     },
1095     
1096     getHorizontalTwoBoxColPositions : function(maxX, minY, box)
1097     {
1098         var pos = [];
1099         
1100         if(box[0].size == 'xs'){
1101             
1102             pos.push({
1103                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1104                 y : minY
1105             });
1106
1107             pos.push({
1108                 x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1109                 y : minY + (this.unitWidth + this.gutter) * (3 - box[1].y)
1110             });
1111             
1112             return pos;
1113             
1114         }
1115         
1116         pos.push({
1117             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1118             y : minY
1119         });
1120
1121         pos.push({
1122             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1123             y : minY + (this.unitWidth + this.gutter) * 2
1124         });
1125         
1126         return pos;
1127         
1128     },
1129     
1130     getHorizontalThreeBoxColPositions : function(maxX, minY, box)
1131     {
1132         var pos = [];
1133         
1134         if(box[0].size == 'xs' && box[1].size == 'xs' && box[2].size == 'xs'){
1135             
1136             pos.push({
1137                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1138                 y : minY
1139             });
1140
1141             pos.push({
1142                 x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1143                 y : minY + (this.unitWidth + this.gutter) * 1
1144             });
1145             
1146             pos.push({
1147                 x : maxX - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1),
1148                 y : minY + (this.unitWidth + this.gutter) * 2
1149             });
1150             
1151             return pos;
1152             
1153         }
1154         
1155         if(box[0].size == 'xs' && box[1].size == 'xs'){
1156             
1157             pos.push({
1158                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1159                 y : minY
1160             });
1161
1162             pos.push({
1163                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1) - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1164                 y : minY
1165             });
1166             
1167             pos.push({
1168                 x : maxX - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1),
1169                 y : minY + (this.unitWidth + this.gutter) * 1
1170             });
1171             
1172             return pos;
1173             
1174         }
1175         
1176         pos.push({
1177             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1178             y : minY
1179         });
1180
1181         pos.push({
1182             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1183             y : minY + (this.unitWidth + this.gutter) * 2
1184         });
1185
1186         pos.push({
1187             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1) - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1),
1188             y : minY + (this.unitWidth + this.gutter) * 2
1189         });
1190             
1191         return pos;
1192         
1193     },
1194     
1195     getHorizontalFourBoxColPositions : function(maxX, minY, box)
1196     {
1197         var pos = [];
1198         
1199         if(box[0].size == 'xs'){
1200             
1201             pos.push({
1202                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1203                 y : minY
1204             });
1205
1206             pos.push({
1207                 x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1) - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1208                 y : minY
1209             });
1210             
1211             pos.push({
1212                 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),
1213                 y : minY
1214             });
1215             
1216             pos.push({
1217                 x : maxX - this.unitWidth * box[3].x - this.gutter * (box[3].x - 1),
1218                 y : minY + (this.unitWidth + this.gutter) * 1
1219             });
1220             
1221             return pos;
1222             
1223         }
1224         
1225         pos.push({
1226             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1227             y : minY
1228         });
1229         
1230         pos.push({
1231             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1232             y : minY + (this.unitWidth + this.gutter) * 2
1233         });
1234         
1235         pos.push({
1236             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1) - this.unitWidth * box[2].x - this.gutter * (box[2].x - 1),
1237             y : minY + (this.unitWidth + this.gutter) * 2
1238         });
1239         
1240         pos.push({
1241             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),
1242             y : minY + (this.unitWidth + this.gutter) * 2
1243         });
1244
1245         return pos;
1246         
1247     },
1248     
1249     /**
1250     * remove a Masonry Brick
1251     * @param {Roo.bootstrap.MasonryBrick} the masonry brick to remove
1252     */
1253     removeBrick : function(brick_id)
1254     {
1255         if (!brick_id) {
1256             return;
1257         }
1258         
1259         for (var i = 0; i<this.bricks.length; i++) {
1260             if (this.bricks[i].id == brick_id) {
1261                 this.bricks.splice(i,1);
1262                 this.selectedBrick = [];
1263                 this.el.dom.removeChild(Roo.get(brick_id).dom);
1264                 this.initial();
1265             }
1266         }
1267     },
1268     
1269     /**
1270     * adds a Masonry Brick
1271     * @param {Roo.bootstrap.MasonryBrick} the masonry brick to add
1272     */
1273     addBrick : function(cfg)
1274     {
1275         var cn = new Roo.bootstrap.MasonryBrick(cfg);
1276         //this.register(cn);
1277         cn.parentId = this.id;
1278         cn.onRender(this.el, null);
1279         return cn;
1280     },
1281     
1282     /**
1283     * register a Masonry Brick
1284     * @param {Roo.bootstrap.MasonryBrick} the masonry brick to add
1285     */
1286     
1287     register : function(brick)
1288     {
1289         this.bricks.push(brick);
1290         brick.masonryId = this.id;
1291     },
1292     
1293     /**
1294     * clear all the Masonry Brick
1295     */
1296     clearAll : function()
1297     {
1298         this.bricks = [];
1299         //this.getChildContainer().dom.innerHTML = "";
1300         this.el.dom.innerHTML = '';
1301     },
1302     
1303     getSelected : function()
1304     {
1305         if (!this.selectedBrick) {
1306             return false;
1307         }
1308         
1309         return this.selectedBrick;
1310     }
1311 });
1312
1313 Roo.apply(Roo.bootstrap.LayoutMasonry, {
1314     
1315     groups: {},
1316      /**
1317     * register a Masonry Layout
1318     * @param {Roo.bootstrap.LayoutMasonry} the masonry layout to add
1319     */
1320     
1321     register : function(layout)
1322     {
1323         this.groups[layout.id] = layout;
1324     },
1325     /**
1326     * fetch a  Masonry Layout based on the masonry layout ID
1327     * @param {string} the masonry layout to add
1328     * @returns {Roo.bootstrap.LayoutMasonry} the masonry layout
1329     */
1330     
1331     get: function(layout_id) {
1332         if (typeof(this.groups[layout_id]) == 'undefined') {
1333             return false;
1334         }
1335         return this.groups[layout_id] ;
1336     }
1337     
1338     
1339     
1340 });
1341
1342  
1343
1344