001package gwt.material.design.addins.client.stepper;
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.event.dom.client.ClickEvent;
025import com.google.gwt.event.dom.client.ClickHandler;
026import com.google.gwt.event.logical.shared.HasSelectionHandlers;
027import com.google.gwt.event.logical.shared.SelectionEvent;
028import com.google.gwt.event.logical.shared.SelectionHandler;
029import com.google.gwt.event.shared.HandlerRegistration;
030import com.google.gwt.user.client.ui.Widget;
031import gwt.material.design.addins.client.stepper.base.mixin.ActiveMixin;
032import gwt.material.design.client.base.*;
033import gwt.material.design.client.constants.Axis;
034import gwt.material.design.client.constants.IconType;
035import gwt.material.design.client.ui.MaterialIcon;
036import gwt.material.design.client.ui.html.Div;
037
038//@formatter:off
039/**
040 * Material Step is a child element of Material Stepper, sometimes called Stepper Item, used to indicate the active
041 * inactive items on the Stepper Component.
042 *
043 * <h3>XML Namespace Declaration</h3>
044 * <pre>
045 * {@code
046 * xmlns:ma='urn:import:gwt.material.design.addins.client'
047 * }
048 * </pre>
049 *
050 * <h3>UiBinder Usage:</h3>
051 * <pre>
052 * {@code
053 *   <ma:stepper.MaterialStep step="1" title="Name of Step 1">
054 *       <m:MaterialPanel width="100%" height="300px" backgroundColor="grey lighten-2"/>
055 *       <m:MaterialButton ui:field="btnContinue1" text="Continue to Step 2" grid="l4" marginTop="12" backgroundColor="blue" textColor="white" waves="DEFAULT"/>
056 *       <m:MaterialButton ui:field="btnPrev1" text="Cancel" grid="l4" marginTop="12" type="FLAT" waves="DEFAULT"/>
057 *   </ma:stepper.MaterialStep>
058 * }
059 * </pre>
060 *
061 * @author kevzlou7979
062 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#steppers">Material Steppers</a>
063 */
064// @formatter:on
065public class MaterialStep extends MaterialWidget implements HasActive, HasTitle, HasError, HasAxis, HasSelectionHandlers<MaterialStep> {
066
067    private int step;
068    private String title;
069    private String description;
070
071    // containers
072    private Div conCircle = new Div();
073    private Div conBody = new Div();
074
075    // elements
076    private Div divCircle = new Div();
077    private Div divLine = new Div();
078    private Div divTitle = new Div();
079    private Div divDescription = new Div();
080    private Div divBody = new Div();
081
082    private MaterialIcon iconError = new MaterialIcon(IconType.REPORT_PROBLEM);
083    private MaterialIcon iconSuccess = new MaterialIcon(IconType.CHECK_CIRCLE);
084    private final ActiveMixin<MaterialStep> activeMixin = new ActiveMixin<>(this);
085    
086    private Axis axis = Axis.VERTICAL;
087
088    public MaterialStep() {
089        super(Document.get().createDivElement(), "step");
090
091        super.add(conCircle);
092        conCircle.add(divCircle);
093        conCircle.add(divLine);
094
095        super.add(conBody);
096        conBody.add(divTitle);
097        conBody.add(divBody);
098
099        divCircle.setStyleName("circle");
100        divLine.setStyleName("line");
101        divTitle.setStyleName("title");
102        divBody.setStyleName("body");
103        
104        ClickHandler handler = new ClickHandler() {
105            @Override
106            public void onClick(ClickEvent event) {
107                if (isEnabled() && isVisible()){
108                    SelectionEvent.fire(MaterialStep.this, MaterialStep.this);                    
109                }
110            }
111        };
112        conCircle.addClickHandler(handler);
113        divTitle.addClickHandler(handler);
114        divDescription.addClickHandler(handler);
115    }
116
117    @Override
118    public void add(Widget child) {
119        divBody.add(child);
120    }
121
122    public int getStep() {
123        return step;
124    }
125
126    public void setStep(int step) {
127        this.step = step;
128        divCircle.getElement().setInnerHTML(String.valueOf(step));
129    }
130
131    @Override
132    public void setTitle(String title) {
133        this.title = title;
134        divTitle.getElement().setInnerHTML(title);
135    }
136
137    public String getTitle() {
138        return title;
139    }
140
141    @Override
142    public void setDescription(String description) {
143        this.description = description;
144        divDescription.setStyleName("description");
145        divDescription.getElement().setInnerHTML(description);
146        conBody.insert(divDescription, 1);
147    }
148
149    public String getDescription() {
150        return description;
151    }
152
153    @Override
154    public void setActive(boolean active) {
155        activeMixin.setActive(active);
156    }
157
158    @Override
159    public boolean isActive() {
160        return activeMixin.isActive();
161    }
162
163    @Override
164    public void setError(String error) {
165        removeStyleName("success");
166        addStyleName("error");
167        applyIconStatus(iconError, "red", error);
168    }
169
170    @Override
171    public void setSuccess(String success) {
172        removeStyleName("error");
173        addStyleName("success");
174        applyIconStatus(iconSuccess, "blue", success);
175    }
176    
177    @Override
178    public void setHelperText(String helperText) {
179        setDescription(helperText);
180    }
181
182    @Override
183    public void clearErrorOrSuccess() {
184        iconError.removeFromParent();
185        iconSuccess.removeFromParent();
186        conCircle.insert(divCircle, 0);
187        removeStyleName("error");
188        removeStyleName("success");
189    }
190
191
192    protected void applyIconStatus(MaterialIcon icon, String color, String description){
193        iconError.removeFromParent();
194        iconSuccess.removeFromParent();
195        divCircle.removeFromParent();
196        conCircle.insert(icon, 0);
197        divDescription.getElement().setInnerHTML(description);
198    }
199
200    public Div getDivBody() {
201        return divBody;
202    }
203    
204    @Override
205    public void setAxis(Axis axis) {
206        if (axis == null){
207            axis = Axis.VERTICAL;
208        }
209        this.axis = axis;
210        switch (axis){
211        case HORIZONTAL:
212            conCircle.add(divTitle);
213            conCircle.add(divLine);
214            conCircle.add(divDescription);
215            break;
216        case VERTICAL:
217            conBody.insert(divTitle, 0);
218            conCircle.add(divLine);
219            break;
220        }
221    }
222    
223    @Override
224    public Axis getAxis() {
225        return axis;
226    }
227
228    @Override
229    public HandlerRegistration addSelectionHandler(final SelectionHandler<MaterialStep> handler) {
230        return this.addHandler(new SelectionHandler<MaterialStep>() {
231            @Override
232            public void onSelection(SelectionEvent<MaterialStep> event) {
233                if(isEnabled()){
234                    handler.onSelection(event);
235                }
236            }
237        }, SelectionEvent.getType());
238    }
239}