import com.google.gwt.user.client.ui.HTML;
import com.vaadin.terminal.gwt.client.ui.Icon;
import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
+import com.vaadin.terminal.gwt.client.ui.VTabsheetBasePaintable;
public class VCaption extends HTML {
private static final String CLASSNAME_CLEAR = CLASSNAME + "-clearelem";
+ private enum InsertPosition {
+ ICON, CAPTION, REQUIRED, ERROR
+ }
+
/**
* Creates a caption that is not linked to a {@link VPaintableWidget}.
*
/**
* Updates the caption from UIDL.
*
+ * This method may only be called when the caption has an owner - otherwise,
+ * use {@link #updateCaptionWithoutOwner(UIDL, String, boolean, boolean)}.
+ *
* @param uidl
* @return true if the position where the caption should be placed has
* changed
// moves it above.
placedAfterComponent = true;
- // TODO otherwise, the user should also call updateCaptionWithoutOwner()
- if (null != owner) {
- String style = CLASSNAME;
- if (owner.getState().hasStyles()) {
- final String[] styles = owner.getState().getStyle().split(" ");
- for (int i = 0; i < styles.length; i++) {
- style += " " + CLASSNAME + "-" + styles[i];
- }
+ String style = CLASSNAME;
+ if (owner.getState().hasStyles()) {
+ final String[] styles = owner.getState().getStyle().split(" ");
+ for (int i = 0; i < styles.length; i++) {
+ style += " " + CLASSNAME + "-" + styles[i];
}
- if (owner.getState().isDisabled()) {
- style += " " + ApplicationConnection.DISABLED_CLASSNAME;
- }
- setStyleName(style);
}
+ if (owner.getState().isDisabled()) {
+ style += " " + ApplicationConnection.DISABLED_CLASSNAME;
+ }
+ setStyleName(style);
boolean hasIcon = uidl
.hasAttribute(VAbstractPaintableWidget.ATTRIBUTE_ICON);
- boolean hasText = uidl
- .hasAttribute(VAbstractPaintableWidget.ATTRIBUTE_CAPTION);
boolean showRequired = uidl
.getBooleanAttribute(VAbstractPaintableWidget.ATTRIBUTE_REQUIRED);
boolean showError = uidl
icon.setWidth("0");
icon.setHeight("0");
- DOM.insertChild(
- getElement(),
- icon.getElement(),
- getInsertPosition(VAbstractPaintableWidget.ATTRIBUTE_ICON));
+ DOM.insertChild(getElement(), icon.getElement(),
+ getInsertPosition(InsertPosition.ICON));
}
// Icon forces the caption to be above the component
placedAfterComponent = false;
icon = null;
}
- if (hasText) {
+ if (owner.getState().getCaption() != null) {
// A caption text should be shown if the attribute is set
// If the caption is null the ATTRIBUTE_CAPTION should not be set to
// avoid ending up here.
captionText = DOM.createDiv();
captionText.setClassName("v-captiontext");
- DOM.insertChild(
- getElement(),
- captionText,
- getInsertPosition(VAbstractPaintableWidget.ATTRIBUTE_CAPTION));
+ DOM.insertChild(getElement(), captionText,
+ getInsertPosition(InsertPosition.CAPTION));
}
// Update caption text
- String c = uidl
- .getStringAttribute(VAbstractPaintableWidget.ATTRIBUTE_CAPTION);
+ String c = owner.getState().getCaption();
// A text forces the caption to be above the component.
placedAfterComponent = false;
if (c == null || c.trim().equals("")) {
captionText = null;
}
- if (null != owner) {
- if (owner.getState().hasDescription() && captionText != null) {
- addStyleDependentName("hasdescription");
- } else {
- removeStyleDependentName("hasdescription");
- }
+ if (owner.getState().hasDescription() && captionText != null) {
+ addStyleDependentName("hasdescription");
+ } else {
+ removeStyleDependentName("hasdescription");
}
if (showRequired) {
.setClassName("v-required-field-indicator");
DOM.setInnerText(requiredFieldIndicator, "*");
- DOM.insertChild(
- getElement(),
- requiredFieldIndicator,
- getInsertPosition(VAbstractPaintableWidget.ATTRIBUTE_REQUIRED));
+ DOM.insertChild(getElement(), requiredFieldIndicator,
+ getInsertPosition(InsertPosition.REQUIRED));
}
} else if (requiredFieldIndicator != null) {
// Remove existing
DOM.setElementProperty(errorIndicatorElement, "className",
"v-errorindicator");
- DOM.insertChild(
- getElement(),
- errorIndicatorElement,
- getInsertPosition(VAbstractPaintableWidget.ATTRIBUTE_ERROR));
+ DOM.insertChild(getElement(), errorIndicatorElement,
+ getInsertPosition(InsertPosition.ERROR));
}
} else if (errorIndicatorElement != null) {
// Remove existing
return (wasPlacedAfterComponent != placedAfterComponent);
}
- private int getInsertPosition(String element) {
+ private int getInsertPosition(InsertPosition element) {
int pos = 0;
- if (element.equals(VAbstractPaintableWidget.ATTRIBUTE_ICON)) {
+ if (InsertPosition.ICON.equals(element)) {
return pos;
}
if (icon != null) {
pos++;
}
- if (element.equals(VAbstractPaintableWidget.ATTRIBUTE_CAPTION)) {
+ if (InsertPosition.CAPTION.equals(element)) {
return pos;
}
pos++;
}
- if (element.equals(VAbstractPaintableWidget.ATTRIBUTE_REQUIRED)) {
+ if (InsertPosition.REQUIRED.equals(element)) {
return pos;
}
if (requiredFieldIndicator != null) {
pos++;
}
- // if (element.equals(ATTRIBUTE_ERROR)) {
+ // if (InsertPosition.ERROR.equals(element)) {
// }
return pos;
}
@Deprecated
- public void updateCaptionWithoutOwner(boolean disabled,
- boolean hasDescription) {
+ public boolean updateCaptionWithoutOwner(UIDL uidl, String caption,
+ boolean disabled, boolean hasDescription) {
// TODO temporary method, needed because some tabsheet and accordion
- // internal captions do not have an owner or shared state.
- // Remaining such cases do not use the "style" attribute - see
- // Tabsheet.paintContent().
+ // internal captions do not have an owner or shared state. Simplified to
+ // only support those cases
+ setVisible(!uidl.getBooleanAttribute("invisible"));
+
+ boolean wasPlacedAfterComponent = placedAfterComponent;
+
+ // Caption is placed after component unless there is some part which
+ // moves it above.
+ placedAfterComponent = true;
+
String style = VCaption.CLASSNAME;
if (disabled) {
style += " " + ApplicationConnection.DISABLED_CLASSNAME;
removeStyleDependentName("hasdescription");
}
}
+ boolean hasIcon = uidl
+ .hasAttribute(VAbstractPaintableWidget.ATTRIBUTE_ICON);
+ boolean showError = uidl
+ .hasAttribute(VAbstractPaintableWidget.ATTRIBUTE_ERROR)
+ && !uidl.getBooleanAttribute(VAbstractPaintableWidget.ATTRIBUTE_HIDEERRORS);
+
+ if (hasIcon) {
+ if (icon == null) {
+ icon = new Icon(client);
+ icon.setWidth("0");
+ icon.setHeight("0");
+
+ DOM.insertChild(getElement(), icon.getElement(),
+ getInsertPosition(InsertPosition.ICON));
+ }
+ // Icon forces the caption to be above the component
+ placedAfterComponent = false;
+
+ icon.setUri(uidl
+ .getStringAttribute(VAbstractPaintableWidget.ATTRIBUTE_ICON));
+
+ } else if (icon != null) {
+ // Remove existing
+ DOM.removeChild(getElement(), icon.getElement());
+ icon = null;
+ }
+
+ if (caption != null) {
+ // A caption text should be shown if the attribute is set
+ // If the caption is null the ATTRIBUTE_CAPTION should not be set to
+ // avoid ending up here.
+
+ if (captionText == null) {
+ captionText = DOM.createDiv();
+ captionText.setClassName("v-captiontext");
+
+ DOM.insertChild(getElement(), captionText,
+ getInsertPosition(InsertPosition.CAPTION));
+ }
+
+ // Update caption text
+ // A text forces the caption to be above the component.
+ placedAfterComponent = false;
+ if (caption.trim().equals("")) {
+ // This is required to ensure that the caption uses space in all
+ // browsers when it is set to the empty string. If there is an
+ // icon, error indicator or required indicator they will ensure
+ // that space is reserved.
+ if (!hasIcon && !showError) {
+ captionText.setInnerHTML(" ");
+ }
+ } else {
+ DOM.setInnerText(captionText, caption);
+ }
+
+ } else if (captionText != null) {
+ // Remove existing
+ DOM.removeChild(getElement(), captionText);
+ captionText = null;
+ }
+
+ if (showError) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = DOM.createDiv();
+ DOM.setInnerHTML(errorIndicatorElement, " ");
+ DOM.setElementProperty(errorIndicatorElement, "className",
+ "v-errorindicator");
+
+ DOM.insertChild(getElement(), errorIndicatorElement,
+ getInsertPosition(InsertPosition.ERROR));
+ }
+ } else if (errorIndicatorElement != null) {
+ // Remove existing
+ getElement().removeChild(errorIndicatorElement);
+ errorIndicatorElement = null;
+ }
+
+ if (clearElement == null) {
+ clearElement = DOM.createDiv();
+ clearElement.setClassName(CLASSNAME_CLEAR);
+ getElement().appendChild(clearElement);
+ }
+
+ return (wasPlacedAfterComponent != placedAfterComponent);
}
@Override
}
}
- public static boolean isNeeded(UIDL uidl) {
- if (uidl.getStringAttribute(VAbstractPaintableWidget.ATTRIBUTE_CAPTION) != null) {
- return true;
+ public static boolean isNeeded(UIDL uidl, ComponentState state) {
+ if (state != null) {
+ if (state.getCaption() != null) {
+ return true;
+ }
+ } else {
+ // TODO fallback for cases where the caption has no owner (Tabsheet,
+ // Accordion)
+ if (uidl.getStringAttribute(VTabsheetBasePaintable.ATTRIBUTE_TAB_CAPTION) != null) {
+ return true;
+ }
}
if (uidl.hasAttribute(VAbstractPaintableWidget.ATTRIBUTE_ERROR)) {
return true;