001package gwt.material.design.client.ui;
002
003import gwt.material.design.client.base.AbstractButton;
004import gwt.material.design.client.base.HasProgress;
005import gwt.material.design.client.base.mixin.ProgressMixin;
006import gwt.material.design.client.constants.Display;
007import gwt.material.design.client.constants.ProgressType;
008import gwt.material.design.client.constants.WavesType;
009import gwt.material.design.client.ui.MaterialCollapsible.HasCollapsibleParent;
010
011import com.google.gwt.dom.client.Document;
012import com.google.gwt.dom.client.Element;
013import com.google.gwt.user.client.ui.HasWidgets;
014import com.google.gwt.user.client.ui.Widget;
015
016/*
017 * #%L
018 * GwtMaterial
019 * %%
020 * Copyright (C) 2015 GwtMaterialDesign
021 * %%
022 * Licensed under the Apache License, Version 2.0 (the "License");
023 * you may not use this file except in compliance with the License.
024 * You may obtain a copy of the License at
025 * 
026 *      http://www.apache.org/licenses/LICENSE-2.0
027 * 
028 * Unless required by applicable law or agreed to in writing, software
029 * distributed under the License is distributed on an "AS IS" BASIS,
030 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
031 * See the License for the specific language governing permissions and
032 * limitations under the License.
033 * #L%
034 */
035
036//@formatter:off
037
038/**
039 * Collapsible element to define every items
040 * @author kevzlou7979
041 * @author Ben Dol
042 * @see <a href="http://gwt-material-demo.herokuapp.com/#collapsibles">Material Collapsibles</a>
043 */
044//@formatter:on
045public class MaterialCollapsibleItem extends AbstractButton implements HasWidgets, HasCollapsibleParent, HasProgress {
046
047    private MaterialCollapsible parent;
048    private MaterialCollapsibleBody body;
049    private MaterialCollapsibleHeader header;
050
051    private final ProgressMixin<MaterialCollapsibleItem> progressMixin = new ProgressMixin<>(this);
052
053    /**
054     * Creates an empty collapsible item.
055     */
056    public MaterialCollapsibleItem() {
057        super();
058    }
059
060    @Override
061    protected Element createElement() {
062        return Document.get().createLIElement();
063    }
064
065    /**
066     * Adds MaterialCollapsible contents.
067     */
068    public MaterialCollapsibleItem(final Widget... widgets) {
069        this();
070        for(Widget w : widgets) {
071            add(w);
072        }
073    }
074
075    @Override
076    public void add(Widget child) {
077        if(child instanceof MaterialCollapsibleBody) {
078            body = (MaterialCollapsibleBody)child;
079        }
080        else if(child instanceof MaterialCollapsibleHeader) {
081            header = (MaterialCollapsibleHeader)child;
082        }
083        super.add(child);
084    }
085
086    @Override
087    public boolean remove(Widget w) {
088        if(w instanceof HasCollapsibleParent) {
089            ((HasCollapsibleParent)w).setParent(null);
090        }
091
092        if(w.equals(body)) {
093            body = null;
094        } else if(w.equals(header)) {
095            header = null;
096        }
097        return super.remove(w);
098    }
099
100    public void setParent(MaterialCollapsible parent) {
101        this.parent = parent;
102
103        for(Widget child : this) {
104            if(child instanceof HasCollapsibleParent) {
105                ((HasCollapsibleParent) child).setParent(parent);
106            }
107        }
108    }
109
110    @Override
111    public void setWaves(WavesType waves) {
112        super.setWaves(waves);
113
114        // Waves change to inline block
115        setDisplay(Display.BLOCK);
116    }
117
118    /**
119     * Expand the body panel.
120     */
121    public void expand() {
122        if(body != null) {
123            setActive(true);
124            body.setDisplay(Display.BLOCK);
125        }
126    }
127
128    public void collapse() {
129        if(body != null) {
130            setActive(false);
131            body.setDisplay(Display.NONE);
132        }
133    }
134
135    public void setActive(boolean active) {
136        removeStyleName("active");
137        if(active) {
138            if(parent != null) {
139                parent.clearActive();
140            }
141            addStyleName("active");
142
143            if(header != null) {
144                header.removeStyleName("active");
145                header.addStyleName("active");
146            }
147        }
148    }
149
150    @Override
151    public void showProgress(ProgressType type) {
152        progressMixin.showProgress(type);
153    }
154
155    @Override
156    public void setPercent(double percent) {
157        progressMixin.setPercent(percent);
158    }
159
160    @Override
161    public void hideProgress() {
162        progressMixin.hideProgress();
163    }
164}