001/*
002 * #%L
003 * GwtMaterial
004 * %%
005 * Copyright (C) 2015 - 2017 GwtMaterialDesign
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 * 
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 * 
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package gwt.material.design.client.ui;
021
022import com.google.gwt.dom.client.Document;
023import com.google.gwt.dom.client.ImageElement;
024import com.google.gwt.event.dom.client.*;
025import com.google.gwt.event.logical.shared.ValueChangeEvent;
026import com.google.gwt.event.logical.shared.ValueChangeHandler;
027import com.google.gwt.event.shared.HandlerRegistration;
028import com.google.gwt.resources.client.ImageResource;
029import com.google.gwt.user.client.ui.HasValue;
030import gwt.material.design.client.base.*;
031import gwt.material.design.client.base.mixin.ActivatesMixin;
032import gwt.material.design.client.base.mixin.CssTypeMixin;
033import gwt.material.design.client.base.mixin.ImageMixin;
034import gwt.material.design.client.constants.CssName;
035import gwt.material.design.client.constants.ImageType;
036
037import static gwt.material.design.client.js.JsMaterialElement.$;
038
039//@formatter:off
040
041/**
042 * Images can be styled in different ways using Material Design
043 * <h3>UiBinder Usage:</h3>
044 * <p>
045 * <pre>
046 * {@code //Simple Image
047 * <m:MaterialImage url="http://assets.materialup.com/uploads/0587e4a8-6a46-4e27-b8bf-836e4350fe82/candycons.gif"/>
048 *
049 * // Circle Image
050 * <m:MaterialImage url="http://assets.materialup.com/uploads/0587e4a8-6a46-4e27-b8bf-836e4350fe82/candycons.gif" type="CIRCLE"/>
051 *
052 * // MaterialBoxed Image
053 * <m:MaterialImage url="http://assets.materialup.com/uploads/0587e4a8-6a46-4e27-b8bf-836e4350fe82/candycons.gif" type="MATERIALBOXED"/>
054 * }
055 * </pre>
056 *
057 * @author kevzlou7979
058 * @author Ben Dol
059 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#media">Material Media</a>
060 * @see <a href="https://material.io/guidelines/style/imagery.html">Material Design Specification</a>
061 */
062//@formatter:on
063public class MaterialImage extends MaterialWidget implements HasCaption, HasType<ImageType>, HasImage,
064        HasLoadHandlers, HasErrorHandlers, HasActivates, HasValue<String> {
065
066    private CssTypeMixin<ImageType, MaterialImage> typeMixin;
067    private ImageMixin<MaterialImage> imageMixin;
068    private ActivatesMixin<MaterialImage> activatesMixin;
069
070    /**
071     * Creates an empty image.
072     */
073    public MaterialImage() {
074        super(Document.get().createImageElement(), CssName.RESPONSIVE_IMG);
075    }
076
077    /**
078     * Creates a simple image.
079     */
080    public MaterialImage(String url) {
081        this();
082        setUrl(url);
083    }
084
085    /**
086     * Creates an image with Specific type.
087     */
088    public MaterialImage(String url, ImageType type) {
089        this(url);
090        setType(type);
091    }
092
093    /**
094     * Creates an image from an ImageResource.
095     */
096    public MaterialImage(ImageResource resource) {
097        this();
098        setResource(resource);
099    }
100
101    /**
102     * Creates an image from an ImageResource with Specific type.
103     */
104    public MaterialImage(ImageResource resource, ImageType type) {
105        this(resource);
106        setType(type);
107    }
108
109    @Override
110    protected void onLoad() {
111        super.onLoad();
112
113        $(".materialboxed").materialbox();
114    }
115
116    @Override
117    public void setType(ImageType type) {
118        getTypeMixin().setType(type);
119    }
120
121    @Override
122    public ImageType getType() {
123        return getTypeMixin().getType();
124    }
125
126    @Override
127    public String getCaption() {
128        return getElement().getAttribute("data-caption");
129    }
130
131    @Override
132    public void setCaption(String caption) {
133        getElement().setAttribute("data-caption", caption);
134    }
135
136    @Override
137    public void setUrl(String url) {
138        setValue(url, true);
139    }
140
141    @Override
142    public String getUrl() {
143        return getValue();
144    }
145
146    @Override
147    public void setResource(ImageResource resource) {
148        getImageMixin().setResource(resource);
149    }
150
151    @Override
152    public ImageResource getResource() {
153        return getImageMixin().getResource();
154    }
155
156    public int getWidth() {
157        return ((ImageElement)getElement().cast()).getWidth();
158    }
159
160    public int getHeight() {
161        return ((ImageElement)getElement().cast()).getHeight();
162    }
163
164    @Override
165    public void setActivates(String activates) {
166        getActivatesMixin().setActivates(activates);
167    }
168
169    @Override
170    public String getActivates() {
171        return getActivatesMixin().getActivates();
172    }
173
174    @Override
175    public String getValue() {
176        return getImageMixin().getUrl();
177    }
178
179    @Override
180    public void setValue(String value) {
181        setValue(value, false);
182    }
183
184    @Override
185    public void setValue(String value, boolean fireEvents) {
186        String oldValue = getUrl();
187        getImageMixin().setUrl(value);
188
189        if(fireEvents) {
190            ValueChangeEvent.fireIfNotEqual(this, oldValue, value);
191        }
192    }
193
194    @Override
195    public HandlerRegistration addLoadHandler(final LoadHandler handler) {
196        return addDomHandler(handler, LoadEvent.getType());
197    }
198
199    @Override
200    public HandlerRegistration addErrorHandler(final ErrorHandler handler) {
201        return addDomHandler(handler, ErrorEvent.getType());
202    }
203
204    @Override
205    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
206        return addHandler(handler, ValueChangeEvent.getType());
207    }
208
209    protected CssTypeMixin<ImageType, MaterialImage> getTypeMixin() {
210        if (typeMixin == null) {
211            typeMixin = new CssTypeMixin<>(this);
212        }
213        return typeMixin;
214    }
215
216    protected ImageMixin<MaterialImage> getImageMixin() {
217        if (imageMixin == null) {
218            imageMixin = new ImageMixin<>(this);
219        }
220        return imageMixin;
221    }
222
223    protected ActivatesMixin<MaterialImage> getActivatesMixin() {
224        if (activatesMixin == null) {
225            activatesMixin = new ActivatesMixin<>(this);
226        }
227        return activatesMixin;
228    }
229}