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.base;
021
022import com.google.gwt.dom.client.Element;
023import com.google.gwt.dom.client.Style;
024import com.google.gwt.user.client.History;
025import gwt.material.design.client.base.mixin.ActivatesMixin;
026import gwt.material.design.client.base.mixin.CssTypeMixin;
027import gwt.material.design.client.constants.*;
028import gwt.material.design.client.ui.html.Span;
029
030/**
031 * @author Ben Dol
032 */
033public abstract class AbstractButton extends MaterialWidget implements HasHref, HasGrid, HasActivates,
034        HasTargetHistoryToken, HasType<ButtonType> {
035
036    private String targetHistoryToken;
037    private Span span = new Span();
038    private ButtonSize size;
039
040    private ActivatesMixin<AbstractButton> activatesMixin;
041    private CssTypeMixin<ButtonType, AbstractButton> typeMixin;
042
043    /**
044     * Creates button with RAISED type.
045     */
046    protected AbstractButton() {
047        setElement(createElement());
048
049        getElement().getStyle().setCursor(Style.Cursor.POINTER);
050    }
051
052    protected AbstractButton(String... initialClass) {
053        this();
054        setInitialClasses(initialClass);
055    }
056
057    protected AbstractButton(String text, Color bgColor, WavesType waves) {
058        this(null, text, bgColor);
059        setWaves(waves);
060    }
061
062    protected AbstractButton(final ButtonType type, String text, Color bgColor, WavesType waves) {
063        this(type, text, bgColor);
064        setWaves(waves);
065    }
066
067    protected AbstractButton(final ButtonType type, String text, Color bgColor) {
068        this(type, text);
069        setBackgroundColor(bgColor);
070    }
071
072    protected AbstractButton(final ButtonType type, String text) {
073        this(type);
074        setText(text);
075    }
076
077    protected AbstractButton(final ButtonType type) {
078        this();
079        setType(type);
080    }
081
082    protected abstract Element createElement();
083
084    @Override
085    public void setHref(String href) {
086        getElement().setAttribute("href", href);
087    }
088
089    @Override
090    public String getHref() {
091        return getElement().getAttribute("href");
092    }
093
094    @Override
095    public void setTarget(String target) {
096        getElement().setAttribute("target", target);
097    }
098
099    @Override
100    public String getTarget() {
101        return getElement().getAttribute("target");
102    }
103
104    @Override
105    public void setActivates(String activates) {
106        removeStyleName(getActivates() + " " + CssName.DROPDOWN_BUTTON);
107        getActivatesMixin().setActivates(activates);
108        addStyleName(activates + " " + CssName.DROPDOWN_BUTTON);
109    }
110
111    @Override
112    public String getActivates() {
113        return getActivatesMixin().getActivates();
114    }
115
116    @Override
117    public void setType(ButtonType type) {
118        getTypeMixin().setType(type);
119    }
120
121    @Override
122    public ButtonType getType() {
123        return getTypeMixin().getType();
124    }
125
126    /**
127     * Set the buttons size.
128     */
129    public void setSize(ButtonSize size) {
130        if (this.size != null) {
131            removeStyleName(this.size.getCssName());
132        }
133        this.size = size;
134
135        if (size != null) {
136            addStyleName(size.getCssName());
137        }
138    }
139
140    /**
141     * Get the buttons size.
142     */
143    public ButtonSize getSize() {
144        return size;
145    }
146
147    /**
148     * Get the buttons span text.
149     */
150    public String getText() {
151        return span.getText();
152    }
153
154    /**
155     * Set the buttons span text.
156     */
157    public void setText(String text) {
158        span.setText(text);
159
160        if (!span.isAttached()) {
161            add(span);
162        }
163    }
164
165    /**
166     * Set the target history token for the widget. Note, that you should use either
167     * {@link #setTargetHistoryToken(String)} or {@link #setHref(String)}, but not both as
168     * {@link #setHref(String)} resets the target history token.
169     *
170     * @param targetHistoryToken String target history token of the widget
171     */
172    @Override
173    public void setTargetHistoryToken(final String targetHistoryToken) {
174        this.targetHistoryToken = targetHistoryToken;
175        if (targetHistoryToken != null) {
176            setHref("#" + History.encodeHistoryToken(targetHistoryToken));
177        }
178    }
179
180    /**
181     * Get the target history token for the widget. May return {@code null} if no
182     * history token has been set or if it has been reset by {@link #setHref(String)}.
183     *
184     * @return String the widget's target history token.
185     */
186    @Override
187    public String getTargetHistoryToken() {
188        return targetHistoryToken;
189    }
190
191    public Span getSpan() {
192        return span;
193    }
194
195    protected ActivatesMixin<AbstractButton> getActivatesMixin() {
196        if (activatesMixin == null) {
197            activatesMixin = new ActivatesMixin<>(this);
198        }
199        return activatesMixin;
200    }
201
202    protected CssTypeMixin<ButtonType, AbstractButton> getTypeMixin() {
203        if (typeMixin == null) {
204            typeMixin = new CssTypeMixin<>(this);
205        }
206        return typeMixin;
207    }
208}