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