blob: 4f72ebc82859541fc009471bb1bf0d56e2377b76 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.user.client.ui;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.FieldSetElement;
import com.google.gwt.dom.client.LegendElement;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.annotations.IsSafeHtml;
import com.google.gwt.safehtml.shared.annotations.SuppressIsSafeHtmlCastCheck;
import java.util.Iterator;
/**
* A panel that wraps its contents in a border with a caption that appears in
* the upper left corner of the border. This is an implementation of the
* fieldset HTML element.
*/
public class CaptionPanel extends Composite implements HasWidgets.ForIsWidget {
/**
* Implementation class without browser-specific hacks.
*/
public static class CaptionPanelImpl {
public void setCaption(
FieldSetElement fieldset, Element legend, SafeHtml caption) {
setCaption(fieldset, legend, caption.asString(), true);
}
public void setCaption(
FieldSetElement fieldset, Element legend, @IsSafeHtml String caption, boolean asHTML) {
// TODO(bruce): rewrite to be inlinable
assert (caption != null);
if (asHTML) {
legend.setInnerHTML(caption);
} else {
legend.setInnerText(caption);
}
if (!"".equals(caption)) {
// This is formulated to become an append (if there's no widget), an
// insertion at index 0 (if there is a widget but no legend already), or
// a no-op (if the legend is already in place).
fieldset.insertBefore(legend, fieldset.getFirstChild());
} else if (legend.getParentNode() != null) {
// We remove the legend from the DOM because leaving it in with an empty
// string renders as an ugly gap in the top border on some browsers.
fieldset.removeChild(legend);
}
}
}
/**
* Implementation class that handles Mozilla rendering issues.
*/
public static class CaptionPanelImplMozilla extends CaptionPanelImpl {
@Override
public void setCaption(
final FieldSetElement fieldset, Element legend, SafeHtml caption) {
setCaption(fieldset, legend, caption.asString(), true);
}
@Override
public void setCaption(
final FieldSetElement fieldset,
Element legend,
@IsSafeHtml String caption,
boolean asHTML) {
fieldset.getStyle().setProperty("display", "none");
super.setCaption(fieldset, legend, caption, asHTML);
fieldset.getStyle().setProperty("display", "");
}
}
/**
* Implementation class that handles Safari rendering issues.
*/
public static class CaptionPanelImplSafari extends CaptionPanelImpl {
@Override
public void setCaption(
final FieldSetElement fieldset, Element legend, SafeHtml caption) {
setCaption(fieldset, legend, caption.asString(), true);
}
@Override
public void setCaption(
final FieldSetElement fieldset,
Element legend,
@IsSafeHtml String caption,
boolean asHTML) {
fieldset.getStyle().setProperty("visibility", "hidden");
super.setCaption(fieldset, legend, caption, asHTML);
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
public void execute() {
fieldset.getStyle().setProperty("visibility", "");
}
});
}
}
/**
* The implementation instance.
*/
private static CaptionPanelImpl impl = (CaptionPanelImpl) GWT.create(CaptionPanelImpl.class);
/**
* The legend element used as the caption.
*/
private LegendElement legend;
/**
* Constructs a CaptionPanel with an empty caption.
*/
public CaptionPanel() {
this("", false);
}
/**
* Constructs a CaptionPanel with specified caption text.
*
* @param caption the text of the caption
*/
public CaptionPanel(SafeHtml caption) {
this(caption.asString(), true);
}
/**
* Constructs a CaptionPanel with specified caption text.
*
* @param captionText the text of the caption, which is automatically escaped
*/
@SuppressIsSafeHtmlCastCheck
public CaptionPanel(String captionText) {
this(captionText, false);
}
/**
* Constructs a CaptionPanel having the specified caption.
*
* @param caption the caption to display
* @param asHTML if <code>true</code>, the <code>caption</code> param is
* interpreted as HTML; otherwise, <code>caption</code> is
* treated as text and automatically escaped
*/
public CaptionPanel(@IsSafeHtml String caption, boolean asHTML) {
FieldSetElement fieldSet = Document.get().createFieldSetElement();
initWidget(new SimplePanel(fieldSet));
legend = Document.get().createLegendElement();
fieldSet.appendChild(legend);
if (asHTML) {
setCaptionHTML(caption);
} else {
setCaptionText(caption);
}
}
public void add(Widget w) {
((SimplePanel) getWidget()).add(w);
}
/**
* Overloaded version for IsWidget.
*
* @see #add(Widget)
*/
public void add(IsWidget w) {
this.add(asWidgetOrNull(w));
}
/**
* Removes the content widget.
*/
public void clear() {
((SimplePanel) getWidget()).clear();
}
/**
* Returns the caption as HTML; note that if the caption was previously set
* using {@link #setCaptionText(String)}, the return value is undefined.
*/
public String getCaptionHTML() {
String html = legend.getInnerHTML();
assert (html != null);
return html;
}
/**
* Returns the caption as text; note that if the caption was previously set
* using {@link #setCaptionHTML(String)}, the return value is undefined.
*/
public String getCaptionText() {
String text = legend.getInnerText();
assert (text != null);
return text;
}
/**
* Accesses the content widget, if present.
*
* @return the content widget specified previously in
* {@link #setContentWidget(Widget)}
*/
public Widget getContentWidget() {
return ((SimplePanel) getWidget()).getWidget();
}
/**
* Iterates over the singular content widget, if present.
*/
public Iterator<Widget> iterator() {
return ((SimplePanel) getWidget()).iterator();
}
/**
* Removes the specified widget, although in practice the specified widget
* must be the content widget.
*
* @param w the widget to remove; note that anything other than the Widget
* returned by {@link #getContentWidget()} will have no effect
*/
public boolean remove(Widget w) {
return ((SimplePanel) getWidget()).remove(w);
}
/**
* Overloaded version for IsWidget.
*
* @see #remove(Widget)
*/
public boolean remove(IsWidget w) {
return this.remove(asWidgetOrNull(w));
}
/**
* Sets the caption for the panel using an HTML fragment. Pass in empty string
* to remove the caption completely, leaving just the unadorned panel.
*
* @param html HTML for the new caption; must not be <code>null</code>
*/
public void setCaptionHTML(@IsSafeHtml String html) {
assert (html != null);
impl.setCaption(FieldSetElement.as(getElement()), legend, html, true);
}
/**
* Sets the caption for the panel using a SafeHtml string.
*
* @param html HTML for the new caption; must not be <code>null</code>
*/
public void setCaptionHTML(SafeHtml html) {
setCaptionHTML(html.asString());
}
/**
* Sets the caption for the panel using text that will be automatically
* escaped. Pass in empty string to remove the caption completely, leaving
* just the unadorned panel.
*
* @param text text for the new caption; must not be <code>null</code>
*/
@SuppressIsSafeHtmlCastCheck
public void setCaptionText(String text) {
assert (text != null);
impl.setCaption(FieldSetElement.as(getElement()), legend, text, false);
}
/**
* Sets or replaces the content widget within the CaptionPanel.
*
* @param w the content widget to be set
*/
public void setContentWidget(Widget w) {
((SimplePanel) getWidget()).setWidget(w);
}
}