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