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.addins.client.tree;
021
022import com.google.gwt.dom.client.Document;
023import com.google.gwt.dom.client.Element;
024import com.google.gwt.event.logical.shared.CloseEvent;
025import com.google.gwt.event.logical.shared.OpenEvent;
026import com.google.gwt.event.logical.shared.SelectionEvent;
027import com.google.gwt.resources.client.ImageResource;
028import com.google.gwt.user.client.ui.Widget;
029import gwt.material.design.addins.client.base.constants.AddinsCssName;
030import gwt.material.design.addins.client.tree.base.HasTreeItems;
031import gwt.material.design.client.base.AbstractIconButton;
032import gwt.material.design.client.base.HasImage;
033import gwt.material.design.client.base.MaterialWidget;
034import gwt.material.design.client.constants.Color;
035import gwt.material.design.client.constants.IconType;
036import gwt.material.design.client.ui.MaterialImage;
037import gwt.material.design.client.ui.html.Span;
038
039import java.util.ArrayList;
040import java.util.List;
041
042//@formatter:off
043
044/**
045 * MaterialTreeItem is a component that is needed by {@link MaterialTree}
046 * <p>
047 * <h3>XML Namespace Declaration</h3>
048 * <pre>
049 * {@code
050 * xmlns:ma='urn:import:gwt.material.design.addins.client'
051 * }
052 * </pre>
053 * <p>
054 * <h3>UiBinder Usage:</h3>
055 * <pre>
056 * {@code
057 * &lt;-- Icon support -->
058 * <ma:tree.MaterialTreeItem text="Folder 1" iconType="FOLDER" />
059 * &lt;-- Image support -->
060 * <ma:tree.MaterialTreeItem text="Item 2.1" resource="{res.batman.png}" />
061 * }
062 * </pre>
063 *
064 * @author kevzlou7979
065 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#treeview">Tree View</a>
066 */
067// @formatter:on
068public class MaterialTreeItem extends AbstractIconButton implements HasImage, HasTreeItems {
069
070    private boolean hide = true;
071    private MaterialWidget divHeader = new MaterialWidget(Document.get().createDivElement());
072    private Span span;
073    private MaterialImage image;
074    private MaterialTree tree;
075    private Object object;
076
077    public MaterialTreeItem() {
078        super(AddinsCssName.TREE_ITEM);
079        divHeader.setStyleName(AddinsCssName.TREE_HEADER);
080        add(divHeader);
081    }
082
083    public MaterialTreeItem(String text) {
084        this();
085        setText(text);
086    }
087
088    public MaterialTreeItem(String text, IconType icon) {
089        this(text);
090        setIconType(icon);
091    }
092
093    public MaterialTreeItem(String text, ImageResource resource) {
094        this(text);
095        setResource(resource);
096    }
097
098    public MaterialTreeItem(String text, IconType icon, Color iconColor) {
099        this(text, icon);
100        setIconColor(iconColor);
101    }
102
103    @Override
104    protected Element createElement() {
105        return Document.get().createDivElement();
106    }
107
108    @Override
109    public void setText(String text) {
110        if (span == null) {
111            span = new Span();
112        }
113        span.setText(text);
114    }
115
116    @Override
117    public String getText() {
118        return span.getText();
119    }
120
121    @Override
122    protected void onLoad() {
123        super.onLoad();
124
125        if(image != null) {
126            divHeader.add(image);
127        }
128
129        if (getIcon() != null) {
130            divHeader.add(getIcon());
131        }
132
133        if (span != null) {
134            divHeader.add(span);
135        }
136
137        registerHandler(divHeader.addClickHandler(event -> select()));
138    }
139
140    @Override
141    public void setUrl(String url) {
142        if (image == null) {
143            image = new MaterialImage();
144        }
145        image.setUrl(url);
146    }
147
148    @Override
149    public String getUrl() {
150        return image.getUrl();
151    }
152
153    @Override
154    public void setResource(ImageResource resource) {
155        if (image == null) {
156            image = new MaterialImage();
157        }
158        image.setResource(resource);
159    }
160
161    @Override
162    public ImageResource getResource() {
163        return image.getResource();
164    }
165
166    public MaterialWidget getDivHeader() {
167        return divHeader;
168    }
169
170    public Span getSpan() {
171        return span;
172    }
173
174    public MaterialImage getImage() {
175        return image;
176    }
177
178    public void select() {
179        // Fire selection event
180        SelectionEvent.fire(getTree(), this);
181
182        List<MaterialTreeItem> treeItems = getTreeItems();
183        if (!treeItems.isEmpty()) {
184            for (MaterialTreeItem treeItem : treeItems) {
185                if (hide) {
186                    treeItem.setVisible(false);
187                } else {
188                    treeItem.setVisible(true);
189                }
190            }
191            // Firing of events based on the status of the tree item
192            if (hide) {
193                CloseEvent.fire(getTree(), this);
194                hide = false;
195            } else {
196                OpenEvent.fire(getTree(), this);
197                hide = true;
198            }
199        }
200    }
201
202    public List<MaterialTreeItem> getTreeItems() {
203        List<MaterialTreeItem> treeItems = new ArrayList<>();
204        for (Widget child : getChildren()) {
205            if (child instanceof MaterialTreeItem) {
206                treeItems.add((MaterialTreeItem) child);
207            }
208        }
209        return treeItems;
210    }
211
212    @Override
213    public MaterialTree getTree() {
214        return tree;
215    }
216
217    protected void setTree(MaterialTree tree) {
218        this.tree = tree;
219
220        for (Widget child : getChildren()) {
221            if (child instanceof MaterialTreeItem) {
222                ((MaterialTreeItem) child).setTree(tree);
223            }
224        }
225    }
226
227    @Override
228    public void setObject(Object object) {
229        this.object = object;
230    }
231
232    @Override
233    public Object getObject() {
234        return object;
235    }
236
237    @Override
238    public void expand() {
239        for (MaterialTreeItem item : getTreeItems()) {
240            item.setVisible(true);
241        }
242    }
243
244    @Override
245    public void collapse() {
246        for (MaterialTreeItem item : getTreeItems()) {
247            item.setVisible(false);
248        }
249    }
250
251    @Override
252    public void setHide(boolean hide) {
253        this.hide = hide;
254    }
255
256    @Override
257    public boolean isHide() {
258        return hide;
259    }
260
261    @Override
262    protected void add(Widget child, com.google.gwt.user.client.Element container) {
263        super.add(child, container);
264        if (child instanceof MaterialTreeItem) {
265            ((MaterialTreeItem) child).setTree(getTree());
266        }
267    }
268
269    @Override
270    protected void insert(Widget child, com.google.gwt.user.client.Element container, int beforeIndex, boolean domInsert) {
271        super.insert(child, container, beforeIndex, domInsert);
272        if (child instanceof MaterialTreeItem) {
273            ((MaterialTreeItem) child).setTree(getTree());
274        }
275    }
276
277    @Override
278    public void addItem(MaterialTreeItem item) {
279        add(item);
280        expand();
281    }
282
283    @Override
284    public void removeItem(MaterialTreeItem item) {
285        remove(item);
286    }
287
288    @Override
289    public void removeItem(int index) {
290        remove(getWidget(index));
291    }
292
293    @Override
294    public void insertItem(MaterialTreeItem item, int index) {
295        insert(item, index);
296        expand();
297    }
298
299    @Override
300    public void removeFromTree() {
301        removeFromParent();
302    }
303
304    @Override
305    public void removeFromParent() {
306        tree = null;
307        super.removeFromParent();
308    }
309}