Widget), VPaintableWidget (paintable connected to a widget).
private HashMap<String, String> unknownComponents;
- private Class<? extends Paintable>[] classes = new Class[1024];
+ private Class<? extends VPaintableWidget>[] classes = new Class[1024];
private String windowId;
return useDebugIdInDom;
}
- public Class<? extends Paintable> getWidgetClassByEncodedTag(String tag) {
+ public Class<? extends VPaintableWidget> getWidgetClassByEncodedTag(String tag) {
try {
int parseInt = Integer.parseInt(tag);
return classes[parseInt];
public void run() {
pending = false;
if (!isBusy()) {
- Class<? extends Paintable> nextType = getNextType();
+ Class<? extends VPaintableWidget> nextType = getNextType();
if (nextType == null) {
// ensured that all widgets are loaded
deferredWidgetLoader = null;
}
}
- private Class<? extends Paintable> getNextType() {
- Class<? extends Paintable>[] deferredLoadedWidgets = widgetSet
+ private Class<? extends VPaintableWidget> getNextType() {
+ Class<? extends VPaintableWidget>[] deferredLoadedWidgets = widgetSet
.getDeferredLoadedWidgets();
if (deferredLoadedWidgets.length <= nextWidgetIndex) {
return null;
*
* Client-side widgets receive updates from the corresponding server-side
* components as calls to
- * {@link Paintable#updateFromUIDL(UIDL, ApplicationConnection)} (not to be
- * confused with the server side interface {@link com.vaadin.terminal.Paintable}
- * ). Any client-side changes (typically resulting from user actions) are sent
- * back to the server as variable changes (see {@link #updateVariable()}).
+ * {@link VPaintableWidget#updateFromUIDL(UIDL, ApplicationConnection)} (not to
+ * be confused with the server side interface
+ * {@link com.vaadin.terminal.Paintable} ). Any client-side changes (typically
+ * resulting from user actions) are sent back to the server as variable changes
+ * (see {@link #updateVariable()}).
*
* TODO document better
*
/** redirectTimer scheduling interval in seconds */
private int sessionExpirationInterval;
- private ArrayList<Paintable> relativeSizeChanges = new ArrayList<Paintable>();;
- private ArrayList<Paintable> componentCaptionSizeChanges = new ArrayList<Paintable>();;
+ private ArrayList<VPaintableWidget> relativeSizeChanges = new ArrayList<VPaintableWidget>();
+ private ArrayList<Widget> componentCaptionSizeChanges = new ArrayList<Widget>();
private Date requestStartTime;
private boolean validatingLayouts = false;
- private Set<Paintable> zeroWidthComponents = null;
+ private Set<VPaintableWidget> zeroWidthComponents = null;
- private Set<Paintable> zeroHeightComponents = null;
+ private Set<VPaintableWidget> zeroHeightComponents = null;
public ApplicationConnection() {
view = GWT.create(VView.class);
*
* @param paintable
*/
- void highlightComponent(Paintable paintable) {
+ void highlightComponent(VPaintableWidget paintable) {
String params = getRepaintAllParameters() + "&highlightComponent="
+ paintableMap.getPid(paintable);
makeUidlRequest("", params, false);
getPaintableMap().clear();
if (meta.containsKey("invalidLayouts")) {
validatingLayouts = true;
- zeroWidthComponents = new HashSet<Paintable>();
- zeroHeightComponents = new HashSet<Paintable>();
+ zeroWidthComponents = new HashSet<VPaintableWidget>();
+ zeroHeightComponents = new HashSet<VPaintableWidget>();
}
}
if (meta.containsKey("timedRedirect")) {
// Process changes
JsArray<ValueMap> changes = json.getJSValueMapArray("changes");
- ArrayList<Paintable> updatedWidgets = new ArrayList<Paintable>();
+ ArrayList<VPaintableWidget> updatedVPaintableWidgets = new ArrayList<VPaintableWidget>();
relativeSizeChanges.clear();
componentCaptionSizeChanges.clear();
final UIDL change = changes.get(i).cast();
final UIDL uidl = change.getChildUIDL(0);
// TODO optimize
- final Paintable paintable = paintableMap
+ final VPaintableWidget paintable = (VPaintableWidget) paintableMap
.getPaintable(uidl.getId());
if (paintable != null) {
paintable.updateFromUIDL(uidl,
ApplicationConnection.this);
-
- updatedWidgets.add(paintable);
+ updatedVPaintableWidgets.add(paintable);
} else {
if (!uidl.getTag().equals(
configuration.getEncodedWindowTag())) {
}
// Check which widgets' size has been updated
- Set<Paintable> sizeUpdatedWidgets = new HashSet<Paintable>();
+ Set<Widget> sizeUpdatedWidgets = new HashSet<Widget>();
- updatedWidgets.addAll(relativeSizeChanges);
+ updatedVPaintableWidgets.addAll(relativeSizeChanges);
sizeUpdatedWidgets.addAll(componentCaptionSizeChanges);
- for (Paintable paintable : updatedWidgets) {
- Widget widget = paintableMap.getWidget(paintable);
+ for (VPaintableWidget paintable : updatedVPaintableWidgets) {
+ Widget widget = paintable.getWidgetForPaintable();
Size oldSize = paintableMap.getOffsetSize(paintable);
Size newSize = new Size(widget.getOffsetWidth(),
widget.getOffsetHeight());
if (oldSize == null || !oldSize.equals(newSize)) {
- sizeUpdatedWidgets.add(paintable);
+ sizeUpdatedWidgets.add(widget);
paintableMap.setOffsetSize(paintable, newSize);
}
* true if the update is to be sent as soon as possible
*/
public void updateVariable(String paintableId, String variableName,
- Paintable newValue, boolean immediate) {
+ VPaintable newValue, boolean immediate) {
String pid = paintableMap.getPid(newValue);
addVariableToQueue(paintableId, variableName, pid, immediate, 'p');
}
buf.append(escapeVariableValue(key));
buf.append(VAR_ARRAYITEM_SEPARATOR);
if (transportType == 'p') {
- buf.append(paintableMap.getPid((Paintable) value));
+ buf.append(paintableMap.getPid((VPaintable) value));
} else {
buf.append(escapeVariableValue(String.valueOf(value)));
}
private char getTransportType(Object value) {
if (value instanceof String) {
return 's';
- } else if (value instanceof Paintable) {
+ } else if (value instanceof VPaintableWidget) {
return 'p';
} else if (value instanceof Boolean) {
return 'b';
// first char tells the type in array
buf.append(transportType);
if (transportType == 'p') {
- buf.append(paintableMap.getPid((Paintable) value));
+ buf.append(paintableMap.getPid((VPaintable) value));
} else {
buf.append(escapeVariableValue(String.valueOf(value)));
}
*/
public boolean updateComponent(Widget component, UIDL uidl,
boolean manageCaption) {
- Paintable paintable = paintableMap.getPaintable(component);
+ VPaintableWidget paintable = paintableMap.getPaintable(component);
String pid = paintableMap.getPid(paintable);
if (pid == null) {
// Must hide caption when component is hidden
final Container parent = Util.getLayout(component);
if (parent != null) {
- parent.updateCaption((Paintable) component, uidl);
+ parent.updateCaption(paintable, uidl);
}
}
return true;
}
- // Switch to correct implementation if needed
- if (!widgetSet.isCorrectImplementation(component, uidl, configuration)) {
- final Widget w = (Widget) widgetSet.createWidget(uidl,
- configuration);
- // deferred binding check TODO change isCorrectImplementation to use
- // stored detected class, making this innecessary
- if (w.getClass() != component.getClass()) {
- final Container parent = Util.getLayout(component);
- if (parent != null) {
- parent.replaceChildComponent(component, w);
- paintableMap.unregisterPaintable(paintable);
- paintableMap.registerPaintable(uidl.getId(), (Paintable) w);
- ((Paintable) w).updateFromUIDL(uidl, this);
- return true;
- }
- }
- }
-
boolean enabled = !uidl.getBooleanAttribute("disabled");
if (uidl.hasAttribute("tabindex") && component instanceof Focusable) {
((Focusable) component).setTabIndex(uidl
if (manageCaption) {
final Container parent = Util.getLayout(component);
if (parent != null) {
- parent.updateCaption((Paintable) component, uidl);
+ parent.updateCaption(paintable, uidl);
}
}
/*
return false;
}
- private void updateComponentSize(Paintable paintable, UIDL uidl) {
+ private void updateComponentSize(VPaintableWidget paintable, UIDL uidl) {
String w = uidl.hasAttribute("width") ? uidl
.getStringAttribute("width") : "";
* development. Published to JavaScript.
*/
public void forceLayout() {
- Set<Paintable> set = new HashSet<Paintable>();
- set.addAll(paintableMap.getPaintables());
+ Set<Widget> set = new HashSet<Widget>();
+ for (VPaintable paintable : paintableMap.getPaintables()) {
+ if (paintable instanceof VPaintableWidget) {
+ set.add(((VPaintableWidget) paintable).getWidgetForPaintable());
+ }
+ }
Util.componentSizeUpdated(set);
}
while (childWidgets.hasNext()) {
final Widget child = childWidgets.next();
- if (child instanceof Paintable) {
+ if (child instanceof VPaintableWidget) {
if (handleComponentRelativeSize(child)) {
/*
* @param child
* @return true if the child has a relative size
*/
- private boolean handleComponentRelativeSize(Paintable paintable) {
+ private boolean handleComponentRelativeSize(VPaintableWidget paintable) {
if (paintable == null) {
return false;
}
* UIDL to create Paintable from.
* @return Either existing or new Paintable corresponding to UIDL.
*/
- public Paintable getPaintable(UIDL uidl) {
+ public VPaintableWidget getPaintable(UIDL uidl) {
final String pid = uidl.getId();
if (!paintableMap.hasPaintable(pid)) {
// Create and register a new paintable if no old was found
- Paintable p = widgetSet.createWidget(uidl, configuration);
+ VPaintableWidget p = widgetSet.createWidget(uidl, configuration);
paintableMap.registerPaintable(pid, p);
}
- return paintableMap.getPaintable(pid);
+ return (VPaintableWidget) paintableMap.getPaintable(pid);
}
/**
* Updating TooltipInfo is done in updateComponent method.
*
*/
- public TooltipInfo getTooltipTitleInfo(Paintable titleOwner, Object key) {
+ public TooltipInfo getTooltipTitleInfo(VPaintableWidget titleOwner,
+ Object key) {
if (null == titleOwner) {
return null;
}
* @param event
* @param owner
*/
- public void handleTooltipEvent(Event event, Paintable owner) {
+ public void handleTooltipEvent(Event event, VPaintableWidget owner) {
tooltip.handleTooltipEvent(event, owner, null);
}
* the key for tooltip if this is "additional" tooltip, null for
* components "main tooltip"
*/
- public void handleTooltipEvent(Event event, Paintable owner, Object key) {
+ public void handleTooltipEvent(Event event, VPaintableWidget owner,
+ Object key) {
tooltip.handleTooltipEvent(event, owner, key);
}
}
};
- private PaintableMap paintableMap = new PaintableMap();
+ private VPaintableMap paintableMap = new VPaintableMap();
/**
* Components can call this function to run all layout functions. This is
* @param component
* the Paintable whose caption has changed
*/
- public void captionSizeUpdated(Paintable component) {
- componentCaptionSizeChanges.add(component);
+ public void captionSizeUpdated(Widget widget) {
+ componentCaptionSizeChanges.add(widget);
}
/**
* this method.
* <p>
* Component must also pipe events to
- * {@link #handleTooltipEvent(Event, Paintable, Object)} method.
+ * {@link #handleTooltipEvent(Event, VPaintableWidget, Object)} method.
* <p>
* This method can also be used to deregister tooltips by using null as
* tooltip
* @param key
* key assosiated with given tooltip. Can be any object. For
* example a related dom element. Same key must be given for
- * {@link #handleTooltipEvent(Event, Paintable, Object)} method.
+ * {@link #handleTooltipEvent(Event, VPaintableWidget, Object)}
+ * method.
*
* @param tooltip
* the TooltipInfo object containing details shown in tooltip,
* null if deregistering tooltip
*/
- public void registerTooltip(Paintable paintable, Object key,
+ public void registerTooltip(VPaintableWidget paintable, Object key,
TooltipInfo tooltip) {
paintableMap.registerTooltip(paintable, key, tooltip);
}
* @return true if at least one listener has been registered on server side
* for the event identified by eventIdentifier.
*/
- public boolean hasEventListeners(Paintable paintable, String eventIdentifier) {
+ public boolean hasEventListeners(VPaintable paintable,
+ String eventIdentifier) {
return paintableMap.hasEventListeners(paintable, eventIdentifier);
}
return uri;
}
- PaintableMap getPaintableMap() {
+ VPaintableMap getPaintableMap() {
return paintableMap;
}
@Deprecated
- public void unregisterPaintable(Paintable p) {
+ public void unregisterPaintable(VPaintable p) {
paintableMap.unregisterPaintable(p);
-
}
}
class ComponentDetail {
- // private Paintable paintable;
private TooltipInfo tooltipInfo = new TooltipInfo();
- // private String pid;
-
public ComponentDetail() {
}
- // public ComponentDetail(String pid, Paintable paintable) {
- // this.paintable = paintable;
- // this.pid = pid;
- // }
-
/**
* Returns a TooltipInfo assosiated with Component. If element is given,
* returns an additional TooltipInfo.
private Size offsetSize;
private HashMap<Object, TooltipInfo> additionalTooltips;
- // /**
- // * @return the pid
- // */
- // String getPid() {
- // return pid;
- // }
-
- // /**
- // * @return the component
- // */
- // Paintable getPaintable() {
- // return paintable;
- // }
-
/**
* @return the relativeSize
*/
Element e = targetElement;
while (true) {
- pid = PaintableMap.get(client).getPid(e);
+ pid = VPaintableMap.get(client).getPid(e);
if (pid != null) {
break;
}
// If we found a Paintable then we use that as reference. We should
// find the Paintable for all but very special cases (like
// overlays).
- w = (Widget) PaintableMap.get(client).getPaintable(pid);
+ w = ((VPaintableWidget) VPaintableMap.get(client).getPaintable(pid))
+ .getWidgetForPaintable();
/*
* Still if the Paintable contains a widget that implements
return null;
}
- String pid = PaintableMap.get(client).getPid(w.getElement());
+ String pid = VPaintableMap.get(client).getPid(w.getElement());
if (isStaticPid(pid)) {
return pid;
}
w = client.getView();
} else if (w == null) {
// Must be static pid (PID_S*)
- w = (Widget) PaintableMap.get(client).getPaintable(part);
+ w = ((VPaintableWidget) VPaintableMap.get(client).getPaintable(
+ part)).getWidgetForPaintable();
} else if (part.startsWith("domChild[")) {
// The target widget has been found and the rest identifies the
// element
public abstract void printLayoutProblems(ValueMap meta,
ApplicationConnection applicationConnection,
- Set<Paintable> zeroHeightComponents,
- Set<Paintable> zeroWidthComponents);
+ Set<VPaintableWidget> zeroHeightComponents,
+ Set<VPaintableWidget> zeroWidthComponents);
public abstract void setQuietMode(boolean quietDebugMode);
import com.google.gwt.user.client.ui.Widget;
-public interface Container extends Paintable {
+public interface Container extends VPaintableWidget {
/**
* Replace child of this layout with another component.
* @param uidl
* UIDL of the child component.
*/
- void updateCaption(Paintable component, UIDL uidl);
+ void updateCaption(VPaintableWidget component, UIDL uidl);
/**
* Called when a child components size has been updated in the rendering
* @return true if the size of the Container remains the same, false if the
* event need to be propagated to the Containers parent
*/
- boolean requestLayout(Set<Paintable> children);
+ boolean requestLayout(Set<Widget> children);
/**
* Returns the size currently allocated for the child component.
*/
public class EventHelper {
- public static HandlerRegistration updateFocusHandler(Paintable paintable,
+ public static HandlerRegistration updateFocusHandler(VPaintableWidget paintable,
ApplicationConnection client,
HandlerRegistration handlerRegistration) {
if (client.hasEventListeners(paintable, FOCUS)) {
return null;
}
- public static HandlerRegistration updateBlurHandler(Paintable paintable,
+ public static HandlerRegistration updateBlurHandler(VPaintableWidget paintable,
ApplicationConnection client,
HandlerRegistration handlerRegistration) {
if (client.hasEventListeners(paintable, BLUR)) {
public void printLayoutProblems(ValueMap meta,
ApplicationConnection applicationConnection,
- Set<Paintable> zeroHeightComponents,
- Set<Paintable> zeroWidthComponents) {
+ Set<VPaintableWidget> zeroHeightComponents,
+ Set<VPaintableWidget> zeroWidthComponents) {
}
public void log(Throwable e) {
+++ /dev/null
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client;
-
-/**
- * An interface used by client-side widgets or paintable parts to receive
- * updates from the corresponding server-side components in the form of
- * {@link UIDL}.
- *
- * Updates can be sent back to the server using the
- * {@link ApplicationConnection#updateVariable()} methods.
- */
-public interface Paintable {
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client);
-}
+++ /dev/null
-package com.vaadin.terminal.gwt.client;\r
-\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.Iterator;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import com.google.gwt.core.client.GWT;\r
-import com.google.gwt.user.client.Element;\r
-import com.google.gwt.user.client.ui.HasWidgets;\r
-import com.google.gwt.user.client.ui.Widget;\r
-import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;\r
-import com.vaadin.terminal.gwt.client.RenderInformation.Size;\r
-\r
-public class PaintableMap {\r
-\r
- private Map<String, Paintable> idToPaintable = new HashMap<String, Paintable>();\r
-\r
- @Deprecated\r
- private final ComponentDetailMap idToComponentDetail = ComponentDetailMap\r
- .create();\r
-\r
- private Set<String> unregistryBag = new HashSet<String>();\r
-\r
- /**\r
- * Returns a Paintable by its paintable id\r
- * \r
- * @param id\r
- * The Paintable id\r
- */\r
- public Paintable getPaintable(String pid) {\r
- return idToPaintable.get(pid);\r
- }\r
-\r
- /**\r
- * Returns a Paintable element by its root element\r
- * \r
- * @param element\r
- * Root element of the paintable\r
- */\r
- public Paintable getPaintable(Element element) {\r
- return getPaintable(getPid(element));\r
- }\r
-\r
- public static PaintableMap get(ApplicationConnection applicationConnection) {\r
- return applicationConnection.getPaintableMap();\r
- }\r
-\r
- /**\r
- * FIXME: What does this even do and why?\r
- * \r
- * @param pid\r
- * @return\r
- */\r
- public boolean isDragAndDropPaintable(String pid) {\r
- return (pid.startsWith("DD"));\r
- }\r
-\r
- /**\r
- * Checks if a paintable with the given paintable id has been registered.\r
- * \r
- * @param pid\r
- * The paintable id to check for\r
- * @return true if a paintable has been registered with the given paintable\r
- * id, false otherwise\r
- */\r
- public boolean hasPaintable(String pid) {\r
- return idToPaintable.containsKey(pid);\r
- }\r
-\r
- /**\r
- * Removes all registered paintable ids\r
- */\r
- public void clear() {\r
- idToPaintable.clear();\r
- idToComponentDetail.clear();\r
- }\r
-\r
- @Deprecated\r
- public Widget getWidget(Paintable paintable) {\r
- return (Widget) paintable;\r
- }\r
-\r
- @Deprecated\r
- public Paintable getPaintable(Widget widget) {\r
- return (Paintable) widget;\r
- }\r
-\r
- public void registerPaintable(String pid, Paintable paintable) {\r
- ComponentDetail componentDetail = GWT.create(ComponentDetail.class);\r
- idToComponentDetail.put(pid, componentDetail);\r
- idToPaintable.put(pid, paintable);\r
- setPid(((Widget) paintable).getElement(), pid);\r
- }\r
-\r
- private native void setPid(Element el, String pid)\r
- /*-{\r
- el.tkPid = pid;\r
- }-*/;\r
-\r
- /**\r
- * Gets the paintableId for a specific paintable.\r
- * <p>\r
- * The paintableId is used in the UIDL to identify a specific widget\r
- * instance, effectively linking the widget with it's server side Component.\r
- * </p>\r
- * \r
- * @param paintable\r
- * the paintable who's id is needed\r
- * @return the id for the given paintable or null if the paintable could not\r
- * be found\r
- */\r
- public String getPid(Paintable paintable) {\r
- return getPid(getWidget(paintable));\r
- }\r
-\r
- @Deprecated\r
- public String getPid(Widget widget) {\r
- if (widget == null) {\r
- return null;\r
- }\r
- return getPid(widget.getElement());\r
- }\r
-\r
- /**\r
- * Gets the paintableId using a DOM element - the element should be the main\r
- * element for a paintable otherwise no id will be found. Use\r
- * {@link #getPid(Paintable)} instead whenever possible.\r
- * \r
- * @see #getPid(Paintable)\r
- * @param el\r
- * element of the paintable whose pid is desired\r
- * @return the pid of the element's paintable, if it's a paintable\r
- */\r
- native String getPid(Element el)\r
- /*-{\r
- return el.tkPid;\r
- }-*/;\r
-\r
- /**\r
- * Gets the main element for the paintable with the given id. The revers of\r
- * {@link #getPid(Element)}.\r
- * \r
- * @param pid\r
- * the pid of the widget whose element is desired\r
- * @return the element for the paintable corresponding to the pid\r
- */\r
- public Element getElement(String pid) {\r
- return ((Widget) getPaintable(pid)).getElement();\r
- }\r
-\r
- /**\r
- * Unregisters the given paintable; always use after removing a paintable.\r
- * This method does not remove the paintable from the DOM, but marks the\r
- * paintable so that ApplicationConnection may clean up its references to\r
- * it. Removing the widget from DOM is component containers responsibility.\r
- * \r
- * @param p\r
- * the paintable to remove\r
- */\r
- public void unregisterPaintable(Paintable p) {\r
-\r
- // add to unregistry que\r
-\r
- if (p == null) {\r
- VConsole.error("WARN: Trying to unregister null paintable");\r
- return;\r
- }\r
- String id = getPid(p);\r
- if (id == null) {\r
- /*\r
- * Uncomment the following to debug unregistring components. No\r
- * paintables with null id should end here. At least one exception\r
- * is our VScrollTableRow, that is hacked to fake it self as a\r
- * Paintable to build support for sizing easier.\r
- */\r
- // if (!(p instanceof VScrollTableRow)) {\r
- // VConsole.log("Trying to unregister Paintable not created by Application Connection.");\r
- // }\r
- if (p instanceof HasWidgets) {\r
- unregisterChildPaintables((HasWidgets) p);\r
- }\r
- } else {\r
- unregistryBag.add(id);\r
- if (p instanceof HasWidgets) {\r
- unregisterChildPaintables((HasWidgets) p);\r
- }\r
- }\r
- }\r
-\r
- void purgeUnregistryBag(boolean unregisterPaintables) {\r
- if (unregisterPaintables) {\r
- for (String pid : unregistryBag) {\r
- Paintable paintable = getPaintable(pid);\r
- if (paintable == null) {\r
- /*\r
- * this should never happen, but it does :-( See e.g.\r
- * com.vaadin.tests.components.accordion.RemoveTabs (with\r
- * test script)\r
- */\r
- VConsole.error("Tried to unregister component (id="\r
- + pid\r
- + ") that is never registered (or already unregistered)");\r
- continue;\r
- }\r
- // check if can be cleaned\r
- Widget component = getWidget(paintable);\r
- if (!component.isAttached()) {\r
- // clean reference to paintable\r
- idToComponentDetail.remove(pid);\r
- idToPaintable.remove(pid);\r
- }\r
- /*\r
- * else NOP : same component has been reattached to another\r
- * parent or replaced by another component implementation.\r
- */\r
- }\r
- }\r
-\r
- unregistryBag.clear();\r
- }\r
-\r
- /**\r
- * Unregisters a paintable and all it's child paintables recursively. Use\r
- * when after removing a paintable that contains other paintables. Does not\r
- * unregister the given container itself. Does not actually remove the\r
- * paintable from the DOM.\r
- * \r
- * @see #unregisterPaintable(Paintable)\r
- * @param container\r
- */\r
- public void unregisterChildPaintables(HasWidgets container) {\r
- final Iterator<Widget> it = container.iterator();\r
- while (it.hasNext()) {\r
- final Widget w = it.next();\r
- if (w instanceof Paintable) {\r
- unregisterPaintable((Paintable) w);\r
- } else if (w instanceof HasWidgets) {\r
- unregisterChildPaintables((HasWidgets) w);\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * FIXME: Should not be here\r
- * \r
- * @param pid\r
- * @param uidl\r
- */\r
- @Deprecated\r
- public void registerEventListenersFromUIDL(String pid, UIDL uidl) {\r
- ComponentDetail cd = idToComponentDetail.get(pid);\r
- if (cd == null) {\r
- throw new IllegalArgumentException("Pid must not be null");\r
- }\r
-\r
- cd.registerEventListenersFromUIDL(uidl);\r
-\r
- }\r
-\r
- /**\r
- * FIXME: Should not be here\r
- * \r
- * @param paintable\r
- * @return\r
- */\r
- @Deprecated\r
- public Size getOffsetSize(Paintable paintable) {\r
- return getComponentDetail(paintable).getOffsetSize();\r
- }\r
-\r
- /**\r
- * FIXME: Should not be here\r
- * \r
- * @param paintable\r
- * @return\r
- */\r
- @Deprecated\r
- public FloatSize getRelativeSize(Paintable paintable) {\r
- return getComponentDetail(paintable).getRelativeSize();\r
- }\r
-\r
- /**\r
- * FIXME: Should not be here\r
- * \r
- * @param paintable\r
- * @return\r
- */\r
- @Deprecated\r
- public void setOffsetSize(Paintable paintable, Size newSize) {\r
- getComponentDetail(paintable).setOffsetSize(newSize);\r
- }\r
-\r
- /**\r
- * FIXME: Should not be here\r
- * \r
- * @param paintable\r
- * @return\r
- */\r
- @Deprecated\r
- public void setRelativeSize(Paintable paintable, FloatSize relativeSize) {\r
- getComponentDetail(paintable).setRelativeSize(relativeSize);\r
-\r
- }\r
-\r
- private ComponentDetail getComponentDetail(Paintable paintable) {\r
- return idToComponentDetail.get(getPid(paintable));\r
- }\r
-\r
- public int size() {\r
- return idToPaintable.size();\r
- }\r
-\r
- /**\r
- * FIXME: Should not be here\r
- * \r
- * @param paintable\r
- * @return\r
- */\r
- @Deprecated\r
- public TooltipInfo getTooltipInfo(Paintable paintable, Object key) {\r
- return getComponentDetail(paintable).getTooltipInfo(key);\r
- }\r
-\r
- public Collection<? extends Paintable> getPaintables() {\r
- return Collections.unmodifiableCollection(idToPaintable.values());\r
- }\r
-\r
- /**\r
- * FIXME: Should not be here\r
- * \r
- * @param paintable\r
- * @return\r
- */\r
- @Deprecated\r
- public void registerTooltip(Paintable paintable, Object key,\r
- TooltipInfo tooltip) {\r
- getComponentDetail(paintable).putAdditionalTooltip(key, tooltip);\r
-\r
- }\r
-\r
- /**\r
- * FIXME: Should not be here\r
- * \r
- * @param paintable\r
- * @return\r
- */\r
- @Deprecated\r
- public boolean hasEventListeners(Paintable paintable, String eventIdentifier) {\r
- return getComponentDetail(paintable).hasEventListeners(eventIdentifier);\r
- }\r
-\r
-}\r
/**
* When a component is updated, it's client side widget's
- * {@link Paintable#updateFromUIDL(UIDL, ApplicationConnection)
+ * {@link VPaintableWidget#updateFromUIDL(UIDL, ApplicationConnection)
* updateFromUIDL()} will be called with the updated ("changes") UIDL received
* from the server.
* <p>
* AbstractComponent.paintContent()}. Note that if the UIDL corresponds to a
* Paintable, a component identifier will be returned instead - this is used
* internally and is not needed within
- * {@link Paintable#updateFromUIDL(UIDL, ApplicationConnection)
+ * {@link VPaintableWidget#updateFromUIDL(UIDL, ApplicationConnection)
* updateFromUIDL()}.
*
* @return the name for this section
* the name of the attribute
* @return the Paintable referenced by the attribute, if it exists
*/
- public Paintable getPaintableAttribute(String name,
+ public VPaintable getPaintableAttribute(String name,
ApplicationConnection connection) {
- return PaintableMap.get(connection).getPaintable(
+ return VPaintableMap.get(connection).getPaintable(
getStringAttribute(name));
}
* the name of the variable
* @return the Paintable referenced by the variable, if it exists
*/
- public Paintable getPaintableVariable(String name,
+ public VPaintable getPaintableVariable(String name,
ApplicationConnection connection) {
- return PaintableMap.get(connection).getPaintable(
+ return VPaintableMap.get(connection).getPaintable(
getStringVariable(name));
}
}-*/;
private static final int LAZY_SIZE_CHANGE_TIMEOUT = 400;
- private static Set<Paintable> latelyChangedWidgets = new HashSet<Paintable>();
+ private static Set<Widget> latelyChangedWidgets = new HashSet<Widget>();
private static Timer lazySizeChangeTimer = new Timer() {
private boolean lazySizeChangeTimerScheduled = false;
* @param lazy
* run componentSizeUpdated lazyly
*/
- public static void notifyParentOfSizeChange(Paintable widget, boolean lazy) {
+ public static void notifyParentOfSizeChange(Widget widget, boolean lazy) {
if (lazy) {
latelyChangedWidgets.add(widget);
lazySizeChangeTimer.schedule(LAZY_SIZE_CHANGE_TIMEOUT);
} else {
- Set<Paintable> widgets = new HashSet<Paintable>();
+ Set<Widget> widgets = new HashSet<Widget>();
widgets.add(widget);
Util.componentSizeUpdated(widgets);
}
*
* @param paintables
*/
- public static void componentSizeUpdated(Set<Paintable> paintables) {
- if (paintables.isEmpty()) {
+ public static void componentSizeUpdated(Set<Widget> widgets) {
+ if (widgets.isEmpty()) {
return;
}
- Map<Container, Set<Paintable>> childWidgets = new HashMap<Container, Set<Paintable>>();
+ Map<Container, Set<Widget>> childWidgets = new HashMap<Container, Set<Widget>>();
- for (Paintable paintable : paintables) {
- Widget widget = (Widget) paintable;
+ for (Widget widget : widgets) {
if (!widget.isAttached()) {
continue;
}
parent = parent.getParent();
}
if (parent != null) {
- Set<Paintable> set = childWidgets.get(parent);
+ Set<Widget> set = childWidgets.get(parent);
if (set == null) {
- set = new HashSet<Paintable>();
+ set = new HashSet<Widget>();
childWidgets.put((Container) parent, set);
}
- set.add(paintable);
+ set.add(widget);
}
}
- Set<Paintable> parentChanges = new HashSet<Paintable>();
+ Set<Widget> parentChanges = new HashSet<Widget>();
for (Container parent : childWidgets.keySet()) {
if (!parent.requestLayout(childWidgets.get(parent))) {
- parentChanges.add(parent);
+ parentChanges.add(parent.getWidgetForPaintable());
}
}
}
public static void updateRelativeChildrenAndSendSizeUpdateEvent(
- ApplicationConnection client, HasWidgets container) {
- updateRelativeChildrenAndSendSizeUpdateEvent(client, container,
- (Paintable) container);
- }
-
- public static void updateRelativeChildrenAndSendSizeUpdateEvent(
- ApplicationConnection client, HasWidgets container, Paintable widget) {
+ ApplicationConnection client, HasWidgets container, Widget widget) {
/*
* Relative sized children must be updated first so the component has
* the correct outer dimensions when signaling a size change to the
client.handleComponentRelativeSize(w);
}
- HashSet<Paintable> widgets = new HashSet<Paintable>();
+ HashSet<Widget> widgets = new HashSet<Widget>();
widgets.add(widget);
Util.componentSizeUpdated(widgets);
}
* The widget that contains <literal>element</literal>.
* @param element
* An element that is a sub element of the parent
- * @return The Paintable which the element is a part of. Null if the element
- * does not belong to a child.
+ * @return The VPaintableWidget which the element is a part of. Null if the
+ * element does not belong to a child.
*/
- public static Paintable getChildPaintableForElement(
+ public static VPaintableWidget getChildPaintableForElement(
ApplicationConnection client, Container parent, Element element) {
- Element rootElement = ((Widget) parent).getElement();
+ Element rootElement = parent.getWidgetForPaintable().getElement();
while (element != null && element != rootElement) {
- Paintable paintable = PaintableMap.get(client)
+ VPaintableWidget paintable = VPaintableMap.get(client)
.getPaintable(element);
if (paintable == null) {
String ownerPid = VCaption.getCaptionOwnerPid(element);
if (ownerPid != null) {
- paintable = PaintableMap.get(client).getPaintable(ownerPid);
+ paintable = (VPaintableWidget) VPaintableMap.get(client)
+ .getPaintable(ownerPid);
}
}
- if (paintable != null) {
- try {
- if (parent.hasChildComponent((Widget) paintable)) {
- return paintable;
- }
- } catch (ClassCastException e) {
- // We assume everything is a widget however there is no need
- // to crash everything if there is a paintable that is not.
- }
+ if (paintable != null
+ && parent.hasChildComponent(paintable
+ .getWidgetForPaintable())) {
+ return paintable;
}
element = (Element) element.getParentElement();
* <literal>element</literal> is not part of any child component, null is
* returned.
*
- * This method returns the deepest nested Paintable. See
+ * This method returns the deepest nested VPaintableWidget. See
* {@link #getChildPaintableForElement(ApplicationConnection, Container, Element)}
* for the immediate child component of parent that contains the element.
*
* The widget that contains <literal>element</literal>.
* @param element
* An element that is a sub element of the parent
- * @return The Paintable which the element is a part of. Null if the element
- * does not belong to a child.
+ * @return The VPaintableWidget which the element is a part of. Null if the
+ * element does not belong to a child.
*/
- public static Paintable getPaintableForElement(
+ public static VPaintableWidget getPaintableForElement(
ApplicationConnection client, Widget parent, Element element) {
Element rootElement = parent.getElement();
while (element != null && element != rootElement) {
- Paintable paintable = PaintableMap.get(client)
+ VPaintableWidget paintable = VPaintableMap.get(client)
.getPaintable(element);
if (paintable == null) {
String ownerPid = VCaption.getCaptionOwnerPid(element);
if (ownerPid != null) {
- paintable = PaintableMap.get(client).getPaintable(ownerPid);
+ paintable = (VPaintableWidget) VPaintableMap.get(client)
+ .getPaintable(ownerPid);
}
}
private static void printPaintablesVariables(ArrayList<String[]> vars,
String id, ApplicationConnection c) {
- Paintable paintable = PaintableMap.get(c).getPaintable(id);
+ VPaintableWidget paintable = (VPaintableWidget) VPaintableMap.get(c)
+ .getPaintable(id);
if (paintable != null) {
VConsole.log("\t" + id + " (" + paintable.getClass() + ") :");
for (String[] var : vars) {
public static final String CLASSNAME = "v-caption";
- private final Paintable owner;
+ private final VPaintableWidget owner;
private Element errorIndicatorElement;
* null
* @param client
*/
- public VCaption(Paintable component, ApplicationConnection client) {
+ public VCaption(VPaintableWidget component, ApplicationConnection client) {
super();
this.client = client;
owner = component;
if (client != null && owner != null) {
- setOwnerPid(getElement(), PaintableMap.get(client).getPid(owner));
+ setOwnerPid(getElement(), VPaintableMap.get(client).getPid(owner));
}
setStyleName(CLASSNAME);
* the responsibility of reacting to ONLOAD from VCaption to layouts
*/
if (owner != null) {
- Util.notifyParentOfSizeChange(owner, true);
+ Util.notifyParentOfSizeChange(owner.getWidgetForPaintable(),
+ true);
} else {
VConsole.log("Warning: Icon load event was not propagated because VCaption owner is unknown.");
}
*
* @return owner Widget
*/
- public Paintable getOwner() {
+ public VPaintableWidget getOwner() {
return owner;
}
package com.vaadin.terminal.gwt.client;
import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.Widget;
public class VCaptionWrapper extends FlowPanel {
public static final String CLASSNAME = "v-captionwrapper";
VCaption caption;
- Paintable widget;
+ VPaintableWidget paintable;
- public VCaptionWrapper(Paintable toBeWrapped, ApplicationConnection client) {
+ public VCaptionWrapper(VPaintableWidget toBeWrapped,
+ ApplicationConnection client) {
caption = new VCaption(toBeWrapped, client);
add(caption);
- widget = toBeWrapped;
- add((Widget) widget);
+ paintable = toBeWrapped;
+ add(paintable.getWidgetForPaintable());
setStyleName(CLASSNAME);
}
setVisible(!uidl.getBooleanAttribute("invisible"));
}
- public Paintable getPaintable() {
- return widget;
+ public VPaintableWidget getPaintable() {
+ return paintable;
}
}
public static void printLayoutProblems(ValueMap meta,
ApplicationConnection applicationConnection,
- Set<Paintable> zeroHeightComponents,
- Set<Paintable> zeroWidthComponents) {
+ Set<VPaintableWidget> zeroHeightComponents,
+ Set<VPaintableWidget> zeroWidthComponents) {
impl.printLayoutProblems(meta, applicationConnection,
zeroHeightComponents, zeroWidthComponents);
}
for (ApplicationConnection a : ApplicationConfiguration
.getRunningApplications()) {
- Paintable paintable = Util.getPaintableForElement(a,
+ VPaintableWidget paintable = Util.getPaintableForElement(a,
a.getView(), eventTarget);
if (paintable == null) {
paintable = Util.getPaintableForElement(a,
RootPanel.get(), eventTarget);
}
if (paintable != null) {
- String pid = PaintableMap.get(a).getPid(paintable);
+ String pid = VPaintableMap.get(a).getPid(paintable);
VUIDLBrowser.highlight(paintable);
label.setText("Currently focused :"
+ paintable.getClass() + " ID:" + pid);
.getClientY());
for (ApplicationConnection a : ApplicationConfiguration
.getRunningApplications()) {
- Paintable paintable = Util.getPaintableForElement(a,
+ VPaintableWidget paintable = Util.getPaintableForElement(a,
a.getView(), eventTarget);
if (paintable == null) {
paintable = Util.getPaintableForElement(a,
}-*/;
public void printLayoutProblems(ValueMap meta, ApplicationConnection ac,
- Set<Paintable> zeroHeightComponents,
- Set<Paintable> zeroWidthComponents) {
+ Set<VPaintableWidget> zeroHeightComponents,
+ Set<VPaintableWidget> zeroWidthComponents) {
JsArray<ValueMap> valueMapArray = meta
.getJSValueMapArray("invalidLayouts");
int size = valueMapArray.length();
}
private void printClientSideDetectedIssues(
- Set<Paintable> zeroHeightComponents, ApplicationConnection ac) {
- for (final Paintable paintable : zeroHeightComponents) {
- final Container layout = Util.getLayout((Widget) paintable);
+ Set<VPaintableWidget> zeroHeightComponents, ApplicationConnection ac) {
+ for (final VPaintableWidget paintable : zeroHeightComponents) {
+ final Container layout = Util.getLayout(paintable
+ .getWidgetForPaintable());
VerticalPanel errorDetails = new VerticalPanel();
errorDetails.add(new Label("" + Util.getSimpleName(paintable)
emphasisInUi.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
if (paintable != null) {
- Element element2 = ((Widget) layout).getElement();
+ Element element2 = layout.getWidgetForPaintable()
+ .getElement();
Widget.setStyleName(element2, "invalidlayout",
emphasisInUi.getValue());
}
private void printLayoutError(ValueMap valueMap, SimpleTree root,
final ApplicationConnection ac) {
final String pid = valueMap.getString("id");
- final Paintable paintable = PaintableMap.get(ac).getPaintable(pid);
+ final VPaintableWidget paintable = (VPaintableWidget) VPaintableMap
+ .get(ac).getPaintable(pid);
SimpleTree errorNode = new SimpleTree();
VerticalPanel errorDetails = new VerticalPanel();
emphasisInUi.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
if (paintable != null) {
- Element element2 = ((Widget) paintable).getElement();
+ Element element2 = paintable.getWidgetForPaintable()
+ .getElement();
Widget.setStyleName(element2, "invalidlayout",
emphasisInUi.getValue());
}
--- /dev/null
+/*\r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
+package com.vaadin.terminal.gwt.client;\r
+\r
+/**\r
+ * TODO\r
+ * \r
+ */\r
+public interface VPaintable {\r
+ /**\r
+ * TODO\r
+ * \r
+ * @param uidl\r
+ * @param client\r
+ */\r
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client);\r
+\r
+}\r
--- /dev/null
+/*\r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
+package com.vaadin.terminal.gwt.client;\r
+\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.user.client.Element;\r
+import com.google.gwt.user.client.ui.HasWidgets;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.Paintable;\r
+import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;\r
+import com.vaadin.terminal.gwt.client.RenderInformation.Size;\r
+\r
+public class VPaintableMap {\r
+\r
+ private Map<String, VPaintable> idToPaintable = new HashMap<String, VPaintable>();\r
+ private Map<VPaintable, String> paintableToId = new HashMap<VPaintable, String>();\r
+\r
+ public static VPaintableMap get(ApplicationConnection applicationConnection) {\r
+ return applicationConnection.getPaintableMap();\r
+ }\r
+\r
+ @Deprecated\r
+ private final ComponentDetailMap idToComponentDetail = ComponentDetailMap\r
+ .create();\r
+\r
+ private Set<String> unregistryBag = new HashSet<String>();\r
+\r
+ /**\r
+ * Returns a Paintable by its paintable id\r
+ * \r
+ * @param id\r
+ * The Paintable id\r
+ */\r
+ public VPaintable getPaintable(String pid) {\r
+ return idToPaintable.get(pid);\r
+ }\r
+\r
+ /**\r
+ * Returns a Paintable element by its root element\r
+ * \r
+ * @param element\r
+ * Root element of the paintable\r
+ */\r
+ public VPaintableWidget getPaintable(Element element) {\r
+ return (VPaintableWidget) getPaintable(getPid(element));\r
+ }\r
+\r
+ /**\r
+ * FIXME: What does this even do and why?\r
+ * \r
+ * @param pid\r
+ * @return\r
+ */\r
+ public boolean isDragAndDropPaintable(String pid) {\r
+ return (pid.startsWith("DD"));\r
+ }\r
+\r
+ /**\r
+ * Checks if a paintable with the given paintable id has been registered.\r
+ * \r
+ * @param pid\r
+ * The paintable id to check for\r
+ * @return true if a paintable has been registered with the given paintable\r
+ * id, false otherwise\r
+ */\r
+ public boolean hasPaintable(String pid) {\r
+ return idToPaintable.containsKey(pid);\r
+ }\r
+\r
+ /**\r
+ * Removes all registered paintable ids\r
+ */\r
+ public void clear() {\r
+ idToPaintable.clear();\r
+ paintableToId.clear();\r
+ idToComponentDetail.clear();\r
+ }\r
+\r
+ @Deprecated\r
+ public Widget getWidget(VPaintableWidget paintable) {\r
+ return paintable.getWidgetForPaintable();\r
+ }\r
+\r
+ @Deprecated\r
+ public VPaintableWidget getPaintable(Widget widget) {\r
+ return getPaintable(widget.getElement());\r
+ }\r
+\r
+ public void registerPaintable(String pid, VPaintable paintable) {\r
+ ComponentDetail componentDetail = GWT.create(ComponentDetail.class);\r
+ idToComponentDetail.put(pid, componentDetail);\r
+ idToPaintable.put(pid, paintable);\r
+ paintableToId.put(paintable, pid);\r
+ if (paintable instanceof VPaintableWidget) {\r
+ VPaintableWidget pw = (VPaintableWidget) paintable;\r
+ setPid(pw.getWidgetForPaintable().getElement(), pid);\r
+ }\r
+ }\r
+\r
+ private native void setPid(Element el, String pid)\r
+ /*-{\r
+ el.tkPid = pid;\r
+ }-*/;\r
+\r
+ /**\r
+ * Gets the paintableId for a specific paintable.\r
+ * <p>\r
+ * The paintableId is used in the UIDL to identify a specific widget\r
+ * instance, effectively linking the widget with it's server side Component.\r
+ * </p>\r
+ * \r
+ * @param paintable\r
+ * the paintable who's id is needed\r
+ * @return the id for the given paintable or null if the paintable could not\r
+ * be found\r
+ */\r
+ public String getPid(VPaintable paintable) {\r
+ if (paintable == null) {\r
+ return null;\r
+ }\r
+ return paintableToId.get(paintable);\r
+ }\r
+\r
+ @Deprecated\r
+ public String getPid(Widget widget) {\r
+ return getPid(widget.getElement());\r
+ }\r
+\r
+ /**\r
+ * Gets the paintableId using a DOM element - the element should be the main\r
+ * element for a paintable otherwise no id will be found. Use\r
+ * {@link #getPid(Paintable)} instead whenever possible.\r
+ * \r
+ * @see #getPid(Paintable)\r
+ * @param el\r
+ * element of the paintable whose pid is desired\r
+ * @return the pid of the element's paintable, if it's a paintable\r
+ */\r
+ native String getPid(Element el)\r
+ /*-{\r
+ return el.tkPid;\r
+ }-*/;\r
+\r
+ /**\r
+ * Gets the main element for the paintable with the given id. The revers of\r
+ * {@link #getPid(Element)}.\r
+ * \r
+ * @param pid\r
+ * the pid of the widget whose element is desired\r
+ * @return the element for the paintable corresponding to the pid\r
+ */\r
+ public Element getElement(String pid) {\r
+ VPaintable p = getPaintable(pid);\r
+ if (p instanceof VPaintableWidget) {\r
+ return ((VPaintableWidget) p).getWidgetForPaintable().getElement();\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Unregisters the given paintable; always use after removing a paintable.\r
+ * This method does not remove the paintable from the DOM, but marks the\r
+ * paintable so that ApplicationConnection may clean up its references to\r
+ * it. Removing the widget from DOM is component containers responsibility.\r
+ * \r
+ * @param p\r
+ * the paintable to remove\r
+ */\r
+ public void unregisterPaintable(VPaintable p) {\r
+\r
+ // add to unregistry que\r
+\r
+ if (p == null) {\r
+ VConsole.error("WARN: Trying to unregister null paintable");\r
+ return;\r
+ }\r
+ String id = getPid(p);\r
+ Widget widget = null;\r
+ if (p instanceof VPaintableWidget) {\r
+ widget = ((VPaintableWidget) p).getWidgetForPaintable();\r
+ }\r
+\r
+ if (id == null) {\r
+ /*\r
+ * Uncomment the following to debug unregistring components. No\r
+ * paintables with null id should end here. At least one exception\r
+ * is our VScrollTableRow, that is hacked to fake it self as a\r
+ * Paintable to build support for sizing easier.\r
+ */\r
+ // if (!(p instanceof VScrollTableRow)) {\r
+ // VConsole.log("Trying to unregister Paintable not created by Application Connection.");\r
+ // }\r
+ } else {\r
+ unregistryBag.add(id);\r
+ }\r
+ if (widget != null && widget instanceof HasWidgets) {\r
+ unregisterChildPaintables((HasWidgets) widget);\r
+ }\r
+\r
+ }\r
+\r
+ void purgeUnregistryBag(boolean unregisterPaintables) {\r
+ if (unregisterPaintables) {\r
+ for (String pid : unregistryBag) {\r
+ VPaintable paintable = getPaintable(pid);\r
+ if (paintable == null) {\r
+ /*\r
+ * this should never happen, but it does :-( See e.g.\r
+ * com.vaadin.tests.components.accordion.RemoveTabs (with\r
+ * test script)\r
+ */\r
+ VConsole.error("Tried to unregister component (id="\r
+ + pid\r
+ + ") that is never registered (or already unregistered)");\r
+ continue;\r
+ }\r
+ Widget widget = null;\r
+ if (paintable instanceof VPaintableWidget) {\r
+ widget = ((VPaintableWidget) paintable)\r
+ .getWidgetForPaintable();\r
+ }\r
+\r
+ // check if can be cleaned\r
+ if (widget == null || !widget.isAttached()) {\r
+ // clean reference to paintable\r
+ idToComponentDetail.remove(pid);\r
+ idToPaintable.remove(pid);\r
+ paintableToId.remove(paintable);\r
+ }\r
+ /*\r
+ * else NOP : same component has been reattached to another\r
+ * parent or replaced by another component implementation.\r
+ */\r
+ }\r
+ }\r
+\r
+ unregistryBag.clear();\r
+ }\r
+\r
+ /**\r
+ * Unregisters a paintable and all it's child paintables recursively. Use\r
+ * when after removing a paintable that contains other paintables. Does not\r
+ * unregister the given container itself. Does not actually remove the\r
+ * paintable from the DOM.\r
+ * \r
+ * @see #unregisterPaintable(Paintable)\r
+ * @param container\r
+ */\r
+ public void unregisterChildPaintables(HasWidgets container) {\r
+ // FIXME: This should be based on the paintable hierarchy\r
+ final Iterator<Widget> it = container.iterator();\r
+ while (it.hasNext()) {\r
+ final Widget w = it.next();\r
+ VPaintableWidget p = getPaintable(w);\r
+ if (p != null) {\r
+ // This will unregister the paintable and all its children\r
+ unregisterPaintable(p);\r
+ } else if (w instanceof HasWidgets) {\r
+ // For normal widget containers, unregister the children\r
+ unregisterChildPaintables((HasWidgets) w);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * FIXME: Should not be here\r
+ * \r
+ * @param pid\r
+ * @param uidl\r
+ */\r
+ @Deprecated\r
+ public void registerEventListenersFromUIDL(String pid, UIDL uidl) {\r
+ ComponentDetail cd = idToComponentDetail.get(pid);\r
+ if (cd == null) {\r
+ throw new IllegalArgumentException("Pid must not be null");\r
+ }\r
+\r
+ cd.registerEventListenersFromUIDL(uidl);\r
+\r
+ }\r
+\r
+ /**\r
+ * FIXME: Should not be here\r
+ * \r
+ * @param paintable\r
+ * @return\r
+ */\r
+ @Deprecated\r
+ public Size getOffsetSize(VPaintableWidget paintable) {\r
+ return getComponentDetail(paintable).getOffsetSize();\r
+ }\r
+\r
+ /**\r
+ * FIXME: Should not be here\r
+ * \r
+ * @param paintable\r
+ * @return\r
+ */\r
+ @Deprecated\r
+ public FloatSize getRelativeSize(VPaintableWidget paintable) {\r
+ return getComponentDetail(paintable).getRelativeSize();\r
+ }\r
+\r
+ /**\r
+ * FIXME: Should not be here\r
+ * \r
+ * @param paintable\r
+ * @return\r
+ */\r
+ @Deprecated\r
+ public void setOffsetSize(VPaintableWidget paintable, Size newSize) {\r
+ getComponentDetail(paintable).setOffsetSize(newSize);\r
+ }\r
+\r
+ /**\r
+ * FIXME: Should not be here\r
+ * \r
+ * @param paintable\r
+ * @return\r
+ */\r
+ @Deprecated\r
+ public void setRelativeSize(VPaintableWidget paintable,\r
+ FloatSize relativeSize) {\r
+ getComponentDetail(paintable).setRelativeSize(relativeSize);\r
+\r
+ }\r
+\r
+ private ComponentDetail getComponentDetail(VPaintable paintable) {\r
+ return idToComponentDetail.get(getPid(paintable));\r
+ }\r
+\r
+ public int size() {\r
+ return idToPaintable.size();\r
+ }\r
+\r
+ /**\r
+ * FIXME: Should not be here\r
+ * \r
+ * @param paintable\r
+ * @return\r
+ */\r
+ @Deprecated\r
+ public TooltipInfo getTooltipInfo(VPaintableWidget paintable, Object key) {\r
+ return getComponentDetail(paintable).getTooltipInfo(key);\r
+ }\r
+\r
+ public Collection<? extends VPaintable> getPaintables() {\r
+ return Collections.unmodifiableCollection(paintableToId.keySet());\r
+ }\r
+\r
+ /**\r
+ * FIXME: Should not be here\r
+ * \r
+ * @param paintable\r
+ * @return\r
+ */\r
+ @Deprecated\r
+ public void registerTooltip(VPaintableWidget paintable, Object key,\r
+ TooltipInfo tooltip) {\r
+ getComponentDetail(paintable).putAdditionalTooltip(key, tooltip);\r
+\r
+ }\r
+\r
+ /**\r
+ * FIXME: Should not be here\r
+ * \r
+ * @param paintable\r
+ * @return\r
+ */\r
+ @Deprecated\r
+ public boolean hasEventListeners(VPaintable paintable,\r
+ String eventIdentifier) {\r
+ return getComponentDetail(paintable).hasEventListeners(eventIdentifier);\r
+ }\r
+\r
+ /**\r
+ * Tests if the widget is the root widget of a VPaintableWidget.\r
+ * \r
+ * @param widget\r
+ * The widget to test\r
+ * @return true if the widget is the root widget of a VPaintableWidget,\r
+ * false otherwise\r
+ */\r
+ public boolean isPaintable(Widget w) {\r
+ return getPid(w) != null;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * An interface used by client-side widgets or paintable parts to receive
+ * updates from the corresponding server-side components in the form of
+ * {@link UIDL}.
+ *
+ * Updates can be sent back to the server using the
+ * {@link ApplicationConnection#updateVariable()} methods.
+ */
+public interface VPaintableWidget extends VPaintable {
+
+ /**
+ * TODO: Renamed to getWidget
+ */
+ public Widget getWidgetForPaintable();
+}
private static final int QUICK_OPEN_DELAY = 100;
VErrorMessage em = new VErrorMessage();
Element description = DOM.createDiv();
- private Paintable tooltipOwner;
+ private VPaintableWidget tooltipOwner;
private boolean closing = false;
private boolean opening = false;
}
}
- public void showTooltip(Paintable owner, Event event, Object key) {
+ public void showTooltip(VPaintableWidget owner, Event event, Object key) {
if (closing && tooltipOwner == owner && tooltipKey == key) {
// return to same tooltip, cancel closing
closeTimer.cancel();
}
- public void handleTooltipEvent(Event event, Paintable owner, Object key) {
+ public void handleTooltipEvent(Event event, VPaintableWidget owner, Object key) {
final int type = DOM.eventGetType(event);
if ((VTooltip.TOOLTIP_EVENTS & type) == type) {
if (type == Event.ONMOUSEOVER) {
private String getNodeName(UIDL uidl, ApplicationConfiguration conf,
String name) {
- Class<? extends Paintable> widgetClassByDecodedTag = conf
+ Class<? extends VPaintableWidget> widgetClassByDecodedTag = conf
.getWidgetClassByEncodedTag(name);
if (widgetClassByDecodedTag == VUnknownComponent.class) {
return conf.getUnknownServerClassNameByEncodedTagName(name)
// same
// host page
for (ApplicationConnection applicationConnection : runningApplications) {
- Paintable paintable = PaintableMap.get(applicationConnection)
- .getPaintable(uidl.getId());
+ VPaintableWidget paintable = (VPaintableWidget) VPaintableMap
+ .get(applicationConnection).getPaintable(uidl.getId());
highlight(paintable);
if (event != null && event.getNativeEvent().getShiftKey()) {
applicationConnection.highlightComponent(paintable);
}
}
- static void highlight(Paintable paintable) {
- Widget w = (Widget) paintable;
+ static void highlight(VPaintableWidget paintable) {
+ Widget w = paintable.getWidgetForPaintable();
if (w != null) {
Style style = highlight.getStyle();
style.setTop(w.getAbsoluteTop(), Unit.PX);
}
}
-}
\ No newline at end of file
+}
* A helper class used by WidgetMap implementation. Used by the generated code.
*/
interface WidgetInstantiator {
- public Paintable get();
+ public VPaintableWidget get();
}
protected static HashMap<Class, WidgetInstantiator> instmap = new HashMap<Class, WidgetInstantiator>();
- public Paintable instantiate(Class<? extends Paintable> classType) {
+ // FIXME: Should use Paintable and not VPaintableWidget
+ public VPaintableWidget instantiate(
+ Class<? extends VPaintableWidget> classType) {
return instmap.get(classType).get();
}
- public abstract Class<? extends Paintable> getImplementationByServerSideClassName(
+ // FIXME: Should use Paintable and not VPaintableWidget
+ public abstract Class<? extends VPaintableWidget> getImplementationByServerSideClassName(
String fullyqualifiedName);
- public abstract Class<? extends Paintable>[] getDeferredLoadedWidgets();
+ // FIXME: Should use Paintable and not VPaintableWidget
+ public abstract Class<? extends VPaintableWidget>[] getDeferredLoadedWidgets();
- public abstract void ensureInstantiator(Class<? extends Paintable> classType);
+ // FIXME: Should use Paintable and not VPaintableWidget
+ public abstract void ensureInstantiator(
+ Class<? extends VPaintableWidget> classType);
}
/**
* Create an uninitialized component that best matches given UIDL. The
- * component must be a {@link Widget} that implements {@link Paintable}.
+ * component must be a {@link Widget} that implements {@link VPaintableWidget}.
*
* @param uidl
* UIDL to be painted with returned component.
* @return New uninitialized and unregistered component that can paint given
* UIDL.
*/
- public Paintable createWidget(UIDL uidl, ApplicationConfiguration conf) {
+ public VPaintableWidget createWidget(UIDL uidl, ApplicationConfiguration conf) {
/*
* Yes, this (including the generated code in WidgetMap) may look very
* odd code, but due the nature of GWT, we cannot do this any cleaner.
* TODO should try to get rid of these exceptions here
*/
- final Class<? extends Paintable> classType = resolveWidgetType(uidl,
+ final Class<? extends VPaintableWidget> classType = resolveWidgetType(uidl,
conf);
if (classType == null || classType == VUnknownComponent.class) {
String serverSideName = conf
}
- protected Class<? extends Paintable> resolveWidgetType(UIDL uidl,
+ protected Class<? extends VPaintableWidget> resolveWidgetType(UIDL uidl,
ApplicationConfiguration conf) {
final String tag = uidl.getTag();
- Class<? extends Paintable> widgetClass = conf
+ Class<? extends VPaintableWidget> widgetClass = conf
.getWidgetClassByEncodedTag(tag);
// add our historical quirks
* @param applicationConfiguration
* @return
*/
- public Class<? extends Paintable> getImplementationByClassName(
+ public Class<? extends VPaintableWidget> getImplementationByClassName(
String fullyqualifiedName) {
if (fullyqualifiedName == null) {
return VUnknownComponent.class;
}
- Class<? extends Paintable> implementationByServerSideClassName = widgetMap
+ Class<? extends VPaintableWidget> implementationByServerSideClassName = widgetMap
.getImplementationByServerSideClassName(fullyqualifiedName);
/*
}
- public Class<? extends Paintable>[] getDeferredLoadedWidgets() {
+ public Class<? extends VPaintableWidget>[] getDeferredLoadedWidgets() {
return widgetMap.getDeferredLoadedWidgets();
}
- public void loadImplementation(Class<? extends Paintable> nextType) {
+ public void loadImplementation(Class<? extends VPaintableWidget> nextType) {
widgetMap.ensureInstantiator(nextType);
}
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.PaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
public abstract class ClickEventHandler implements DoubleClickHandler,
ContextMenuHandler, MouseUpHandler {
private HandlerRegistration contextMenuHandlerRegistration;
protected String clickEventIdentifier;
- protected Paintable paintable;
+ protected VPaintableWidget paintable;
private ApplicationConnection client;
- public ClickEventHandler(Paintable paintable, String clickEventIdentifier) {
+ public ClickEventHandler(VPaintableWidget paintable,
+ String clickEventIdentifier) {
this.paintable = paintable;
this.clickEventIdentifier = clickEventIdentifier;
}
protected void fireClick(NativeEvent event) {
ApplicationConnection client = getApplicationConnection();
- String pid = PaintableMap.get(getApplicationConnection()).getPid(
+ String pid = VPaintableMap.get(getApplicationConnection()).getPid(
paintable);
MouseEventDetails mouseDetails = new MouseEventDetails(event,
* or null if no relative coordinates can be calculated.
*/
protected Element getRelativeToElement() {
- if (paintable instanceof Widget) {
- return ((Widget) paintable).getElement();
- }
-
- return null;
+ return paintable.getWidgetForPaintable().getElement();
}
}
\ No newline at end of file
import com.google.gwt.user.client.Element;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.PaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
public abstract class LayoutClickEventHandler extends ClickEventHandler {
- public LayoutClickEventHandler(Paintable paintable,
+ public LayoutClickEventHandler(VPaintableWidget paintable,
String clickEventIdentifier) {
super(paintable, clickEventIdentifier);
}
- protected abstract Paintable getChildComponent(Element element);
+ protected abstract VPaintableWidget getChildComponent(Element element);
@Override
protected void fireClick(NativeEvent event) {
ApplicationConnection client = getApplicationConnection();
- String pid = PaintableMap.get(getApplicationConnection()).getPid(
+ String pid = VPaintableMap.get(getApplicationConnection()).getPid(
paintable);
MouseEventDetails mouseDetails = new MouseEventDetails(event,
getRelativeToElement());
- Paintable childComponent = getChildComponent((Element) event
+ VPaintableWidget childComponent = getChildComponent((Element) event
.getEventTarget().cast());
Map<String, Object> parameters = new HashMap<String, Object>();
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextArea;
/**
}
/**
- * A focusable {@link Paintable} implementing this interface will be
+ * A focusable {@link VPaintableWidget} implementing this interface will be
* notified before shortcut actions are handled if it will be the target of
* the action (most commonly means it is the focused component during the
* keyboard combination is triggered by the user).
*/
- public interface BeforeShortcutActionListener extends Paintable {
+ public interface BeforeShortcutActionListener extends VPaintableWidget {
/**
* This method is called by ShortcutActionHandler before firing the
* shortcut if the Paintable is currently focused (aka the target of the
}
}
- public void handleKeyboardEvent(final Event event, Paintable target) {
+ public void handleKeyboardEvent(final Event event, VPaintableWidget target) {
final int modifiers = KeyboardListenerCollection
.getKeyboardModifiers(event);
final char keyCode = (char) DOM.eventGetKeyCode(event);
}
private void fireAction(final Event event, final ShortcutAction a,
- Paintable target) {
+ VPaintableWidget target) {
final Element et = DOM.eventGetTarget(event);
if (target == null) {
Widget w = Util.findWidget(et, null);
- while (w != null && !(w instanceof Paintable)) {
+ VPaintableMap paintableMap = VPaintableMap.get(client);
+ while (w != null && !paintableMap.isPaintable(w)) {
w = w.getParent();
}
- target = (Paintable) w;
+ target = paintableMap.getPaintable(w);
}
- final Paintable finalTarget = target;
+ final VPaintableWidget finalTarget = target;
event.preventDefault();
package com.vaadin.terminal.gwt.client.ui;
import com.google.gwt.user.client.ui.HasWidgets;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
-public interface Table extends Paintable, HasWidgets {
+public interface Table extends VPaintableWidget, HasWidgets {
final int SELECT_MODE_NONE = 0;
final int SELECT_MODE_SINGLE = 1;
final int SELECT_MODE_MULTI = 2;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VCaption;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
public class VAbsoluteLayout extends ComplexPanel implements Container {
this, EventId.LAYOUT_CLICK) {
@Override
- protected Paintable getChildComponent(Element element) {
+ protected VPaintableWidget getChildComponent(Element element) {
return getComponent(element);
}
}
}
- public boolean requestLayout(Set<Paintable> children) {
+ public boolean requestLayout(Set<Widget> children) {
// component inside an absolute panel never affects parent nor the
// layout
return true;
}
- public void updateCaption(Paintable component, UIDL uidl) {
- AbsoluteWrapper parent2 = (AbsoluteWrapper) ((Widget) component)
- .getParent();
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ AbsoluteWrapper parent2 = (AbsoluteWrapper) (component
+ .getWidgetForPaintable()).getParent();
parent2.updateCaption(uidl);
}
private String bottom;
private String zIndex;
- private Paintable paintable;
+ private VPaintableWidget paintable;
private VCaption caption;
- public AbsoluteWrapper(Paintable paintable) {
+ public AbsoluteWrapper(VPaintableWidget paintable) {
this.paintable = paintable;
setStyleName(CLASSNAME + "-wrapper");
}
@Override
public void setWidget(Widget w) {
// this fixes #5457 (Widget implementation can change on-the-fly)
- paintable = (Paintable) w;
+ paintable = VPaintableMap.get(client).getPaintable(w);
super.setWidget(w);
}
public void updateFromUIDL(UIDL componentUIDL) {
setPosition(componentUIDL.getStringAttribute("css"));
- if (getWidget() != paintable) {
- setWidget((Widget) paintable);
+ if (getWidget() != paintable.getWidgetForPaintable()) {
+ setWidget(paintable.getWidgetForPaintable());
}
UIDL childUIDL = componentUIDL.getChildUIDL(0);
paintable.updateFromUIDL(childUIDL, client);
// child may need relative size adjustment if wrapper details
// have changed this could be optimized (check if wrapper size
// has changed)
- client.handleComponentRelativeSize((Widget) paintable);
+ client.handleComponentRelativeSize(paintable
+ .getWidgetForPaintable());
}
}
* @return The Paintable which the element is a part of. Null if the element
* belongs to the layout and not to a child.
*/
- private Paintable getComponent(Element element) {
+ private VPaintableWidget getComponent(Element element) {
return Util.getPaintableForElement(client, this, element);
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VCaption;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
public class VAccordion extends VTabsheetBase implements
ContainerResizedListener {
public static final String CLASSNAME = "v-accordion";
- private Set<Paintable> paintables = new HashSet<Paintable>();
+ private Set<Widget> widgets = new HashSet<Widget>();
private String height;
private StackItem moveStackItemIfNeeded(StackItem item, int newIndex,
UIDL tabUidl) {
UIDL tabContentUIDL = null;
- Paintable tabContent = null;
+ VPaintableWidget tabContent = null;
if (tabUidl.getChildCount() > 0) {
tabContentUIDL = tabUidl.getChildUIDL(0);
tabContent = client.getPaintable(tabContentUIDL);
}
public void setHeightFromWidget() {
- Widget paintable = getPaintable();
- if (paintable == null) {
+ Widget widget = getChildWidget();
+ if (widget == null) {
return;
}
- int paintableHeight = (paintable).getElement().getOffsetHeight();
+ int paintableHeight = widget.getElement().getOffsetHeight();
setHeight(paintableHeight);
}
return content;
}
- public Widget getPaintable() {
+ public Widget getChildWidget() {
if (getWidgetCount() > 1) {
return getWidget(1);
} else {
}
}
- public void replacePaintable(Paintable newPntbl) {
+ public void replaceWidget(Widget newWidget) {
if (getWidgetCount() > 1) {
- client.unregisterPaintable((Paintable) getWidget(1));
- paintables.remove(getWidget(1));
+ Widget oldWidget = getWidget(1);
+ VPaintableWidget oldPaintable = VPaintableMap.get(client)
+ .getPaintable(oldWidget);
+ VPaintableMap.get(client).unregisterPaintable(oldPaintable);
+ widgets.remove(oldWidget);
remove(1);
}
- add((Widget) newPntbl, content);
- paintables.add(newPntbl);
+ add(newWidget, content);
+ widgets.add(newWidget);
}
public void open() {
}
public void setContent(UIDL contentUidl) {
- final Paintable newPntbl = client.getPaintable(contentUidl);
- if (getPaintable() == null) {
- add((Widget) newPntbl, content);
- paintables.add(newPntbl);
- } else if (getPaintable() != newPntbl) {
- replacePaintable(newPntbl);
+ final VPaintableWidget newPntbl = client.getPaintable(contentUidl);
+ Widget newWidget = newPntbl.getWidgetForPaintable();
+ if (getChildWidget() == null) {
+ add(newWidget, content);
+ widgets.add(newWidget);
+ } else if (getChildWidget() != newWidget) {
+ replaceWidget(newWidget);
}
newPntbl.updateFromUIDL(contentUidl, client);
if (contentUidl.getBooleanAttribute("cached")) {
* The size of a cached, relative sized component must be
* updated to report correct size.
*/
- client.handleComponentRelativeSize((Widget) newPntbl);
+ client.handleComponentRelativeSize(newPntbl
+ .getWidgetForPaintable());
}
if (isOpen() && isDynamicHeight()) {
setHeightFromWidget();
return DOM.getFirstChild(content).getOffsetWidth();
}
- public boolean contains(Paintable p) {
- return (getPaintable() == p);
+ public boolean contains(VPaintableWidget p) {
+ return (getChildWidget() == p.getWidgetForPaintable());
}
public boolean isCaptionVisible() {
@Override
@SuppressWarnings("unchecked")
- protected Iterator<Object> getPaintableIterator() {
- return (Iterator) paintables.iterator();
+ protected Iterator<Widget> getWidgetIterator() {
+ return widgets.iterator();
}
public boolean hasChildComponent(Widget component) {
- if (paintables.contains(component)) {
- return true;
- } else {
- return false;
+ for (Widget w : widgets) {
+ if (w == component) {
+ return true;
+ }
}
+ return false;
}
public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
for (Widget w : getChildren()) {
StackItem item = (StackItem) w;
- if (item.getPaintable() == oldComponent) {
- item.replacePaintable((Paintable) newComponent);
+ if (item.getChildWidget() == oldComponent) {
+ item.replaceWidget(newComponent);
return;
}
}
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
/* Accordion does not render its children's captions */
}
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
if (!isDynamicHeight() && !isDynamicWidth()) {
/*
* If the height and width has been specified for this container the
* child components cannot make the size of the layout change
*/
// layout size change may affect its available space (scrollbars)
- for (Paintable paintable : child) {
- client.handleComponentRelativeSize((Widget) paintable);
+ for (Widget widget : children) {
+ client.handleComponentRelativeSize(widget);
}
return true;
}
@Override
- protected Paintable getTab(int index) {
+ protected VPaintableWidget getTab(int index) {
if (index < getWidgetCount()) {
- return (Paintable) (getStackItem(index)).getPaintable();
+ Widget w = getStackItem(index);
+ return VPaintableMap.get(client).getPaintable(w);
}
return null;
private StackItem getStackItem(int index) {
return (StackItem) getWidget(index);
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.UIDL;
protected String getDefaultAltHtml() {
return "Your browser does not support the <code>audio</code> element.";
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Accessibility;
import com.google.gwt.user.client.ui.FocusWidget;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.EventHelper;
import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VTooltip;
-public class VButton extends FocusWidget implements Paintable, ClickHandler,
- FocusHandler, BlurHandler {
+public class VButton extends FocusWidget implements VPaintableWidget,
+ ClickHandler, FocusHandler, BlurHandler {
public static final String CLASSNAME = "v-button";
private static final String CLASSNAME_PRESSED = "v-pressed";
client.updateVariable(id, EventId.BLUR, "", true);
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
// elapsed, another timer is triggered to go off every 150ms. Both\r
// timers are cancelled on mouseup or mouseout.\r
if (event.getSource() instanceof VEventButton) {\r
- final Widget sender = (Widget) event.getSource();\r
+ final VEventButton sender = (VEventButton) event.getSource();\r
processClickEvent(sender);\r
mouseTimer = new Timer() {\r
@Override\r
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.EventHelper;
import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VTooltip;
public class VCheckBox extends com.google.gwt.user.client.ui.CheckBox implements
- Paintable, Field, FocusHandler, BlurHandler {
+ VPaintableWidget, Field, FocusHandler, BlurHandler {
public static final String VARIABLE_STATE = "state";
public void onBlur(BlurEvent arg0) {
client.updateVariable(id, EventId.BLUR, "", true);
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.StyleConstants;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VCaption;
import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ValueMap;
-public class VCssLayout extends SimplePanel implements Paintable, Container {
+public class VCssLayout extends SimplePanel implements VPaintableWidget,
+ Container {
public static final String TAGNAME = "csslayout";
public static final String CLASSNAME = "v-" + TAGNAME;
this, EventId.LAYOUT_CLICK) {
@Override
- protected Paintable getChildComponent(Element element) {
+ protected VPaintableWidget getChildComponent(Element element) {
return panel.getComponent(element);
}
panel.replaceChildComponent(oldComponent, newComponent);
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
panel.updateCaption(component, uidl);
}
public void updateRelativeSizes() {
for (Widget w : getChildren()) {
- if (w instanceof Paintable) {
+ if (w instanceof VPaintableWidget) {
client.handleComponentRelativeSize(w);
}
}
for (final Iterator<Object> i = uidl.getChildIterator(); i
.hasNext();) {
final UIDL r = (UIDL) i.next();
- final Paintable child = client.getPaintable(r);
- final Widget widget = (Widget) child;
+ final VPaintableWidget child = client.getPaintable(r);
+ final Widget widget = child.getWidgetForPaintable();
if (widget.getParent() == this) {
- oldWidgets.remove(child);
- VCaption vCaption = widgetToCaption.get(child);
+ oldWidgets.remove(widget);
+ VCaption vCaption = widgetToCaption.get(widget);
if (vCaption != null) {
addOrMove(vCaption, lastIndex++);
oldWidgets.remove(vCaption);
// them
for (Widget w : oldWidgets) {
remove(w);
- if (w instanceof Paintable) {
- final Paintable p = (Paintable) w;
+ VPaintableMap paintableMap = VPaintableMap.get(client);
+ if (paintableMap.isPaintable(w)) {
+ final VPaintableWidget p = VPaintableMap.get(client)
+ .getPaintable(w);
client.unregisterPaintable(p);
}
VCaption vCaption = widgetToCaption.remove(w);
}
}
- public void updateCaption(Paintable component, UIDL uidl) {
- VCaption caption = widgetToCaption.get(component);
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ Widget widget = paintable.getWidgetForPaintable();
+ VCaption caption = widgetToCaption.get(widget);
if (VCaption.isNeeded(uidl)) {
- Widget widget = (Widget) component;
if (caption == null) {
- caption = new VCaption(component, client);
+ caption = new VCaption(paintable, client);
widgetToCaption.put(widget, caption);
insert(caption, getWidgetIndex(widget));
lastIndex++;
caption.updateCaption(uidl);
} else if (caption != null) {
remove(caption);
- widgetToCaption.remove(component);
+ widgetToCaption.remove(widget);
}
}
- private Paintable getComponent(Element element) {
+ private VPaintableWidget getComponent(Element element) {
return Util
.getPaintableForElement(client, VCssLayout.this, element);
}
return space;
}
- public boolean requestLayout(Set<Paintable> children) {
+ public boolean requestLayout(Set<Widget> children) {
if (hasSize()) {
return true;
} else {
}
return cssProperty;
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
public class VCustomComponent extends SimplePanel implements Container {
final UIDL child = uidl.getChildUIDL(0);
if (child != null) {
- final Paintable p = client.getPaintable(child);
- if (p != getWidget()) {
+ final VPaintableWidget paintable = client.getPaintable(child);
+ Widget widget = paintable.getWidgetForPaintable();
+ if (widget != getWidget()) {
if (getWidget() != null) {
- client.unregisterPaintable((Paintable) getWidget());
+ client.unregisterPaintable(VPaintableMap.get(client)
+ .getPaintable(getWidget()));
clear();
}
- setWidget((Widget) p);
+ setWidget(widget);
}
- p.updateFromUIDL(child, client);
+ paintable.updateFromUIDL(child, client);
}
boolean updateDynamicSize = updateDynamicSize();
}
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
// NOP, custom component dont render composition roots caption
}
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
// If a child grows in size, it will not necessarily be calculated
// correctly unless we remove previous size definitions
if (isDynamicWidth()) {
}
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VCaption;
import com.vaadin.terminal.gwt.client.VCaptionWrapper;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
/**
* Custom Layout implements complex layout defined with HTML template.
* @author Vaadin Ltd
*
*/
-public class VCustomLayout extends ComplexPanel implements Paintable,
+public class VCustomLayout extends ComplexPanel implements VPaintableWidget,
Container, ContainerResizedListener {
public static final String CLASSNAME = "v-customlayout";
private final HashMap<String, Widget> locationToWidget = new HashMap<String, Widget>();
/** Widget to captionwrapper map */
- private final HashMap<Paintable, VCaptionWrapper> widgetToCaptionWrapper = new HashMap<Paintable, VCaptionWrapper>();
+ private final HashMap<VPaintableWidget, VCaptionWrapper> paintableToCaptionWrapper = new HashMap<VPaintableWidget, VCaptionWrapper>();
/** Name of the currently rendered style */
String currentTemplateName;
final UIDL uidlForChild = (UIDL) i.next();
if (uidlForChild.getTag().equals("location")) {
final String location = uidlForChild.getStringAttribute("name");
- final Paintable child = client.getPaintable(uidlForChild
- .getChildUIDL(0));
+ UIDL childUIDL = uidlForChild.getChildUIDL(0);
+ final VPaintableWidget childPaintable = client
+ .getPaintable(childUIDL);
+ Widget childWidget = childPaintable.getWidgetForPaintable();
try {
- setWidget((Widget) child, location);
- child.updateFromUIDL(uidlForChild.getChildUIDL(0), client);
+ setWidget(childWidget, location);
+ childPaintable.updateFromUIDL(childUIDL, client);
} catch (final IllegalArgumentException e) {
// If no location is found, this component is not visible
}
- oldWidgets.remove(child);
+ oldWidgets.remove(childWidget);
}
}
for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
}
/** Update caption for given widget */
- public void updateCaption(Paintable component, UIDL uidl) {
- VCaptionWrapper wrapper = widgetToCaptionWrapper.get(component);
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ VCaptionWrapper wrapper = paintableToCaptionWrapper.get(paintable);
+ Widget widget = paintable.getWidgetForPaintable();
if (VCaption.isNeeded(uidl)) {
if (wrapper == null) {
- final String loc = getLocation((Widget) component);
- super.remove((Widget) component);
- wrapper = new VCaptionWrapper(component, client);
+ // Add a wrapper between the layout and the child widget
+ final String loc = getLocation(widget);
+ super.remove(widget);
+ wrapper = new VCaptionWrapper(paintable, client);
super.add(wrapper, locationToElement.get(loc));
- widgetToCaptionWrapper.put(component, wrapper);
+ paintableToCaptionWrapper.put(paintable, wrapper);
}
wrapper.updateCaption(uidl);
} else {
if (wrapper != null) {
- final String loc = getLocation((Widget) component);
+ // Remove the wrapper and add the widget directly to the layout
+ final String loc = getLocation(widget);
super.remove(wrapper);
- super.add((Widget) wrapper.getPaintable(),
- locationToElement.get(loc));
- widgetToCaptionWrapper.remove(component);
+ super.add(widget, locationToElement.get(loc));
+ paintableToCaptionWrapper.remove(paintable);
}
}
}
/** Removes given widget from the layout */
@Override
public boolean remove(Widget w) {
- client.unregisterPaintable((Paintable) w);
+ VPaintableWidget paintable = VPaintableMap.get(client).getPaintable(w);
+ client.unregisterPaintable(paintable);
final String location = getLocation(w);
if (location != null) {
locationToWidget.remove(location);
}
- final VCaptionWrapper cw = widgetToCaptionWrapper.get(w);
+ final VCaptionWrapper cw = paintableToCaptionWrapper.get(paintable);
if (cw != null) {
- widgetToCaptionWrapper.remove(w);
+ paintableToCaptionWrapper.remove(paintable);
return super.remove(cw);
} else if (w != null) {
return super.remove(w);
public void clear() {
super.clear();
locationToWidget.clear();
- widgetToCaptionWrapper.clear();
+ paintableToCaptionWrapper.clear();
}
public void iLayout() {
}
}-*/;
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
updateRelativeSizedComponents(true, true);
if (width.equals("") || height.equals("")) {
return larger;
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
-/* \r
-@VaadinApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import java.util.Date;\r
-\r
-import com.google.gwt.user.client.Event;\r
-import com.google.gwt.user.client.ui.FlowPanel;\r
-import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
-import com.vaadin.terminal.gwt.client.DateTimeService;\r
-import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;\r
-import com.vaadin.terminal.gwt.client.Paintable;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-import com.vaadin.terminal.gwt.client.VConsole;\r
-import com.vaadin.terminal.gwt.client.VTooltip;\r
-\r
-public class VDateField extends FlowPanel implements Paintable, Field {\r
-\r
- public static final String CLASSNAME = "v-datefield";\r
-\r
- private String id;\r
-\r
- private ApplicationConnection client;\r
-\r
- protected boolean immediate;\r
-\r
- public static final int RESOLUTION_YEAR = 1;\r
- public static final int RESOLUTION_MONTH = 2;\r
- public static final int RESOLUTION_DAY = 4;\r
- public static final int RESOLUTION_HOUR = 8;\r
- public static final int RESOLUTION_MIN = 16;\r
- public static final int RESOLUTION_SEC = 32;\r
-\r
- public static final String WEEK_NUMBERS = "wn";\r
-\r
- static String resolutionToString(int res) {\r
- if (res > RESOLUTION_DAY) {\r
- return "full";\r
- }\r
- if (res == RESOLUTION_DAY) {\r
- return "day";\r
- }\r
- if (res == RESOLUTION_MONTH) {\r
- return "month";\r
- }\r
- return "year";\r
- }\r
-\r
- protected int currentResolution = RESOLUTION_YEAR;\r
-\r
- protected String currentLocale;\r
-\r
- protected boolean readonly;\r
-\r
- protected boolean enabled;\r
-\r
- /**\r
- * The date that is selected in the date field. Null if an invalid date is\r
- * specified.\r
- */\r
- private Date date = null;\r
-\r
- protected DateTimeService dts;\r
-\r
- private boolean showISOWeekNumbers = false;\r
-\r
- public VDateField() {\r
- setStyleName(CLASSNAME);\r
- dts = new DateTimeService();\r
- sinkEvents(VTooltip.TOOLTIP_EVENTS);\r
- }\r
-\r
- @Override\r
- public void onBrowserEvent(Event event) {\r
- super.onBrowserEvent(event);\r
- if (client != null) {\r
- client.handleTooltipEvent(event, this);\r
- }\r
- }\r
-\r
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
- // Ensure correct implementation and let layout manage caption\r
- if (client.updateComponent(this, uidl, true)) {\r
- return;\r
- }\r
-\r
- // Save details\r
- this.client = client;\r
- id = uidl.getId();\r
- immediate = uidl.getBooleanAttribute("immediate");\r
-\r
- readonly = uidl.getBooleanAttribute("readonly");\r
- enabled = !uidl.getBooleanAttribute("disabled");\r
-\r
- if (uidl.hasAttribute("locale")) {\r
- final String locale = uidl.getStringAttribute("locale");\r
- try {\r
- dts.setLocale(locale);\r
- currentLocale = locale;\r
- } catch (final LocaleNotLoadedException e) {\r
- currentLocale = dts.getLocale();\r
- VConsole.error("Tried to use an unloaded locale \"" + locale\r
- + "\". Using default locale (" + currentLocale + ").");\r
- VConsole.error(e);\r
- }\r
- }\r
-\r
- // We show week numbers only if the week starts with Monday, as ISO 8601\r
- // specifies\r
- showISOWeekNumbers = uidl.getBooleanAttribute(WEEK_NUMBERS)\r
- && dts.getFirstDayOfWeek() == 1;\r
-\r
- int newResolution;\r
- if (uidl.hasVariable("sec")) {\r
- newResolution = RESOLUTION_SEC;\r
- } else if (uidl.hasVariable("min")) {\r
- newResolution = RESOLUTION_MIN;\r
- } else if (uidl.hasVariable("hour")) {\r
- newResolution = RESOLUTION_HOUR;\r
- } else if (uidl.hasVariable("day")) {\r
- newResolution = RESOLUTION_DAY;\r
- } else if (uidl.hasVariable("month")) {\r
- newResolution = RESOLUTION_MONTH;\r
- } else {\r
- newResolution = RESOLUTION_YEAR;\r
- }\r
-\r
- currentResolution = newResolution;\r
-\r
- // Add stylename that indicates current resolution\r
- addStyleName(CLASSNAME + "-" + resolutionToString(currentResolution));\r
-\r
- final int year = uidl.getIntVariable("year");\r
- final int month = (currentResolution >= RESOLUTION_MONTH) ? uidl\r
- .getIntVariable("month") : -1;\r
- final int day = (currentResolution >= RESOLUTION_DAY) ? uidl\r
- .getIntVariable("day") : -1;\r
- final int hour = (currentResolution >= RESOLUTION_HOUR) ? uidl\r
- .getIntVariable("hour") : 0;\r
- final int min = (currentResolution >= RESOLUTION_MIN) ? uidl\r
- .getIntVariable("min") : 0;\r
- final int sec = (currentResolution >= RESOLUTION_SEC) ? uidl\r
- .getIntVariable("sec") : 0;\r
-\r
- // Construct new date for this datefield (only if not null)\r
- if (year > -1) {\r
- setCurrentDate(new Date((long) getTime(year, month, day, hour, min,\r
- sec, 0)));\r
- } else {\r
- setCurrentDate(null);\r
- }\r
- }\r
-\r
- /*\r
- * We need this redundant native function because Java's Date object doesn't\r
- * have a setMilliseconds method.\r
- */\r
- private static native double getTime(int y, int m, int d, int h, int mi,\r
- int s, int ms)\r
- /*-{\r
- try {\r
- var date = new Date(2000,1,1,1); // don't use current date here\r
- if(y && y >= 0) date.setFullYear(y);\r
- if(m && m >= 1) date.setMonth(m-1);\r
- if(d && d >= 0) date.setDate(d);\r
- if(h >= 0) date.setHours(h);\r
- if(mi >= 0) date.setMinutes(mi);\r
- if(s >= 0) date.setSeconds(s);\r
- if(ms >= 0) date.setMilliseconds(ms);\r
- return date.getTime();\r
- } catch (e) {\r
- // TODO print some error message on the console\r
- //console.log(e);\r
- return (new Date()).getTime();\r
- }\r
- }-*/;\r
-\r
- public int getMilliseconds() {\r
- return DateTimeService.getMilliseconds(date);\r
- }\r
-\r
- public void setMilliseconds(int ms) {\r
- DateTimeService.setMilliseconds(date, ms);\r
- }\r
-\r
- public int getCurrentResolution() {\r
- return currentResolution;\r
- }\r
-\r
- public void setCurrentResolution(int currentResolution) {\r
- this.currentResolution = currentResolution;\r
- }\r
-\r
- public String getCurrentLocale() {\r
- return currentLocale;\r
- }\r
-\r
- public void setCurrentLocale(String currentLocale) {\r
- this.currentLocale = currentLocale;\r
- }\r
-\r
- public Date getCurrentDate() {\r
- return date;\r
- }\r
-\r
- public void setCurrentDate(Date date) {\r
- this.date = date;\r
- }\r
-\r
- public boolean isImmediate() {\r
- return immediate;\r
- }\r
-\r
- public boolean isReadonly() {\r
- return readonly;\r
- }\r
-\r
- public boolean isEnabled() {\r
- return enabled;\r
- }\r
-\r
- public DateTimeService getDateTimeService() {\r
- return dts;\r
- }\r
-\r
- public String getId() {\r
- return id;\r
- }\r
-\r
- public ApplicationConnection getClient() {\r
- return client;\r
- }\r
-\r
- /**\r
- * Returns whether ISO 8601 week numbers should be shown in the date\r
- * selector or not. ISO 8601 defines that a week always starts with a Monday\r
- * so the week numbers are only shown if this is the case.\r
- * \r
- * @return true if week number should be shown, false otherwise\r
- */\r
- public boolean isShowISOWeekNumbers() {\r
- return showISOWeekNumbers;\r
- }\r
-\r
- /**\r
- * Returns a copy of the current date. Modifying the returned date will not\r
- * modify the value of this VDateField. Use {@link #setDate(Date)} to change\r
- * the current date.\r
- * \r
- * @return A copy of the current date\r
- */\r
- protected Date getDate() {\r
- Date current = getCurrentDate();\r
- if (current == null) {\r
- return null;\r
- } else {\r
- return (Date) getCurrentDate().clone();\r
- }\r
- }\r
-\r
- /**\r
- * Sets the current date for this VDateField.\r
- * \r
- * @param date\r
- * The new date to use\r
- */\r
- protected void setDate(Date date) {\r
- this.date = date;\r
- }\r
-}\r
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.DateTimeService;
+import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VTooltip;
+
+public class VDateField extends FlowPanel implements VPaintableWidget, Field {
+
+ public static final String CLASSNAME = "v-datefield";
+
+ private String id;
+
+ private ApplicationConnection client;
+
+ protected boolean immediate;
+
+ public static final int RESOLUTION_YEAR = 1;
+ public static final int RESOLUTION_MONTH = 2;
+ public static final int RESOLUTION_DAY = 4;
+ public static final int RESOLUTION_HOUR = 8;
+ public static final int RESOLUTION_MIN = 16;
+ public static final int RESOLUTION_SEC = 32;
+
+ public static final String WEEK_NUMBERS = "wn";
+
+ static String resolutionToString(int res) {
+ if (res > RESOLUTION_DAY) {
+ return "full";
+ }
+ if (res == RESOLUTION_DAY) {
+ return "day";
+ }
+ if (res == RESOLUTION_MONTH) {
+ return "month";
+ }
+ return "year";
+ }
+
+ protected int currentResolution = RESOLUTION_YEAR;
+
+ protected String currentLocale;
+
+ protected boolean readonly;
+
+ protected boolean enabled;
+
+ /**
+ * The date that is selected in the date field. Null if an invalid date is
+ * specified.
+ */
+ private Date date = null;
+
+ protected DateTimeService dts;
+
+ private boolean showISOWeekNumbers = false;
+
+ public VDateField() {
+ setStyleName(CLASSNAME);
+ dts = new DateTimeService();
+ sinkEvents(VTooltip.TOOLTIP_EVENTS);
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ super.onBrowserEvent(event);
+ if (client != null) {
+ client.handleTooltipEvent(event, this);
+ }
+ }
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Ensure correct implementation and let layout manage caption
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ // Save details
+ this.client = client;
+ id = uidl.getId();
+ immediate = uidl.getBooleanAttribute("immediate");
+
+ readonly = uidl.getBooleanAttribute("readonly");
+ enabled = !uidl.getBooleanAttribute("disabled");
+
+ if (uidl.hasAttribute("locale")) {
+ final String locale = uidl.getStringAttribute("locale");
+ try {
+ dts.setLocale(locale);
+ currentLocale = locale;
+ } catch (final LocaleNotLoadedException e) {
+ currentLocale = dts.getLocale();
+ VConsole.error("Tried to use an unloaded locale \"" + locale
+ + "\". Using default locale (" + currentLocale + ").");
+ VConsole.error(e);
+ }
+ }
+
+ // We show week numbers only if the week starts with Monday, as ISO 8601
+ // specifies
+ showISOWeekNumbers = uidl.getBooleanAttribute(WEEK_NUMBERS)
+ && dts.getFirstDayOfWeek() == 1;
+
+ int newResolution;
+ if (uidl.hasVariable("sec")) {
+ newResolution = RESOLUTION_SEC;
+ } else if (uidl.hasVariable("min")) {
+ newResolution = RESOLUTION_MIN;
+ } else if (uidl.hasVariable("hour")) {
+ newResolution = RESOLUTION_HOUR;
+ } else if (uidl.hasVariable("day")) {
+ newResolution = RESOLUTION_DAY;
+ } else if (uidl.hasVariable("month")) {
+ newResolution = RESOLUTION_MONTH;
+ } else {
+ newResolution = RESOLUTION_YEAR;
+ }
+
+ currentResolution = newResolution;
+
+ // Add stylename that indicates current resolution
+ addStyleName(CLASSNAME + "-" + resolutionToString(currentResolution));
+
+ final int year = uidl.getIntVariable("year");
+ final int month = (currentResolution >= RESOLUTION_MONTH) ? uidl
+ .getIntVariable("month") : -1;
+ final int day = (currentResolution >= RESOLUTION_DAY) ? uidl
+ .getIntVariable("day") : -1;
+ final int hour = (currentResolution >= RESOLUTION_HOUR) ? uidl
+ .getIntVariable("hour") : 0;
+ final int min = (currentResolution >= RESOLUTION_MIN) ? uidl
+ .getIntVariable("min") : 0;
+ final int sec = (currentResolution >= RESOLUTION_SEC) ? uidl
+ .getIntVariable("sec") : 0;
+
+ // Construct new date for this datefield (only if not null)
+ if (year > -1) {
+ setCurrentDate(new Date((long) getTime(year, month, day, hour, min,
+ sec, 0)));
+ } else {
+ setCurrentDate(null);
+ }
+ }
+
+ /*
+ * We need this redundant native function because Java's Date object doesn't
+ * have a setMilliseconds method.
+ */
+ private static native double getTime(int y, int m, int d, int h, int mi,
+ int s, int ms)
+ /*-{
+ try {
+ var date = new Date(2000,1,1,1); // don't use current date here
+ if(y && y >= 0) date.setFullYear(y);
+ if(m && m >= 1) date.setMonth(m-1);
+ if(d && d >= 0) date.setDate(d);
+ if(h >= 0) date.setHours(h);
+ if(mi >= 0) date.setMinutes(mi);
+ if(s >= 0) date.setSeconds(s);
+ if(ms >= 0) date.setMilliseconds(ms);
+ return date.getTime();
+ } catch (e) {
+ // TODO print some error message on the console
+ //console.log(e);
+ return (new Date()).getTime();
+ }
+ }-*/;
+
+ public int getMilliseconds() {
+ return DateTimeService.getMilliseconds(date);
+ }
+
+ public void setMilliseconds(int ms) {
+ DateTimeService.setMilliseconds(date, ms);
+ }
+
+ public int getCurrentResolution() {
+ return currentResolution;
+ }
+
+ public void setCurrentResolution(int currentResolution) {
+ this.currentResolution = currentResolution;
+ }
+
+ public String getCurrentLocale() {
+ return currentLocale;
+ }
+
+ public void setCurrentLocale(String currentLocale) {
+ this.currentLocale = currentLocale;
+ }
+
+ public Date getCurrentDate() {
+ return date;
+ }
+
+ public void setCurrentDate(Date date) {
+ this.date = date;
+ }
+
+ public boolean isImmediate() {
+ return immediate;
+ }
+
+ public boolean isReadonly() {
+ return readonly;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public DateTimeService getDateTimeService() {
+ return dts;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public ApplicationConnection getClient() {
+ return client;
+ }
+
+ /**
+ * Returns whether ISO 8601 week numbers should be shown in the date
+ * selector or not. ISO 8601 defines that a week always starts with a Monday
+ * so the week numbers are only shown if this is the case.
+ *
+ * @return true if week number should be shown, false otherwise
+ */
+ public boolean isShowISOWeekNumbers() {
+ return showISOWeekNumbers;
+ }
+
+ /**
+ * Returns a copy of the current date. Modifying the returned date will not
+ * modify the value of this VDateField. Use {@link #setDate(Date)} to change
+ * the current date.
+ *
+ * @return A copy of the current date
+ */
+ protected Date getDate() {
+ Date current = getCurrentDate();
+ if (current == null) {
+ return null;
+ } else {
+ return (Date) getCurrentDate().clone();
+ }
+ }
+
+ /**
+ * Sets the current date for this VDateField.
+ *
+ * @param date
+ * The new date to use
+ */
+ protected void setDate(Date date) {
+ this.date = date;
+ }
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+}
import com.google.gwt.xhr.client.XMLHttpRequest;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.PaintableMap;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderInformation.Size;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintable;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
import com.vaadin.terminal.gwt.client.ValueMap;
import com.vaadin.terminal.gwt.client.ui.dd.DDUtil;
VTransferable transferable = new VTransferable();
transferable.setDragSource(VDragAndDropWrapper.this);
- Paintable paintable;
- Widget w = Util.findWidget((Element) event.getEventTarget().cast(),
- null);
- while (w != null && !(w instanceof Paintable)) {
- w = w.getParent();
+ Widget widget = Util.findWidget((Element) event.getEventTarget()
+ .cast(), null);
+ VPaintableMap vPaintableMap = VPaintableMap.get(client);
+ while (widget != null && !vPaintableMap.isPaintable(widget)) {
+ widget = widget.getParent();
}
- paintable = (Paintable) w;
+ VPaintableWidget paintable = vPaintableMap.getPaintable(widget);
transferable.setData("component", paintable);
VDragEvent dragEvent = VDragAndDropManager.get().startDrag(
if (dragStartMode == WRAPPER) {
dragEvent.createDragImage(getElement(), true);
} else {
- dragEvent.createDragImage(((Widget) paintable).getElement(),
- true);
+ dragEvent.createDragImage(widget.getElement(), true);
}
return true;
}
}
private String getPid() {
- return PaintableMap.get(client).getPid((Paintable) this);
+ return VPaintableMap.get(client).getPid((VPaintable) this);
}
public VDropHandler getDropHandler() {
}
@Override
- public Paintable getPaintable() {
+ public VPaintableWidget getPaintable() {
return VDragAndDropWrapper.this;
}
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
import com.vaadin.terminal.gwt.client.VTooltip;
-public class VEmbedded extends HTML implements Paintable {
+public class VEmbedded extends HTML implements VPaintableWidget {
public static final String CLICK_EVENT_IDENTIFIER = "click";
private static String CLASSNAME = "v-embedded";
}
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.Focusable;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
* TODO needs major refactoring (to be extensible etc)
*/
@SuppressWarnings("deprecation")
-public class VFilterSelect extends Composite implements Paintable, Field,
+public class VFilterSelect extends Composite implements VPaintableWidget, Field,
KeyDownHandler, KeyUpHandler, ClickHandler, FocusHandler, BlurHandler,
Focusable {
super.onDetach();
suggestionPopup.hide();
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
-/* \r
-@VaadinApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import java.util.Set;\r
-\r
-import com.google.gwt.dom.client.Style.Display;\r
-import com.google.gwt.event.dom.client.KeyDownEvent;\r
-import com.google.gwt.event.dom.client.KeyDownHandler;\r
-import com.google.gwt.event.shared.HandlerRegistration;\r
-import com.google.gwt.user.client.DOM;\r
-import com.google.gwt.user.client.Element;\r
-import com.google.gwt.user.client.Event;\r
-import com.google.gwt.user.client.ui.ComplexPanel;\r
-import com.google.gwt.user.client.ui.Widget;\r
-import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
-import com.vaadin.terminal.gwt.client.Container;\r
-import com.vaadin.terminal.gwt.client.Paintable;\r
-import com.vaadin.terminal.gwt.client.RenderInformation;\r
-import com.vaadin.terminal.gwt.client.RenderSpace;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-import com.vaadin.terminal.gwt.client.Util;\r
-import com.vaadin.terminal.gwt.client.VConsole;\r
-import com.vaadin.terminal.gwt.client.VErrorMessage;\r
-\r
-public class VForm extends ComplexPanel implements Container, KeyDownHandler {\r
-\r
- protected String id;\r
-\r
- private String height = "";\r
-\r
- private String width = "";\r
-\r
- public static final String CLASSNAME = "v-form";\r
-\r
- private Container lo;\r
- private Element legend = DOM.createLegend();\r
- private Element caption = DOM.createSpan();\r
- private Element errorIndicatorElement = DOM.createDiv();\r
- private Element desc = DOM.createDiv();\r
- private Icon icon;\r
- private VErrorMessage errorMessage = new VErrorMessage();\r
-\r
- private Element fieldContainer = DOM.createDiv();\r
-\r
- private Element footerContainer = DOM.createDiv();\r
-\r
- private Element fieldSet = DOM.createFieldSet();\r
-\r
- private Container footer;\r
-\r
- private ApplicationConnection client;\r
-\r
- private RenderInformation renderInformation = new RenderInformation();\r
-\r
- private int borderPaddingHorizontal = -1;\r
-\r
- private boolean rendering = false;\r
-\r
- ShortcutActionHandler shortcutHandler;\r
-\r
- private HandlerRegistration keyDownRegistration;\r
-\r
- public VForm() {\r
- setElement(DOM.createDiv());\r
- getElement().appendChild(fieldSet);\r
- setStyleName(CLASSNAME);\r
- fieldSet.appendChild(legend);\r
- legend.appendChild(caption);\r
- errorIndicatorElement.setClassName("v-errorindicator");\r
- errorIndicatorElement.getStyle().setDisplay(Display.NONE);\r
- errorIndicatorElement.setInnerText(" "); // needed for IE\r
- desc.setClassName("v-form-description");\r
- fieldSet.appendChild(desc); // Adding description for initial padding\r
- // measurements, removed later if no\r
- // description is set\r
- fieldSet.appendChild(fieldContainer);\r
- errorMessage.setVisible(false);\r
- errorMessage.setStyleName(CLASSNAME + "-errormessage");\r
- fieldSet.appendChild(errorMessage.getElement());\r
- fieldSet.appendChild(footerContainer);\r
- }\r
-\r
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
- rendering = true;\r
- this.client = client;\r
- id = uidl.getId();\r
-\r
- if (client.updateComponent(this, uidl, false)) {\r
- rendering = false;\r
- return;\r
- }\r
-\r
- boolean legendEmpty = true;\r
- if (uidl.hasAttribute("caption")) {\r
- caption.setInnerText(uidl.getStringAttribute("caption"));\r
- legendEmpty = false;\r
- } else {\r
- caption.setInnerText("");\r
- }\r
- if (uidl.hasAttribute("icon")) {\r
- if (icon == null) {\r
- icon = new Icon(client);\r
- legend.insertFirst(icon.getElement());\r
- }\r
- icon.setUri(uidl.getStringAttribute("icon"));\r
- legendEmpty = false;\r
- } else {\r
- if (icon != null) {\r
- legend.removeChild(icon.getElement());\r
- }\r
- }\r
- if (legendEmpty) {\r
- addStyleDependentName("nocaption");\r
- } else {\r
- removeStyleDependentName("nocaption");\r
- }\r
-\r
- if (uidl.hasAttribute("error")) {\r
- final UIDL errorUidl = uidl.getErrors();\r
- errorMessage.updateFromUIDL(errorUidl);\r
- errorMessage.setVisible(true);\r
-\r
- } else {\r
- errorMessage.setVisible(false);\r
- }\r
-\r
- if (uidl.hasAttribute("description")) {\r
- desc.setInnerHTML(uidl.getStringAttribute("description"));\r
- if (desc.getParentElement() == null) {\r
- fieldSet.insertAfter(desc, legend);\r
- }\r
- } else {\r
- desc.setInnerHTML("");\r
- if (desc.getParentElement() != null) {\r
- fieldSet.removeChild(desc);\r
- }\r
- }\r
-\r
- updateSize();\r
-\r
- // first render footer so it will be easier to handle relative height of\r
- // main layout\r
- if (uidl.getChildCount() > 1\r
- && !uidl.getChildUIDL(1).getTag().equals("actions")) {\r
- // render footer\r
- Container newFooter = (Container) client.getPaintable(uidl\r
- .getChildUIDL(1));\r
- if (footer == null) {\r
- add((Widget) newFooter, footerContainer);\r
- footer = newFooter;\r
- } else if (newFooter != footer) {\r
- remove((Widget) footer);\r
- client.unregisterPaintable(footer);\r
- add((Widget) newFooter, footerContainer);\r
- }\r
- footer = newFooter;\r
- footer.updateFromUIDL(uidl.getChildUIDL(1), client);\r
- // needed for the main layout to know the space it has available\r
- updateSize();\r
- } else {\r
- if (footer != null) {\r
- remove((Widget) footer);\r
- client.unregisterPaintable(footer);\r
- // needed for the main layout to know the space it has available\r
- updateSize();\r
- }\r
- }\r
-\r
- final UIDL layoutUidl = uidl.getChildUIDL(0);\r
- Container newLo = (Container) client.getPaintable(layoutUidl);\r
- if (lo == null) {\r
- lo = newLo;\r
- add((Widget) lo, fieldContainer);\r
- } else if (lo != newLo) {\r
- client.unregisterPaintable(lo);\r
- remove((Widget) lo);\r
- lo = newLo;\r
- add((Widget) lo, fieldContainer);\r
- }\r
- lo.updateFromUIDL(layoutUidl, client);\r
-\r
- // also recalculates size of the footer if undefined size form - see\r
- // #3710\r
- updateSize();\r
- client.runDescendentsLayout(this);\r
-\r
- // We may have actions attached\r
- if (uidl.getChildCount() > 1) {\r
- UIDL childUidl = uidl.getChildByTagName("actions");\r
- if (childUidl != null) {\r
- if (shortcutHandler == null) {\r
- shortcutHandler = new ShortcutActionHandler(id, client);\r
- keyDownRegistration = addDomHandler(this,\r
- KeyDownEvent.getType());\r
- }\r
- shortcutHandler.updateActionMap(childUidl);\r
- }\r
- } else if (shortcutHandler != null) {\r
- keyDownRegistration.removeHandler();\r
- shortcutHandler = null;\r
- keyDownRegistration = null;\r
- }\r
-\r
- rendering = false;\r
- }\r
-\r
- public void updateSize() {\r
-\r
- renderInformation.updateSize(getElement());\r
-\r
- renderInformation.setContentAreaHeight(renderInformation\r
- .getRenderedSize().getHeight() - getSpaceConsumedVertically());\r
- renderInformation.setContentAreaWidth(renderInformation\r
- .getRenderedSize().getWidth() - borderPaddingHorizontal);\r
- }\r
-\r
- public RenderSpace getAllocatedSpace(Widget child) {\r
- if (child == lo) {\r
- return renderInformation.getContentAreaSize();\r
- } else if (child == footer) {\r
- return new RenderSpace(renderInformation.getContentAreaSize()\r
- .getWidth(), 0);\r
- } else {\r
- VConsole.error("Invalid child requested RenderSpace information");\r
- return null;\r
- }\r
- }\r
-\r
- public boolean hasChildComponent(Widget component) {\r
- return component != null && (component == lo || component == footer);\r
- }\r
-\r
- public void replaceChildComponent(Widget oldComponent, Widget newComponent) {\r
- if (!hasChildComponent(oldComponent)) {\r
- throw new IllegalArgumentException(\r
- "Old component is not inside this Container");\r
- }\r
- remove(oldComponent);\r
- if (oldComponent == lo) {\r
- lo = (Container) newComponent;\r
- add((Widget) lo, fieldContainer);\r
- } else {\r
- footer = (Container) newComponent;\r
- add((Widget) footer, footerContainer);\r
- }\r
-\r
- }\r
-\r
- public boolean requestLayout(Set<Paintable> child) {\r
-\r
- if (height != null && !"".equals(height) && width != null\r
- && !"".equals(width)) {\r
- /*\r
- * If the height and width has been specified the child components\r
- * cannot make the size of the layout change\r
- */\r
-\r
- return true;\r
- }\r
-\r
- if (renderInformation.updateSize(getElement())) {\r
- return false;\r
- } else {\r
- return true;\r
- }\r
-\r
- }\r
-\r
- public void updateCaption(Paintable component, UIDL uidl) {\r
- // NOP form don't render caption for neither field layout nor footer\r
- // layout\r
- }\r
-\r
- @Override\r
- public void setHeight(String height) {\r
- if (this.height.equals(height)) {\r
- return;\r
- }\r
-\r
- this.height = height;\r
- super.setHeight(height);\r
-\r
- updateSize();\r
- }\r
-\r
- /**\r
- * @return pixels consumed by decoration, captions, descrioptiosn etc.. In\r
- * other words space, not used by the actual layout in form.\r
- */\r
- private int getSpaceConsumedVertically() {\r
- int offsetHeight2 = fieldSet.getOffsetHeight();\r
- int offsetHeight3 = fieldContainer.getOffsetHeight();\r
- int borderPadding = offsetHeight2 - offsetHeight3;\r
- return borderPadding;\r
- }\r
-\r
- @Override\r
- public void setWidth(String width) {\r
- if (borderPaddingHorizontal < 0) {\r
- // measure excess size lazily after stylename setting, but before\r
- // setting width\r
- int ow = getOffsetWidth();\r
- int dow = desc.getOffsetWidth();\r
- borderPaddingHorizontal = ow - dow;\r
- }\r
- if (Util.equals(this.width, width)) {\r
- return;\r
- }\r
-\r
- this.width = width;\r
- super.setWidth(width);\r
-\r
- updateSize();\r
-\r
- if (!rendering && height.equals("")) {\r
- // Width might affect height\r
- Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this);\r
- }\r
- }\r
-\r
- public void onKeyDown(KeyDownEvent event) {\r
- shortcutHandler.handleKeyboardEvent(Event.as(event.getNativeEvent()));\r
- }\r
-}\r
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Set;
+
+import com.google.gwt.dom.client.Style.Display;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.event.dom.client.KeyDownHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.ComplexPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.Container;
+import com.vaadin.terminal.gwt.client.RenderInformation;
+import com.vaadin.terminal.gwt.client.RenderSpace;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VErrorMessage;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+
+public class VForm extends ComplexPanel implements Container, KeyDownHandler {
+
+ protected String id;
+
+ private String height = "";
+
+ private String width = "";
+
+ public static final String CLASSNAME = "v-form";
+
+ private Container lo;
+ private Element legend = DOM.createLegend();
+ private Element caption = DOM.createSpan();
+ private Element errorIndicatorElement = DOM.createDiv();
+ private Element desc = DOM.createDiv();
+ private Icon icon;
+ private VErrorMessage errorMessage = new VErrorMessage();
+
+ private Element fieldContainer = DOM.createDiv();
+
+ private Element footerContainer = DOM.createDiv();
+
+ private Element fieldSet = DOM.createFieldSet();
+
+ private Container footer;
+
+ private ApplicationConnection client;
+
+ private RenderInformation renderInformation = new RenderInformation();
+
+ private int borderPaddingHorizontal = -1;
+
+ private boolean rendering = false;
+
+ ShortcutActionHandler shortcutHandler;
+
+ private HandlerRegistration keyDownRegistration;
+
+ public VForm() {
+ setElement(DOM.createDiv());
+ getElement().appendChild(fieldSet);
+ setStyleName(CLASSNAME);
+ fieldSet.appendChild(legend);
+ legend.appendChild(caption);
+ errorIndicatorElement.setClassName("v-errorindicator");
+ errorIndicatorElement.getStyle().setDisplay(Display.NONE);
+ errorIndicatorElement.setInnerText(" "); // needed for IE
+ desc.setClassName("v-form-description");
+ fieldSet.appendChild(desc); // Adding description for initial padding
+ // measurements, removed later if no
+ // description is set
+ fieldSet.appendChild(fieldContainer);
+ errorMessage.setVisible(false);
+ errorMessage.setStyleName(CLASSNAME + "-errormessage");
+ fieldSet.appendChild(errorMessage.getElement());
+ fieldSet.appendChild(footerContainer);
+ }
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ rendering = true;
+ this.client = client;
+ id = uidl.getId();
+
+ if (client.updateComponent(this, uidl, false)) {
+ rendering = false;
+ return;
+ }
+
+ boolean legendEmpty = true;
+ if (uidl.hasAttribute("caption")) {
+ caption.setInnerText(uidl.getStringAttribute("caption"));
+ legendEmpty = false;
+ } else {
+ caption.setInnerText("");
+ }
+ if (uidl.hasAttribute("icon")) {
+ if (icon == null) {
+ icon = new Icon(client);
+ legend.insertFirst(icon.getElement());
+ }
+ icon.setUri(uidl.getStringAttribute("icon"));
+ legendEmpty = false;
+ } else {
+ if (icon != null) {
+ legend.removeChild(icon.getElement());
+ }
+ }
+ if (legendEmpty) {
+ addStyleDependentName("nocaption");
+ } else {
+ removeStyleDependentName("nocaption");
+ }
+
+ if (uidl.hasAttribute("error")) {
+ final UIDL errorUidl = uidl.getErrors();
+ errorMessage.updateFromUIDL(errorUidl);
+ errorMessage.setVisible(true);
+
+ } else {
+ errorMessage.setVisible(false);
+ }
+
+ if (uidl.hasAttribute("description")) {
+ desc.setInnerHTML(uidl.getStringAttribute("description"));
+ if (desc.getParentElement() == null) {
+ fieldSet.insertAfter(desc, legend);
+ }
+ } else {
+ desc.setInnerHTML("");
+ if (desc.getParentElement() != null) {
+ fieldSet.removeChild(desc);
+ }
+ }
+
+ updateSize();
+
+ // first render footer so it will be easier to handle relative height of
+ // main layout
+ if (uidl.getChildCount() > 1
+ && !uidl.getChildUIDL(1).getTag().equals("actions")) {
+ // render footer
+ Container newFooter = (Container) client.getPaintable(uidl
+ .getChildUIDL(1));
+ if (footer == null) {
+ add(newFooter.getWidgetForPaintable(), footerContainer);
+ footer = newFooter;
+ } else if (newFooter != footer) {
+ remove(footer.getWidgetForPaintable());
+ client.unregisterPaintable(footer);
+ add(newFooter.getWidgetForPaintable(), footerContainer);
+ }
+ footer = newFooter;
+ footer.updateFromUIDL(uidl.getChildUIDL(1), client);
+ // needed for the main layout to know the space it has available
+ updateSize();
+ } else {
+ if (footer != null) {
+ remove(footer.getWidgetForPaintable());
+ client.unregisterPaintable(footer);
+ // needed for the main layout to know the space it has available
+ updateSize();
+ }
+ }
+
+ final UIDL layoutUidl = uidl.getChildUIDL(0);
+ Container newLo = (Container) client.getPaintable(layoutUidl);
+ if (lo == null) {
+ lo = newLo;
+ add(lo.getWidgetForPaintable(), fieldContainer);
+ } else if (lo != newLo) {
+ client.unregisterPaintable(lo);
+ remove(lo.getWidgetForPaintable());
+ lo = newLo;
+ add(lo.getWidgetForPaintable(), fieldContainer);
+ }
+ lo.updateFromUIDL(layoutUidl, client);
+
+ // also recalculates size of the footer if undefined size form - see
+ // #3710
+ updateSize();
+ client.runDescendentsLayout(this);
+
+ // We may have actions attached
+ if (uidl.getChildCount() > 1) {
+ UIDL childUidl = uidl.getChildByTagName("actions");
+ if (childUidl != null) {
+ if (shortcutHandler == null) {
+ shortcutHandler = new ShortcutActionHandler(id, client);
+ keyDownRegistration = addDomHandler(this,
+ KeyDownEvent.getType());
+ }
+ shortcutHandler.updateActionMap(childUidl);
+ }
+ } else if (shortcutHandler != null) {
+ keyDownRegistration.removeHandler();
+ shortcutHandler = null;
+ keyDownRegistration = null;
+ }
+
+ rendering = false;
+ }
+
+ public void updateSize() {
+
+ renderInformation.updateSize(getElement());
+
+ renderInformation.setContentAreaHeight(renderInformation
+ .getRenderedSize().getHeight() - getSpaceConsumedVertically());
+ renderInformation.setContentAreaWidth(renderInformation
+ .getRenderedSize().getWidth() - borderPaddingHorizontal);
+ }
+
+ public RenderSpace getAllocatedSpace(Widget child) {
+ if (child == lo) {
+ return renderInformation.getContentAreaSize();
+ } else if (child == footer) {
+ return new RenderSpace(renderInformation.getContentAreaSize()
+ .getWidth(), 0);
+ } else {
+ VConsole.error("Invalid child requested RenderSpace information");
+ return null;
+ }
+ }
+
+ public boolean hasChildComponent(Widget component) {
+ return component != null && (component == lo || component == footer);
+ }
+
+ public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+ if (!hasChildComponent(oldComponent)) {
+ throw new IllegalArgumentException(
+ "Old component is not inside this Container");
+ }
+ remove(oldComponent);
+ if (oldComponent == lo) {
+ lo = (Container) VPaintableMap.get(client).getPaintable(
+ newComponent);
+ add(newComponent, fieldContainer);
+ } else {
+ footer = (Container) VPaintableMap.get(client).getPaintable(
+ newComponent);
+ add(newComponent, footerContainer);
+ }
+
+ }
+
+ public boolean requestLayout(Set<Widget> child) {
+
+ if (height != null && !"".equals(height) && width != null
+ && !"".equals(width)) {
+ /*
+ * If the height and width has been specified the child components
+ * cannot make the size of the layout change
+ */
+
+ return true;
+ }
+
+ if (renderInformation.updateSize(getElement())) {
+ return false;
+ } else {
+ return true;
+ }
+
+ }
+
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
+ // NOP form don't render caption for neither field layout nor footer
+ // layout
+ }
+
+ @Override
+ public void setHeight(String height) {
+ if (this.height.equals(height)) {
+ return;
+ }
+
+ this.height = height;
+ super.setHeight(height);
+
+ updateSize();
+ }
+
+ /**
+ * @return pixels consumed by decoration, captions, descrioptiosn etc.. In
+ * other words space, not used by the actual layout in form.
+ */
+ private int getSpaceConsumedVertically() {
+ int offsetHeight2 = fieldSet.getOffsetHeight();
+ int offsetHeight3 = fieldContainer.getOffsetHeight();
+ int borderPadding = offsetHeight2 - offsetHeight3;
+ return borderPadding;
+ }
+
+ @Override
+ public void setWidth(String width) {
+ if (borderPaddingHorizontal < 0) {
+ // measure excess size lazily after stylename setting, but before
+ // setting width
+ int ow = getOffsetWidth();
+ int dow = desc.getOffsetWidth();
+ borderPaddingHorizontal = ow - dow;
+ }
+ if (Util.equals(this.width, width)) {
+ return;
+ }
+
+ this.width = width;
+ super.setWidth(width);
+
+ updateSize();
+
+ if (!rendering && height.equals("")) {
+ // Width might affect height
+ Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this,
+ this);
+ }
+ }
+
+ public void onKeyDown(KeyDownEvent event) {
+ shortcutHandler.handleKeyboardEvent(Event.as(event.getNativeEvent()));
+ }
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+}
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.Focusable;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.StyleConstants;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
/**
private static final int COLUMN_ERRORFLAG = 1;
private static final int COLUMN_WIDGET = 2;
- private HashMap<Paintable, Caption> componentToCaption = new HashMap<Paintable, Caption>();
- private HashMap<Paintable, ErrorFlag> componentToError = new HashMap<Paintable, ErrorFlag>();
+ private HashMap<Widget, Caption> widgetToCaption = new HashMap<Widget, Caption>();
+ private HashMap<Widget, ErrorFlag> widgetToError = new HashMap<Widget, ErrorFlag>();
public VFormLayoutTable() {
DOM.setElementProperty(getElement(), "cellPadding", "0");
for (final Iterator<?> it = uidl.getChildIterator(); it.hasNext(); i++) {
prepareCell(i, 1);
final UIDL childUidl = (UIDL) it.next();
- final Paintable p = client.getPaintable(childUidl);
- Caption caption = componentToCaption.get(p);
+ final VPaintableWidget childPaintable = client
+ .getPaintable(childUidl);
+ Widget childWidget = childPaintable.getWidgetForPaintable();
+ Caption caption = widgetToCaption.get(childWidget);
if (caption == null) {
- caption = new Caption(p, client,
+ caption = new Caption(childPaintable, client,
getStylesFromUIDL(childUidl));
caption.addClickHandler(this);
- componentToCaption.put(p, caption);
+ widgetToCaption.put(childWidget, caption);
}
- ErrorFlag error = componentToError.get(p);
+ ErrorFlag error = widgetToError.get(childWidget);
if (error == null) {
error = new ErrorFlag();
- componentToError.put(p, error);
+ widgetToError.put(childWidget, error);
}
prepareCell(i, COLUMN_WIDGET);
- final Paintable oldComponent = (Paintable) getWidget(i,
- COLUMN_WIDGET);
- if (oldComponent == null) {
- setWidget(i, COLUMN_WIDGET, (Widget) p);
- } else if (oldComponent != p) {
- client.unregisterPaintable(oldComponent);
- setWidget(i, COLUMN_WIDGET, (Widget) p);
+
+ Widget oldWidget = getWidget(i, COLUMN_WIDGET);
+ if (oldWidget == null) {
+ setWidget(i, COLUMN_WIDGET, childWidget);
+ } else if (oldWidget != childWidget) {
+ final VPaintableWidget oldPaintable = VPaintableMap.get(
+ client).getPaintable(oldWidget);
+ client.unregisterPaintable(oldPaintable);
+ setWidget(i, COLUMN_WIDGET, childWidget);
}
getCellFormatter().setStyleName(i, COLUMN_WIDGET,
CLASSNAME + "-contentcell");
CLASSNAME + "-errorcell");
setWidget(i, COLUMN_ERRORFLAG, error);
- p.updateFromUIDL(childUidl, client);
+ childPaintable.updateFromUIDL(childUidl, client);
String rowstyles = CLASSNAME + "-row";
if (i == 0) {
}
while (getRowCount() > i) {
- final Paintable p = (Paintable) getWidget(i, COLUMN_WIDGET);
+ Widget w = getWidget(i, COLUMN_WIDGET);
+ final VPaintableWidget p = VPaintableMap.get(client)
+ .getPaintable(w);
client.unregisterPaintable(p);
- componentToCaption.remove(p);
+ widgetToCaption.remove(w);
removeRow(i);
}
* Must update relative sized fields last when it is clear how much
* space they are allowed to use
*/
- for (Paintable p : componentToCaption.keySet()) {
- client.handleComponentRelativeSize((Widget) p);
+ for (Widget p : widgetToCaption.keySet()) {
+ client.handleComponentRelativeSize(p);
}
}
for (i = 0; i < getRowCount(); i++) {
Widget candidate = getWidget(i, COLUMN_WIDGET);
if (oldComponent == candidate) {
- Caption oldCap = componentToCaption.get(oldComponent);
- final Caption newCap = new Caption(
- (Paintable) newComponent, client, null);
+ VPaintableMap paintableMap = VPaintableMap.get(client);
+ VPaintableWidget oldPaintable = paintableMap
+ .getPaintable(oldComponent);
+ VPaintableWidget newPaintable = paintableMap
+ .getPaintable(newComponent);
+ Caption oldCap = widgetToCaption.get(oldComponent);
+ final Caption newCap = new Caption(newPaintable, client,
+ null);
newCap.addClickHandler(this);
newCap.setStyleName(oldCap.getStyleName());
- componentToCaption.put((Paintable) newComponent, newCap);
- ErrorFlag error = componentToError.get(newComponent);
+ widgetToCaption.put(newComponent, newCap);
+ ErrorFlag error = widgetToError.get(newComponent);
if (error == null) {
error = new ErrorFlag();
- componentToError.put((Paintable) newComponent, error);
+ widgetToError.put(newComponent, error);
}
setWidget(i, COLUMN_CAPTION, newCap);
}
public boolean hasChildComponent(Widget component) {
- return componentToCaption.containsKey(component);
+ return widgetToCaption.containsKey(component);
}
- public void updateCaption(Paintable component, UIDL uidl) {
- final Caption c = componentToCaption.get(component);
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ final Caption c = widgetToCaption.get(paintable
+ .getWidgetForPaintable());
if (c != null) {
c.updateCaption(uidl);
}
- final ErrorFlag e = componentToError.get(component);
+ final ErrorFlag e = widgetToError.get(paintable
+ .getWidgetForPaintable());
if (e != null) {
- e.updateFromUIDL(uidl, component);
+ e.updateFromUIDL(uidl, paintable);
}
}
public int getAllocatedWidth(Widget child, int availableWidth) {
- Caption caption = componentToCaption.get(child);
- ErrorFlag error = componentToError.get(child);
+ Caption caption = widgetToCaption.get(child);
+ ErrorFlag error = widgetToError.get(child);
int width = availableWidth;
if (caption != null) {
table.replaceChildComponent(oldComponent, newComponent);
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
table.updateCaption(component, uidl);
}
public static final String CLASSNAME = "v-caption";
- private final Paintable owner;
+ private final VPaintableWidget owner;
private Element requiredFieldIndicator;
* return null
* @param client
*/
- public Caption(Paintable component, ApplicationConnection client,
- String[] styles) {
+ public Caption(VPaintableWidget component,
+ ApplicationConnection client, String[] styles) {
super();
this.client = client;
owner = component;
*
* @return owner Widget
*/
- public Paintable getOwner() {
+ public VPaintableWidget getOwner() {
return owner;
}
private static final String CLASSNAME = VFormLayout.CLASSNAME
+ "-error-indicator";
Element errorIndicatorElement;
- private Paintable owner;
+ private VPaintableWidget owner;
public ErrorFlag() {
setStyleName(CLASSNAME);
sinkEvents(VTooltip.TOOLTIP_EVENTS);
}
- public void updateFromUIDL(UIDL uidl, Paintable component) {
+ public void updateFromUIDL(UIDL uidl, VPaintableWidget component) {
owner = component;
if (uidl.hasAttribute("error")
&& !uidl.getBooleanAttribute("hideErrors")) {
}
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
if (height.equals("") || width.equals("")) {
// A dynamic size might change due to children changes
return false;
table.setContentWidths();
if (height.equals("")) {
// Width might affect height
- Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this);
+ Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this,
+ this);
}
}
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.StyleConstants;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayout;
import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer;
-public class VGridLayout extends SimplePanel implements Paintable, Container {
+public class VGridLayout extends SimplePanel implements VPaintableWidget,
+ Container {
public static final String CLASSNAME = "v-gridlayout";
protected HashMap<Widget, ChildComponentContainer> widgetToComponentContainer = new HashMap<Widget, ChildComponentContainer>();
- private HashMap<Paintable, Cell> paintableToCell = new HashMap<Paintable, Cell>();
+ private HashMap<Widget, Cell> widgetToCell = new HashMap<Widget, Cell>();
private int spacingPixelsHorizontal;
private int spacingPixelsVertical;
this, EventId.LAYOUT_CLICK) {
@Override
- protected Paintable getChildComponent(Element element) {
+ protected VPaintableWidget getChildComponent(Element element) {
return getComponent(element);
}
for (Widget w : nonRenderedWidgets.keySet()) {
ChildComponentContainer childComponentContainer = widgetToComponentContainer
.get(w);
- paintableToCell.remove(w);
+ widgetToCell.remove(w);
widgetToComponentContainer.remove(w);
childComponentContainer.removeFromParent();
- client.unregisterPaintable((Paintable) w);
+ VPaintableMap paintableMap = VPaintableMap.get(client);
+ paintableMap.unregisterPaintable(paintableMap.getPaintable(w));
}
nonRenderedWidgets = null;
} else {
expandRows();
layoutCells();
- for (Paintable c : paintableToCell.keySet()) {
- client.handleComponentRelativeSize((Widget) c);
+ for (Widget w : widgetToCell.keySet()) {
+ client.handleComponentRelativeSize(w);
}
}
}
}
layoutCells();
- for (Paintable c : paintableToCell.keySet()) {
- client.handleComponentRelativeSize((Widget) c);
+ for (Widget w : widgetToCell.keySet()) {
+ client.handleComponentRelativeSize(w);
}
if (heightChanged && "".equals(height)) {
Util.notifyParentOfSizeChange(this, false);
}
public boolean hasChildComponent(Widget component) {
- return paintableToCell.containsKey(component);
+ return widgetToCell.containsKey(component);
}
public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
return;
}
- componentContainer.setWidget(newComponent);
+ componentContainer.setPaintable(VPaintableMap.get(client).getPaintable(
+ newComponent));
widgetToComponentContainer.put(newComponent, componentContainer);
- paintableToCell.put((Paintable) newComponent,
- paintableToCell.get(oldComponent));
+ widgetToCell.put(newComponent, widgetToCell.get(oldComponent));
}
- public void updateCaption(Paintable component, UIDL uidl) {
- ChildComponentContainer cc = widgetToComponentContainer.get(component);
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ Widget widget = paintable.getWidgetForPaintable();
+ ChildComponentContainer cc = widgetToComponentContainer.get(widget);
if (cc != null) {
cc.updateCaption(uidl, client);
}
if (!rendering) {
// ensure rel size details are updated
- paintableToCell.get(component).updateRelSizeStatus(uidl);
+ widgetToCell.get(widget).updateRelSizeStatus(uidl);
/*
* This was a component-only update and the possible size change
* must be propagated to the layout
*/
- client.captionSizeUpdated(component);
+ client.captionSizeUpdated(widget);
}
}
- public boolean requestLayout(final Set<Paintable> changedChildren) {
+ public boolean requestLayout(final Set<Widget> changedChildren) {
boolean needsLayout = false;
boolean reDistributeColSpanWidths = false;
boolean reDistributeRowSpanHeights = false;
}
ArrayList<Integer> dirtyColumns = new ArrayList<Integer>();
ArrayList<Integer> dirtyRows = new ArrayList<Integer>();
- for (Paintable paintable : changedChildren) {
+ for (Widget widget : changedChildren) {
- Cell cell = paintableToCell.get(paintable);
+ Cell cell = widgetToCell.get(widget);
if (!cell.hasRelativeHeight() || !cell.hasRelativeWidth()) {
// cell sizes will only stay still if only relatively
// sized components
}
public RenderSpace getAllocatedSpace(Widget child) {
- Cell cell = paintableToCell.get(child);
+ Cell cell = widgetToCell.get(child);
assert cell != null;
return cell.getAllocatedSpace();
}
protected void render() {
assert childUidl != null;
- Paintable paintable = client.getPaintable(childUidl);
+ VPaintableWidget paintable = client.getPaintable(childUidl);
+ Widget w = paintable.getWidgetForPaintable();
assert paintable != null;
- if (cc == null || cc.getWidget() != paintable) {
- if (widgetToComponentContainer.containsKey(paintable)) {
+ if (cc == null || cc.getWidget() != w) {
+ if (widgetToComponentContainer.containsKey(w)) {
// Component moving from one place to another
- cc = widgetToComponentContainer.get(paintable);
+ cc = widgetToComponentContainer.get(w);
cc.setWidth("");
cc.setHeight("");
/*
* and this layout has been hidden when moving out, see
* #5372
*/
- cc.setWidget((Widget) paintable);
+ cc.setPaintable(paintable);
} else {
// A new component
- cc = new ChildComponentContainer((Widget) paintable,
+ cc = new ChildComponentContainer(paintable,
CellBasedLayout.ORIENTATION_VERTICAL);
- widgetToComponentContainer.put((Widget) paintable, cc);
+ widgetToComponentContainer.put(w, cc);
cc.setWidth("");
canvas.add(cc, 0, 0);
}
- paintableToCell.put(paintable, this);
+ widgetToCell.put(w, this);
}
cc.renderChild(childUidl, client, -1);
if (sizeChangedDuringRendering && Util.isCached(childUidl)) {
client.handleComponentRelativeSize(cc.getWidget());
}
cc.updateWidgetSize();
- nonRenderedWidgets.remove(paintable);
+ nonRenderedWidgets.remove(w);
}
public UIDL getChildUIDL() {
// canvas later during the render phase
cc = null;
} else if (cc != null
- && cc.getWidget() != client.getPaintable(c)) {
+ && cc.getWidget() != client.getPaintable(c)
+ .getWidgetForPaintable()) {
// content has changed
cc = null;
- Paintable paintable = client.getPaintable(c);
- if (widgetToComponentContainer.containsKey(paintable)) {
+ VPaintableWidget paintable = client.getPaintable(c);
+ Widget w = paintable.getWidgetForPaintable();
+ if (widgetToComponentContainer.containsKey(w)) {
// cc exist for this component (moved) use that for this
// cell
- cc = widgetToComponentContainer.get(paintable);
+ cc = widgetToComponentContainer.get(w);
cc.setWidth("");
cc.setHeight("");
- paintableToCell.put(paintable, this);
+ widgetToCell.put(w, this);
}
}
}
* @return The Paintable which the element is a part of. Null if the element
* belongs to the layout and not to a child.
*/
- private Paintable getComponent(Element element) {
+ private VPaintableWidget getComponent(Element element) {
return Util.getPaintableForElement(client, this, element);
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
package com.vaadin.terminal.gwt.client.ui;
-import com.google.gwt.dom.client.Document;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.dom.client.PreElement;
-import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTML;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VTooltip;
-public class VLabel extends HTML implements Paintable {
+public class VLabel extends HTML {
public static final String CLASSNAME = "v-label";
private static final String CLASSNAME_UNDEFINED_WIDTH = "v-label-undef-w";
- private ApplicationConnection client;
private int verticalPaddingBorder = 0;
private int horizontalPaddingBorder = 0;
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (event.getTypeInt() == Event.ONLOAD) {
+ // FIXME: Should not be here but in paintable
Util.notifyParentOfSizeChange(this, true);
event.cancelBubble(true);
return;
}
- if (client != null) {
- client.handleTooltipEvent(event, this);
- }
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- this.client = client;
-
- boolean sinkOnloads = false;
-
- final String mode = uidl.getStringAttribute("mode");
- if (mode == null || "text".equals(mode)) {
- setText(uidl.getChildString(0));
- } else if ("pre".equals(mode)) {
- PreElement preElement = Document.get().createPreElement();
- preElement.setInnerText(uidl.getChildUIDL(0).getChildString(0));
- // clear existing content
- setHTML("");
- // add preformatted text to dom
- getElement().appendChild(preElement);
- } else if ("uidl".equals(mode)) {
- setHTML(uidl.getChildrenAsXML());
- } else if ("xhtml".equals(mode)) {
- UIDL content = uidl.getChildUIDL(0).getChildUIDL(0);
- if (content.getChildCount() > 0) {
- setHTML(content.getChildString(0));
- } else {
- setHTML("");
- }
- sinkOnloads = true;
- } else if ("xml".equals(mode)) {
- setHTML(uidl.getChildUIDL(0).getChildString(0));
- } else if ("raw".equals(mode)) {
- setHTML(uidl.getChildUIDL(0).getChildString(0));
- sinkOnloads = true;
- } else {
- setText("");
- }
- if (sinkOnloads) {
- sinkOnloadsForContainedImgs();
- }
- }
-
- private void sinkOnloadsForContainedImgs() {
- NodeList<Element> images = getElement().getElementsByTagName("img");
- for (int i = 0; i < images.getLength(); i++) {
- Element img = images.getItem(i);
- DOM.sinkEvents((com.google.gwt.user.client.Element) img,
- Event.ONLOAD);
- }
-
+ // FIXME: Move to paintable
+ // if (client != null) {
+ // client.handleTooltipEvent(event, this);
+ // }
}
@Override
--- /dev/null
+/*\r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.dom.client.Document;\r
+import com.google.gwt.dom.client.PreElement;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.KeyDownEvent;\r
+import com.google.gwt.event.dom.client.KeyDownHandler;\r
+import com.google.gwt.event.dom.client.MouseMoveEvent;\r
+import com.google.gwt.event.dom.client.MouseMoveHandler;\r
+import com.google.gwt.event.dom.client.MouseOutEvent;\r
+import com.google.gwt.event.dom.client.MouseOutHandler;\r
+import com.google.gwt.event.dom.client.MouseOverEvent;\r
+import com.google.gwt.event.dom.client.MouseOverHandler;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.Util;\r
+import com.vaadin.terminal.gwt.client.VPaintableWidget;\r
+\r
+public class VLabelPaintable implements VPaintableWidget {\r
+\r
+ private VLabel widget = GWT.create(VLabel.class);\r
+ private ApplicationConnection client;\r
+\r
+ class TooltipHandler implements ClickHandler, KeyDownHandler,\r
+ MouseOverHandler, MouseOutHandler, MouseMoveHandler {\r
+\r
+ public void onClick(ClickEvent event) {\r
+ // TODO Auto-generated method stub\r
+\r
+ }\r
+\r
+ public void onMouseMove(MouseMoveEvent event) {\r
+ // TODO Auto-generated method stub\r
+\r
+ }\r
+\r
+ public void onMouseOut(MouseOutEvent event) {\r
+ // TODO Auto-generated method stub\r
+\r
+ }\r
+\r
+ public void onMouseOver(MouseOverEvent event) {\r
+ // TODO Auto-generated method stub\r
+\r
+ }\r
+\r
+ public void onKeyDown(KeyDownEvent event) {\r
+ // TODO Auto-generated method stub\r
+\r
+ }\r
+\r
+ }\r
+\r
+ public VLabelPaintable() {\r
+ TooltipHandler handler = new TooltipHandler();\r
+\r
+ widget.addDomHandler(handler, ClickEvent.getType());\r
+ widget.addDomHandler(handler, KeyDownEvent.getType());\r
+ widget.addDomHandler(handler, MouseOverEvent.getType());\r
+ widget.addDomHandler(handler, MouseOutEvent.getType());\r
+ widget.addDomHandler(handler, MouseMoveEvent.getType());\r
+\r
+ }\r
+\r
+ public VLabel getWidget() {\r
+ return widget;\r
+ }\r
+\r
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+\r
+ if (client.updateComponent(getWidget(), uidl, true)) {\r
+ return;\r
+ }\r
+\r
+ this.client = client;\r
+\r
+ boolean sinkOnloads = false;\r
+\r
+ final String mode = uidl.getStringAttribute("mode");\r
+ if (mode == null || "text".equals(mode)) {\r
+ getWidget().setText(uidl.getChildString(0));\r
+ } else if ("pre".equals(mode)) {\r
+ PreElement preElement = Document.get().createPreElement();\r
+ preElement.setInnerText(uidl.getChildUIDL(0).getChildString(0));\r
+ // clear existing content\r
+ getWidget().setHTML("");\r
+ // add preformatted text to dom\r
+ getWidget().getElement().appendChild(preElement);\r
+ } else if ("uidl".equals(mode)) {\r
+ getWidget().setHTML(uidl.getChildrenAsXML());\r
+ } else if ("xhtml".equals(mode)) {\r
+ UIDL content = uidl.getChildUIDL(0).getChildUIDL(0);\r
+ if (content.getChildCount() > 0) {\r
+ getWidget().setHTML(content.getChildString(0));\r
+ } else {\r
+ getWidget().setHTML("");\r
+ }\r
+ sinkOnloads = true;\r
+ } else if ("xml".equals(mode)) {\r
+ getWidget().setHTML(uidl.getChildUIDL(0).getChildString(0));\r
+ } else if ("raw".equals(mode)) {\r
+ getWidget().setHTML(uidl.getChildUIDL(0).getChildString(0));\r
+ sinkOnloads = true;\r
+ } else {\r
+ getWidget().setText("");\r
+ }\r
+ if (sinkOnloads) {\r
+ Util.sinkOnloadForImages(getWidget().getElement());\r
+ }\r
+ }\r
+\r
+ public Widget getWidgetForPaintable() {\r
+ return getWidget();\r
+ }\r
+\r
+}\r
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VTooltip;
-public class VLink extends HTML implements Paintable, ClickHandler {
+public class VLink extends HTML implements VPaintableWidget, ClickHandler {
public static final String CLASSNAME = "v-link";
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VTooltip;
select.setFocus(true);
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
/**
*/
class TooltipListBox extends ListBox {
private ApplicationConnection client;
- private Paintable pntbl;
+ private VPaintableWidget pntbl;
TooltipListBox(boolean isMultiselect) {
super(isMultiselect);
this.client = client;
}
- public void setSelect(Paintable s) {
+ public void setSelect(VPaintableWidget s) {
pntbl = s;
}
client.handleTooltipEvent(event, pntbl);
}
}
+
}
\ No newline at end of file
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-public abstract class VMediaBase extends Widget implements Paintable {
+public abstract class VMediaBase extends Widget implements VPaintableWidget {
public static final String ATTR_PAUSE = "pause";
public static final String ATTR_PLAY = "play";
public static final String ATTR_MUTED = "muted";
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.PaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.TooltipInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
-public class VMenuBar extends SimpleFocusablePanel implements Paintable,
+public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
CloseHandler<PopupPanel>, ContainerResizedListener, KeyPressHandler,
KeyDownHandler, FocusHandler, SubPartAware {
moreItem.setHTML(itemHTML.toString());
moreItem.setCommand(emptyCommand);
- collapsedRootItems = new VMenuBar(true, (VMenuBar) PaintableMap
+ collapsedRootItems = new VMenuBar(true, (VMenuBar) VPaintableMap
.get(client).getPaintable(uidlId));
moreItem.setSubMenu(collapsedRootItems);
moreItem.addStyleName(CLASSNAME + "-more-menuitem");
return null;
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.EventHelper;
import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VTooltip;
-public class VNativeButton extends Button implements Paintable, ClickHandler,
- FocusHandler, BlurHandler {
+public class VNativeButton extends Button implements VPaintableWidget,
+ ClickHandler, FocusHandler, BlurHandler {
public static final String CLASSNAME = "v-nativebutton";
}
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
import java.util.Iterator;
import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.UIDL;
public class VNativeSelect extends VOptionGroupBase implements Field {
select.setFocus(true);
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
-/*\r
-@VaadinApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import com.google.gwt.core.client.Scheduler;\r
-import com.google.gwt.event.dom.client.BlurEvent;\r
-import com.google.gwt.event.dom.client.BlurHandler;\r
-import com.google.gwt.event.dom.client.ClickEvent;\r
-import com.google.gwt.event.dom.client.FocusEvent;\r
-import com.google.gwt.event.dom.client.FocusHandler;\r
-import com.google.gwt.event.dom.client.LoadEvent;\r
-import com.google.gwt.event.dom.client.LoadHandler;\r
-import com.google.gwt.event.shared.HandlerRegistration;\r
-import com.google.gwt.user.client.Command;\r
-import com.google.gwt.user.client.ui.CheckBox;\r
-import com.google.gwt.user.client.ui.FocusWidget;\r
-import com.google.gwt.user.client.ui.Focusable;\r
-import com.google.gwt.user.client.ui.Panel;\r
-import com.google.gwt.user.client.ui.RadioButton;\r
-import com.google.gwt.user.client.ui.Widget;\r
-import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
-import com.vaadin.terminal.gwt.client.EventId;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-import com.vaadin.terminal.gwt.client.Util;\r
-\r
-public class VOptionGroup extends VOptionGroupBase implements FocusHandler,\r
- BlurHandler {\r
-\r
- public static final String HTML_CONTENT_ALLOWED = "usehtml";\r
-\r
- public static final String CLASSNAME = "v-select-optiongroup";\r
-\r
- private final Panel panel;\r
-\r
- private final Map<CheckBox, String> optionsToKeys;\r
-\r
- private boolean sendFocusEvents = false;\r
- private boolean sendBlurEvents = false;\r
- private List<HandlerRegistration> focusHandlers = null;\r
- private List<HandlerRegistration> blurHandlers = null;\r
-\r
- private final LoadHandler iconLoadHandler = new LoadHandler() {\r
- public void onLoad(LoadEvent event) {\r
- Util.notifyParentOfSizeChange(VOptionGroup.this, true);\r
- }\r
- };\r
-\r
- /**\r
- * used to check whether a blur really was a blur of the complete\r
- * optiongroup: if a control inside this optiongroup gains focus right after\r
- * blur of another control inside this optiongroup (meaning: if onFocus\r
- * fires after onBlur has fired), the blur and focus won't be sent to the\r
- * server side as only a focus change inside this optiongroup occured\r
- */\r
- private boolean blurOccured = false;\r
-\r
- private boolean htmlContentAllowed = false;\r
-\r
- public VOptionGroup() {\r
- super(CLASSNAME);\r
- panel = (Panel) optionsContainer;\r
- optionsToKeys = new HashMap<CheckBox, String>();\r
- }\r
-\r
- @Override\r
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
- htmlContentAllowed = uidl.hasAttribute(HTML_CONTENT_ALLOWED);\r
-\r
- super.updateFromUIDL(uidl, client);\r
-\r
- sendFocusEvents = client.hasEventListeners(this, EventId.FOCUS);\r
- sendBlurEvents = client.hasEventListeners(this, EventId.BLUR);\r
-\r
- if (focusHandlers != null) {\r
- for (HandlerRegistration reg : focusHandlers) {\r
- reg.removeHandler();\r
- }\r
- focusHandlers.clear();\r
- focusHandlers = null;\r
-\r
- for (HandlerRegistration reg : blurHandlers) {\r
- reg.removeHandler();\r
- }\r
- blurHandlers.clear();\r
- blurHandlers = null;\r
- }\r
-\r
- if (sendFocusEvents || sendBlurEvents) {\r
- focusHandlers = new ArrayList<HandlerRegistration>();\r
- blurHandlers = new ArrayList<HandlerRegistration>();\r
-\r
- // add focus and blur handlers to checkboxes / radio buttons\r
- for (Widget wid : panel) {\r
- if (wid instanceof CheckBox) {\r
- focusHandlers.add(((CheckBox) wid).addFocusHandler(this));\r
- blurHandlers.add(((CheckBox) wid).addBlurHandler(this));\r
- }\r
- }\r
- }\r
- }\r
-\r
- /*\r
- * Return true if no elements were changed, false otherwise.\r
- */\r
- @Override\r
- protected void buildOptions(UIDL uidl) {\r
- panel.clear();\r
- for (final Iterator<?> it = uidl.getChildIterator(); it.hasNext();) {\r
- final UIDL opUidl = (UIDL) it.next();\r
- CheckBox op;\r
-\r
- String itemHtml = opUidl.getStringAttribute("caption");\r
- if (!htmlContentAllowed) {\r
- itemHtml = Util.escapeHTML(itemHtml);\r
- }\r
-\r
- String icon = opUidl.getStringAttribute("icon");\r
- if (icon != null && icon.length() != 0) {\r
- String iconUrl = client.translateVaadinUri(icon);\r
- itemHtml = "<img src=\"" + iconUrl + "\" class=\""\r
- + Icon.CLASSNAME + "\" alt=\"\" />" + itemHtml;\r
- }\r
-\r
- if (isMultiselect()) {\r
- op = new VCheckBox();\r
- op.setHTML(itemHtml);\r
- } else {\r
- op = new RadioButton(id, itemHtml, true);\r
- op.setStyleName("v-radiobutton");\r
- }\r
-\r
- if (icon != null && icon.length() != 0) {\r
- Util.sinkOnloadForImages(op.getElement());\r
- op.addHandler(iconLoadHandler, LoadEvent.getType());\r
- }\r
-\r
- op.addStyleName(CLASSNAME_OPTION);\r
- op.setValue(opUidl.getBooleanAttribute("selected"));\r
- boolean enabled = !opUidl.getBooleanAttribute("disabled")\r
- && !isReadonly() && !isDisabled();\r
- op.setEnabled(enabled);\r
- setStyleName(op.getElement(),\r
- ApplicationConnection.DISABLED_CLASSNAME, !enabled);\r
- op.addClickHandler(this);\r
- optionsToKeys.put(op, opUidl.getStringAttribute("key"));\r
- panel.add(op);\r
- }\r
- }\r
-\r
- @Override\r
- protected String[] getSelectedItems() {\r
- return selectedKeys.toArray(new String[selectedKeys.size()]);\r
- }\r
-\r
- @Override\r
- public void onClick(ClickEvent event) {\r
- super.onClick(event);\r
- if (event.getSource() instanceof CheckBox) {\r
- final boolean selected = ((CheckBox) event.getSource()).getValue();\r
- final String key = optionsToKeys.get(event.getSource());\r
- if (!isMultiselect()) {\r
- selectedKeys.clear();\r
- }\r
- if (selected) {\r
- selectedKeys.add(key);\r
- } else {\r
- selectedKeys.remove(key);\r
- }\r
- client.updateVariable(id, "selected", getSelectedItems(),\r
- isImmediate());\r
- }\r
- }\r
-\r
- @Override\r
- protected void setTabIndex(int tabIndex) {\r
- for (Iterator<Widget> iterator = panel.iterator(); iterator.hasNext();) {\r
- FocusWidget widget = (FocusWidget) iterator.next();\r
- widget.setTabIndex(tabIndex);\r
- }\r
- }\r
-\r
- public void focus() {\r
- Iterator<Widget> iterator = panel.iterator();\r
- if (iterator.hasNext()) {\r
- ((Focusable) iterator.next()).setFocus(true);\r
- }\r
- }\r
-\r
- public void onFocus(FocusEvent arg0) {\r
- if (!blurOccured) {\r
- // no blur occured before this focus event\r
- // panel was blurred => fire the event to the server side if\r
- // requested by server side\r
- if (sendFocusEvents) {\r
- client.updateVariable(id, EventId.FOCUS, "", true);\r
- }\r
- } else {\r
- // blur occured before this focus event\r
- // another control inside the panel (checkbox / radio box) was\r
- // blurred => do not fire the focus and set blurOccured to false, so\r
- // blur will not be fired, too\r
- blurOccured = false;\r
- }\r
- }\r
-\r
- public void onBlur(BlurEvent arg0) {\r
- blurOccured = true;\r
- if (sendBlurEvents) {\r
- Scheduler.get().scheduleDeferred(new Command() {\r
- public void execute() {\r
- // check whether blurOccured still is true and then send the\r
- // event out to the server\r
- if (blurOccured) {\r
- client.updateVariable(id, EventId.BLUR, "", true);\r
- blurOccured = false;\r
- }\r
- }\r
- });\r
- }\r
- }\r
-}\r
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.event.dom.client.BlurEvent;
+import com.google.gwt.event.dom.client.BlurHandler;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.LoadEvent;
+import com.google.gwt.event.dom.client.LoadHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.CheckBox;
+import com.google.gwt.user.client.ui.FocusWidget;
+import com.google.gwt.user.client.ui.Focusable;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.RadioButton;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventId;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+
+public class VOptionGroup extends VOptionGroupBase implements FocusHandler,
+ BlurHandler {
+
+ public static final String HTML_CONTENT_ALLOWED = "usehtml";
+
+ public static final String CLASSNAME = "v-select-optiongroup";
+
+ private final Panel panel;
+
+ private final Map<CheckBox, String> optionsToKeys;
+
+ private boolean sendFocusEvents = false;
+ private boolean sendBlurEvents = false;
+ private List<HandlerRegistration> focusHandlers = null;
+ private List<HandlerRegistration> blurHandlers = null;
+
+ private final LoadHandler iconLoadHandler = new LoadHandler() {
+ public void onLoad(LoadEvent event) {
+ Util.notifyParentOfSizeChange(VOptionGroup.this, true);
+ }
+ };
+
+ /**
+ * used to check whether a blur really was a blur of the complete
+ * optiongroup: if a control inside this optiongroup gains focus right after
+ * blur of another control inside this optiongroup (meaning: if onFocus
+ * fires after onBlur has fired), the blur and focus won't be sent to the
+ * server side as only a focus change inside this optiongroup occured
+ */
+ private boolean blurOccured = false;
+
+ private boolean htmlContentAllowed = false;
+
+ public VOptionGroup() {
+ super(CLASSNAME);
+ panel = (Panel) optionsContainer;
+ optionsToKeys = new HashMap<CheckBox, String>();
+ }
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ htmlContentAllowed = uidl.hasAttribute(HTML_CONTENT_ALLOWED);
+
+ super.updateFromUIDL(uidl, client);
+
+ sendFocusEvents = client.hasEventListeners(this, EventId.FOCUS);
+ sendBlurEvents = client.hasEventListeners(this, EventId.BLUR);
+
+ if (focusHandlers != null) {
+ for (HandlerRegistration reg : focusHandlers) {
+ reg.removeHandler();
+ }
+ focusHandlers.clear();
+ focusHandlers = null;
+
+ for (HandlerRegistration reg : blurHandlers) {
+ reg.removeHandler();
+ }
+ blurHandlers.clear();
+ blurHandlers = null;
+ }
+
+ if (sendFocusEvents || sendBlurEvents) {
+ focusHandlers = new ArrayList<HandlerRegistration>();
+ blurHandlers = new ArrayList<HandlerRegistration>();
+
+ // add focus and blur handlers to checkboxes / radio buttons
+ for (Widget wid : panel) {
+ if (wid instanceof CheckBox) {
+ focusHandlers.add(((CheckBox) wid).addFocusHandler(this));
+ blurHandlers.add(((CheckBox) wid).addBlurHandler(this));
+ }
+ }
+ }
+ }
+
+ /*
+ * Return true if no elements were changed, false otherwise.
+ */
+ @Override
+ protected void buildOptions(UIDL uidl) {
+ panel.clear();
+ for (final Iterator<?> it = uidl.getChildIterator(); it.hasNext();) {
+ final UIDL opUidl = (UIDL) it.next();
+ CheckBox op;
+
+ String itemHtml = opUidl.getStringAttribute("caption");
+ if (!htmlContentAllowed) {
+ itemHtml = Util.escapeHTML(itemHtml);
+ }
+
+ String icon = opUidl.getStringAttribute("icon");
+ if (icon != null && icon.length() != 0) {
+ String iconUrl = client.translateVaadinUri(icon);
+ itemHtml = "<img src=\"" + iconUrl + "\" class=\""
+ + Icon.CLASSNAME + "\" alt=\"\" />" + itemHtml;
+ }
+
+ if (isMultiselect()) {
+ op = new VCheckBox();
+ op.setHTML(itemHtml);
+ } else {
+ op = new RadioButton(id, itemHtml, true);
+ op.setStyleName("v-radiobutton");
+ }
+
+ if (icon != null && icon.length() != 0) {
+ Util.sinkOnloadForImages(op.getElement());
+ op.addHandler(iconLoadHandler, LoadEvent.getType());
+ }
+
+ op.addStyleName(CLASSNAME_OPTION);
+ op.setValue(opUidl.getBooleanAttribute("selected"));
+ boolean enabled = !opUidl.getBooleanAttribute("disabled")
+ && !isReadonly() && !isDisabled();
+ op.setEnabled(enabled);
+ setStyleName(op.getElement(),
+ ApplicationConnection.DISABLED_CLASSNAME, !enabled);
+ op.addClickHandler(this);
+ optionsToKeys.put(op, opUidl.getStringAttribute("key"));
+ panel.add(op);
+ }
+ }
+
+ @Override
+ protected String[] getSelectedItems() {
+ return selectedKeys.toArray(new String[selectedKeys.size()]);
+ }
+
+ @Override
+ public void onClick(ClickEvent event) {
+ super.onClick(event);
+ if (event.getSource() instanceof CheckBox) {
+ final boolean selected = ((CheckBox) event.getSource()).getValue();
+ final String key = optionsToKeys.get(event.getSource());
+ if (!isMultiselect()) {
+ selectedKeys.clear();
+ }
+ if (selected) {
+ selectedKeys.add(key);
+ } else {
+ selectedKeys.remove(key);
+ }
+ client.updateVariable(id, "selected", getSelectedItems(),
+ isImmediate());
+ }
+ }
+
+ @Override
+ protected void setTabIndex(int tabIndex) {
+ for (Iterator<Widget> iterator = panel.iterator(); iterator.hasNext();) {
+ FocusWidget widget = (FocusWidget) iterator.next();
+ widget.setTabIndex(tabIndex);
+ }
+ }
+
+ public void focus() {
+ Iterator<Widget> iterator = panel.iterator();
+ if (iterator.hasNext()) {
+ ((Focusable) iterator.next()).setFocus(true);
+ }
+ }
+
+ public void onFocus(FocusEvent arg0) {
+ if (!blurOccured) {
+ // no blur occured before this focus event
+ // panel was blurred => fire the event to the server side if
+ // requested by server side
+ if (sendFocusEvents) {
+ client.updateVariable(id, EventId.FOCUS, "", true);
+ }
+ } else {
+ // blur occured before this focus event
+ // another control inside the panel (checkbox / radio box) was
+ // blurred => do not fire the focus and set blurOccured to false, so
+ // blur will not be fired, too
+ blurOccured = false;
+ }
+ }
+
+ public void onBlur(BlurEvent arg0) {
+ blurOccured = true;
+ if (sendBlurEvents) {
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ // check whether blurOccured still is true and then send the
+ // event out to the server
+ if (blurOccured) {
+ client.updateVariable(id, EventId.BLUR, "", true);
+ blurOccured = false;
+ }
+ }
+ });
+ }
+ }
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
+}
-/*\r
-@VaadinApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import java.util.Set;\r
-\r
-import com.google.gwt.event.dom.client.ChangeEvent;\r
-import com.google.gwt.event.dom.client.ChangeHandler;\r
-import com.google.gwt.event.dom.client.ClickEvent;\r
-import com.google.gwt.event.dom.client.ClickHandler;\r
-import com.google.gwt.event.dom.client.KeyCodes;\r
-import com.google.gwt.event.dom.client.KeyPressEvent;\r
-import com.google.gwt.event.dom.client.KeyPressHandler;\r
-import com.google.gwt.user.client.ui.Composite;\r
-import com.google.gwt.user.client.ui.FlowPanel;\r
-import com.google.gwt.user.client.ui.Panel;\r
-import com.google.gwt.user.client.ui.Widget;\r
-import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
-import com.vaadin.terminal.gwt.client.Focusable;\r
-import com.vaadin.terminal.gwt.client.Paintable;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-\r
-abstract class VOptionGroupBase extends Composite implements Paintable, Field,\r
- ClickHandler, ChangeHandler, KeyPressHandler, Focusable {\r
-\r
- public static final String CLASSNAME_OPTION = "v-select-option";\r
-\r
- protected ApplicationConnection client;\r
-\r
- protected String id;\r
-\r
- protected Set<String> selectedKeys;\r
-\r
- private boolean immediate;\r
-\r
- private boolean multiselect;\r
-\r
- private boolean disabled;\r
-\r
- private boolean readonly;\r
-\r
- private int cols = 0;\r
-\r
- private int rows = 0;\r
-\r
- private boolean nullSelectionAllowed = true;\r
-\r
- private boolean nullSelectionItemAvailable = false;\r
-\r
- /**\r
- * Widget holding the different options (e.g. ListBox or Panel for radio\r
- * buttons) (optional, fallbacks to container Panel)\r
- */\r
- protected Widget optionsContainer;\r
-\r
- /**\r
- * Panel containing the component\r
- */\r
- private final Panel container;\r
-\r
- private VTextField newItemField;\r
-\r
- private VNativeButton newItemButton;\r
-\r
- public VOptionGroupBase(String classname) {\r
- container = new FlowPanel();\r
- initWidget(container);\r
- optionsContainer = container;\r
- container.setStyleName(classname);\r
- immediate = false;\r
- multiselect = false;\r
- }\r
-\r
- /*\r
- * Call this if you wish to specify your own container for the option\r
- * elements (e.g. SELECT)\r
- */\r
- public VOptionGroupBase(Widget w, String classname) {\r
- this(classname);\r
- optionsContainer = w;\r
- container.add(optionsContainer);\r
- }\r
-\r
- protected boolean isImmediate() {\r
- return immediate;\r
- }\r
-\r
- protected boolean isMultiselect() {\r
- return multiselect;\r
- }\r
-\r
- protected boolean isDisabled() {\r
- return disabled;\r
- }\r
-\r
- protected boolean isReadonly() {\r
- return readonly;\r
- }\r
-\r
- protected boolean isNullSelectionAllowed() {\r
- return nullSelectionAllowed;\r
- }\r
-\r
- protected boolean isNullSelectionItemAvailable() {\r
- return nullSelectionItemAvailable;\r
- }\r
-\r
- /**\r
- * @return "cols" specified in uidl, 0 if not specified\r
- */\r
- protected int getColumns() {\r
- return cols;\r
- }\r
-\r
- /**\r
- * @return "rows" specified in uidl, 0 if not specified\r
- */\r
-\r
- protected int getRows() {\r
- return rows;\r
- }\r
-\r
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
- this.client = client;\r
- id = uidl.getId();\r
-\r
- if (client.updateComponent(this, uidl, true)) {\r
- return;\r
- }\r
-\r
- selectedKeys = uidl.getStringArrayVariableAsSet("selected");\r
-\r
- readonly = uidl.getBooleanAttribute("readonly");\r
- disabled = uidl.getBooleanAttribute("disabled");\r
- multiselect = "multi".equals(uidl.getStringAttribute("selectmode"));\r
- immediate = uidl.getBooleanAttribute("immediate");\r
- nullSelectionAllowed = uidl.getBooleanAttribute("nullselect");\r
- nullSelectionItemAvailable = uidl.getBooleanAttribute("nullselectitem");\r
-\r
- if (uidl.hasAttribute("cols")) {\r
- cols = uidl.getIntAttribute("cols");\r
- }\r
- if (uidl.hasAttribute("rows")) {\r
- rows = uidl.getIntAttribute("rows");\r
- }\r
-\r
- final UIDL ops = uidl.getChildUIDL(0);\r
-\r
- if (getColumns() > 0) {\r
- container.setWidth(getColumns() + "em");\r
- if (container != optionsContainer) {\r
- optionsContainer.setWidth("100%");\r
- }\r
- }\r
-\r
- buildOptions(ops);\r
-\r
- if (uidl.getBooleanAttribute("allownewitem")) {\r
- if (newItemField == null) {\r
- newItemButton = new VNativeButton();\r
- newItemButton.setText("+");\r
- newItemButton.addClickHandler(this);\r
- newItemField = new VTextField();\r
- newItemField.addKeyPressHandler(this);\r
- }\r
- newItemField.setEnabled(!disabled && !readonly);\r
- newItemButton.setEnabled(!disabled && !readonly);\r
-\r
- if (newItemField == null || newItemField.getParent() != container) {\r
- container.add(newItemField);\r
- container.add(newItemButton);\r
- final int w = container.getOffsetWidth()\r
- - newItemButton.getOffsetWidth();\r
- newItemField.setWidth(Math.max(w, 0) + "px");\r
- }\r
- } else if (newItemField != null) {\r
- container.remove(newItemField);\r
- container.remove(newItemButton);\r
- }\r
-\r
- setTabIndex(uidl.hasAttribute("tabindex") ? uidl\r
- .getIntAttribute("tabindex") : 0);\r
-\r
- }\r
-\r
- abstract protected void setTabIndex(int tabIndex);\r
-\r
- public void onClick(ClickEvent event) {\r
- if (event.getSource() == newItemButton\r
- && !newItemField.getText().equals("")) {\r
- client.updateVariable(id, "newitem", newItemField.getText(), true);\r
- newItemField.setText("");\r
- }\r
- }\r
-\r
- public void onChange(ChangeEvent event) {\r
- if (multiselect) {\r
- client.updateVariable(id, "selected", getSelectedItems(), immediate);\r
- } else {\r
- client.updateVariable(id, "selected", new String[] { ""\r
- + getSelectedItem() }, immediate);\r
- }\r
- }\r
-\r
- public void onKeyPress(KeyPressEvent event) {\r
- if (event.getSource() == newItemField\r
- && event.getCharCode() == KeyCodes.KEY_ENTER) {\r
- newItemButton.click();\r
- }\r
- }\r
-\r
- protected abstract void buildOptions(UIDL uidl);\r
-\r
- protected abstract String[] getSelectedItems();\r
-\r
- protected String getSelectedItem() {\r
- final String[] sel = getSelectedItems();\r
- if (sel.length > 0) {\r
- return sel[0];\r
- } else {\r
- return null;\r
- }\r
- }\r
-\r
-}\r
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Set;
+
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.KeyPressEvent;
+import com.google.gwt.event.dom.client.KeyPressHandler;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.Focusable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+abstract class VOptionGroupBase extends Composite implements VPaintableWidget,
+ Field, ClickHandler, ChangeHandler, KeyPressHandler, Focusable {
+
+ public static final String CLASSNAME_OPTION = "v-select-option";
+
+ protected ApplicationConnection client;
+
+ protected String id;
+
+ protected Set<String> selectedKeys;
+
+ private boolean immediate;
+
+ private boolean multiselect;
+
+ private boolean disabled;
+
+ private boolean readonly;
+
+ private int cols = 0;
+
+ private int rows = 0;
+
+ private boolean nullSelectionAllowed = true;
+
+ private boolean nullSelectionItemAvailable = false;
+
+ /**
+ * Widget holding the different options (e.g. ListBox or Panel for radio
+ * buttons) (optional, fallbacks to container Panel)
+ */
+ protected Widget optionsContainer;
+
+ /**
+ * Panel containing the component
+ */
+ private final Panel container;
+
+ private VTextField newItemField;
+
+ private VNativeButton newItemButton;
+
+ public VOptionGroupBase(String classname) {
+ container = new FlowPanel();
+ initWidget(container);
+ optionsContainer = container;
+ container.setStyleName(classname);
+ immediate = false;
+ multiselect = false;
+ }
+
+ /*
+ * Call this if you wish to specify your own container for the option
+ * elements (e.g. SELECT)
+ */
+ public VOptionGroupBase(Widget w, String classname) {
+ this(classname);
+ optionsContainer = w;
+ container.add(optionsContainer);
+ }
+
+ protected boolean isImmediate() {
+ return immediate;
+ }
+
+ protected boolean isMultiselect() {
+ return multiselect;
+ }
+
+ protected boolean isDisabled() {
+ return disabled;
+ }
+
+ protected boolean isReadonly() {
+ return readonly;
+ }
+
+ protected boolean isNullSelectionAllowed() {
+ return nullSelectionAllowed;
+ }
+
+ protected boolean isNullSelectionItemAvailable() {
+ return nullSelectionItemAvailable;
+ }
+
+ /**
+ * @return "cols" specified in uidl, 0 if not specified
+ */
+ protected int getColumns() {
+ return cols;
+ }
+
+ /**
+ * @return "rows" specified in uidl, 0 if not specified
+ */
+
+ protected int getRows() {
+ return rows;
+ }
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ this.client = client;
+ id = uidl.getId();
+
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ selectedKeys = uidl.getStringArrayVariableAsSet("selected");
+
+ readonly = uidl.getBooleanAttribute("readonly");
+ disabled = uidl.getBooleanAttribute("disabled");
+ multiselect = "multi".equals(uidl.getStringAttribute("selectmode"));
+ immediate = uidl.getBooleanAttribute("immediate");
+ nullSelectionAllowed = uidl.getBooleanAttribute("nullselect");
+ nullSelectionItemAvailable = uidl.getBooleanAttribute("nullselectitem");
+
+ if (uidl.hasAttribute("cols")) {
+ cols = uidl.getIntAttribute("cols");
+ }
+ if (uidl.hasAttribute("rows")) {
+ rows = uidl.getIntAttribute("rows");
+ }
+
+ final UIDL ops = uidl.getChildUIDL(0);
+
+ if (getColumns() > 0) {
+ container.setWidth(getColumns() + "em");
+ if (container != optionsContainer) {
+ optionsContainer.setWidth("100%");
+ }
+ }
+
+ buildOptions(ops);
+
+ if (uidl.getBooleanAttribute("allownewitem")) {
+ if (newItemField == null) {
+ newItemButton = new VNativeButton();
+ newItemButton.setText("+");
+ newItemButton.addClickHandler(this);
+ newItemField = new VTextField();
+ newItemField.addKeyPressHandler(this);
+ }
+ newItemField.setEnabled(!disabled && !readonly);
+ newItemButton.setEnabled(!disabled && !readonly);
+
+ if (newItemField == null || newItemField.getParent() != container) {
+ container.add(newItemField);
+ container.add(newItemButton);
+ final int w = container.getOffsetWidth()
+ - newItemButton.getOffsetWidth();
+ newItemField.setWidth(Math.max(w, 0) + "px");
+ }
+ } else if (newItemField != null) {
+ container.remove(newItemField);
+ container.remove(newItemButton);
+ }
+
+ setTabIndex(uidl.hasAttribute("tabindex") ? uidl
+ .getIntAttribute("tabindex") : 0);
+
+ }
+
+ abstract protected void setTabIndex(int tabIndex);
+
+ public void onClick(ClickEvent event) {
+ if (event.getSource() == newItemButton
+ && !newItemField.getText().equals("")) {
+ client.updateVariable(id, "newitem", newItemField.getText(), true);
+ newItemField.setText("");
+ }
+ }
+
+ public void onChange(ChangeEvent event) {
+ if (multiselect) {
+ client.updateVariable(id, "selected", getSelectedItems(), immediate);
+ } else {
+ client.updateVariable(id, "selected", new String[] { ""
+ + getSelectedItem() }, immediate);
+ }
+ }
+
+ public void onKeyPress(KeyPressEvent event) {
+ if (event.getSource() == newItemField
+ && event.getCharCode() == KeyCodes.KEY_ENTER) {
+ newItemButton.click();
+ }
+ }
+
+ protected abstract void buildOptions(UIDL uidl);
+
+ protected abstract String[] getSelectedItems();
+
+ protected String getSelectedItem() {
+ final String[] sel = getSelectedItems();
+ if (sel.length > 0) {
+ return sel[0];
+ } else {
+ return null;
+ }
+ }
+
+}
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.PaintableMap;
import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
import com.vaadin.terminal.gwt.client.RenderInformation.Size;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ValueMap;
import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayout;
import com.vaadin.terminal.gwt.client.ui.layout.ChildComponentContainer;
this, EventId.LAYOUT_CLICK) {
@Override
- protected Paintable getChildComponent(Element element) {
+ protected VPaintableWidget getChildComponent(Element element) {
return getComponent(element);
}
int pos = 0;
for (final Iterator<Object> it = uidl.getChildIterator(); it.hasNext();) {
final UIDL childUIDL = (UIDL) it.next();
- final Paintable child = client.getPaintable(childUIDL);
- Widget widget = (Widget) child;
+ final VPaintableWidget childPaintable = client
+ .getPaintable(childUIDL);
+ Widget widget = childPaintable.getWidgetForPaintable();
// Create container for component
ChildComponentContainer childComponentContainer = getComponentContainer(widget);
if (childComponentContainer == null) {
// This is a new component
- childComponentContainer = createChildContainer(widget);
+ childComponentContainer = createChildContainer(childPaintable);
} else {
/*
* The widget may be null if the same paintable has been
* been invisible. Ensure the childComponentContainer has the
* widget attached. See e.g. #5372
*/
- childComponentContainer.setWidget(widget);
+ childComponentContainer.setPaintable(childPaintable);
}
addOrMoveChild(childComponentContainer, pos++);
return orientation == ORIENTATION_VERTICAL;
}
- private ChildComponentContainer createChildContainer(Widget child) {
+ private ChildComponentContainer createChildContainer(VPaintableWidget child) {
// Create a container DIV for the child
ChildComponentContainer childComponent = new ChildComponentContainer(
root.getStyle().setPropertyPx("height", activeLayoutSize.getHeight());
}
- public boolean requestLayout(Set<Paintable> children) {
- for (Paintable p : children) {
+ public boolean requestLayout(Set<Widget> children) {
+ for (Widget p : children) {
/* Update widget size from DOM */
- ChildComponentContainer componentContainer = getComponentContainer((Widget) p);
+ ChildComponentContainer componentContainer = getComponentContainer(p);
// This should no longer be needed (after #2563)
// if (isDynamicWidth()) {
// componentContainer.setUnlimitedContainerWidth();
protected void updateAlignmentsAndExpandRatios(UIDL uidl,
ArrayList<Widget> renderedWidgets) {
- /*\r
+ /*
*/
alignments = uidl.getMapAttribute("alignments");
for (int i = 0; i < renderedWidgets.size(); i++) {
Widget widget = renderedWidgets.get(i);
- String pid = PaintableMap.get(client).getPid(widget);
+ String pid = VPaintableMap.get(client).getPid(widget);
ChildComponentContainer container = getComponentContainer(widget);
}
}
- public void updateCaption(Paintable component, UIDL uidl) {
- ChildComponentContainer componentContainer = getComponentContainer((Widget) component);
+ public void updateCaption(VPaintableWidget paintable, UIDL uidl) {
+ Widget widget = paintable.getWidgetForPaintable();
+ ChildComponentContainer componentContainer = getComponentContainer(widget);
componentContainer.updateCaption(uidl, client);
if (!isRendering) {
/*
* This was a component-only update and the possible size change
* must be propagated to the layout
*/
- client.captionSizeUpdated(component);
+ client.captionSizeUpdated(widget);
}
}
* @return The Paintable which the element is a part of. Null if the element
* belongs to the layout and not to a child.
*/
- private Paintable getComponent(Element element) {
+ private VPaintableWidget getComponent(Element element) {
return Util.getPaintableForElement(client, this, element);
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.Focusable;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
public class VPanel extends SimplePanel implements Container,
private String height;
- private Paintable layout;
+ private VPaintableWidget layout;
ShortcutActionHandler shortcutHandler;
// Render content
final UIDL layoutUidl = uidl.getChildUIDL(0);
- final Paintable newLayout = client.getPaintable(layoutUidl);
+ final VPaintableWidget newLayout = client.getPaintable(layoutUidl);
if (newLayout != layout) {
if (layout != null) {
client.unregisterPaintable(layout);
}
- setWidget((Widget) newLayout);
+ setWidget(newLayout.getWidgetForPaintable());
layout = newLayout;
}
layout.updateFromUIDL(layoutUidl, client);
*/
int captionWidth = captionText.getOffsetWidth()
+ getCaptionMarginLeft() + getCaptionPaddingHorizontal();
- int layoutWidth = ((Widget) layout).getOffsetWidth()
+ int layoutWidth = layout.getWidgetForPaintable().getOffsetWidth()
+ getContainerBorderWidth();
int width = layoutWidth;
if (captionWidth > width) {
if (height.equals("")) {
// Width change may affect height
- Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this);
+ Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this,
+ this);
}
}
public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
// TODO This is untested as no layouts require this
- if (oldComponent != layout) {
+ if (oldComponent != layout.getWidgetForPaintable()) {
return;
}
setWidget(newComponent);
- layout = (Paintable) newComponent;
+ layout = VPaintableMap.get(client).getPaintable(newComponent);
}
public RenderSpace getAllocatedSpace(Widget child) {
return new RenderSpace(w, h, true);
}
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
// content size change might cause change to its available space
// (scrollbars)
- client.handleComponentRelativeSize((Widget) layout);
+ client.handleComponentRelativeSize(layout.getWidgetForPaintable());
if (height != null && height != "" && width != null && width != "") {
/*
* If the height and width has been specified the child components
return !renderInformation.updateSize(getElement());
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
// NOP: layouts caption, errors etc not rendered in Panel
}
return shortcutHandler;
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
-/*\r
-@VaadinApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import java.util.Date;\r
-\r
-import com.google.gwt.core.client.GWT;\r
-import com.google.gwt.event.dom.client.ClickEvent;\r
-import com.google.gwt.event.dom.client.ClickHandler;\r
-import com.google.gwt.event.dom.client.DomEvent;\r
-import com.google.gwt.event.dom.client.KeyCodes;\r
-import com.google.gwt.event.logical.shared.CloseEvent;\r
-import com.google.gwt.event.logical.shared.CloseHandler;\r
-import com.google.gwt.user.client.DOM;\r
-import com.google.gwt.user.client.Element;\r
-import com.google.gwt.user.client.Event;\r
-import com.google.gwt.user.client.Timer;\r
-import com.google.gwt.user.client.Window;\r
-import com.google.gwt.user.client.ui.Button;\r
-import com.google.gwt.user.client.ui.PopupPanel;\r
-import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;\r
-import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
-import com.vaadin.terminal.gwt.client.BrowserInfo;\r
-import com.vaadin.terminal.gwt.client.DateTimeService;\r
-import com.vaadin.terminal.gwt.client.Paintable;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-import com.vaadin.terminal.gwt.client.VConsole;\r
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusChangeListener;\r
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;\r
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;\r
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.TimeChangeListener;\r
-\r
-/**\r
- * Represents a date selection component with a text field and a popup date\r
- * selector.\r
- * \r
- * <b>Note:</b> To change the keyboard assignments used in the popup dialog you\r
- * should extend <code>com.vaadin.terminal.gwt.client.ui.VCalendarPanel</code>\r
- * and then pass set it by calling the\r
- * <code>setCalendarPanel(VCalendarPanel panel)</code> method.\r
- * \r
- */\r
-public class VPopupCalendar extends VTextualDate implements Paintable, Field,\r
- ClickHandler, CloseHandler<PopupPanel>, SubPartAware {\r
-\r
- private final Button calendarToggle;\r
-\r
- private VCalendarPanel calendar;\r
-\r
- private final VOverlay popup;\r
- private boolean open = false;\r
- private boolean parsable = true;\r
-\r
- public VPopupCalendar() {\r
- super();\r
-\r
- calendarToggle = new Button();\r
- calendarToggle.setStyleName(CLASSNAME + "-button");\r
- calendarToggle.setText("");\r
- calendarToggle.addClickHandler(this);\r
- // -2 instead of -1 to avoid FocusWidget.onAttach to reset it\r
- calendarToggle.getElement().setTabIndex(-2);\r
- add(calendarToggle);\r
-\r
- calendar = GWT.create(VCalendarPanel.class);\r
- calendar.setFocusOutListener(new FocusOutListener() {\r
- public boolean onFocusOut(DomEvent<?> event) {\r
- event.preventDefault();\r
- closeCalendarPanel();\r
- return true;\r
- }\r
- });\r
-\r
- calendar.setSubmitListener(new SubmitListener() {\r
- public void onSubmit() {\r
- // Update internal value and send valuechange event if immediate\r
- updateValue(calendar.getDate());\r
-\r
- // Update text field (a must when not immediate).\r
- buildDate(true);\r
-\r
- closeCalendarPanel();\r
- }\r
-\r
- public void onCancel() {\r
- closeCalendarPanel();\r
- }\r
- });\r
-\r
- popup = new VOverlay(true, true, true);\r
- popup.setStyleName(VDateField.CLASSNAME + "-popup");\r
- popup.setWidget(calendar);\r
- popup.addCloseHandler(this);\r
-\r
- DOM.setElementProperty(calendar.getElement(), "id",\r
- "PID_VAADIN_POPUPCAL");\r
-\r
- sinkEvents(Event.ONKEYDOWN);\r
-\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void updateValue(Date newDate) {\r
- Date currentDate = getCurrentDate();\r
- if (currentDate == null || newDate.getTime() != currentDate.getTime()) {\r
- setCurrentDate((Date) newDate.clone());\r
- getClient().updateVariable(getId(), "year",\r
- newDate.getYear() + 1900, false);\r
- if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {\r
- getClient().updateVariable(getId(), "month",\r
- newDate.getMonth() + 1, false);\r
- if (getCurrentResolution() > RESOLUTION_MONTH) {\r
- getClient().updateVariable(getId(), "day",\r
- newDate.getDate(), false);\r
- if (getCurrentResolution() > RESOLUTION_DAY) {\r
- getClient().updateVariable(getId(), "hour",\r
- newDate.getHours(), false);\r
- if (getCurrentResolution() > RESOLUTION_HOUR) {\r
- getClient().updateVariable(getId(), "min",\r
- newDate.getMinutes(), false);\r
- if (getCurrentResolution() > RESOLUTION_MIN) {\r
- getClient().updateVariable(getId(), "sec",\r
- newDate.getSeconds(), false);\r
- }\r
- }\r
- }\r
- }\r
- }\r
- if (isImmediate()) {\r
- getClient().sendPendingVariableChanges();\r
- }\r
- }\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see\r
- * com.vaadin.terminal.gwt.client.ui.VTextualDate#updateFromUIDL(com.vaadin\r
- * .terminal.gwt.client.UIDL,\r
- * com.vaadin.terminal.gwt.client.ApplicationConnection)\r
- */\r
- @Override\r
- @SuppressWarnings("deprecation")\r
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
- boolean lastReadOnlyState = readonly;\r
- parsable = uidl.getBooleanAttribute("parsable");\r
-\r
- super.updateFromUIDL(uidl, client);\r
-\r
- popup.setStyleName(VDateField.CLASSNAME + "-popup "\r
- + VDateField.CLASSNAME + "-"\r
- + resolutionToString(currentResolution));\r
- calendar.setDateTimeService(getDateTimeService());\r
- calendar.setShowISOWeekNumbers(isShowISOWeekNumbers());\r
- if (calendar.getResolution() != currentResolution) {\r
- calendar.setResolution(currentResolution);\r
- if (calendar.getDate() != null) {\r
- calendar.setDate((Date) getCurrentDate().clone());\r
- // force re-render when changing resolution only\r
- calendar.renderCalendar();\r
- }\r
- }\r
- calendarToggle.setEnabled(enabled);\r
-\r
- if (currentResolution <= RESOLUTION_MONTH) {\r
- calendar.setFocusChangeListener(new FocusChangeListener() {\r
- public void focusChanged(Date date) {\r
- updateValue(date);\r
- buildDate();\r
- Date date2 = calendar.getDate();\r
- date2.setYear(date.getYear());\r
- date2.setMonth(date.getMonth());\r
- }\r
- });\r
- } else {\r
- calendar.setFocusChangeListener(null);\r
- }\r
-\r
- if (currentResolution > RESOLUTION_DAY) {\r
- calendar.setTimeChangeListener(new TimeChangeListener() {\r
- public void changed(int hour, int min, int sec, int msec) {\r
- Date d = getDate();\r
- if (d == null) {\r
- // date currently null, use the value from calendarPanel\r
- // (~ client time at the init of the widget)\r
- d = (Date) calendar.getDate().clone();\r
- }\r
- d.setHours(hour);\r
- d.setMinutes(min);\r
- d.setSeconds(sec);\r
- DateTimeService.setMilliseconds(d, msec);\r
-\r
- // Always update time changes to the server\r
- updateValue(d);\r
-\r
- // Update text field\r
- buildDate();\r
- }\r
- });\r
- }\r
-\r
- if (readonly) {\r
- calendarToggle.addStyleName(CLASSNAME + "-button-readonly");\r
- } else {\r
- calendarToggle.removeStyleName(CLASSNAME + "-button-readonly");\r
- }\r
-\r
- if (lastReadOnlyState != readonly) {\r
- updateWidth();\r
- }\r
-\r
- calendarToggle.setEnabled(true);\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see\r
- * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)\r
- */\r
- @Override\r
- public void setStyleName(String style) {\r
- // make sure the style is there before size calculation\r
- super.setStyleName(style + " " + CLASSNAME + "-popupcalendar");\r
- }\r
-\r
- /**\r
- * Opens the calendar panel popup\r
- */\r
- public void openCalendarPanel() {\r
-\r
- if (!open && !readonly) {\r
- open = true;\r
-\r
- if (getCurrentDate() != null) {\r
- calendar.setDate((Date) getCurrentDate().clone());\r
- } else {\r
- calendar.setDate(new Date());\r
- }\r
-\r
- // clear previous values\r
- popup.setWidth("");\r
- popup.setHeight("");\r
- popup.setPopupPositionAndShow(new PositionCallback() {\r
- public void setPosition(int offsetWidth, int offsetHeight) {\r
- final int w = offsetWidth;\r
- final int h = offsetHeight;\r
- final int browserWindowWidth = Window.getClientWidth()\r
- + Window.getScrollLeft();\r
- final int browserWindowHeight = Window.getClientHeight()\r
- + Window.getScrollTop();\r
- int t = calendarToggle.getAbsoluteTop();\r
- int l = calendarToggle.getAbsoluteLeft();\r
-\r
- // Add a little extra space to the right to avoid\r
- // problems with IE7 scrollbars and to make it look\r
- // nicer.\r
- int extraSpace = 30;\r
-\r
- boolean overflowRight = false;\r
- if (l + +w + extraSpace > browserWindowWidth) {\r
- overflowRight = true;\r
- // Part of the popup is outside the browser window\r
- // (to the right)\r
- l = browserWindowWidth - w - extraSpace;\r
- }\r
-\r
- if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) {\r
- // Part of the popup is outside the browser window\r
- // (below)\r
- t = browserWindowHeight - h\r
- - calendarToggle.getOffsetHeight() - 30;\r
- if (!overflowRight) {\r
- // Show to the right of the popup button unless we\r
- // are in the lower right corner of the screen\r
- l += calendarToggle.getOffsetWidth();\r
- }\r
- }\r
-\r
- // fix size\r
- popup.setWidth(w + "px");\r
- popup.setHeight(h + "px");\r
-\r
- popup.setPopupPosition(l,\r
- t + calendarToggle.getOffsetHeight() + 2);\r
-\r
- /*\r
- * We have to wait a while before focusing since the popup\r
- * needs to be opened before we can focus\r
- */\r
- Timer focusTimer = new Timer() {\r
- @Override\r
- public void run() {\r
- setFocus(true);\r
- }\r
- };\r
-\r
- focusTimer.schedule(100);\r
- }\r
- });\r
- } else {\r
- VConsole.error("Cannot reopen popup, it is already open!");\r
- }\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see\r
- * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event\r
- * .dom.client.ClickEvent)\r
- */\r
- public void onClick(ClickEvent event) {\r
- if (event.getSource() == calendarToggle && isEnabled()) {\r
- openCalendarPanel();\r
- }\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see\r
- * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt\r
- * .event.logical.shared.CloseEvent)\r
- */\r
- public void onClose(CloseEvent<PopupPanel> event) {\r
- if (event.getSource() == popup) {\r
- buildDate();\r
- if (!BrowserInfo.get().isTouchDevice()) {\r
- /*\r
- * Move focus to textbox, unless on touch device (avoids opening\r
- * virtual keyboard).\r
- */\r
- focus();\r
- }\r
-\r
- // TODO resolve what the "Sigh." is all about and document it here\r
- // Sigh.\r
- Timer t = new Timer() {\r
- @Override\r
- public void run() {\r
- open = false;\r
- }\r
- };\r
- t.schedule(100);\r
- }\r
- }\r
-\r
- /**\r
- * Sets focus to Calendar panel.\r
- * \r
- * @param focus\r
- */\r
- public void setFocus(boolean focus) {\r
- calendar.setFocus(focus);\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#getFieldExtraWidth()\r
- */\r
- @Override\r
- protected int getFieldExtraWidth() {\r
- if (fieldExtraWidth < 0) {\r
- fieldExtraWidth = super.getFieldExtraWidth();\r
- fieldExtraWidth += calendarToggle.getOffsetWidth();\r
- }\r
- return fieldExtraWidth;\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#buildDate()\r
- */\r
- @Override\r
- protected void buildDate() {\r
- // Save previous value\r
- String previousValue = getText();\r
- super.buildDate();\r
-\r
- // Restore previous value if the input could not be parsed\r
- if (!parsable) {\r
- setText(previousValue);\r
- }\r
- }\r
-\r
- /**\r
- * Update the text field contents from the date. See {@link #buildDate()}.\r
- * \r
- * @param forceValid\r
- * true to force the text field to be updated, false to only\r
- * update if the parsable flag is true.\r
- */\r
- protected void buildDate(boolean forceValid) {\r
- if (forceValid) {\r
- parsable = true;\r
- }\r
- buildDate();\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see\r
- * com.vaadin.terminal.gwt.client.ui.VDateField#onBrowserEvent(com.google\r
- * .gwt.user.client.Event)\r
- */\r
- @Override\r
- public void onBrowserEvent(com.google.gwt.user.client.Event event) {\r
- super.onBrowserEvent(event);\r
- if (DOM.eventGetType(event) == Event.ONKEYDOWN\r
- && event.getKeyCode() == getOpenCalenderPanelKey()) {\r
- openCalendarPanel();\r
- event.preventDefault();\r
- }\r
- }\r
-\r
- /**\r
- * Get the key code that opens the calendar panel. By default it is the down\r
- * key but you can override this to be whatever you like\r
- * \r
- * @return\r
- */\r
- protected int getOpenCalenderPanelKey() {\r
- return KeyCodes.KEY_DOWN;\r
- }\r
-\r
- /**\r
- * Closes the open popup panel\r
- */\r
- public void closeCalendarPanel() {\r
- if (open) {\r
- popup.hide(true);\r
- }\r
- }\r
-\r
- private final String CALENDAR_TOGGLE_ID = "popupButton";\r
-\r
- @Override\r
- public Element getSubPartElement(String subPart) {\r
- if (subPart.equals(CALENDAR_TOGGLE_ID)) {\r
- return calendarToggle.getElement();\r
- }\r
-\r
- return super.getSubPartElement(subPart);\r
- }\r
-\r
- @Override\r
- public String getSubPartName(Element subElement) {\r
- if (calendarToggle.getElement().isOrHasChild(subElement)) {\r
- return CALENDAR_TOGGLE_ID;\r
- }\r
-\r
- return super.getSubPartName(subElement);\r
- }\r
-\r
-}\r
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.DomEvent;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.CloseHandler;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.DateTimeService;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusChangeListener;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.TimeChangeListener;
+
+/**
+ * Represents a date selection component with a text field and a popup date
+ * selector.
+ *
+ * <b>Note:</b> To change the keyboard assignments used in the popup dialog you
+ * should extend <code>com.vaadin.terminal.gwt.client.ui.VCalendarPanel</code>
+ * and then pass set it by calling the
+ * <code>setCalendarPanel(VCalendarPanel panel)</code> method.
+ *
+ */
+public class VPopupCalendar extends VTextualDate implements VPaintableWidget,
+ Field, ClickHandler, CloseHandler<PopupPanel>, SubPartAware {
+
+ private final Button calendarToggle;
+
+ private VCalendarPanel calendar;
+
+ private final VOverlay popup;
+ private boolean open = false;
+ private boolean parsable = true;
+
+ public VPopupCalendar() {
+ super();
+
+ calendarToggle = new Button();
+ calendarToggle.setStyleName(CLASSNAME + "-button");
+ calendarToggle.setText("");
+ calendarToggle.addClickHandler(this);
+ // -2 instead of -1 to avoid FocusWidget.onAttach to reset it
+ calendarToggle.getElement().setTabIndex(-2);
+ add(calendarToggle);
+
+ calendar = GWT.create(VCalendarPanel.class);
+ calendar.setFocusOutListener(new FocusOutListener() {
+ public boolean onFocusOut(DomEvent<?> event) {
+ event.preventDefault();
+ closeCalendarPanel();
+ return true;
+ }
+ });
+
+ calendar.setSubmitListener(new SubmitListener() {
+ public void onSubmit() {
+ // Update internal value and send valuechange event if immediate
+ updateValue(calendar.getDate());
+
+ // Update text field (a must when not immediate).
+ buildDate(true);
+
+ closeCalendarPanel();
+ }
+
+ public void onCancel() {
+ closeCalendarPanel();
+ }
+ });
+
+ popup = new VOverlay(true, true, true);
+ popup.setStyleName(VDateField.CLASSNAME + "-popup");
+ popup.setWidget(calendar);
+ popup.addCloseHandler(this);
+
+ DOM.setElementProperty(calendar.getElement(), "id",
+ "PID_VAADIN_POPUPCAL");
+
+ sinkEvents(Event.ONKEYDOWN);
+
+ }
+
+ @SuppressWarnings("deprecation")
+ private void updateValue(Date newDate) {
+ Date currentDate = getCurrentDate();
+ if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
+ setCurrentDate((Date) newDate.clone());
+ getClient().updateVariable(getId(), "year",
+ newDate.getYear() + 1900, false);
+ if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
+ getClient().updateVariable(getId(), "month",
+ newDate.getMonth() + 1, false);
+ if (getCurrentResolution() > RESOLUTION_MONTH) {
+ getClient().updateVariable(getId(), "day",
+ newDate.getDate(), false);
+ if (getCurrentResolution() > RESOLUTION_DAY) {
+ getClient().updateVariable(getId(), "hour",
+ newDate.getHours(), false);
+ if (getCurrentResolution() > RESOLUTION_HOUR) {
+ getClient().updateVariable(getId(), "min",
+ newDate.getMinutes(), false);
+ if (getCurrentResolution() > RESOLUTION_MIN) {
+ getClient().updateVariable(getId(), "sec",
+ newDate.getSeconds(), false);
+ }
+ }
+ }
+ }
+ }
+ if (isImmediate()) {
+ getClient().sendPendingVariableChanges();
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.ui.VTextualDate#updateFromUIDL(com.vaadin
+ * .terminal.gwt.client.UIDL,
+ * com.vaadin.terminal.gwt.client.ApplicationConnection)
+ */
+ @Override
+ @SuppressWarnings("deprecation")
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ boolean lastReadOnlyState = readonly;
+ parsable = uidl.getBooleanAttribute("parsable");
+
+ super.updateFromUIDL(uidl, client);
+
+ popup.setStyleName(VDateField.CLASSNAME + "-popup "
+ + VDateField.CLASSNAME + "-"
+ + resolutionToString(currentResolution));
+ calendar.setDateTimeService(getDateTimeService());
+ calendar.setShowISOWeekNumbers(isShowISOWeekNumbers());
+ if (calendar.getResolution() != currentResolution) {
+ calendar.setResolution(currentResolution);
+ if (calendar.getDate() != null) {
+ calendar.setDate((Date) getCurrentDate().clone());
+ // force re-render when changing resolution only
+ calendar.renderCalendar();
+ }
+ }
+ calendarToggle.setEnabled(enabled);
+
+ if (currentResolution <= RESOLUTION_MONTH) {
+ calendar.setFocusChangeListener(new FocusChangeListener() {
+ public void focusChanged(Date date) {
+ updateValue(date);
+ buildDate();
+ Date date2 = calendar.getDate();
+ date2.setYear(date.getYear());
+ date2.setMonth(date.getMonth());
+ }
+ });
+ } else {
+ calendar.setFocusChangeListener(null);
+ }
+
+ if (currentResolution > RESOLUTION_DAY) {
+ calendar.setTimeChangeListener(new TimeChangeListener() {
+ public void changed(int hour, int min, int sec, int msec) {
+ Date d = getDate();
+ if (d == null) {
+ // date currently null, use the value from calendarPanel
+ // (~ client time at the init of the widget)
+ d = (Date) calendar.getDate().clone();
+ }
+ d.setHours(hour);
+ d.setMinutes(min);
+ d.setSeconds(sec);
+ DateTimeService.setMilliseconds(d, msec);
+
+ // Always update time changes to the server
+ updateValue(d);
+
+ // Update text field
+ buildDate();
+ }
+ });
+ }
+
+ if (readonly) {
+ calendarToggle.addStyleName(CLASSNAME + "-button-readonly");
+ } else {
+ calendarToggle.removeStyleName(CLASSNAME + "-button-readonly");
+ }
+
+ if (lastReadOnlyState != readonly) {
+ updateWidth();
+ }
+
+ calendarToggle.setEnabled(true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)
+ */
+ @Override
+ public void setStyleName(String style) {
+ // make sure the style is there before size calculation
+ super.setStyleName(style + " " + CLASSNAME + "-popupcalendar");
+ }
+
+ /**
+ * Opens the calendar panel popup
+ */
+ public void openCalendarPanel() {
+
+ if (!open && !readonly) {
+ open = true;
+
+ if (getCurrentDate() != null) {
+ calendar.setDate((Date) getCurrentDate().clone());
+ } else {
+ calendar.setDate(new Date());
+ }
+
+ // clear previous values
+ popup.setWidth("");
+ popup.setHeight("");
+ popup.setPopupPositionAndShow(new PositionCallback() {
+ public void setPosition(int offsetWidth, int offsetHeight) {
+ final int w = offsetWidth;
+ final int h = offsetHeight;
+ final int browserWindowWidth = Window.getClientWidth()
+ + Window.getScrollLeft();
+ final int browserWindowHeight = Window.getClientHeight()
+ + Window.getScrollTop();
+ int t = calendarToggle.getAbsoluteTop();
+ int l = calendarToggle.getAbsoluteLeft();
+
+ // Add a little extra space to the right to avoid
+ // problems with IE7 scrollbars and to make it look
+ // nicer.
+ int extraSpace = 30;
+
+ boolean overflowRight = false;
+ if (l + +w + extraSpace > browserWindowWidth) {
+ overflowRight = true;
+ // Part of the popup is outside the browser window
+ // (to the right)
+ l = browserWindowWidth - w - extraSpace;
+ }
+
+ if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) {
+ // Part of the popup is outside the browser window
+ // (below)
+ t = browserWindowHeight - h
+ - calendarToggle.getOffsetHeight() - 30;
+ if (!overflowRight) {
+ // Show to the right of the popup button unless we
+ // are in the lower right corner of the screen
+ l += calendarToggle.getOffsetWidth();
+ }
+ }
+
+ // fix size
+ popup.setWidth(w + "px");
+ popup.setHeight(h + "px");
+
+ popup.setPopupPosition(l,
+ t + calendarToggle.getOffsetHeight() + 2);
+
+ /*
+ * We have to wait a while before focusing since the popup
+ * needs to be opened before we can focus
+ */
+ Timer focusTimer = new Timer() {
+ @Override
+ public void run() {
+ setFocus(true);
+ }
+ };
+
+ focusTimer.schedule(100);
+ }
+ });
+ } else {
+ VConsole.error("Cannot reopen popup, it is already open!");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
+ * .dom.client.ClickEvent)
+ */
+ public void onClick(ClickEvent event) {
+ if (event.getSource() == calendarToggle && isEnabled()) {
+ openCalendarPanel();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt
+ * .event.logical.shared.CloseEvent)
+ */
+ public void onClose(CloseEvent<PopupPanel> event) {
+ if (event.getSource() == popup) {
+ buildDate();
+ if (!BrowserInfo.get().isTouchDevice()) {
+ /*
+ * Move focus to textbox, unless on touch device (avoids opening
+ * virtual keyboard).
+ */
+ focus();
+ }
+
+ // TODO resolve what the "Sigh." is all about and document it here
+ // Sigh.
+ Timer t = new Timer() {
+ @Override
+ public void run() {
+ open = false;
+ }
+ };
+ t.schedule(100);
+ }
+ }
+
+ /**
+ * Sets focus to Calendar panel.
+ *
+ * @param focus
+ */
+ public void setFocus(boolean focus) {
+ calendar.setFocus(focus);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#getFieldExtraWidth()
+ */
+ @Override
+ protected int getFieldExtraWidth() {
+ if (fieldExtraWidth < 0) {
+ fieldExtraWidth = super.getFieldExtraWidth();
+ fieldExtraWidth += calendarToggle.getOffsetWidth();
+ }
+ return fieldExtraWidth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#buildDate()
+ */
+ @Override
+ protected void buildDate() {
+ // Save previous value
+ String previousValue = getText();
+ super.buildDate();
+
+ // Restore previous value if the input could not be parsed
+ if (!parsable) {
+ setText(previousValue);
+ }
+ }
+
+ /**
+ * Update the text field contents from the date. See {@link #buildDate()}.
+ *
+ * @param forceValid
+ * true to force the text field to be updated, false to only
+ * update if the parsable flag is true.
+ */
+ protected void buildDate(boolean forceValid) {
+ if (forceValid) {
+ parsable = true;
+ }
+ buildDate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.ui.VDateField#onBrowserEvent(com.google
+ * .gwt.user.client.Event)
+ */
+ @Override
+ public void onBrowserEvent(com.google.gwt.user.client.Event event) {
+ super.onBrowserEvent(event);
+ if (DOM.eventGetType(event) == Event.ONKEYDOWN
+ && event.getKeyCode() == getOpenCalenderPanelKey()) {
+ openCalendarPanel();
+ event.preventDefault();
+ }
+ }
+
+ /**
+ * Get the key code that opens the calendar panel. By default it is the down
+ * key but you can override this to be whatever you like
+ *
+ * @return
+ */
+ protected int getOpenCalenderPanelKey() {
+ return KeyCodes.KEY_DOWN;
+ }
+
+ /**
+ * Closes the open popup panel
+ */
+ public void closeCalendarPanel() {
+ if (open) {
+ popup.hide(true);
+ }
+ }
+
+ private final String CALENDAR_TOGGLE_ID = "popupButton";
+
+ @Override
+ public Element getSubPartElement(String subPart) {
+ if (subPart.equals(CALENDAR_TOGGLE_ID)) {
+ return calendarToggle.getElement();
+ }
+
+ return super.getSubPartElement(subPart);
+ }
+
+ @Override
+ public String getSubPartName(Element subElement) {
+ if (calendarToggle.getElement().isOrHasChild(subElement)) {
+ return CALENDAR_TOGGLE_ID;
+ }
+
+ return super.getSubPartName(subElement);
+ }
+
+}
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderInformation.Size;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VCaption;
import com.vaadin.terminal.gwt.client.VCaptionWrapper;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextArea;
/**
*
*
- * @see com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal.gwt.client.UIDL,
+ * @see com.vaadin.terminal.gwt.client.VPaintableWidget#updateFromUIDL(com.vaadin.terminal.gwt.client.UIDL,
* com.vaadin.terminal.gwt.client.ApplicationConnection)
*/
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
*/
protected class CustomPopup extends VOverlay {
- private Paintable popupComponentPaintable = null;
+ private VPaintableWidget popupComponentPaintable = null;
private Widget popupComponentWidget = null;
private VCaptionWrapper captionWrapper = null;
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- Paintable newPopupComponent = client.getPaintable(uidl
+ VPaintableWidget newPopupComponent = client.getPaintable(uidl
.getChildUIDL(0));
if (newPopupComponent != popupComponentPaintable) {
-
- setWidget((Widget) newPopupComponent);
-
- popupComponentWidget = (Widget) newPopupComponent;
-
+ Widget newWidget = newPopupComponent.getWidgetForPaintable();
+ setWidget(newWidget);
+ popupComponentWidget = newWidget;
popupComponentPaintable = newPopupComponent;
}
popup.popupComponentWidget = newComponent;
}
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
popup.updateShadowSizeAndPosition();
return true;
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
if (VCaption.isNeeded(uidl)) {
if (popup.captionWrapper != null) {
popup.captionWrapper.updateCaption(uidl);
popup.setWidget(popup.popupComponentWidget);
}
}
-
- popup.popupComponentWidget = (Widget) component;
- popup.popupComponentPaintable = component;
}
@Override
};
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}// class VPopupView
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-public class VProgressIndicator extends Widget implements Paintable {
+public class VProgressIndicator extends Widget implements VPaintableWidget {
private static final String CLASSNAME = "v-progressindicator";
Element wrapper = DOM.createDiv();
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.Focusable;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.PaintableMap;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.TooltipInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
import com.vaadin.terminal.gwt.client.ui.dd.DDUtil;
private void purgeUnregistryBag() {
for (Iterator<Panel> iterator = lazyUnregistryBag.iterator(); iterator
.hasNext();) {
- PaintableMap.get(client).unregisterChildPaintables(iterator.next());
+ VPaintableMap.get(client)
+ .unregisterChildPaintables(iterator.next());
}
lazyUnregistryBag.clear();
}
addCell(uidl, cell.toString(), aligns[col++], style,
isRenderHtmlInCells(), sorted, description);
} else {
- final Paintable cellContent = client
+ final VPaintableWidget cellContent = client
.getPaintable((UIDL) cell);
- addCell(uidl, (Widget) cellContent, aligns[col++],
- style, sorted);
+ addCell(uidl, cellContent.getWidgetForPaintable(),
+ aligns[col++], style, sorted);
paintComponent(cellContent, (UIDL) cell);
}
}
return index;
}
- protected void paintComponent(Paintable p, UIDL uidl) {
+ protected void paintComponent(VPaintableWidget p, UIDL uidl) {
if (isAttached()) {
p.updateFromUIDL(uidl, client);
} else {
super.onAttach();
if (pendingComponentPaints != null) {
for (UIDL uidl : pendingComponentPaints) {
- Paintable paintable = client.getPaintable(uidl);
+ VPaintableWidget paintable = (VPaintableWidget) VPaintableMap
+ .get(client).getPaintable(uidl.getId());
paintable.updateFromUIDL(uidl, client);
}
}
}
- public boolean requestLayout(Set<Paintable> children) {
+ public boolean requestLayout(Set<Widget> children) {
// row size should never change and system wouldn't event
// survive as this is a kind of fake paitable
return true;
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
// NOP, not rendered
}
// Component container interface faked here to get layouts
// render properly
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
protected class VScrollTableGeneratedRow extends VScrollTableRow {
if (!hasFocus) {
scrollBodyPanel.setFocus(true);
}
+
}
+
}
/**
}
@Override
- public Paintable getPaintable() {
+ public VPaintableWidget getPaintable() {
return VScrollTable.this;
}
VConsole.error(msg);
}
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
-/* \r
-@VaadinApache2LicenseForJavaFiles@\r
- */\r
-// \r
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import com.google.gwt.core.client.Scheduler;\r
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;\r
-import com.google.gwt.event.dom.client.KeyCodes;\r
-import com.google.gwt.user.client.Command;\r
-import com.google.gwt.user.client.DOM;\r
-import com.google.gwt.user.client.Element;\r
-import com.google.gwt.user.client.Event;\r
-import com.google.gwt.user.client.Window;\r
-import com.google.gwt.user.client.ui.HTML;\r
-import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
-import com.vaadin.terminal.gwt.client.BrowserInfo;\r
-import com.vaadin.terminal.gwt.client.ContainerResizedListener;\r
-import com.vaadin.terminal.gwt.client.Paintable;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-import com.vaadin.terminal.gwt.client.Util;\r
-import com.vaadin.terminal.gwt.client.VConsole;\r
-\r
-public class VSlider extends SimpleFocusablePanel implements Paintable, Field,\r
- ContainerResizedListener {\r
-\r
- public static final String CLASSNAME = "v-slider";\r
-\r
- /**\r
- * Minimum size (width or height, depending on orientation) of the slider\r
- * base.\r
- */\r
- private static final int MIN_SIZE = 50;\r
-\r
- ApplicationConnection client;\r
-\r
- String id;\r
-\r
- private boolean immediate;\r
- private boolean disabled;\r
- private boolean readonly;\r
-\r
- private int acceleration = 1;\r
- private double min;\r
- private double max;\r
- private int resolution;\r
- private Double value;\r
- private boolean vertical;\r
-\r
- private final HTML feedback = new HTML("", false);\r
- private final VOverlay feedbackPopup = new VOverlay(true, false, true) {\r
- @Override\r
- public void show() {\r
- super.show();\r
- updateFeedbackPosition();\r
- }\r
- };\r
-\r
- /* DOM element for slider's base */\r
- private final Element base;\r
- private final int BASE_BORDER_WIDTH = 1;\r
-\r
- /* DOM element for slider's handle */\r
- private final Element handle;\r
-\r
- /* DOM element for decrement arrow */\r
- private final Element smaller;\r
-\r
- /* DOM element for increment arrow */\r
- private final Element bigger;\r
-\r
- /* Temporary dragging/animation variables */\r
- private boolean dragging = false;\r
-\r
- private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,\r
- new ScheduledCommand() {\r
-\r
- public void execute() {\r
- updateValueToServer();\r
- acceleration = 1;\r
- }\r
- });\r
-\r
- public VSlider() {\r
- super();\r
-\r
- base = DOM.createDiv();\r
- handle = DOM.createDiv();\r
- smaller = DOM.createDiv();\r
- bigger = DOM.createDiv();\r
-\r
- setStyleName(CLASSNAME);\r
- DOM.setElementProperty(base, "className", CLASSNAME + "-base");\r
- DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");\r
- DOM.setElementProperty(smaller, "className", CLASSNAME + "-smaller");\r
- DOM.setElementProperty(bigger, "className", CLASSNAME + "-bigger");\r
-\r
- DOM.appendChild(getElement(), bigger);\r
- DOM.appendChild(getElement(), smaller);\r
- DOM.appendChild(getElement(), base);\r
- DOM.appendChild(base, handle);\r
-\r
- // Hide initially\r
- DOM.setStyleAttribute(smaller, "display", "none");\r
- DOM.setStyleAttribute(bigger, "display", "none");\r
- DOM.setStyleAttribute(handle, "visibility", "hidden");\r
-\r
- sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS\r
- | Event.FOCUSEVENTS | Event.TOUCHEVENTS);\r
-\r
- feedbackPopup.addStyleName(CLASSNAME + "-feedback");\r
- feedbackPopup.setWidget(feedback);\r
- }\r
-\r
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
-\r
- this.client = client;\r
- id = uidl.getId();\r
-\r
- // Ensure correct implementation\r
- if (client.updateComponent(this, uidl, true)) {\r
- return;\r
- }\r
-\r
- immediate = uidl.getBooleanAttribute("immediate");\r
- disabled = uidl.getBooleanAttribute("disabled");\r
- readonly = uidl.getBooleanAttribute("readonly");\r
-\r
- vertical = uidl.hasAttribute("vertical");\r
-\r
- String style = "";\r
- if (uidl.hasAttribute("style")) {\r
- style = uidl.getStringAttribute("style");\r
- }\r
-\r
- if (vertical) {\r
- addStyleName(CLASSNAME + "-vertical");\r
- } else {\r
- removeStyleName(CLASSNAME + "-vertical");\r
- }\r
-\r
- min = uidl.getDoubleAttribute("min");\r
- max = uidl.getDoubleAttribute("max");\r
- resolution = uidl.getIntAttribute("resolution");\r
- value = new Double(uidl.getDoubleVariable("value"));\r
-\r
- setFeedbackValue(value);\r
-\r
- buildBase();\r
-\r
- if (!vertical) {\r
- // Draw handle with a delay to allow base to gain maximum width\r
- Scheduler.get().scheduleDeferred(new Command() {\r
- public void execute() {\r
- buildHandle();\r
- setValue(value, false);\r
- }\r
- });\r
- } else {\r
- buildHandle();\r
- setValue(value, false);\r
- }\r
- }\r
-\r
- private void setFeedbackValue(double value) {\r
- String currentValue = "" + value;\r
- if (resolution == 0) {\r
- currentValue = "" + new Double(value).intValue();\r
- }\r
- feedback.setText(currentValue);\r
- }\r
-\r
- private void updateFeedbackPosition() {\r
- if (vertical) {\r
- feedbackPopup.setPopupPosition(\r
- DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth(),\r
- DOM.getAbsoluteTop(handle) + handle.getOffsetHeight() / 2\r
- - feedbackPopup.getOffsetHeight() / 2);\r
- } else {\r
- feedbackPopup.setPopupPosition(\r
- DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth() / 2\r
- - feedbackPopup.getOffsetWidth() / 2,\r
- DOM.getAbsoluteTop(handle)\r
- - feedbackPopup.getOffsetHeight());\r
- }\r
- }\r
-\r
- private void buildBase() {\r
- final String styleAttribute = vertical ? "height" : "width";\r
- final String domProperty = vertical ? "offsetHeight" : "offsetWidth";\r
-\r
- final Element p = DOM.getParent(getElement());\r
- if (DOM.getElementPropertyInt(p, domProperty) > 50) {\r
- if (vertical) {\r
- setHeight();\r
- } else {\r
- DOM.setStyleAttribute(base, styleAttribute, "");\r
- }\r
- } else {\r
- // Set minimum size and adjust after all components have\r
- // (supposedly) been drawn completely.\r
- DOM.setStyleAttribute(base, styleAttribute, MIN_SIZE + "px");\r
- Scheduler.get().scheduleDeferred(new Command() {\r
- public void execute() {\r
- final Element p = DOM.getParent(getElement());\r
- if (DOM.getElementPropertyInt(p, domProperty) > (MIN_SIZE + 5)) {\r
- if (vertical) {\r
- setHeight();\r
- } else {\r
- DOM.setStyleAttribute(base, styleAttribute, "");\r
- }\r
- // Ensure correct position\r
- setValue(value, false);\r
- }\r
- }\r
- });\r
- }\r
-\r
- // TODO attach listeners for focusing and arrow keys\r
- }\r
-\r
- private void buildHandle() {\r
- final String handleAttribute = vertical ? "marginTop" : "marginLeft";\r
-\r
- DOM.setStyleAttribute(handle, handleAttribute, "0");\r
-\r
- // Restore visibility\r
- DOM.setStyleAttribute(handle, "visibility", "visible");\r
-\r
- }\r
-\r
- private void setValue(Double value, boolean updateToServer) {\r
- if (value == null) {\r
- return;\r
- }\r
-\r
- if (value < min) {\r
- value = min;\r
- } else if (value > max) {\r
- value = max;\r
- }\r
-\r
- // Update handle position\r
- final String styleAttribute = vertical ? "marginTop" : "marginLeft";\r
- final String domProperty = vertical ? "offsetHeight" : "offsetWidth";\r
- final int handleSize = Integer.parseInt(DOM.getElementProperty(handle,\r
- domProperty));\r
- final int baseSize = Integer.parseInt(DOM.getElementProperty(base,\r
- domProperty)) - (2 * BASE_BORDER_WIDTH);\r
-\r
- final int range = baseSize - handleSize;\r
- double v = value.doubleValue();\r
-\r
- // Round value to resolution\r
- if (resolution > 0) {\r
- v = Math.round(v * Math.pow(10, resolution));\r
- v = v / Math.pow(10, resolution);\r
- } else {\r
- v = Math.round(v);\r
- }\r
- final double valueRange = max - min;\r
- double p = 0;\r
- if (valueRange > 0) {\r
- p = range * ((v - min) / valueRange);\r
- }\r
- if (p < 0) {\r
- p = 0;\r
- }\r
- if (vertical) {\r
- p = range - p;\r
- }\r
- final double pos = p;\r
-\r
- DOM.setStyleAttribute(handle, styleAttribute, (Math.round(pos)) + "px");\r
-\r
- // Update value\r
- this.value = new Double(v);\r
- setFeedbackValue(v);\r
-\r
- if (updateToServer) {\r
- updateValueToServer();\r
- }\r
- }\r
-\r
- @Override\r
- public void onBrowserEvent(Event event) {\r
- if (disabled || readonly) {\r
- return;\r
- }\r
- final Element targ = DOM.eventGetTarget(event);\r
-\r
- if (DOM.eventGetType(event) == Event.ONMOUSEWHEEL) {\r
- processMouseWheelEvent(event);\r
- } else if (dragging || targ == handle) {\r
- processHandleEvent(event);\r
- } else if (targ == smaller) {\r
- decreaseValue(true);\r
- } else if (targ == bigger) {\r
- increaseValue(true);\r
- } else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) {\r
- processBaseEvent(event);\r
- } else if ((BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYPRESS)\r
- || (!BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYDOWN)) {\r
-\r
- if (handleNavigation(event.getKeyCode(), event.getCtrlKey(),\r
- event.getShiftKey())) {\r
-\r
- feedbackPopup.show();\r
-\r
- delayedValueUpdater.trigger();\r
-\r
- DOM.eventPreventDefault(event);\r
- DOM.eventCancelBubble(event, true);\r
- }\r
- } else if (targ.equals(getElement())\r
- && DOM.eventGetType(event) == Event.ONFOCUS) {\r
- feedbackPopup.show();\r
- } else if (targ.equals(getElement())\r
- && DOM.eventGetType(event) == Event.ONBLUR) {\r
- feedbackPopup.hide();\r
- } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {\r
- feedbackPopup.show();\r
- }\r
- if (Util.isTouchEvent(event)) {\r
- event.preventDefault(); // avoid simulated events\r
- event.stopPropagation();\r
- }\r
- }\r
-\r
- private void processMouseWheelEvent(final Event event) {\r
- final int dir = DOM.eventGetMouseWheelVelocityY(event);\r
-\r
- if (dir < 0) {\r
- increaseValue(false);\r
- } else {\r
- decreaseValue(false);\r
- }\r
-\r
- delayedValueUpdater.trigger();\r
-\r
- DOM.eventPreventDefault(event);\r
- DOM.eventCancelBubble(event, true);\r
- }\r
-\r
- private void processHandleEvent(Event event) {\r
- switch (DOM.eventGetType(event)) {\r
- case Event.ONMOUSEDOWN:\r
- case Event.ONTOUCHSTART:\r
- if (!disabled && !readonly) {\r
- focus();\r
- feedbackPopup.show();\r
- dragging = true;\r
- DOM.setElementProperty(handle, "className", CLASSNAME\r
- + "-handle " + CLASSNAME + "-handle-active");\r
- DOM.setCapture(getElement());\r
- DOM.eventPreventDefault(event); // prevent selecting text\r
- DOM.eventCancelBubble(event, true);\r
- event.stopPropagation();\r
- VConsole.log("Slider move start");\r
- }\r
- break;\r
- case Event.ONMOUSEMOVE:\r
- case Event.ONTOUCHMOVE:\r
- if (dragging) {\r
- VConsole.log("Slider move");\r
- setValueByEvent(event, false);\r
- updateFeedbackPosition();\r
- event.stopPropagation();\r
- }\r
- break;\r
- case Event.ONTOUCHEND:\r
- feedbackPopup.hide();\r
- case Event.ONMOUSEUP:\r
- // feedbackPopup.hide();\r
- VConsole.log("Slider move end");\r
- dragging = false;\r
- DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");\r
- DOM.releaseCapture(getElement());\r
- setValueByEvent(event, true);\r
- event.stopPropagation();\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- private void processBaseEvent(Event event) {\r
- if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {\r
- if (!disabled && !readonly && !dragging) {\r
- setValueByEvent(event, true);\r
- DOM.eventCancelBubble(event, true);\r
- }\r
- } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN && dragging) {\r
- dragging = false;\r
- DOM.releaseCapture(getElement());\r
- setValueByEvent(event, true);\r
- }\r
- }\r
-\r
- private void decreaseValue(boolean updateToServer) {\r
- setValue(new Double(value.doubleValue() - Math.pow(10, -resolution)),\r
- updateToServer);\r
- }\r
-\r
- private void increaseValue(boolean updateToServer) {\r
- setValue(new Double(value.doubleValue() + Math.pow(10, -resolution)),\r
- updateToServer);\r
- }\r
-\r
- private void setValueByEvent(Event event, boolean updateToServer) {\r
- double v = min; // Fallback to min\r
-\r
- final int coord = getEventPosition(event);\r
-\r
- final int handleSize, baseSize, baseOffset;\r
- if (vertical) {\r
- handleSize = handle.getOffsetHeight();\r
- baseSize = base.getOffsetHeight();\r
- baseOffset = base.getAbsoluteTop() - Window.getScrollTop()\r
- - handleSize / 2;\r
- } else {\r
- handleSize = handle.getOffsetWidth();\r
- baseSize = base.getOffsetWidth();\r
- baseOffset = base.getAbsoluteLeft() - Window.getScrollLeft()\r
- + handleSize / 2;\r
- }\r
-\r
- if (vertical) {\r
- v = ((baseSize - (coord - baseOffset)) / (double) (baseSize - handleSize))\r
- * (max - min) + min;\r
- } else {\r
- v = ((coord - baseOffset) / (double) (baseSize - handleSize))\r
- * (max - min) + min;\r
- }\r
-\r
- if (v < min) {\r
- v = min;\r
- } else if (v > max) {\r
- v = max;\r
- }\r
-\r
- setValue(v, updateToServer);\r
- }\r
-\r
- /**\r
- * TODO consider extracting touches support to an impl class specific for\r
- * webkit (only browser that really supports touches).\r
- * \r
- * @param event\r
- * @return\r
- */\r
- protected int getEventPosition(Event event) {\r
- if (vertical) {\r
- return Util.getTouchOrMouseClientY(event);\r
- } else {\r
- return Util.getTouchOrMouseClientX(event);\r
- }\r
- }\r
-\r
- public void iLayout() {\r
- if (vertical) {\r
- setHeight();\r
- }\r
- // Update handle position\r
- setValue(value, false);\r
- }\r
-\r
- private void setHeight() {\r
- // Calculate decoration size\r
- DOM.setStyleAttribute(base, "height", "0");\r
- DOM.setStyleAttribute(base, "overflow", "hidden");\r
- int h = DOM.getElementPropertyInt(getElement(), "offsetHeight");\r
- if (h < MIN_SIZE) {\r
- h = MIN_SIZE;\r
- }\r
- DOM.setStyleAttribute(base, "height", h + "px");\r
- DOM.setStyleAttribute(base, "overflow", "");\r
- }\r
-\r
- private void updateValueToServer() {\r
- client.updateVariable(id, "value", value.doubleValue(), immediate);\r
- }\r
-\r
- /**\r
- * Handles the keyboard events handled by the Slider\r
- * \r
- * @param event\r
- * The keyboard event received\r
- * @return true iff the navigation event was handled\r
- */\r
- public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {\r
-\r
- // No support for ctrl moving\r
- if (ctrl) {\r
- return false;\r
- }\r
-\r
- if ((keycode == getNavigationUpKey() && vertical)\r
- || (keycode == getNavigationRightKey() && !vertical)) {\r
- if (shift) {\r
- for (int a = 0; a < acceleration; a++) {\r
- increaseValue(false);\r
- }\r
- acceleration++;\r
- } else {\r
- increaseValue(false);\r
- }\r
- return true;\r
- } else if (keycode == getNavigationDownKey() && vertical\r
- || (keycode == getNavigationLeftKey() && !vertical)) {\r
- if (shift) {\r
- for (int a = 0; a < acceleration; a++) {\r
- decreaseValue(false);\r
- }\r
- acceleration++;\r
- } else {\r
- decreaseValue(false);\r
- }\r
- return true;\r
- }\r
-\r
- return false;\r
- }\r
-\r
- /**\r
- * Get the key that increases the vertical slider. By default it is the up\r
- * arrow key but by overriding this you can change the key to whatever you\r
- * want.\r
- * \r
- * @return The keycode of the key\r
- */\r
- protected int getNavigationUpKey() {\r
- return KeyCodes.KEY_UP;\r
- }\r
-\r
- /**\r
- * Get the key that decreases the vertical slider. By default it is the down\r
- * arrow key but by overriding this you can change the key to whatever you\r
- * want.\r
- * \r
- * @return The keycode of the key\r
- */\r
- protected int getNavigationDownKey() {\r
- return KeyCodes.KEY_DOWN;\r
- }\r
-\r
- /**\r
- * Get the key that decreases the horizontal slider. By default it is the\r
- * left arrow key but by overriding this you can change the key to whatever\r
- * you want.\r
- * \r
- * @return The keycode of the key\r
- */\r
- protected int getNavigationLeftKey() {\r
- return KeyCodes.KEY_LEFT;\r
- }\r
-\r
- /**\r
- * Get the key that increases the horizontal slider. By default it is the\r
- * right arrow key but by overriding this you can change the key to whatever\r
- * you want.\r
- * \r
- * @return The keycode of the key\r
- */\r
- protected int getNavigationRightKey() {\r
- return KeyCodes.KEY_RIGHT;\r
- }\r
-}\r
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+//
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.ContainerResizedListener;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
+
+public class VSlider extends SimpleFocusablePanel implements VPaintableWidget,
+ Field, ContainerResizedListener {
+
+ public static final String CLASSNAME = "v-slider";
+
+ /**
+ * Minimum size (width or height, depending on orientation) of the slider
+ * base.
+ */
+ private static final int MIN_SIZE = 50;
+
+ ApplicationConnection client;
+
+ String id;
+
+ private boolean immediate;
+ private boolean disabled;
+ private boolean readonly;
+
+ private int acceleration = 1;
+ private double min;
+ private double max;
+ private int resolution;
+ private Double value;
+ private boolean vertical;
+
+ private final HTML feedback = new HTML("", false);
+ private final VOverlay feedbackPopup = new VOverlay(true, false, true) {
+ @Override
+ public void show() {
+ super.show();
+ updateFeedbackPosition();
+ }
+ };
+
+ /* DOM element for slider's base */
+ private final Element base;
+ private final int BASE_BORDER_WIDTH = 1;
+
+ /* DOM element for slider's handle */
+ private final Element handle;
+
+ /* DOM element for decrement arrow */
+ private final Element smaller;
+
+ /* DOM element for increment arrow */
+ private final Element bigger;
+
+ /* Temporary dragging/animation variables */
+ private boolean dragging = false;
+
+ private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,
+ new ScheduledCommand() {
+
+ public void execute() {
+ updateValueToServer();
+ acceleration = 1;
+ }
+ });
+
+ public VSlider() {
+ super();
+
+ base = DOM.createDiv();
+ handle = DOM.createDiv();
+ smaller = DOM.createDiv();
+ bigger = DOM.createDiv();
+
+ setStyleName(CLASSNAME);
+ DOM.setElementProperty(base, "className", CLASSNAME + "-base");
+ DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
+ DOM.setElementProperty(smaller, "className", CLASSNAME + "-smaller");
+ DOM.setElementProperty(bigger, "className", CLASSNAME + "-bigger");
+
+ DOM.appendChild(getElement(), bigger);
+ DOM.appendChild(getElement(), smaller);
+ DOM.appendChild(getElement(), base);
+ DOM.appendChild(base, handle);
+
+ // Hide initially
+ DOM.setStyleAttribute(smaller, "display", "none");
+ DOM.setStyleAttribute(bigger, "display", "none");
+ DOM.setStyleAttribute(handle, "visibility", "hidden");
+
+ sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS
+ | Event.FOCUSEVENTS | Event.TOUCHEVENTS);
+
+ feedbackPopup.addStyleName(CLASSNAME + "-feedback");
+ feedbackPopup.setWidget(feedback);
+ }
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+ this.client = client;
+ id = uidl.getId();
+
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ immediate = uidl.getBooleanAttribute("immediate");
+ disabled = uidl.getBooleanAttribute("disabled");
+ readonly = uidl.getBooleanAttribute("readonly");
+
+ vertical = uidl.hasAttribute("vertical");
+
+ String style = "";
+ if (uidl.hasAttribute("style")) {
+ style = uidl.getStringAttribute("style");
+ }
+
+ if (vertical) {
+ addStyleName(CLASSNAME + "-vertical");
+ } else {
+ removeStyleName(CLASSNAME + "-vertical");
+ }
+
+ min = uidl.getDoubleAttribute("min");
+ max = uidl.getDoubleAttribute("max");
+ resolution = uidl.getIntAttribute("resolution");
+ value = new Double(uidl.getDoubleVariable("value"));
+
+ setFeedbackValue(value);
+
+ buildBase();
+
+ if (!vertical) {
+ // Draw handle with a delay to allow base to gain maximum width
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ buildHandle();
+ setValue(value, false);
+ }
+ });
+ } else {
+ buildHandle();
+ setValue(value, false);
+ }
+ }
+
+ private void setFeedbackValue(double value) {
+ String currentValue = "" + value;
+ if (resolution == 0) {
+ currentValue = "" + new Double(value).intValue();
+ }
+ feedback.setText(currentValue);
+ }
+
+ private void updateFeedbackPosition() {
+ if (vertical) {
+ feedbackPopup.setPopupPosition(
+ DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth(),
+ DOM.getAbsoluteTop(handle) + handle.getOffsetHeight() / 2
+ - feedbackPopup.getOffsetHeight() / 2);
+ } else {
+ feedbackPopup.setPopupPosition(
+ DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth() / 2
+ - feedbackPopup.getOffsetWidth() / 2,
+ DOM.getAbsoluteTop(handle)
+ - feedbackPopup.getOffsetHeight());
+ }
+ }
+
+ private void buildBase() {
+ final String styleAttribute = vertical ? "height" : "width";
+ final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
+
+ final Element p = DOM.getParent(getElement());
+ if (DOM.getElementPropertyInt(p, domProperty) > 50) {
+ if (vertical) {
+ setHeight();
+ } else {
+ DOM.setStyleAttribute(base, styleAttribute, "");
+ }
+ } else {
+ // Set minimum size and adjust after all components have
+ // (supposedly) been drawn completely.
+ DOM.setStyleAttribute(base, styleAttribute, MIN_SIZE + "px");
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ final Element p = DOM.getParent(getElement());
+ if (DOM.getElementPropertyInt(p, domProperty) > (MIN_SIZE + 5)) {
+ if (vertical) {
+ setHeight();
+ } else {
+ DOM.setStyleAttribute(base, styleAttribute, "");
+ }
+ // Ensure correct position
+ setValue(value, false);
+ }
+ }
+ });
+ }
+
+ // TODO attach listeners for focusing and arrow keys
+ }
+
+ private void buildHandle() {
+ final String handleAttribute = vertical ? "marginTop" : "marginLeft";
+
+ DOM.setStyleAttribute(handle, handleAttribute, "0");
+
+ // Restore visibility
+ DOM.setStyleAttribute(handle, "visibility", "visible");
+
+ }
+
+ private void setValue(Double value, boolean updateToServer) {
+ if (value == null) {
+ return;
+ }
+
+ if (value < min) {
+ value = min;
+ } else if (value > max) {
+ value = max;
+ }
+
+ // Update handle position
+ final String styleAttribute = vertical ? "marginTop" : "marginLeft";
+ final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
+ final int handleSize = Integer.parseInt(DOM.getElementProperty(handle,
+ domProperty));
+ final int baseSize = Integer.parseInt(DOM.getElementProperty(base,
+ domProperty)) - (2 * BASE_BORDER_WIDTH);
+
+ final int range = baseSize - handleSize;
+ double v = value.doubleValue();
+
+ // Round value to resolution
+ if (resolution > 0) {
+ v = Math.round(v * Math.pow(10, resolution));
+ v = v / Math.pow(10, resolution);
+ } else {
+ v = Math.round(v);
+ }
+ final double valueRange = max - min;
+ double p = 0;
+ if (valueRange > 0) {
+ p = range * ((v - min) / valueRange);
+ }
+ if (p < 0) {
+ p = 0;
+ }
+ if (vertical) {
+ p = range - p;
+ }
+ final double pos = p;
+
+ DOM.setStyleAttribute(handle, styleAttribute, (Math.round(pos)) + "px");
+
+ // Update value
+ this.value = new Double(v);
+ setFeedbackValue(v);
+
+ if (updateToServer) {
+ updateValueToServer();
+ }
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ if (disabled || readonly) {
+ return;
+ }
+ final Element targ = DOM.eventGetTarget(event);
+
+ if (DOM.eventGetType(event) == Event.ONMOUSEWHEEL) {
+ processMouseWheelEvent(event);
+ } else if (dragging || targ == handle) {
+ processHandleEvent(event);
+ } else if (targ == smaller) {
+ decreaseValue(true);
+ } else if (targ == bigger) {
+ increaseValue(true);
+ } else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) {
+ processBaseEvent(event);
+ } else if ((BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYPRESS)
+ || (!BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYDOWN)) {
+
+ if (handleNavigation(event.getKeyCode(), event.getCtrlKey(),
+ event.getShiftKey())) {
+
+ feedbackPopup.show();
+
+ delayedValueUpdater.trigger();
+
+ DOM.eventPreventDefault(event);
+ DOM.eventCancelBubble(event, true);
+ }
+ } else if (targ.equals(getElement())
+ && DOM.eventGetType(event) == Event.ONFOCUS) {
+ feedbackPopup.show();
+ } else if (targ.equals(getElement())
+ && DOM.eventGetType(event) == Event.ONBLUR) {
+ feedbackPopup.hide();
+ } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
+ feedbackPopup.show();
+ }
+ if (Util.isTouchEvent(event)) {
+ event.preventDefault(); // avoid simulated events
+ event.stopPropagation();
+ }
+ }
+
+ private void processMouseWheelEvent(final Event event) {
+ final int dir = DOM.eventGetMouseWheelVelocityY(event);
+
+ if (dir < 0) {
+ increaseValue(false);
+ } else {
+ decreaseValue(false);
+ }
+
+ delayedValueUpdater.trigger();
+
+ DOM.eventPreventDefault(event);
+ DOM.eventCancelBubble(event, true);
+ }
+
+ private void processHandleEvent(Event event) {
+ switch (DOM.eventGetType(event)) {
+ case Event.ONMOUSEDOWN:
+ case Event.ONTOUCHSTART:
+ if (!disabled && !readonly) {
+ focus();
+ feedbackPopup.show();
+ dragging = true;
+ DOM.setElementProperty(handle, "className", CLASSNAME
+ + "-handle " + CLASSNAME + "-handle-active");
+ DOM.setCapture(getElement());
+ DOM.eventPreventDefault(event); // prevent selecting text
+ DOM.eventCancelBubble(event, true);
+ event.stopPropagation();
+ VConsole.log("Slider move start");
+ }
+ break;
+ case Event.ONMOUSEMOVE:
+ case Event.ONTOUCHMOVE:
+ if (dragging) {
+ VConsole.log("Slider move");
+ setValueByEvent(event, false);
+ updateFeedbackPosition();
+ event.stopPropagation();
+ }
+ break;
+ case Event.ONTOUCHEND:
+ feedbackPopup.hide();
+ case Event.ONMOUSEUP:
+ // feedbackPopup.hide();
+ VConsole.log("Slider move end");
+ dragging = false;
+ DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
+ DOM.releaseCapture(getElement());
+ setValueByEvent(event, true);
+ event.stopPropagation();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void processBaseEvent(Event event) {
+ if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
+ if (!disabled && !readonly && !dragging) {
+ setValueByEvent(event, true);
+ DOM.eventCancelBubble(event, true);
+ }
+ } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN && dragging) {
+ dragging = false;
+ DOM.releaseCapture(getElement());
+ setValueByEvent(event, true);
+ }
+ }
+
+ private void decreaseValue(boolean updateToServer) {
+ setValue(new Double(value.doubleValue() - Math.pow(10, -resolution)),
+ updateToServer);
+ }
+
+ private void increaseValue(boolean updateToServer) {
+ setValue(new Double(value.doubleValue() + Math.pow(10, -resolution)),
+ updateToServer);
+ }
+
+ private void setValueByEvent(Event event, boolean updateToServer) {
+ double v = min; // Fallback to min
+
+ final int coord = getEventPosition(event);
+
+ final int handleSize, baseSize, baseOffset;
+ if (vertical) {
+ handleSize = handle.getOffsetHeight();
+ baseSize = base.getOffsetHeight();
+ baseOffset = base.getAbsoluteTop() - Window.getScrollTop()
+ - handleSize / 2;
+ } else {
+ handleSize = handle.getOffsetWidth();
+ baseSize = base.getOffsetWidth();
+ baseOffset = base.getAbsoluteLeft() - Window.getScrollLeft()
+ + handleSize / 2;
+ }
+
+ if (vertical) {
+ v = ((baseSize - (coord - baseOffset)) / (double) (baseSize - handleSize))
+ * (max - min) + min;
+ } else {
+ v = ((coord - baseOffset) / (double) (baseSize - handleSize))
+ * (max - min) + min;
+ }
+
+ if (v < min) {
+ v = min;
+ } else if (v > max) {
+ v = max;
+ }
+
+ setValue(v, updateToServer);
+ }
+
+ /**
+ * TODO consider extracting touches support to an impl class specific for
+ * webkit (only browser that really supports touches).
+ *
+ * @param event
+ * @return
+ */
+ protected int getEventPosition(Event event) {
+ if (vertical) {
+ return Util.getTouchOrMouseClientY(event);
+ } else {
+ return Util.getTouchOrMouseClientX(event);
+ }
+ }
+
+ public void iLayout() {
+ if (vertical) {
+ setHeight();
+ }
+ // Update handle position
+ setValue(value, false);
+ }
+
+ private void setHeight() {
+ // Calculate decoration size
+ DOM.setStyleAttribute(base, "height", "0");
+ DOM.setStyleAttribute(base, "overflow", "hidden");
+ int h = DOM.getElementPropertyInt(getElement(), "offsetHeight");
+ if (h < MIN_SIZE) {
+ h = MIN_SIZE;
+ }
+ DOM.setStyleAttribute(base, "height", h + "px");
+ DOM.setStyleAttribute(base, "overflow", "");
+ }
+
+ private void updateValueToServer() {
+ client.updateVariable(id, "value", value.doubleValue(), immediate);
+ }
+
+ /**
+ * Handles the keyboard events handled by the Slider
+ *
+ * @param event
+ * The keyboard event received
+ * @return true iff the navigation event was handled
+ */
+ public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
+
+ // No support for ctrl moving
+ if (ctrl) {
+ return false;
+ }
+
+ if ((keycode == getNavigationUpKey() && vertical)
+ || (keycode == getNavigationRightKey() && !vertical)) {
+ if (shift) {
+ for (int a = 0; a < acceleration; a++) {
+ increaseValue(false);
+ }
+ acceleration++;
+ } else {
+ increaseValue(false);
+ }
+ return true;
+ } else if (keycode == getNavigationDownKey() && vertical
+ || (keycode == getNavigationLeftKey() && !vertical)) {
+ if (shift) {
+ for (int a = 0; a < acceleration; a++) {
+ decreaseValue(false);
+ }
+ acceleration++;
+ } else {
+ decreaseValue(false);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the key that increases the vertical slider. By default it is the up
+ * arrow key but by overriding this you can change the key to whatever you
+ * want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationUpKey() {
+ return KeyCodes.KEY_UP;
+ }
+
+ /**
+ * Get the key that decreases the vertical slider. By default it is the down
+ * arrow key but by overriding this you can change the key to whatever you
+ * want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationDownKey() {
+ return KeyCodes.KEY_DOWN;
+ }
+
+ /**
+ * Get the key that decreases the horizontal slider. By default it is the
+ * left arrow key but by overriding this you can change the key to whatever
+ * you want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationLeftKey() {
+ return KeyCodes.KEY_LEFT;
+ }
+
+ /**
+ * Get the key that increases the horizontal slider. By default it is the
+ * right arrow key but by overriding this you can change the key to whatever
+ * you want.
+ *
+ * @return The keycode of the key
+ */
+ protected int getNavigationRightKey() {
+ return KeyCodes.KEY_RIGHT;
+ }
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+}
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
public class VSplitPanel extends ComplexPanel implements Container,
ContainerResizedListener {
position = uidl.getStringAttribute("position");
setSplitPosition(position);
- final Paintable newFirstChild = client.getPaintable(uidl
- .getChildUIDL(0));
- final Paintable newSecondChild = client.getPaintable(uidl
- .getChildUIDL(1));
+ final VPaintableWidget newFirstChildPaintable = client
+ .getPaintable(uidl.getChildUIDL(0));
+ final VPaintableWidget newSecondChildPaintable = client
+ .getPaintable(uidl.getChildUIDL(1));
+ Widget newFirstChild = newFirstChildPaintable.getWidgetForPaintable();
+ Widget newSecondChild = newSecondChildPaintable.getWidgetForPaintable();
+
if (firstChild != newFirstChild) {
if (firstChild != null) {
- client.unregisterPaintable((Paintable) firstChild);
+ client.unregisterPaintable(VPaintableMap.get(client)
+ .getPaintable(firstChild));
}
- setFirstWidget((Widget) newFirstChild);
+ setFirstWidget(newFirstChild);
}
if (secondChild != newSecondChild) {
if (secondChild != null) {
- client.unregisterPaintable((Paintable) secondChild);
+ client.unregisterPaintable(VPaintableMap.get(client)
+ .getPaintable(secondChild));
}
- setSecondWidget((Widget) newSecondChild);
+ setSecondWidget(newSecondChild);
}
- newFirstChild.updateFromUIDL(uidl.getChildUIDL(0), client);
- newSecondChild.updateFromUIDL(uidl.getChildUIDL(1), client);
+ newFirstChildPaintable.updateFromUIDL(uidl.getChildUIDL(0), client);
+ newSecondChildPaintable.updateFromUIDL(uidl.getChildUIDL(1), client);
renderInformation.updateSize(getElement());
}
}
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
// content size change might cause change to its available space
// (scrollbars)
- for (Paintable paintable : child) {
- client.handleComponentRelativeSize((Widget) paintable);
+ for (Widget widget : children) {
+ client.handleComponentRelativeSize(widget);
}
if (height != null && width != null) {
/*
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
// TODO Implement caption handling
}
public boolean isEnabled() {
return enabled;
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
/**
* TODO make this work (just an early prototype). We may want to have paging
* style table which will be much lighter than VScrollTable is.
*/
-public class VTablePaging extends Composite implements Table, Paintable,
+public class VTablePaging extends Composite implements Table, VPaintableWidget,
ClickHandler {
private final Grid tBody = new Grid();
tBody.setWidget(curRowIndex, colIndex, new BodyCell(row,
(String) cell));
} else {
- final Paintable cellContent = client
+ final VPaintableWidget cellContent = client
.getPaintable((UIDL) cell);
final BodyCell bodyCell = new BodyCell(row);
- bodyCell.setWidget((Widget) cellContent);
+ bodyCell.setWidget(cellContent.getWidgetForPaintable());
tBody.setWidget(curRowIndex, colIndex, bodyCell);
}
colIndex++;
// TODO Auto-generated method stub
return false;
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.TooltipInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VCaption;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
public class VTabsheet extends VTabsheetBase {
tab.recalculateCaptionWidth();
UIDL tabContentUIDL = null;
- Paintable tabContent = null;
+ VPaintableWidget tabContentPaintable = null;
+ Widget tabContentWidget = null;
if (tabUidl.getChildCount() > 0) {
tabContentUIDL = tabUidl.getChildUIDL(0);
- tabContent = client.getPaintable(tabContentUIDL);
+ tabContentPaintable = client.getPaintable(tabContentUIDL);
+ tabContentWidget = tabContentPaintable.getWidgetForPaintable();
}
- if (tabContent != null) {
+ if (tabContentPaintable != null) {
/* This is a tab with content information */
- int oldIndex = tp.getWidgetIndex((Widget) tabContent);
+ int oldIndex = tp.getWidgetIndex(tabContentWidget);
if (oldIndex != -1 && oldIndex != index) {
/*
* The tab has previously been rendered in another position so
* we must move the cached content to correct position
*/
- tp.insert((Widget) tabContent, index);
+ tp.insert(tabContentWidget, index);
}
} else {
/* A tab whose content has not yet been loaded */
} else {
if (tabContentUIDL != null) {
// updating a drawn child on hidden tab
- if (tp.getWidgetIndex((Widget) tabContent) < 0) {
- tp.insert((Widget) tabContent, index);
+ if (tp.getWidgetIndex(tabContentWidget) < 0) {
+ tp.insert(tabContentWidget, index);
}
- tabContent.updateFromUIDL(tabContentUIDL, client);
+ tabContentPaintable.updateFromUIDL(tabContentUIDL, client);
} else if (tp.getWidgetCount() <= index) {
tp.add(new PlaceHolder());
}
}
private void renderContent(final UIDL contentUIDL) {
- final Paintable content = client.getPaintable(contentUIDL);
+ final VPaintableWidget content = client.getPaintable(contentUIDL);
if (tp.getWidgetCount() > activeTabIndex) {
Widget old = tp.getWidget(activeTabIndex);
if (old != content) {
tp.remove(activeTabIndex);
- if (old instanceof Paintable) {
- client.unregisterPaintable((Paintable) old);
+ VPaintableMap paintableMap = VPaintableMap.get(client);
+ if (paintableMap.isPaintable(old)) {
+ paintableMap.unregisterPaintable(paintableMap
+ .getPaintable(old));
}
- tp.insert((Widget) content, activeTabIndex);
+ tp.insert(content.getWidgetForPaintable(), activeTabIndex);
}
} else {
- tp.add((Widget) content);
+ tp.add(content.getWidgetForPaintable());
}
tp.showWidget(activeTabIndex);
VTabsheet.this.iLayout();
- (content).updateFromUIDL(contentUIDL, client);
+ content.updateFromUIDL(contentUIDL, client);
/*
* The size of a cached, relative sized component must be updated to
* report correct size to updateOpenTabSize().
*/
if (contentUIDL.getBooleanAttribute("cached")) {
- client.handleComponentRelativeSize((Widget) content);
+ client.handleComponentRelativeSize(content.getWidgetForPaintable());
}
updateOpenTabSize();
VTabsheet.this.removeStyleDependentName("loading");
}
@Override
- protected Iterator getPaintableIterator() {
+ protected Iterator<Widget> getWidgetIterator() {
return tp.iterator();
}
tp.replaceComponent(oldComponent, newComponent);
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
/* Tabsheet does not render its children's captions */
}
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
if (!isDynamicHeight() && !isDynamicWidth()) {
/*
* If the height and width has been specified for this container the
* child components cannot make the size of the layout change
*/
// layout size change may affect its available space (scrollbars)
- for (Paintable paintable : child) {
- client.handleComponentRelativeSize((Widget) paintable);
+ for (Widget widget : children) {
+ client.handleComponentRelativeSize(widget);
}
return true;
}
}
@Override
- protected Paintable getTab(int index) {
+ protected VPaintableWidget getTab(int index) {
if (tp.getWidgetCount() > index) {
- return (Paintable) tp.getWidget(index);
+ Widget widget = tp.getWidget(index);
+ return VPaintableMap.get(client).getPaintable(widget);
}
return null;
}
}
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Container;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
abstract class VTabsheetBase extends ComplexPanel implements Container {
final UIDL tabs = uidl.getChildUIDL(0);
// Paintables in the TabSheet before update
- ArrayList<Object> oldPaintables = new ArrayList<Object>();
- for (Iterator<Object> iterator = getPaintableIterator(); iterator
+ ArrayList<Widget> oldWidgets = new ArrayList<Widget>();
+ for (Iterator<Widget> iterator = getWidgetIterator(); iterator
.hasNext();) {
- oldPaintables.add(iterator.next());
+ oldWidgets.add(iterator.next());
}
// Clear previous values
}
for (int i = 0; i < getTabCount(); i++) {
- Paintable p = getTab(i);
- oldPaintables.remove(p);
+ VPaintableWidget p = getTab(i);
+ // During the initial rendering the paintable might be null (this is
+ // weird...)
+ if (p != null) {
+ oldWidgets.remove(p.getWidgetForPaintable());
+ }
}
// Perform unregister for any paintables removed during update
- for (Iterator<Object> iterator = oldPaintables.iterator(); iterator
+ for (Iterator<Widget> iterator = oldWidgets.iterator(); iterator
.hasNext();) {
- Object oldPaintable = iterator.next();
- if (oldPaintable instanceof Paintable) {
- Widget w = (Widget) oldPaintable;
- if (w.isAttached()) {
- w.removeFromParent();
- }
- client.unregisterPaintable((Paintable) oldPaintable);
+ Widget oldWidget = iterator.next();
+ VPaintableWidget oldPaintable = VPaintableMap.get(client)
+ .getPaintable(oldWidget);
+ if (oldWidget.isAttached()) {
+ oldWidget.removeFromParent();
}
+ VPaintableMap.get(client).unregisterPaintable(oldPaintable);
}
}
* {@link #updateFromUIDL(UIDL, ApplicationConnection)} checks if
* instanceof Paintable. Therefore set to <Object>
*/
- abstract protected Iterator<Object> getPaintableIterator();
+ abstract protected Iterator<Widget> getWidgetIterator();
/**
* Clears current tabs and contents
* Implement in extending classes. This method should return the Paintable
* corresponding to the given index.
*/
- protected abstract Paintable getTab(int index);
+ protected abstract VPaintableWidget getTab(int index);
/**
* Implement in extending classes. This method should remove the rendered
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.TextBoxBase;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.EventId;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VTooltip;
* @author Vaadin Ltd.
*
*/
-public class VTextField extends TextBoxBase implements Paintable, Field,
+public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
ChangeHandler, FocusHandler, BlurHandler, BeforeShortcutActionListener,
KeyDownHandler {
valueChange(false);
}
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
import com.vaadin.terminal.gwt.client.Focusable;
import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;
import com.vaadin.terminal.gwt.client.LocaleService;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VConsole;
-public class VTextualDate extends VDateField implements Paintable, Field,
+public class VTextualDate extends VDateField implements VPaintableWidget, Field,
ChangeHandler, ContainerResizedListener, Focusable, SubPartAware {
private static final String PARSE_ERROR_CLASSNAME = CLASSNAME
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.TooltipInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
/**
*
*/
-public class VTree extends FocusElementPanel implements Paintable,
+public class VTree extends FocusElementPanel implements VPaintableWidget,
VHasDropHandler, FocusHandler, BlurHandler, KeyPressHandler,
KeyDownHandler, SubPartAware, ActionOwner {
}
@Override
- public Paintable getPaintable() {
+ public VPaintableWidget getPaintable() {
return VTree.this;
}
event.preventDefault();
}
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
-/*\r
-@VaadinApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashSet;\r
-import java.util.Iterator;\r
-import java.util.Set;\r
-\r
-import com.google.gwt.dom.client.Style.Overflow;\r
-import com.google.gwt.event.dom.client.ClickEvent;\r
-import com.google.gwt.event.dom.client.DoubleClickEvent;\r
-import com.google.gwt.event.dom.client.DoubleClickHandler;\r
-import com.google.gwt.event.dom.client.HasDoubleClickHandlers;\r
-import com.google.gwt.event.dom.client.KeyCodes;\r
-import com.google.gwt.event.dom.client.KeyDownEvent;\r
-import com.google.gwt.event.dom.client.KeyDownHandler;\r
-import com.google.gwt.event.dom.client.MouseDownEvent;\r
-import com.google.gwt.event.dom.client.MouseDownHandler;\r
-import com.google.gwt.event.shared.HandlerRegistration;\r
-import com.google.gwt.user.client.DOM;\r
-import com.google.gwt.user.client.Element;\r
-import com.google.gwt.user.client.ui.FlowPanel;\r
-import com.google.gwt.user.client.ui.HTML;\r
-import com.google.gwt.user.client.ui.ListBox;\r
-import com.google.gwt.user.client.ui.Panel;\r
-import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-import com.vaadin.terminal.gwt.client.Util;\r
-\r
-public class VTwinColSelect extends VOptionGroupBase implements KeyDownHandler,\r
- MouseDownHandler, DoubleClickHandler, SubPartAware {\r
-\r
- private static final String CLASSNAME = "v-select-twincol";\r
- public static final String ATTRIBUTE_LEFT_CAPTION = "lc";\r
- public static final String ATTRIBUTE_RIGHT_CAPTION = "rc";\r
-\r
- private static final int VISIBLE_COUNT = 10;\r
-\r
- private static final int DEFAULT_COLUMN_COUNT = 10;\r
-\r
- private final DoubleClickListBox options;\r
-\r
- private final DoubleClickListBox selections;\r
-\r
- private FlowPanel captionWrapper;\r
-\r
- private HTML optionsCaption = null;\r
-\r
- private HTML selectionsCaption = null;\r
-\r
- private final VButton add;\r
-\r
- private final VButton remove;\r
-\r
- private final FlowPanel buttons;\r
-\r
- private final Panel panel;\r
-\r
- private boolean widthSet = false;\r
-\r
- /**\r
- * A ListBox which catches double clicks\r
- * \r
- */\r
- public class DoubleClickListBox extends ListBox implements\r
- HasDoubleClickHandlers {\r
- public DoubleClickListBox(boolean isMultipleSelect) {\r
- super(isMultipleSelect);\r
- }\r
-\r
- public DoubleClickListBox() {\r
- super();\r
- }\r
-\r
- @Override\r
- public HandlerRegistration addDoubleClickHandler(\r
- DoubleClickHandler handler) {\r
- return addDomHandler(handler, DoubleClickEvent.getType());\r
- }\r
- }\r
-\r
- public VTwinColSelect() {\r
- super(CLASSNAME);\r
-\r
- captionWrapper = new FlowPanel();\r
-\r
- options = new DoubleClickListBox();\r
- options.addClickHandler(this);\r
- options.addDoubleClickHandler(this);\r
- options.setVisibleItemCount(VISIBLE_COUNT);\r
- options.setStyleName(CLASSNAME + "-options");\r
-\r
- selections = new DoubleClickListBox();\r
- selections.addClickHandler(this);\r
- selections.addDoubleClickHandler(this);\r
- selections.setVisibleItemCount(VISIBLE_COUNT);\r
- selections.setStyleName(CLASSNAME + "-selections");\r
-\r
- buttons = new FlowPanel();\r
- buttons.setStyleName(CLASSNAME + "-buttons");\r
- add = new VButton();\r
- add.setText(">>");\r
- add.addClickHandler(this);\r
- remove = new VButton();\r
- remove.setText("<<");\r
- remove.addClickHandler(this);\r
-\r
- panel = ((Panel) optionsContainer);\r
-\r
- panel.add(captionWrapper);\r
- captionWrapper.getElement().getStyle().setOverflow(Overflow.HIDDEN);\r
- // Hide until there actually is a caption to prevent IE from rendering\r
- // extra empty space\r
- captionWrapper.setVisible(false);\r
-\r
- panel.add(options);\r
- buttons.add(add);\r
- final HTML br = new HTML("<span/>");\r
- br.setStyleName(CLASSNAME + "-deco");\r
- buttons.add(br);\r
- buttons.add(remove);\r
- panel.add(buttons);\r
- panel.add(selections);\r
-\r
- options.addKeyDownHandler(this);\r
- options.addMouseDownHandler(this);\r
-\r
- selections.addMouseDownHandler(this);\r
- selections.addKeyDownHandler(this);\r
- }\r
-\r
- public HTML getOptionsCaption() {\r
- if (optionsCaption == null) {\r
- optionsCaption = new HTML();\r
- optionsCaption.setStyleName(CLASSNAME + "-caption-left");\r
- optionsCaption.getElement().getStyle()\r
- .setFloat(com.google.gwt.dom.client.Style.Float.LEFT);\r
- captionWrapper.add(optionsCaption);\r
- }\r
-\r
- return optionsCaption;\r
- }\r
-\r
- public HTML getSelectionsCaption() {\r
- if (selectionsCaption == null) {\r
- selectionsCaption = new HTML();\r
- selectionsCaption.setStyleName(CLASSNAME + "-caption-right");\r
- selectionsCaption.getElement().getStyle()\r
- .setFloat(com.google.gwt.dom.client.Style.Float.RIGHT);\r
- captionWrapper.add(selectionsCaption);\r
- }\r
-\r
- return selectionsCaption;\r
- }\r
-\r
- @Override\r
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
- // Captions are updated before super call to ensure the widths are set\r
- // correctly\r
- if (!uidl.getBooleanAttribute("cached")) {\r
- updateCaptions(uidl);\r
- }\r
-\r
- super.updateFromUIDL(uidl, client);\r
- }\r
-\r
- private void updateCaptions(UIDL uidl) {\r
- String leftCaption = (uidl.hasAttribute(ATTRIBUTE_LEFT_CAPTION) ? uidl\r
- .getStringAttribute(ATTRIBUTE_LEFT_CAPTION) : null);\r
- String rightCaption = (uidl.hasAttribute(ATTRIBUTE_RIGHT_CAPTION) ? uidl\r
- .getStringAttribute(ATTRIBUTE_RIGHT_CAPTION) : null);\r
-\r
- boolean hasCaptions = (leftCaption != null || rightCaption != null);\r
-\r
- if (leftCaption == null) {\r
- removeOptionsCaption();\r
- } else {\r
- getOptionsCaption().setText(leftCaption);\r
-\r
- }\r
-\r
- if (rightCaption == null) {\r
- removeSelectionsCaption();\r
- } else {\r
- getSelectionsCaption().setText(rightCaption);\r
- }\r
-\r
- captionWrapper.setVisible(hasCaptions);\r
- }\r
-\r
- private void removeOptionsCaption() {\r
- if (optionsCaption == null) {\r
- return;\r
- }\r
-\r
- if (optionsCaption.getParent() != null) {\r
- captionWrapper.remove(optionsCaption);\r
- }\r
-\r
- optionsCaption = null;\r
- }\r
-\r
- private void removeSelectionsCaption() {\r
- if (selectionsCaption == null) {\r
- return;\r
- }\r
-\r
- if (selectionsCaption.getParent() != null) {\r
- captionWrapper.remove(selectionsCaption);\r
- }\r
-\r
- selectionsCaption = null;\r
- }\r
-\r
- @Override\r
- protected void buildOptions(UIDL uidl) {\r
- final boolean enabled = !isDisabled() && !isReadonly();\r
- options.setMultipleSelect(isMultiselect());\r
- selections.setMultipleSelect(isMultiselect());\r
- options.setEnabled(enabled);\r
- selections.setEnabled(enabled);\r
- add.setEnabled(enabled);\r
- remove.setEnabled(enabled);\r
- options.clear();\r
- selections.clear();\r
- for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {\r
- final UIDL optionUidl = (UIDL) i.next();\r
- if (optionUidl.hasAttribute("selected")) {\r
- selections.addItem(optionUidl.getStringAttribute("caption"),\r
- optionUidl.getStringAttribute("key"));\r
- } else {\r
- options.addItem(optionUidl.getStringAttribute("caption"),\r
- optionUidl.getStringAttribute("key"));\r
- }\r
- }\r
-\r
- int cols = -1;\r
- if (getColumns() > 0) {\r
- cols = getColumns();\r
- } else if (!widthSet) {\r
- cols = DEFAULT_COLUMN_COUNT;\r
- }\r
-\r
- if (cols >= 0) {\r
- String colWidth = cols + "em";\r
- String containerWidth = (2 * cols + 4) + "em";\r
- // Caption wrapper width == optionsSelect + buttons +\r
- // selectionsSelect\r
- String captionWrapperWidth = (2 * cols + 4 - 0.5) + "em";\r
-\r
- options.setWidth(colWidth);\r
- if (optionsCaption != null) {\r
- optionsCaption.setWidth(colWidth);\r
- }\r
- selections.setWidth(colWidth);\r
- if (selectionsCaption != null) {\r
- selectionsCaption.setWidth(colWidth);\r
- }\r
- buttons.setWidth("3.5em");\r
- optionsContainer.setWidth(containerWidth);\r
- captionWrapper.setWidth(captionWrapperWidth);\r
- }\r
- if (getRows() > 0) {\r
- options.setVisibleItemCount(getRows());\r
- selections.setVisibleItemCount(getRows());\r
-\r
- }\r
-\r
- }\r
-\r
- @Override\r
- protected String[] getSelectedItems() {\r
- final ArrayList<String> selectedItemKeys = new ArrayList<String>();\r
- for (int i = 0; i < selections.getItemCount(); i++) {\r
- selectedItemKeys.add(selections.getValue(i));\r
- }\r
- return selectedItemKeys.toArray(new String[selectedItemKeys.size()]);\r
- }\r
-\r
- private boolean[] getSelectionBitmap(ListBox listBox) {\r
- final boolean[] selectedIndexes = new boolean[listBox.getItemCount()];\r
- for (int i = 0; i < listBox.getItemCount(); i++) {\r
- if (listBox.isItemSelected(i)) {\r
- selectedIndexes[i] = true;\r
- } else {\r
- selectedIndexes[i] = false;\r
- }\r
- }\r
- return selectedIndexes;\r
- }\r
-\r
- private void addItem() {\r
- Set<String> movedItems = moveSelectedItems(options, selections);\r
- selectedKeys.addAll(movedItems);\r
-\r
- client.updateVariable(id, "selected",\r
- selectedKeys.toArray(new String[selectedKeys.size()]),\r
- isImmediate());\r
- }\r
-\r
- private void removeItem() {\r
- Set<String> movedItems = moveSelectedItems(selections, options);\r
- selectedKeys.removeAll(movedItems);\r
-\r
- client.updateVariable(id, "selected",\r
- selectedKeys.toArray(new String[selectedKeys.size()]),\r
- isImmediate());\r
- }\r
-\r
- private Set<String> moveSelectedItems(ListBox source, ListBox target) {\r
- final boolean[] sel = getSelectionBitmap(source);\r
- final Set<String> movedItems = new HashSet<String>();\r
- int lastSelected = 0;\r
- for (int i = 0; i < sel.length; i++) {\r
- if (sel[i]) {\r
- final int optionIndex = i\r
- - (sel.length - source.getItemCount());\r
- movedItems.add(source.getValue(optionIndex));\r
-\r
- // Move selection to another column\r
- final String text = source.getItemText(optionIndex);\r
- final String value = source.getValue(optionIndex);\r
- target.addItem(text, value);\r
- target.setItemSelected(target.getItemCount() - 1, true);\r
- source.removeItem(optionIndex);\r
-\r
- if (source.getItemCount() > 0) {\r
- lastSelected = optionIndex > 0 ? optionIndex - 1 : 0;\r
- }\r
- }\r
- }\r
-\r
- if (source.getItemCount() > 0) {\r
- source.setSelectedIndex(lastSelected);\r
- }\r
-\r
- // If no items are left move the focus to the selections\r
- if (source.getItemCount() == 0) {\r
- target.setFocus(true);\r
- } else {\r
- source.setFocus(true);\r
- }\r
-\r
- return movedItems;\r
- }\r
-\r
- @Override\r
- public void onClick(ClickEvent event) {\r
- super.onClick(event);\r
- if (event.getSource() == add) {\r
- addItem();\r
-\r
- } else if (event.getSource() == remove) {\r
- removeItem();\r
-\r
- } else if (event.getSource() == options) {\r
- // unselect all in other list, to avoid mistakes (i.e wrong button)\r
- final int c = selections.getItemCount();\r
- for (int i = 0; i < c; i++) {\r
- selections.setItemSelected(i, false);\r
- }\r
- } else if (event.getSource() == selections) {\r
- // unselect all in other list, to avoid mistakes (i.e wrong button)\r
- final int c = options.getItemCount();\r
- for (int i = 0; i < c; i++) {\r
- options.setItemSelected(i, false);\r
- }\r
- }\r
- }\r
-\r
- @Override\r
- public void setHeight(String height) {\r
- super.setHeight(height);\r
- if ("".equals(height)) {\r
- options.setHeight("");\r
- selections.setHeight("");\r
- } else {\r
- setInternalHeights();\r
- }\r
- }\r
-\r
- private void setInternalHeights() {\r
- int captionHeight = 0;\r
- int totalHeight = getOffsetHeight();\r
-\r
- if (optionsCaption != null) {\r
- captionHeight = Util.getRequiredHeight(optionsCaption);\r
- } else if (selectionsCaption != null) {\r
- captionHeight = Util.getRequiredHeight(selectionsCaption);\r
- }\r
- String selectHeight = (totalHeight - captionHeight) + "px";\r
-\r
- selections.setHeight(selectHeight);\r
- options.setHeight(selectHeight);\r
-\r
- }\r
-\r
- @Override\r
- public void setWidth(String width) {\r
- super.setWidth(width);\r
- if (!"".equals(width) && width != null) {\r
- setInternalWidths();\r
- widthSet = true;\r
- } else {\r
- widthSet = false;\r
- }\r
- }\r
-\r
- private void setInternalWidths() {\r
- DOM.setStyleAttribute(getElement(), "position", "relative");\r
- int bordersAndPaddings = Util.measureHorizontalPaddingAndBorder(\r
- buttons.getElement(), 0);\r
-\r
- int buttonWidth = Util.getRequiredWidth(buttons);\r
- int totalWidth = getOffsetWidth();\r
-\r
- int spaceForSelect = (totalWidth - buttonWidth - bordersAndPaddings) / 2;\r
-\r
- options.setWidth(spaceForSelect + "px");\r
- if (optionsCaption != null) {\r
- optionsCaption.setWidth(spaceForSelect + "px");\r
- }\r
-\r
- selections.setWidth(spaceForSelect + "px");\r
- if (selectionsCaption != null) {\r
- selectionsCaption.setWidth(spaceForSelect + "px");\r
- }\r
- captionWrapper.setWidth("100%");\r
- }\r
-\r
- @Override\r
- protected void setTabIndex(int tabIndex) {\r
- options.setTabIndex(tabIndex);\r
- selections.setTabIndex(tabIndex);\r
- add.setTabIndex(tabIndex);\r
- remove.setTabIndex(tabIndex);\r
- }\r
-\r
- public void focus() {\r
- options.setFocus(true);\r
- }\r
-\r
- /**\r
- * Get the key that selects an item in the table. By default it is the Enter\r
- * key but by overriding this you can change the key to whatever you want.\r
- * \r
- * @return\r
- */\r
- protected int getNavigationSelectKey() {\r
- return KeyCodes.KEY_ENTER;\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see\r
- * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt\r
- * .event.dom.client.KeyDownEvent)\r
- */\r
- public void onKeyDown(KeyDownEvent event) {\r
- int keycode = event.getNativeKeyCode();\r
-\r
- // Catch tab and move between select:s\r
- if (keycode == KeyCodes.KEY_TAB && event.getSource() == options) {\r
- // Prevent default behavior\r
- event.preventDefault();\r
-\r
- // Remove current selections\r
- for (int i = 0; i < options.getItemCount(); i++) {\r
- options.setItemSelected(i, false);\r
- }\r
-\r
- // Focus selections\r
- selections.setFocus(true);\r
- }\r
-\r
- if (keycode == KeyCodes.KEY_TAB && event.isShiftKeyDown()\r
- && event.getSource() == selections) {\r
- // Prevent default behavior\r
- event.preventDefault();\r
-\r
- // Remove current selections\r
- for (int i = 0; i < selections.getItemCount(); i++) {\r
- selections.setItemSelected(i, false);\r
- }\r
-\r
- // Focus options\r
- options.setFocus(true);\r
- }\r
-\r
- if (keycode == getNavigationSelectKey()) {\r
- // Prevent default behavior\r
- event.preventDefault();\r
-\r
- // Decide which select the selection was made in\r
- if (event.getSource() == options) {\r
- // Prevents the selection to become a single selection when\r
- // using Enter key\r
- // as the selection key (default)\r
- options.setFocus(false);\r
-\r
- addItem();\r
-\r
- } else if (event.getSource() == selections) {\r
- // Prevents the selection to become a single selection when\r
- // using Enter key\r
- // as the selection key (default)\r
- selections.setFocus(false);\r
-\r
- removeItem();\r
- }\r
- }\r
-\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see\r
- * com.google.gwt.event.dom.client.MouseDownHandler#onMouseDown(com.google\r
- * .gwt.event.dom.client.MouseDownEvent)\r
- */\r
- public void onMouseDown(MouseDownEvent event) {\r
- // Ensure that items are deselected when selecting\r
- // from a different source. See #3699 for details.\r
- if (event.getSource() == options) {\r
- for (int i = 0; i < selections.getItemCount(); i++) {\r
- selections.setItemSelected(i, false);\r
- }\r
- } else if (event.getSource() == selections) {\r
- for (int i = 0; i < options.getItemCount(); i++) {\r
- options.setItemSelected(i, false);\r
- }\r
- }\r
-\r
- }\r
-\r
- /*\r
- * (non-Javadoc)\r
- * \r
- * @see\r
- * com.google.gwt.event.dom.client.DoubleClickHandler#onDoubleClick(com.\r
- * google.gwt.event.dom.client.DoubleClickEvent)\r
- */\r
- public void onDoubleClick(DoubleClickEvent event) {\r
- if (event.getSource() == options) {\r
- addItem();\r
- options.setSelectedIndex(-1);\r
- options.setFocus(false);\r
- } else if (event.getSource() == selections) {\r
- removeItem();\r
- selections.setSelectedIndex(-1);\r
- selections.setFocus(false);\r
- }\r
-\r
- }\r
-\r
- private static final String SUBPART_OPTION_SELECT = "leftSelect";\r
- private static final String SUBPART_OPTION_SELECT_ITEM = SUBPART_OPTION_SELECT\r
- + "-item";\r
- private static final String SUBPART_SELECTION_SELECT = "rightSelect";\r
- private static final String SUBPART_SELECTION_SELECT_ITEM = SUBPART_SELECTION_SELECT\r
- + "-item";\r
- private static final String SUBPART_LEFT_CAPTION = "leftCaption";\r
- private static final String SUBPART_RIGHT_CAPTION = "rightCaption";\r
- private static final String SUBPART_ADD_BUTTON = "add";\r
- private static final String SUBPART_REMOVE_BUTTON = "remove";\r
-\r
- public Element getSubPartElement(String subPart) {\r
- if (SUBPART_OPTION_SELECT.equals(subPart)) {\r
- return options.getElement();\r
- } else if (subPart.startsWith(SUBPART_OPTION_SELECT_ITEM)) {\r
- String idx = subPart.substring(SUBPART_OPTION_SELECT_ITEM.length());\r
- return (Element) options.getElement().getChild(\r
- Integer.parseInt(idx));\r
- } else if (SUBPART_SELECTION_SELECT.equals(subPart)) {\r
- return selections.getElement();\r
- } else if (subPart.startsWith(SUBPART_SELECTION_SELECT_ITEM)) {\r
- String idx = subPart.substring(SUBPART_SELECTION_SELECT_ITEM\r
- .length());\r
- return (Element) selections.getElement().getChild(\r
- Integer.parseInt(idx));\r
- } else if (optionsCaption != null\r
- && SUBPART_LEFT_CAPTION.equals(subPart)) {\r
- return optionsCaption.getElement();\r
- } else if (selectionsCaption != null\r
- && SUBPART_RIGHT_CAPTION.equals(subPart)) {\r
- return selectionsCaption.getElement();\r
- } else if (SUBPART_ADD_BUTTON.equals(subPart)) {\r
- return add.getElement();\r
- } else if (SUBPART_REMOVE_BUTTON.equals(subPart)) {\r
- return remove.getElement();\r
- }\r
-\r
- return null;\r
- }\r
-\r
- public String getSubPartName(Element subElement) {\r
- if (optionsCaption != null\r
- && optionsCaption.getElement().isOrHasChild(subElement)) {\r
- return SUBPART_LEFT_CAPTION;\r
- } else if (selectionsCaption != null\r
- && selectionsCaption.getElement().isOrHasChild(subElement)) {\r
- return SUBPART_RIGHT_CAPTION;\r
- } else if (options.getElement().isOrHasChild(subElement)) {\r
- if (options.getElement() == subElement) {\r
- return SUBPART_OPTION_SELECT;\r
- } else {\r
- int idx = Util.getChildElementIndex(subElement);\r
- return SUBPART_OPTION_SELECT_ITEM + idx;\r
- }\r
- } else if (selections.getElement().isOrHasChild(subElement)) {\r
- if (selections.getElement() == subElement) {\r
- return SUBPART_SELECTION_SELECT;\r
- } else {\r
- int idx = Util.getChildElementIndex(subElement);\r
- return SUBPART_SELECTION_SELECT_ITEM + idx;\r
- }\r
- } else if (add.getElement().isOrHasChild(subElement)) {\r
- return SUBPART_ADD_BUTTON;\r
- } else if (remove.getElement().isOrHasChild(subElement)) {\r
- return SUBPART_REMOVE_BUTTON;\r
- }\r
-\r
- return null;\r
- }\r
-}\r
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import com.google.gwt.dom.client.Style.Overflow;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.DoubleClickEvent;
+import com.google.gwt.event.dom.client.DoubleClickHandler;
+import com.google.gwt.event.dom.client.HasDoubleClickHandlers;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.event.dom.client.KeyDownHandler;
+import com.google.gwt.event.dom.client.MouseDownEvent;
+import com.google.gwt.event.dom.client.MouseDownHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+
+public class VTwinColSelect extends VOptionGroupBase implements KeyDownHandler,
+ MouseDownHandler, DoubleClickHandler, SubPartAware {
+
+ private static final String CLASSNAME = "v-select-twincol";
+ public static final String ATTRIBUTE_LEFT_CAPTION = "lc";
+ public static final String ATTRIBUTE_RIGHT_CAPTION = "rc";
+
+ private static final int VISIBLE_COUNT = 10;
+
+ private static final int DEFAULT_COLUMN_COUNT = 10;
+
+ private final DoubleClickListBox options;
+
+ private final DoubleClickListBox selections;
+
+ private FlowPanel captionWrapper;
+
+ private HTML optionsCaption = null;
+
+ private HTML selectionsCaption = null;
+
+ private final VButton add;
+
+ private final VButton remove;
+
+ private final FlowPanel buttons;
+
+ private final Panel panel;
+
+ private boolean widthSet = false;
+
+ /**
+ * A ListBox which catches double clicks
+ *
+ */
+ public class DoubleClickListBox extends ListBox implements
+ HasDoubleClickHandlers {
+ public DoubleClickListBox(boolean isMultipleSelect) {
+ super(isMultipleSelect);
+ }
+
+ public DoubleClickListBox() {
+ super();
+ }
+
+ @Override
+ public HandlerRegistration addDoubleClickHandler(
+ DoubleClickHandler handler) {
+ return addDomHandler(handler, DoubleClickEvent.getType());
+ }
+ }
+
+ public VTwinColSelect() {
+ super(CLASSNAME);
+
+ captionWrapper = new FlowPanel();
+
+ options = new DoubleClickListBox();
+ options.addClickHandler(this);
+ options.addDoubleClickHandler(this);
+ options.setVisibleItemCount(VISIBLE_COUNT);
+ options.setStyleName(CLASSNAME + "-options");
+
+ selections = new DoubleClickListBox();
+ selections.addClickHandler(this);
+ selections.addDoubleClickHandler(this);
+ selections.setVisibleItemCount(VISIBLE_COUNT);
+ selections.setStyleName(CLASSNAME + "-selections");
+
+ buttons = new FlowPanel();
+ buttons.setStyleName(CLASSNAME + "-buttons");
+ add = new VButton();
+ add.setText(">>");
+ add.addClickHandler(this);
+ remove = new VButton();
+ remove.setText("<<");
+ remove.addClickHandler(this);
+
+ panel = ((Panel) optionsContainer);
+
+ panel.add(captionWrapper);
+ captionWrapper.getElement().getStyle().setOverflow(Overflow.HIDDEN);
+ // Hide until there actually is a caption to prevent IE from rendering
+ // extra empty space
+ captionWrapper.setVisible(false);
+
+ panel.add(options);
+ buttons.add(add);
+ final HTML br = new HTML("<span/>");
+ br.setStyleName(CLASSNAME + "-deco");
+ buttons.add(br);
+ buttons.add(remove);
+ panel.add(buttons);
+ panel.add(selections);
+
+ options.addKeyDownHandler(this);
+ options.addMouseDownHandler(this);
+
+ selections.addMouseDownHandler(this);
+ selections.addKeyDownHandler(this);
+ }
+
+ public HTML getOptionsCaption() {
+ if (optionsCaption == null) {
+ optionsCaption = new HTML();
+ optionsCaption.setStyleName(CLASSNAME + "-caption-left");
+ optionsCaption.getElement().getStyle()
+ .setFloat(com.google.gwt.dom.client.Style.Float.LEFT);
+ captionWrapper.add(optionsCaption);
+ }
+
+ return optionsCaption;
+ }
+
+ public HTML getSelectionsCaption() {
+ if (selectionsCaption == null) {
+ selectionsCaption = new HTML();
+ selectionsCaption.setStyleName(CLASSNAME + "-caption-right");
+ selectionsCaption.getElement().getStyle()
+ .setFloat(com.google.gwt.dom.client.Style.Float.RIGHT);
+ captionWrapper.add(selectionsCaption);
+ }
+
+ return selectionsCaption;
+ }
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // Captions are updated before super call to ensure the widths are set
+ // correctly
+ if (!uidl.getBooleanAttribute("cached")) {
+ updateCaptions(uidl);
+ }
+
+ super.updateFromUIDL(uidl, client);
+ }
+
+ private void updateCaptions(UIDL uidl) {
+ String leftCaption = (uidl.hasAttribute(ATTRIBUTE_LEFT_CAPTION) ? uidl
+ .getStringAttribute(ATTRIBUTE_LEFT_CAPTION) : null);
+ String rightCaption = (uidl.hasAttribute(ATTRIBUTE_RIGHT_CAPTION) ? uidl
+ .getStringAttribute(ATTRIBUTE_RIGHT_CAPTION) : null);
+
+ boolean hasCaptions = (leftCaption != null || rightCaption != null);
+
+ if (leftCaption == null) {
+ removeOptionsCaption();
+ } else {
+ getOptionsCaption().setText(leftCaption);
+
+ }
+
+ if (rightCaption == null) {
+ removeSelectionsCaption();
+ } else {
+ getSelectionsCaption().setText(rightCaption);
+ }
+
+ captionWrapper.setVisible(hasCaptions);
+ }
+
+ private void removeOptionsCaption() {
+ if (optionsCaption == null) {
+ return;
+ }
+
+ if (optionsCaption.getParent() != null) {
+ captionWrapper.remove(optionsCaption);
+ }
+
+ optionsCaption = null;
+ }
+
+ private void removeSelectionsCaption() {
+ if (selectionsCaption == null) {
+ return;
+ }
+
+ if (selectionsCaption.getParent() != null) {
+ captionWrapper.remove(selectionsCaption);
+ }
+
+ selectionsCaption = null;
+ }
+
+ @Override
+ protected void buildOptions(UIDL uidl) {
+ final boolean enabled = !isDisabled() && !isReadonly();
+ options.setMultipleSelect(isMultiselect());
+ selections.setMultipleSelect(isMultiselect());
+ options.setEnabled(enabled);
+ selections.setEnabled(enabled);
+ add.setEnabled(enabled);
+ remove.setEnabled(enabled);
+ options.clear();
+ selections.clear();
+ for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
+ final UIDL optionUidl = (UIDL) i.next();
+ if (optionUidl.hasAttribute("selected")) {
+ selections.addItem(optionUidl.getStringAttribute("caption"),
+ optionUidl.getStringAttribute("key"));
+ } else {
+ options.addItem(optionUidl.getStringAttribute("caption"),
+ optionUidl.getStringAttribute("key"));
+ }
+ }
+
+ int cols = -1;
+ if (getColumns() > 0) {
+ cols = getColumns();
+ } else if (!widthSet) {
+ cols = DEFAULT_COLUMN_COUNT;
+ }
+
+ if (cols >= 0) {
+ String colWidth = cols + "em";
+ String containerWidth = (2 * cols + 4) + "em";
+ // Caption wrapper width == optionsSelect + buttons +
+ // selectionsSelect
+ String captionWrapperWidth = (2 * cols + 4 - 0.5) + "em";
+
+ options.setWidth(colWidth);
+ if (optionsCaption != null) {
+ optionsCaption.setWidth(colWidth);
+ }
+ selections.setWidth(colWidth);
+ if (selectionsCaption != null) {
+ selectionsCaption.setWidth(colWidth);
+ }
+ buttons.setWidth("3.5em");
+ optionsContainer.setWidth(containerWidth);
+ captionWrapper.setWidth(captionWrapperWidth);
+ }
+ if (getRows() > 0) {
+ options.setVisibleItemCount(getRows());
+ selections.setVisibleItemCount(getRows());
+
+ }
+
+ }
+
+ @Override
+ protected String[] getSelectedItems() {
+ final ArrayList<String> selectedItemKeys = new ArrayList<String>();
+ for (int i = 0; i < selections.getItemCount(); i++) {
+ selectedItemKeys.add(selections.getValue(i));
+ }
+ return selectedItemKeys.toArray(new String[selectedItemKeys.size()]);
+ }
+
+ private boolean[] getSelectionBitmap(ListBox listBox) {
+ final boolean[] selectedIndexes = new boolean[listBox.getItemCount()];
+ for (int i = 0; i < listBox.getItemCount(); i++) {
+ if (listBox.isItemSelected(i)) {
+ selectedIndexes[i] = true;
+ } else {
+ selectedIndexes[i] = false;
+ }
+ }
+ return selectedIndexes;
+ }
+
+ private void addItem() {
+ Set<String> movedItems = moveSelectedItems(options, selections);
+ selectedKeys.addAll(movedItems);
+
+ client.updateVariable(id, "selected",
+ selectedKeys.toArray(new String[selectedKeys.size()]),
+ isImmediate());
+ }
+
+ private void removeItem() {
+ Set<String> movedItems = moveSelectedItems(selections, options);
+ selectedKeys.removeAll(movedItems);
+
+ client.updateVariable(id, "selected",
+ selectedKeys.toArray(new String[selectedKeys.size()]),
+ isImmediate());
+ }
+
+ private Set<String> moveSelectedItems(ListBox source, ListBox target) {
+ final boolean[] sel = getSelectionBitmap(source);
+ final Set<String> movedItems = new HashSet<String>();
+ int lastSelected = 0;
+ for (int i = 0; i < sel.length; i++) {
+ if (sel[i]) {
+ final int optionIndex = i
+ - (sel.length - source.getItemCount());
+ movedItems.add(source.getValue(optionIndex));
+
+ // Move selection to another column
+ final String text = source.getItemText(optionIndex);
+ final String value = source.getValue(optionIndex);
+ target.addItem(text, value);
+ target.setItemSelected(target.getItemCount() - 1, true);
+ source.removeItem(optionIndex);
+
+ if (source.getItemCount() > 0) {
+ lastSelected = optionIndex > 0 ? optionIndex - 1 : 0;
+ }
+ }
+ }
+
+ if (source.getItemCount() > 0) {
+ source.setSelectedIndex(lastSelected);
+ }
+
+ // If no items are left move the focus to the selections
+ if (source.getItemCount() == 0) {
+ target.setFocus(true);
+ } else {
+ source.setFocus(true);
+ }
+
+ return movedItems;
+ }
+
+ @Override
+ public void onClick(ClickEvent event) {
+ super.onClick(event);
+ if (event.getSource() == add) {
+ addItem();
+
+ } else if (event.getSource() == remove) {
+ removeItem();
+
+ } else if (event.getSource() == options) {
+ // unselect all in other list, to avoid mistakes (i.e wrong button)
+ final int c = selections.getItemCount();
+ for (int i = 0; i < c; i++) {
+ selections.setItemSelected(i, false);
+ }
+ } else if (event.getSource() == selections) {
+ // unselect all in other list, to avoid mistakes (i.e wrong button)
+ final int c = options.getItemCount();
+ for (int i = 0; i < c; i++) {
+ options.setItemSelected(i, false);
+ }
+ }
+ }
+
+ @Override
+ public void setHeight(String height) {
+ super.setHeight(height);
+ if ("".equals(height)) {
+ options.setHeight("");
+ selections.setHeight("");
+ } else {
+ setInternalHeights();
+ }
+ }
+
+ private void setInternalHeights() {
+ int captionHeight = 0;
+ int totalHeight = getOffsetHeight();
+
+ if (optionsCaption != null) {
+ captionHeight = Util.getRequiredHeight(optionsCaption);
+ } else if (selectionsCaption != null) {
+ captionHeight = Util.getRequiredHeight(selectionsCaption);
+ }
+ String selectHeight = (totalHeight - captionHeight) + "px";
+
+ selections.setHeight(selectHeight);
+ options.setHeight(selectHeight);
+
+ }
+
+ @Override
+ public void setWidth(String width) {
+ super.setWidth(width);
+ if (!"".equals(width) && width != null) {
+ setInternalWidths();
+ widthSet = true;
+ } else {
+ widthSet = false;
+ }
+ }
+
+ private void setInternalWidths() {
+ DOM.setStyleAttribute(getElement(), "position", "relative");
+ int bordersAndPaddings = Util.measureHorizontalPaddingAndBorder(
+ buttons.getElement(), 0);
+
+ int buttonWidth = Util.getRequiredWidth(buttons);
+ int totalWidth = getOffsetWidth();
+
+ int spaceForSelect = (totalWidth - buttonWidth - bordersAndPaddings) / 2;
+
+ options.setWidth(spaceForSelect + "px");
+ if (optionsCaption != null) {
+ optionsCaption.setWidth(spaceForSelect + "px");
+ }
+
+ selections.setWidth(spaceForSelect + "px");
+ if (selectionsCaption != null) {
+ selectionsCaption.setWidth(spaceForSelect + "px");
+ }
+ captionWrapper.setWidth("100%");
+ }
+
+ @Override
+ protected void setTabIndex(int tabIndex) {
+ options.setTabIndex(tabIndex);
+ selections.setTabIndex(tabIndex);
+ add.setTabIndex(tabIndex);
+ remove.setTabIndex(tabIndex);
+ }
+
+ public void focus() {
+ options.setFocus(true);
+ }
+
+ /**
+ * Get the key that selects an item in the table. By default it is the Enter
+ * key but by overriding this you can change the key to whatever you want.
+ *
+ * @return
+ */
+ protected int getNavigationSelectKey() {
+ return KeyCodes.KEY_ENTER;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt
+ * .event.dom.client.KeyDownEvent)
+ */
+ public void onKeyDown(KeyDownEvent event) {
+ int keycode = event.getNativeKeyCode();
+
+ // Catch tab and move between select:s
+ if (keycode == KeyCodes.KEY_TAB && event.getSource() == options) {
+ // Prevent default behavior
+ event.preventDefault();
+
+ // Remove current selections
+ for (int i = 0; i < options.getItemCount(); i++) {
+ options.setItemSelected(i, false);
+ }
+
+ // Focus selections
+ selections.setFocus(true);
+ }
+
+ if (keycode == KeyCodes.KEY_TAB && event.isShiftKeyDown()
+ && event.getSource() == selections) {
+ // Prevent default behavior
+ event.preventDefault();
+
+ // Remove current selections
+ for (int i = 0; i < selections.getItemCount(); i++) {
+ selections.setItemSelected(i, false);
+ }
+
+ // Focus options
+ options.setFocus(true);
+ }
+
+ if (keycode == getNavigationSelectKey()) {
+ // Prevent default behavior
+ event.preventDefault();
+
+ // Decide which select the selection was made in
+ if (event.getSource() == options) {
+ // Prevents the selection to become a single selection when
+ // using Enter key
+ // as the selection key (default)
+ options.setFocus(false);
+
+ addItem();
+
+ } else if (event.getSource() == selections) {
+ // Prevents the selection to become a single selection when
+ // using Enter key
+ // as the selection key (default)
+ selections.setFocus(false);
+
+ removeItem();
+ }
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.MouseDownHandler#onMouseDown(com.google
+ * .gwt.event.dom.client.MouseDownEvent)
+ */
+ public void onMouseDown(MouseDownEvent event) {
+ // Ensure that items are deselected when selecting
+ // from a different source. See #3699 for details.
+ if (event.getSource() == options) {
+ for (int i = 0; i < selections.getItemCount(); i++) {
+ selections.setItemSelected(i, false);
+ }
+ } else if (event.getSource() == selections) {
+ for (int i = 0; i < options.getItemCount(); i++) {
+ options.setItemSelected(i, false);
+ }
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.google.gwt.event.dom.client.DoubleClickHandler#onDoubleClick(com.
+ * google.gwt.event.dom.client.DoubleClickEvent)
+ */
+ public void onDoubleClick(DoubleClickEvent event) {
+ if (event.getSource() == options) {
+ addItem();
+ options.setSelectedIndex(-1);
+ options.setFocus(false);
+ } else if (event.getSource() == selections) {
+ removeItem();
+ selections.setSelectedIndex(-1);
+ selections.setFocus(false);
+ }
+
+ }
+
+ private static final String SUBPART_OPTION_SELECT = "leftSelect";
+ private static final String SUBPART_OPTION_SELECT_ITEM = SUBPART_OPTION_SELECT
+ + "-item";
+ private static final String SUBPART_SELECTION_SELECT = "rightSelect";
+ private static final String SUBPART_SELECTION_SELECT_ITEM = SUBPART_SELECTION_SELECT
+ + "-item";
+ private static final String SUBPART_LEFT_CAPTION = "leftCaption";
+ private static final String SUBPART_RIGHT_CAPTION = "rightCaption";
+ private static final String SUBPART_ADD_BUTTON = "add";
+ private static final String SUBPART_REMOVE_BUTTON = "remove";
+
+ public Element getSubPartElement(String subPart) {
+ if (SUBPART_OPTION_SELECT.equals(subPart)) {
+ return options.getElement();
+ } else if (subPart.startsWith(SUBPART_OPTION_SELECT_ITEM)) {
+ String idx = subPart.substring(SUBPART_OPTION_SELECT_ITEM.length());
+ return (Element) options.getElement().getChild(
+ Integer.parseInt(idx));
+ } else if (SUBPART_SELECTION_SELECT.equals(subPart)) {
+ return selections.getElement();
+ } else if (subPart.startsWith(SUBPART_SELECTION_SELECT_ITEM)) {
+ String idx = subPart.substring(SUBPART_SELECTION_SELECT_ITEM
+ .length());
+ return (Element) selections.getElement().getChild(
+ Integer.parseInt(idx));
+ } else if (optionsCaption != null
+ && SUBPART_LEFT_CAPTION.equals(subPart)) {
+ return optionsCaption.getElement();
+ } else if (selectionsCaption != null
+ && SUBPART_RIGHT_CAPTION.equals(subPart)) {
+ return selectionsCaption.getElement();
+ } else if (SUBPART_ADD_BUTTON.equals(subPart)) {
+ return add.getElement();
+ } else if (SUBPART_REMOVE_BUTTON.equals(subPart)) {
+ return remove.getElement();
+ }
+
+ return null;
+ }
+
+ public String getSubPartName(Element subElement) {
+ if (optionsCaption != null
+ && optionsCaption.getElement().isOrHasChild(subElement)) {
+ return SUBPART_LEFT_CAPTION;
+ } else if (selectionsCaption != null
+ && selectionsCaption.getElement().isOrHasChild(subElement)) {
+ return SUBPART_RIGHT_CAPTION;
+ } else if (options.getElement().isOrHasChild(subElement)) {
+ if (options.getElement() == subElement) {
+ return SUBPART_OPTION_SELECT;
+ } else {
+ int idx = Util.getChildElementIndex(subElement);
+ return SUBPART_OPTION_SELECT_ITEM + idx;
+ }
+ } else if (selections.getElement().isOrHasChild(subElement)) {
+ if (selections.getElement() == subElement) {
+ return SUBPART_SELECTION_SELECT;
+ } else {
+ int idx = Util.getChildElementIndex(subElement);
+ return SUBPART_SELECTION_SELECT_ITEM + idx;
+ }
+ } else if (add.getElement().isOrHasChild(subElement)) {
+ return SUBPART_ADD_BUTTON;
+ } else if (remove.getElement().isOrHasChild(subElement)) {
+ return SUBPART_REMOVE_BUTTON;
+ }
+
+ return null;
+ }
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+}
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.SimpleTree;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VUIDLBrowser;
-public class VUnknownComponent extends Composite implements Paintable {
+public class VUnknownComponent extends Composite implements VPaintableWidget {
com.google.gwt.user.client.ui.Label caption = new com.google.gwt.user.client.ui.Label();;
SimpleTree uidlTree;
public void setCaption(String c) {
caption.getElement().setInnerHTML(c);
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VConsole;
import com.vaadin.terminal.gwt.client.VTooltip;
* events even though the upload component is already detached.
*
*/
-public class VUpload extends SimplePanel implements Paintable {
+public class VUpload extends SimplePanel implements VPaintableWidget {
private final class MyFileUpload extends FileUpload {
@Override
}
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.VideoElement;
import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
protected String getDefaultAltHtml() {
return "Your browser does not support the <code>video</code> element.";
}
+
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
}
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.Focusable;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
/**
private String theme;
- private Paintable layout;
+ private VPaintableWidget layout;
private final LinkedHashSet<VWindow> subWindows = new LinkedHashSet<VWindow>();
// Draw this application level window
UIDL childUidl = uidl.getChildUIDL(childIndex);
- final Paintable lo = client.getPaintable(childUidl);
+ final VPaintableWidget lo = client.getPaintable(childUidl);
if (layout != null) {
if (layout != lo) {
// remove old
client.unregisterPaintable(layout);
// add new
- setWidget((Widget) lo);
+ setWidget(lo.getWidgetForPaintable());
layout = lo;
}
} else {
- setWidget((Widget) lo);
+ setWidget(lo.getWidgetForPaintable());
layout = lo;
}
}
} else {
// subwindows
- final Paintable w = client.getPaintable(childUidl);
+ final VPaintableWidget w = client.getPaintable(childUidl);
if (subWindows.contains(w)) {
removedSubWindows.remove(w);
} else {
// set focused component when render phase is finished
Scheduler.get().scheduleDeferred(new Command() {
public void execute() {
- final Paintable toBeFocused = uidl.getPaintableAttribute(
- "focused", connection);
+ VPaintableWidget paintable = (VPaintableWidget) uidl
+ .getPaintableAttribute("focused", connection);
+ final Widget toBeFocused = paintable
+ .getWidgetForPaintable();
/*
* Two types of Widgets can be focused, either implementing
* GWT HasFocus of a thinner Vaadin specific Focusable
if (uidl.hasAttribute("scrollTo")) {
Scheduler.get().scheduleDeferred(new Command() {
public void execute() {
- final Paintable paintable = uidl.getPaintableAttribute(
- "scrollTo", connection);
- ((Widget) paintable).getElement().scrollIntoView();
+ final VPaintableWidget paintable = (VPaintableWidget) uidl
+ .getPaintableAttribute("scrollTo", connection);
+ paintable.getWidgetForPaintable().getElement()
+ .scrollIntoView();
}
});
}
Element targetElement;
if (appId.equals(ownAppId)) {
// Only hide the contents of current application
- targetElement = ((Widget) layout).getElement();
+ targetElement = layout.getWidgetForPaintable().getElement();
} else {
// Hide everything for other applications
targetElement = Document.get().getElementById(appId);
String appId = vaadinApps.get(i);
Element targetElement;
if (appId.equals(ownAppId)) {
- targetElement = ((Widget) layout).getElement();
+ targetElement = layout.getWidgetForPaintable().getElement();
} else {
targetElement = Document.get().getElementById(appId);
}
}
setWidget(newComponent);
- layout = (Paintable) newComponent;
+ layout = (VPaintableWidget) newComponent;
}
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
/*
* Can never propagate further and we do not want need to re-layout the
* layout which has caused this request.
updateParentFrameSize();
// layout size change may affect its available space (scrollbars)
- connection.handleComponentRelativeSize((Widget) layout);
+ connection.handleComponentRelativeSize(layout.getWidgetForPaintable());
return true;
return null;
}-*/;
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
// NOP Subwindows never draw caption for their first child (layout)
}
getElement().focus();
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.EventId;
import com.vaadin.terminal.gwt.client.Focusable;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
public static final int Z_INDEX = 10000;
- private Paintable layout;
+ private VPaintableWidget layout;
private Element contents;
childUidl = uidl.getChildUIDL(childIndex++);
}
- final Paintable lo = client.getPaintable(childUidl);
+ final VPaintableWidget lo = client.getPaintable(childUidl);
if (layout != null) {
if (layout != lo) {
// remove old
client.unregisterPaintable(layout);
- contentPanel.remove((Widget) layout);
+ contentPanel.remove(layout.getWidgetForPaintable());
// add new
if (!showingUrl) {
- contentPanel.setWidget((Widget) lo);
+ contentPanel.setWidget(lo.getWidgetForPaintable());
}
layout = lo;
}
} else if (!showingUrl) {
- contentPanel.setWidget((Widget) lo);
+ contentPanel.setWidget(lo.getWidgetForPaintable());
layout = lo;
}
private void updateContentsSize() {
// Update child widget dimensions
if (client != null) {
- client.handleComponentRelativeSize((Widget) layout);
- client.runDescendentsLayout((HasWidgets) layout);
+ client.handleComponentRelativeSize(layout.getWidgetForPaintable());
+ client.runDescendentsLayout((HasWidgets) layout
+ .getWidgetForPaintable());
}
Util.runWebkitOverflowAutoFix(contentPanel.getElement());
while (w != null) {
if (w instanceof Console) {
return true; // allow debug-window clicks
- } else if (w instanceof Paintable) {
+ } else if (w instanceof VPaintableWidget) {
return false;
}
w = w.getParent();
contentPanel.setWidget(newComponent);
}
- public boolean requestLayout(Set<Paintable> child) {
+ public boolean requestLayout(Set<Widget> children) {
if (dynamicWidth && !layoutRelativeWidth) {
setNaturalWidth();
}
}
updateShadowSizeAndPosition();
// layout size change may affect its available space (scrollbars)
- client.handleComponentRelativeSize((Widget) layout);
+ client.handleComponentRelativeSize(layout.getWidgetForPaintable());
return true;
}
- public void updateCaption(Paintable component, UIDL uidl) {
+ public void updateCaption(VPaintableWidget component, UIDL uidl) {
// NOP, window has own caption, layout captio not rendered
}
contentPanel.focus();
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
import com.vaadin.event.Transferable;
import com.vaadin.event.dd.DropTarget;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
public abstract class VAbstractDropHandler implements VDropHandler {
* side counterpart of the Paintable is expected to implement
* {@link DropTarget} interface.
*/
- public abstract Paintable getPaintable();
+ public abstract VPaintableWidget getPaintable();
}
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ValueMap;
/**
}
private void addActiveDragSourceStyleName() {
- Paintable dragSource = currentDrag.getTransferable()
+ VPaintableWidget dragSource = currentDrag.getTransferable()
.getDragSource();
- ((Widget) dragSource)
- .addStyleName(ACTIVE_DRAG_SOURCE_STYLENAME);
+ dragSource.getWidgetForPaintable().addStyleName(
+ ACTIVE_DRAG_SOURCE_STYLENAME);
}
};
* handled. E.g. hidden on start, removed in drophandler ->
* would flicker in case removed eagerly.
*/
- final Paintable dragSource = currentDrag.getTransferable()
- .getDragSource();
+ final VPaintableWidget dragSource = currentDrag
+ .getTransferable().getDragSource();
final ApplicationConnection client = currentDropHandler
.getApplicationConnection();
Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
}
- private void removeActiveDragSourceStyleName(Paintable dragSource) {
- ((Widget) dragSource).removeStyleName(ACTIVE_DRAG_SOURCE_STYLENAME);
+ private void removeActiveDragSourceStyleName(VPaintableWidget dragSource) {
+ dragSource.getWidgetForPaintable().removeStyleName(
+ ACTIVE_DRAG_SOURCE_STYLENAME);
}
private void clearDragElement() {
if (currentDropHandler == null) {
return;
}
- Paintable paintable = currentDropHandler.getPaintable();
+ VPaintableWidget paintable = currentDropHandler.getPaintable();
ApplicationConnection client = currentDropHandler
.getApplicationConnection();
/*
*/
package com.vaadin.terminal.gwt.client.ui.dd;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.PaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
/**
* TODO Javadoc!
@Override
protected boolean accept(VDragEvent drag, UIDL configuration) {
try {
- Paintable component = drag.getTransferable().getDragSource();
+ VPaintableWidget component = drag.getTransferable().getDragSource();
int c = configuration.getIntAttribute("c");
for (int i = 0; i < c; i++) {
String requiredPid = configuration
.getStringAttribute("component" + i);
VDropHandler currentDropHandler = VDragAndDropManager.get()
.getCurrentDropHandler();
- Paintable paintable = PaintableMap.get(
- currentDropHandler.getApplicationConnection())
+ VPaintableWidget paintable = (VPaintableWidget) VPaintableMap
+ .get(currentDropHandler.getApplicationConnection())
.getPaintable(requiredPid);
if (paintable == component) {
return true;
package com.vaadin.terminal.gwt.client.ui.dd;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
/**
* Vaadin Widgets that want to receive something via drag and drop implement
/**
* Returns the Paintable into which this DragHandler is associated
*/
- public Paintable getPaintable();
+ public VPaintableWidget getPaintable();
/**
* Returns the application connection to which this {@link VDropHandler}
*/
package com.vaadin.terminal.gwt.client.ui.dd;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
/**
* Used to detect Widget from widget tree that has {@link #getDropHandler()}
*
* Decide whether to get rid of this class. If so, {@link VAbstractDropHandler}
- * must extend {@link Paintable}.
+ * must extend {@link VPaintableWidget}.
*
*/
public interface VHasDropHandler {
*/
package com.vaadin.terminal.gwt.client.ui.dd;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.PaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
final public class VIsOverId extends VAcceptCriterion {
String pid = configuration.getStringAttribute("s");
VDropHandler currentDropHandler = VDragAndDropManager.get()
.getCurrentDropHandler();
- Paintable paintable = currentDropHandler.getPaintable();
- PaintableMap paintableMap = PaintableMap.get(currentDropHandler
+ VPaintableWidget paintable = currentDropHandler.getPaintable();
+ VPaintableMap paintableMap = VPaintableMap.get(currentDropHandler
.getApplicationConnection());
String pid2 = paintableMap.getPid(paintable);
*/
package com.vaadin.terminal.gwt.client.ui.dd;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.PaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
final public class VItemIdIs extends VAcceptCriterion {
protected boolean accept(VDragEvent drag, UIDL configuration) {
try {
String pid = configuration.getStringAttribute("s");
- Paintable dragSource = drag.getTransferable().getDragSource();
+ VPaintableWidget dragSource = drag.getTransferable()
+ .getDragSource();
VDropHandler currentDropHandler = VDragAndDropManager.get()
.getCurrentDropHandler();
- String pid2 = PaintableMap.get(
+ String pid2 = VPaintableMap.get(
currentDropHandler.getApplicationConnection()).getPid(
dragSource);
if (pid2.equals(pid)) {
*/
package com.vaadin.terminal.gwt.client.ui.dd;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
final public class VSourceIsTarget extends VAcceptCriterion {
@Override
protected boolean accept(VDragEvent drag, UIDL configuration) {
- Paintable dragSource = drag.getTransferable().getDragSource();
- Paintable paintable = VDragAndDropManager.get().getCurrentDropHandler()
+ VPaintableWidget dragSource = drag.getTransferable().getDragSource();
+ VPaintableWidget paintable = VDragAndDropManager.get().getCurrentDropHandler()
.getPaintable();
return paintable == dragSource;
import java.util.Map;
import com.vaadin.event.dd.DragSource;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
/**
* Client side counterpart for Transferable in com.vaadin.event.Transferable
*/
public class VTransferable {
- private Paintable component;
+ private VPaintableWidget component;
private final Map<String, Object> variables = new HashMap<String, Object>();
*
* @return the component
*/
- public Paintable getDragSource() {
+ public VPaintableWidget getDragSource() {
return component;
}
* @param component
* the component to set
*/
- public void setDragSource(Paintable component) {
+ public void setDragSource(VPaintableWidget component) {
this.component = component;
}
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.VMarginInfo;
public abstract class CellBasedLayout extends ComplexPanel implements Container {
widgetToComponentContainer.remove(widget);
remove(child);
if (!relocated) {
- Paintable p = (Paintable) widget;
- client.unregisterPaintable(p);
+ VPaintableMap paintableMap = VPaintableMap.get(client);
+ VPaintableWidget p = paintableMap.getPaintable(widget);
+ paintableMap.unregisterPaintable(p);
}
}
return;
}
- componentContainer.setWidget(newComponent);
- client.unregisterPaintable((Paintable) oldComponent);
+ componentContainer.setPaintable(VPaintableMap.get(client).getPaintable(
+ newComponent));
+ client.unregisterPaintable(VPaintableMap.get(client).getPaintable(
+ oldComponent));
widgetToComponentContainer.put(newComponent, componentContainer);
}
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
import com.vaadin.terminal.gwt.client.RenderInformation.Size;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VCaption;
import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.AlignmentInfo;
public class ChildComponentContainer extends Panel {
private VCaption caption = null;
private DivElement containerDIV;
private DivElement widgetDIV;
+ private VPaintableWidget paintable;
private Widget widget;
private FloatSize relativeSize = null;
- public ChildComponentContainer(Widget widget, int orientation) {
+ public ChildComponentContainer(VPaintableWidget child, int orientation) {
super();
containerDIV = Document.get().createDivElement();
setOrientation(orientation);
- setWidget(widget);
+ setPaintable(child);
+ }
+ public void setPaintable(VPaintableWidget childPaintable) {
+ paintable = childPaintable;
+ setWidget(childPaintable.getWidgetForPaintable());
}
- public void setWidget(Widget w) {
+ private void setWidget(Widget w) {
// Validate
if (w == widget) {
return;
if (fixedWidth < 0 && BrowserInfo.get().isOpera()) {
setUnlimitedContainerWidth();
}
- ((Paintable) widget).updateFromUIDL(childUIDL, client);
+ paintable.updateFromUIDL(childUIDL, client);
}
public void setUnlimitedContainerWidth() {
VCaption newCaption = caption;
if (newCaption == null) {
- newCaption = new VCaption((Paintable) widget, client);
+ newCaption = new VCaption(paintable, client);
// Set initial height to avoid Safari flicker
newCaption.setHeight("18px");
// newCaption.setHeight(newCaption.getHeight()); // This might
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.ui.Field;
* @author Vaadin Ltd.
*
*/
-public class VRichTextArea extends Composite implements Paintable, Field,
+public class VRichTextArea extends Composite implements VPaintableWidget, Field,
ChangeHandler, BlurHandler, KeyPressHandler, KeyDownHandler,
BeforeShortcutActionListener, Focusable {
rta.setTabIndex(index);
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
* A server side component sends its state to the client in a paint request (see
* {@link Paintable} and {@link PaintTarget} on the server side). The client
* widget receives these paint requests as calls to
- * {@link com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL()}. The client
+ * {@link com.vaadin.terminal.gwt.client.VPaintableWidget#updateFromUIDL()}. The client
* component communicates back to the server by sending a list of variable
* changes (see {@link ApplicationConnection#updateVariable()} and
* {@link VariableOwner#changeVariables(Object, Map)}).
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.vaadin.terminal.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.VView;
import com.vaadin.ui.ClientWidget;
import com.vaadin.ui.ClientWidget.LoadStyle;
*/
public class WidgetMapGenerator extends Generator {
+ private static String paintableClassName = VPaintableWidget.class.getName();
+
private String packageName;
private String className;
.iterator(); iterator.hasNext();) {
Class<? extends Paintable> class1 = iterator.next();
- Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = getClientClass(class1);
+ Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget> clientClass = getClientClass(class1);
if (typeOracle.findType(clientClass.getName()) == null) {
// GWT widget not inherited
logger.log(Type.WARN, "Widget class " + clientClass.getName()
// TODO detect if it would be noticably faster to instantiate with a
// lookup with index than with the hashmap
- sourceWriter
- .println("public void ensureInstantiator(Class<? extends Paintable> classType) {");
+ sourceWriter.println("public void ensureInstantiator(Class<? extends "
+ + paintableClassName + "> classType) {");
sourceWriter.println("if(!instmap.containsKey(classType)){");
boolean first = true;
ArrayList<Class<? extends Paintable>> lazyLoadedWidgets = new ArrayList<Class<? extends Paintable>>();
-
- HashSet<Class<? extends com.vaadin.terminal.gwt.client.Paintable>> widgetsWithInstantiator = new HashSet<Class<? extends com.vaadin.terminal.gwt.client.Paintable>>();
-
+
+ HashSet<Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget>> widgetsWithInstantiator = new HashSet<Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget>>();
+
for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) {
- Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = getClientClass(class1);
- if(widgetsWithInstantiator.contains(clientClass)) {
+ Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget> clientClass = getClientClass(class1);
+ if (widgetsWithInstantiator.contains(clientClass)) {
continue;
}
if (clientClass == VView.class) {
sourceWriter.print("if( classType == " + clientClass.getName()
+ ".class) {");
- String instantiator = "new WidgetInstantiator() {\n public Paintable get() {\n return GWT.create("
+ String instantiator = "new WidgetInstantiator() {\n public "
+ + paintableClassName + " get() {\n return GWT.create("
+ clientClass.getName() + ".class );\n}\n}\n";
LoadStyle loadStyle = getLoadStyle(class1);
sourceWriter.println("}");
- sourceWriter
- .println("public Class<? extends Paintable>[] getDeferredLoadedWidgets() {");
+ sourceWriter.println("public Class<? extends " + paintableClassName
+ + ">[] getDeferredLoadedWidgets() {");
sourceWriter.println("return new Class[] {");
first = true;
}
first = false;
ClientWidget annotation = class2.getAnnotation(ClientWidget.class);
- Class<? extends com.vaadin.terminal.gwt.client.Paintable> value = annotation
+ Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget> value = annotation
.value();
sourceWriter.print(value.getName() + ".class");
}
// TODO an index of last ensured widget in array
- sourceWriter
- .println("public Paintable instantiate(Class<? extends Paintable> classType) {");
+ sourceWriter.println("public " + paintableClassName
+ + " instantiate(Class<? extends " + paintableClassName
+ + "> classType) {");
sourceWriter.indent();
- sourceWriter
- .println("Paintable p = super.instantiate(classType); if(p!= null) return p;");
+ sourceWriter.println(paintableClassName
+ + " p = super.instantiate(classType); if(p!= null) return p;");
sourceWriter.println("return instmap.get(classType).get();");
sourceWriter.outdent();
SourceWriter sourceWriter,
Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) {
sourceWriter
- .println("public Class<? extends Paintable> "
+ .println("public Class<? extends "
+ + paintableClassName
+ + "> "
+ "getImplementationByServerSideClassName(String fullyQualifiedName) {");
sourceWriter.indent();
sourceWriter
.println("fullyQualifiedName = fullyQualifiedName.intern();");
for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) {
- Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = getClientClass(class1);
+ Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget> clientClass = getClientClass(class1);
sourceWriter.print("if ( fullyQualifiedName == \"");
sourceWriter.print(class1.getName());
sourceWriter.print("\" ) { ensureInstantiator("
}
- private static Class<? extends com.vaadin.terminal.gwt.client.Paintable> getClientClass(
+ private static Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget> getClientClass(
Class<? extends Paintable> class1) {
- Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass;
+ Class<? extends com.vaadin.terminal.gwt.client.VPaintableWidget> clientClass;
if (Root.class == class1) {
clientClass = VView.class;
} else {
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.widgetsetutils.CustomWidgetMapGenerator;
import com.vaadin.terminal.gwt.widgetsetutils.EagerWidgetMapGenerator;
import com.vaadin.terminal.gwt.widgetsetutils.LazyWidgetMapGenerator;
/**
* @return the client side counterpart for the annotated component
*/
- Class<? extends Paintable> value();
+ Class<? extends VPaintableWidget> value();
/**
* Depending on the used WidgetMap generator, these optional hints may be
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VLabel;
+import com.vaadin.terminal.gwt.client.ui.VLabelPaintable;
import com.vaadin.ui.ClientWidget.LoadStyle;
/**
* @since 3.0
*/
@SuppressWarnings("serial")
-@ClientWidget(value = VLabel.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VLabelPaintable.class, loadStyle = LoadStyle.EAGER)
// TODO generics for interface Property
public class Label extends AbstractComponent implements Property,
Property.Viewer, Property.ValueChangeListener,
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager;
import com.vaadin.terminal.gwt.client.ui.dd.VTransferable;
/**
* Example code to implement Component that has something to drag.
*/
-public class VMyDragSource extends Composite implements Paintable,
+public class VMyDragSource extends Composite implements VPaintableWidget,
MouseDownHandler, MouseMoveHandler, MouseOutHandler {
private boolean mouseDown;
mDownEvent = null;
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}
package com.vaadin.tests.dd;
import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.ui.dd.VDragEvent;
import com.vaadin.terminal.gwt.client.ui.dd.VDropHandler;
import com.vaadin.terminal.gwt.client.ui.dd.VHasDropHandler;
public class VMyDropTarget extends Composite implements VHasDropHandler,
- VDropHandler, Paintable {
+ VDropHandler, VPaintableWidget {
private ApplicationConnection client;
return false;
}
- public Paintable getPaintable() {
+ public VPaintableWidget getPaintable() {
// Drophandler implemented by Paintable itself
return this;
}
}
+ public Widget getWidgetForPaintable() {
+ return this;
+ }
+
}