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.mixin;
021
022import com.google.gwt.event.shared.HandlerRegistration;
023import com.google.gwt.user.client.ui.HasEnabled;
024import com.google.gwt.user.client.ui.UIObject;
025import com.google.gwt.user.client.ui.Widget;
026import gwt.material.design.client.base.MaterialWidget;
027import gwt.material.design.client.constants.CssName;
028
029/**
030 * @author Ben Dol
031 * @author kevzlou7979
032 */
033public class EnabledMixin<T extends Widget & HasEnabled> extends AbstractMixin<T> implements HasEnabled {
034    private static final String DISABLED = "disabled";
035
036    private HandlerRegistration handler;
037
038    private boolean propagateToChildren;
039
040    public EnabledMixin(final T widget) {
041        super(widget);
042    }
043
044    @Override
045    public void setUiObject(T uiObject) {
046        super.setUiObject(uiObject);
047
048        // Clean up previous handler
049        if (handler != null) {
050            handler.removeHandler();
051            handler = null;
052        }
053    }
054
055    @Override
056    public boolean isEnabled() {
057        return !uiObject.getElement().hasAttribute("disabled");
058    }
059
060    @Override
061    public void setEnabled(boolean enabled) {
062        if (!uiObject.isAttached() && handler == null) {
063            handler = uiObject.addAttachHandler(event -> {
064                if (event.isAttached()) {
065                    applyEnabled(enabled, uiObject);
066                } else if (handler != null) {
067                    handler.removeHandler();
068                    handler = null;
069                }
070            });
071        } else {
072            applyEnabled(enabled, uiObject);
073        }
074    }
075
076    public void setEnabled(MaterialWidget widget, boolean enabled) {
077        setEnabled(enabled);
078
079        if(isPropagateToChildren()) {
080            for (Widget child : widget.getChildren()) {
081                if (child instanceof MaterialWidget) {
082                    ((MaterialWidget) child).setEnabled(enabled);
083                } else if (child instanceof HasEnabled) {
084                    ((HasEnabled) child).setEnabled(enabled);
085                }
086            }
087        }
088    }
089
090    private void applyEnabled(boolean enabled, UIObject obj) {
091        if (enabled) {
092            obj.removeStyleName(CssName.DISABLED);
093            obj.getElement().removeAttribute(DISABLED);
094        } else {
095            obj.addStyleName(CssName.DISABLED);
096            obj.getElement().setAttribute(DISABLED, "");
097        }
098
099        updateWaves(enabled, obj);
100    }
101
102    public void updateWaves(boolean enabled, UIObject obj) {
103        if (obj instanceof MaterialWidget) {
104            MaterialWidget widget = (MaterialWidget) obj;
105            if (enabled) {
106                if (widget.getWaves() != null) {
107                    widget.getElement().addClassName(CssName.WAVES_EFFECT);
108                }
109            } else {
110                widget.getElement().removeClassName(CssName.WAVES_EFFECT);
111            }
112        }
113    }
114
115    public boolean isPropagateToChildren() {
116        return propagateToChildren;
117    }
118
119    public void setPropagateToChildren(boolean propagateToChildren) {
120        this.propagateToChildren = propagateToChildren;
121    }
122}