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