001package gwt.material.design.addins.client.masonry; 002 003/* 004 * #%L 005 * GwtMaterial 006 * %% 007 * Copyright (C) 2015 GwtMaterialDesign 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import com.google.gwt.dom.client.Document; 024import com.google.gwt.dom.client.Element; 025import gwt.material.design.addins.client.MaterialAddins; 026import gwt.material.design.client.MaterialDesignBase; 027import gwt.material.design.client.base.MaterialWidget; 028import gwt.material.design.client.ui.MaterialRow; 029 030//@formatter:off 031 032/** 033 * Masonry works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall. 034 * 035 * <h3>XML Namespace Declaration</h3> 036 * <pre> 037 * {@code 038 * xmlns:m.addins='urn:import:gwt.material.design.addins.client.ui' 039 * } 040 * </pre> 041 * 042 * <h3>UiBinder Usage:</h3> 043 * <pre> 044 * { 045 * @code 046 * <m.addins:MaterialMasonry> 047 * <m:MaterialColumn grid="l1" padding="4" backgroundColor="blue" height="200px"> 048 * <m:MaterialLabel text="1"/> 049 * </m:MaterialColumn> 050 * <-- Other columns here --> 051 * </m.addins:MaterialMasonry> 052 * } 053 * </pre> 054 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#masonry">Material Masonry</a> 055 * @author kevzlou7979 056 */ 057//@formatter:on 058public class MaterialMasonry extends MaterialRow { 059 060 static { 061 if(MaterialAddins.isDebug()) { 062 MaterialDesignBase.injectDebugJs(MaterialMasonryDebugClientBundle.INSTANCE.masonryJsDebug()); 063 MaterialDesignBase.injectDebugJs(MaterialMasonryDebugClientBundle.INSTANCE.imageLoadedJsDebug()); 064 } else { 065 MaterialDesignBase.injectJs(MaterialMasonryClientBundle.INSTANCE.masonryJs()); 066 MaterialDesignBase.injectJs(MaterialMasonryClientBundle.INSTANCE.imageLoadedJs()); 067 } 068 } 069 070 private String itemSelector = ".col"; 071 private boolean percentPosition = true; 072 private boolean originLeft = true; 073 private boolean originTop = true; 074 private double transitionDuration = 400; 075 076 private MaterialWidget sizerDiv = new MaterialWidget(Document.get().createDivElement()); 077 078 public MaterialMasonry() { 079 super(Document.get().createDivElement(), "masonry", "row"); 080 sizerDiv.setWidth("8.3333%"); 081 sizerDiv.setStyleName("col-sizer"); 082 add(sizerDiv); 083 } 084 085 @Override 086 protected void onLoad() { 087 super.onLoad(); 088 initMasonry(); 089 } 090 091 protected void initMasonry() { 092 initMasonry(getElement()); 093 } 094 095 /** 096 * Initialize the masonry component 097 * @param e 098 */ 099 protected native void initMasonry(Element e) /*-{ 100 var that = this; 101 $wnd.jQuery(window).ready(function() { 102 $wnd.jQuery('.masonry').imagesLoaded( function() { 103 var grid = $wnd.jQuery(e).masonry({ 104 // options... 105 itemSelector: '.masonry >' + that.@gwt.material.design.addins.client.masonry.MaterialMasonry::getItemSelector()(), 106 percentPosition: that.@gwt.material.design.addins.client.masonry.MaterialMasonry::isPercentPosition()(), 107 originLeft: that.@gwt.material.design.addins.client.masonry.MaterialMasonry::isOriginLeft()(), 108 originTop: that.@gwt.material.design.addins.client.masonry.MaterialMasonry::isOriginTop()(), 109 transitionDuration: that.@gwt.material.design.addins.client.masonry.MaterialMasonry::getTransitionDuration()() + 'ms', 110 columnWidth: '.col-sizer' 111 }); 112 }); 113 }); 114 }-*/; 115 116 /** 117 * Get the item selector 118 * @return 119 */ 120 public String getItemSelector() { 121 return itemSelector; 122 } 123 124 /** 125 * Specifies which child elements will be used as item elements in the layout.It's .col by default for grid components 126 * @param itemSelector 127 */ 128 public void setItemSelector(String itemSelector) { 129 this.itemSelector = itemSelector; 130 } 131 132 /** 133 * Get the percent position boolean value 134 * @return 135 */ 136 public boolean isPercentPosition() { 137 return percentPosition; 138 } 139 140 /** 141 * Sets item positions in percent values, rather than pixel values. percentPosition: true works well with percent-width items, as items will not transition their position on resize. 142 * @param percentPosition 143 */ 144 public void setPercentPosition(boolean percentPosition) { 145 this.percentPosition = percentPosition; 146 } 147 148 /** 149 * Get the boolean value of origin left 150 * @return 151 */ 152 public boolean isOriginLeft() { 153 return originLeft; 154 } 155 156 /** 157 * Controls the horizontal flow of the layout. By default, item elements start positioning at the left, with originLeft: true. Set originLeft: false for right-to-left layouts. 158 * @param originLeft 159 */ 160 public void setOriginLeft(boolean originLeft) { 161 this.originLeft = originLeft; 162 } 163 164 /** 165 * Get the boolean value of origin top 166 * @return 167 */ 168 public boolean isOriginTop() { 169 return originTop; 170 } 171 172 /** 173 * Controls the vertical flow of the layout. By default, item elements start positioning at the top, with originTop: true. Set originTop: false for bottom-up layouts. It’s like Tetris 174 * @param originTop 175 */ 176 public void setOriginTop(boolean originTop) { 177 this.originTop = originTop; 178 } 179 180 /** 181 * Get the transition duration in milliseconds 182 * @return 183 */ 184 public double getTransitionDuration() { 185 return transitionDuration; 186 } 187 188 /** 189 * Sets the transition duration in milliseconds, if 0 then there will be no transition 190 * @param transitionDuration 191 */ 192 public void setTransitionDuration(double transitionDuration) { 193 this.transitionDuration = transitionDuration; 194 } 195 196 197}