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 *     &lt;-- 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}