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