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