package org.gwtoolbox.widget.client.panel.fieldset;
import com.google.gwt.dom.client.FieldSetElement;
import com.google.gwt.dom.client.LegendElement;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.Widget;
import org.gwtoolbox.commons.collections.client.ArrayIterator;
import org.gwtoolbox.commons.collections.client.SingleElementIterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import static org.gwtoolbox.widget.client.panel.LayoutUtils.preventBoxStyles;
/**
* @author Uri Boness
*/
public class FieldSet extends Panel implements RequiresResize {
private String label;
private boolean collapsable;
private boolean collapsed;
private Collapser collapser;
private Widget widget;
private LegendElement legendElement;
private Element labelElement;
private Element collapseButtonElement;
private Element widgetContainerElement;
private CollapserListener collapserListener = new CollapserListener();
private List<Listener> listeners = new ArrayList<Listener>();
public FieldSet(String label) {
this(label, false, null);
}
public FieldSet(String label, Widget widget) {
this(label, false, widget);
}
public FieldSet(String label, boolean collapsible, Widget widget) {
FieldSetElement fieldSetElement = FieldSetElement.as(DOM.createFieldSet());
setElement(fieldSetElement);
legendElement = LegendElement.as(DOM.createLegend());
legendElement.setClassName("Legend");
fieldSetElement.appendChild(legendElement);
setCollapser(new DefaultCollapser());
labelElement = DOM.createSpan();
labelElement.setClassName("Label");
legendElement.appendChild(labelElement);
widgetContainerElement = preventBoxStyles(DOM.createDiv());
fieldSetElement.appendChild(widgetContainerElement);
setLabel(label);
setCollapsable(collapsible);
if (widget != null) {
setWidget(widget);
}
setCollapsed(false);
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
labelElement.setInnerHTML(label);
}
public boolean isCollapsable() {
return collapsable;
}
public void setCollapsable(boolean collapsable) {
setVisible(collapseButtonElement, collapsable);
this.collapsable = collapsable;
if (!isCollapsable()) {
setCollapsed(false);
}
}
public boolean isCollapsed() {
return collapsed;
}
public void setCollapsed(boolean collapsed) {
if (!isCollapsable()) {
return;
}
this.collapsed = collapsed;
String styleName = collapsed ? "FieldSet-collapsed" : "FieldSet";
setStyleName(styleName);
setVisible(widgetContainerElement, !collapsed);
fireCollapseEvent(collapsed);
}
public void onResize() {
if (widget instanceof RequiresResize) {
((RequiresResize) widget).onResize();
}
}
public void add(Widget widget) {
if (this.widget != null) {
throw new IllegalStateException("Can only add one widget to the FitPanel");
}
setWidget(widget);
}
public void setWidget(Widget child) {
assert child != null;
if (widget == child) {
return;
}
if (widget != null) {
// Orphan old.
orphan(widget);
// Physical detach old.
DOM.removeChild(widgetContainerElement, widget.getElement());
}
widget = child;
DOM.appendChild(widgetContainerElement, widget.getElement());
adopt(widget);
}
public boolean remove(Widget child) {
if (child != widget) {
return false;
}
orphan(child);
DOM.removeChild(widgetContainerElement, child.getElement());
widget = null;
return false;
}
public Iterator<Widget> iterator() {
return widget != null ?
new ArrayIterator<Widget>(widget, collapser.getWidget()) :
new SingleElementIterator<Widget>(collapser.getWidget());
}
public void setCollapser(Collapser collapser) {
if (this.collapser != null) {
this.collapser.removeListener(collapserListener);
orphan(this.collapser.getWidget());
}
this.collapser = collapser;
collapser.addListener(collapserListener);
Widget collapserWidget = collapser.getWidget();
if (collapseButtonElement == null) {
collapseButtonElement = collapserWidget.getElement();
legendElement.appendChild(collapseButtonElement);
} else {
legendElement.replaceChild(collapserWidget.getElement(), collapseButtonElement);
}
adopt(collapserWidget);
collapser.setCollapse(isCollapsed(), false);
}
public void addListener(Listener listener) {
listeners.add(listener);
}
public void removeListener(Listener listener) {
listeners.remove(listener);
}
//================================================ Helper Methods ==================================================
private void fireCollapseEvent(boolean collapse) {
for (Listener listener : listeners) {
listener.handleCollapse(collapse);
}
}
//================================================= Inner Classes ==================================================
public interface Listener {
void handleCollapse(boolean collapse);
}
private class CollapserListener implements Collapser.Listener {
public void stateChanged(boolean collapse) {
setCollapsed(collapse);
}
}
}