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