From 70173cfc6ec1a5d67f33c0477ae135935cf81314 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Sun, 22 Jan 2012 19:48:38 +0200 Subject: [PATCH] Split Paintable from Widget so we have VPaintable (paintable without any Widget), VPaintableWidget (paintable connected to a widget). --- .../gwt/client/ApplicationConfiguration.java | 10 +- .../gwt/client/ApplicationConnection.java | 121 +- .../terminal/gwt/client/ComponentDetail.java | 22 - .../terminal/gwt/client/ComponentLocator.java | 10 +- .../vaadin/terminal/gwt/client/Console.java | 4 +- .../vaadin/terminal/gwt/client/Container.java | 6 +- .../terminal/gwt/client/EventHelper.java | 4 +- .../terminal/gwt/client/NullConsole.java | 4 +- src/com/vaadin/terminal/gwt/client/UIDL.java | 12 +- src/com/vaadin/terminal/gwt/client/Util.java | 77 +- .../vaadin/terminal/gwt/client/VCaption.java | 11 +- .../terminal/gwt/client/VCaptionWrapper.java | 14 +- .../vaadin/terminal/gwt/client/VConsole.java | 4 +- .../terminal/gwt/client/VDebugConsole.java | 26 +- .../terminal/gwt/client/VPaintable.java | 19 + .../{PaintableMap.java => VPaintableMap.java} | 128 +- .../{Paintable.java => VPaintableWidget.java} | 9 +- .../vaadin/terminal/gwt/client/VTooltip.java | 6 +- .../terminal/gwt/client/VUIDLBrowser.java | 12 +- .../gwt/client/WidgetInstantiator.java | 2 +- .../vaadin/terminal/gwt/client/WidgetMap.java | 14 +- .../vaadin/terminal/gwt/client/WidgetSet.java | 18 +- .../gwt/client/ui/ClickEventHandler.java | 18 +- .../client/ui/LayoutClickEventHandler.java | 12 +- .../gwt/client/ui/ShortcutActionHandler.java | 18 +- .../vaadin/terminal/gwt/client/ui/Table.java | 4 +- .../gwt/client/ui/VAbsoluteLayout.java | 32 +- .../terminal/gwt/client/ui/VAccordion.java | 83 +- .../vaadin/terminal/gwt/client/ui/VAudio.java | 6 + .../terminal/gwt/client/ui/VButton.java | 11 +- .../gwt/client/ui/VCalendarPanel.java | 2 +- .../terminal/gwt/client/ui/VCheckBox.java | 10 +- .../terminal/gwt/client/ui/VCssLayout.java | 44 +- .../gwt/client/ui/VCustomComponent.java | 23 +- .../terminal/gwt/client/ui/VCustomLayout.java | 56 +- .../terminal/gwt/client/ui/VDateField.java | 549 +++---- .../gwt/client/ui/VDragAndDropWrapper.java | 24 +- .../terminal/gwt/client/ui/VEmbedded.java | 9 +- .../terminal/gwt/client/ui/VFilterSelect.java | 9 +- .../vaadin/terminal/gwt/client/ui/VForm.java | 662 ++++----- .../terminal/gwt/client/ui/VFormLayout.java | 105 +- .../terminal/gwt/client/ui/VGridLayout.java | 85 +- .../vaadin/terminal/gwt/client/ui/VLabel.java | 72 +- .../gwt/client/ui/VLabelPaintable.java | 122 ++ .../vaadin/terminal/gwt/client/ui/VLink.java | 9 +- .../terminal/gwt/client/ui/VListSelect.java | 12 +- .../terminal/gwt/client/ui/VMediaBase.java | 4 +- .../terminal/gwt/client/ui/VMenuBar.java | 12 +- .../terminal/gwt/client/ui/VNativeButton.java | 10 +- .../terminal/gwt/client/ui/VNativeSelect.java | 4 + .../terminal/gwt/client/ui/VOptionGroup.java | 463 +++--- .../gwt/client/ui/VOptionGroupBase.java | 454 +++--- .../gwt/client/ui/VOrderedLayout.java | 40 +- .../vaadin/terminal/gwt/client/ui/VPanel.java | 28 +- .../gwt/client/ui/VPopupCalendar.java | 924 ++++++------ .../terminal/gwt/client/ui/VPopupView.java | 27 +- .../gwt/client/ui/VProgressIndicator.java | 8 +- .../terminal/gwt/client/ui/VScrollTable.java | 35 +- .../terminal/gwt/client/ui/VSlider.java | 1141 +++++++-------- .../terminal/gwt/client/ui/VSplitPanel.java | 40 +- .../terminal/gwt/client/ui/VTablePaging.java | 12 +- .../terminal/gwt/client/ui/VTabsheet.java | 55 +- .../terminal/gwt/client/ui/VTabsheetBase.java | 36 +- .../terminal/gwt/client/ui/VTextField.java | 9 +- .../terminal/gwt/client/ui/VTextualDate.java | 4 +- .../vaadin/terminal/gwt/client/ui/VTree.java | 10 +- .../gwt/client/ui/VTwinColSelect.java | 1265 +++++++++-------- .../gwt/client/ui/VUnknownComponent.java | 9 +- .../terminal/gwt/client/ui/VUpload.java | 9 +- .../vaadin/terminal/gwt/client/ui/VVideo.java | 5 + .../vaadin/terminal/gwt/client/ui/VView.java | 41 +- .../terminal/gwt/client/ui/VWindow.java | 29 +- .../client/ui/dd/VAbstractDropHandler.java | 4 +- .../gwt/client/ui/dd/VDragAndDropManager.java | 19 +- .../gwt/client/ui/dd/VDragSourceIs.java | 10 +- .../gwt/client/ui/dd/VDropHandler.java | 4 +- .../gwt/client/ui/dd/VHasDropHandler.java | 4 +- .../terminal/gwt/client/ui/dd/VIsOverId.java | 8 +- .../terminal/gwt/client/ui/dd/VItemIdIs.java | 9 +- .../gwt/client/ui/dd/VSourceIsTarget.java | 6 +- .../gwt/client/ui/dd/VTransferable.java | 8 +- .../gwt/client/ui/layout/CellBasedLayout.java | 14 +- .../ui/layout/ChildComponentContainer.java | 17 +- .../client/ui/richtextarea/VRichTextArea.java | 8 +- .../server/AbstractCommunicationManager.java | 2 +- .../widgetsetutils/WidgetMapGenerator.java | 47 +- src/com/vaadin/ui/ClientWidget.java | 4 +- src/com/vaadin/ui/Label.java | 4 +- .../com/vaadin/tests/dd/VMyDragSource.java | 9 +- .../com/vaadin/tests/dd/VMyDropTarget.java | 11 +- 90 files changed, 3872 insertions(+), 3500 deletions(-) create mode 100644 src/com/vaadin/terminal/gwt/client/VPaintable.java rename src/com/vaadin/terminal/gwt/client/{PaintableMap.java => VPaintableMap.java} (68%) rename src/com/vaadin/terminal/gwt/client/{Paintable.java => VPaintableWidget.java} (65%) create mode 100644 src/com/vaadin/terminal/gwt/client/ui/VLabelPaintable.java diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java index 0bd4be4d92..169934024b 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java @@ -206,7 +206,7 @@ public class ApplicationConfiguration implements EntryPoint { private HashMap unknownComponents; - private Class[] classes = new Class[1024]; + private Class[] classes = new Class[1024]; private String windowId; @@ -381,7 +381,7 @@ public class ApplicationConfiguration implements EntryPoint { return useDebugIdInDom; } - public Class getWidgetClassByEncodedTag(String tag) { + public Class getWidgetClassByEncodedTag(String tag) { try { int parseInt = Integer.parseInt(tag); return classes[parseInt]; @@ -483,7 +483,7 @@ public class ApplicationConfiguration implements EntryPoint { public void run() { pending = false; if (!isBusy()) { - Class nextType = getNextType(); + Class nextType = getNextType(); if (nextType == null) { // ensured that all widgets are loaded deferredWidgetLoader = null; @@ -496,8 +496,8 @@ public class ApplicationConfiguration implements EntryPoint { } } - private Class getNextType() { - Class[] deferredLoadedWidgets = widgetSet + private Class getNextType() { + Class[] deferredLoadedWidgets = widgetSet .getDeferredLoadedWidgets(); if (deferredLoadedWidgets.length <= nextWidgetIndex) { return null; diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 04703b2dd0..f8ca0a6959 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -50,10 +50,11 @@ import com.vaadin.terminal.gwt.server.AbstractCommunicationManager; * * 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 * @@ -135,16 +136,16 @@ public class ApplicationConnection { /** redirectTimer scheduling interval in seconds */ private int sessionExpirationInterval; - private ArrayList relativeSizeChanges = new ArrayList();; - private ArrayList componentCaptionSizeChanges = new ArrayList();; + private ArrayList relativeSizeChanges = new ArrayList(); + private ArrayList componentCaptionSizeChanges = new ArrayList(); private Date requestStartTime; private boolean validatingLayouts = false; - private Set zeroWidthComponents = null; + private Set zeroWidthComponents = null; - private Set zeroHeightComponents = null; + private Set zeroHeightComponents = null; public ApplicationConnection() { view = GWT.create(VView.class); @@ -411,7 +412,7 @@ public class ApplicationConnection { * * @param paintable */ - void highlightComponent(Paintable paintable) { + void highlightComponent(VPaintableWidget paintable) { String params = getRepaintAllParameters() + "&highlightComponent=" + paintableMap.getPid(paintable); makeUidlRequest("", params, false); @@ -931,8 +932,8 @@ public class ApplicationConnection { getPaintableMap().clear(); if (meta.containsKey("invalidLayouts")) { validatingLayouts = true; - zeroWidthComponents = new HashSet(); - zeroHeightComponents = new HashSet(); + zeroWidthComponents = new HashSet(); + zeroHeightComponents = new HashSet(); } } if (meta.containsKey("timedRedirect")) { @@ -956,7 +957,7 @@ public class ApplicationConnection { // Process changes JsArray changes = json.getJSValueMapArray("changes"); - ArrayList updatedWidgets = new ArrayList(); + ArrayList updatedVPaintableWidgets = new ArrayList(); relativeSizeChanges.clear(); componentCaptionSizeChanges.clear(); @@ -966,13 +967,12 @@ public class ApplicationConnection { 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())) { @@ -1007,19 +1007,19 @@ public class ApplicationConnection { } // Check which widgets' size has been updated - Set sizeUpdatedWidgets = new HashSet(); + Set sizeUpdatedWidgets = new HashSet(); - 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); } @@ -1226,7 +1226,7 @@ public class ApplicationConnection { * 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'); } @@ -1404,7 +1404,7 @@ public class ApplicationConnection { 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))); } @@ -1421,7 +1421,7 @@ public class ApplicationConnection { 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'; @@ -1505,7 +1505,7 @@ public class ApplicationConnection { // 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))); } @@ -1588,7 +1588,7 @@ public class ApplicationConnection { */ 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) { @@ -1617,7 +1617,7 @@ public class ApplicationConnection { // 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); } } @@ -1635,24 +1635,6 @@ public class ApplicationConnection { 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 @@ -1734,7 +1716,7 @@ public class ApplicationConnection { if (manageCaption) { final Container parent = Util.getLayout(component); if (parent != null) { - parent.updateCaption((Paintable) component, uidl); + parent.updateCaption(paintable, uidl); } } /* @@ -1747,7 +1729,7 @@ public class ApplicationConnection { return false; } - private void updateComponentSize(Paintable paintable, UIDL uidl) { + private void updateComponentSize(VPaintableWidget paintable, UIDL uidl) { String w = uidl.hasAttribute("width") ? uidl .getStringAttribute("width") : ""; @@ -1821,8 +1803,12 @@ public class ApplicationConnection { * development. Published to JavaScript. */ public void forceLayout() { - Set set = new HashSet(); - set.addAll(paintableMap.getPaintables()); + Set set = new HashSet(); + for (VPaintable paintable : paintableMap.getPaintables()) { + if (paintable instanceof VPaintableWidget) { + set.add(((VPaintableWidget) paintable).getWidgetForPaintable()); + } + } Util.componentSizeUpdated(set); } @@ -1833,7 +1819,7 @@ public class ApplicationConnection { while (childWidgets.hasNext()) { final Widget child = childWidgets.next(); - if (child instanceof Paintable) { + if (child instanceof VPaintableWidget) { if (handleComponentRelativeSize(child)) { /* @@ -1864,7 +1850,7 @@ public class ApplicationConnection { * @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; } @@ -2038,14 +2024,14 @@ public class ApplicationConnection { * 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); } /** @@ -2138,7 +2124,8 @@ public class ApplicationConnection { * 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; } @@ -2157,7 +2144,7 @@ public class ApplicationConnection { * @param event * @param owner */ - public void handleTooltipEvent(Event event, Paintable owner) { + public void handleTooltipEvent(Event event, VPaintableWidget owner) { tooltip.handleTooltipEvent(event, owner, null); } @@ -2175,7 +2162,8 @@ public class ApplicationConnection { * 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); } @@ -2204,7 +2192,7 @@ public class ApplicationConnection { } }; - private PaintableMap paintableMap = new PaintableMap(); + private VPaintableMap paintableMap = new VPaintableMap(); /** * Components can call this function to run all layout functions. This is @@ -2225,8 +2213,8 @@ public class ApplicationConnection { * @param component * the Paintable whose caption has changed */ - public void captionSizeUpdated(Paintable component) { - componentCaptionSizeChanges.add(component); + public void captionSizeUpdated(Widget widget) { + componentCaptionSizeChanges.add(widget); } /** @@ -2244,7 +2232,7 @@ public class ApplicationConnection { * this method. *

* Component must also pipe events to - * {@link #handleTooltipEvent(Event, Paintable, Object)} method. + * {@link #handleTooltipEvent(Event, VPaintableWidget, Object)} method. *

* This method can also be used to deregister tooltips by using null as * tooltip @@ -2254,13 +2242,14 @@ public class ApplicationConnection { * @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); } @@ -2286,7 +2275,8 @@ public class ApplicationConnection { * @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); } @@ -2331,14 +2321,13 @@ public class ApplicationConnection { return uri; } - PaintableMap getPaintableMap() { + VPaintableMap getPaintableMap() { return paintableMap; } @Deprecated - public void unregisterPaintable(Paintable p) { + public void unregisterPaintable(VPaintable p) { paintableMap.unregisterPaintable(p); - } } diff --git a/src/com/vaadin/terminal/gwt/client/ComponentDetail.java b/src/com/vaadin/terminal/gwt/client/ComponentDetail.java index c83c570068..8e4e13aa1c 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentDetail.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentDetail.java @@ -11,20 +11,12 @@ import com.vaadin.terminal.gwt.client.RenderInformation.Size; 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. @@ -56,20 +48,6 @@ class ComponentDetail { private Size offsetSize; private HashMap additionalTooltips; - // /** - // * @return the pid - // */ - // String getPid() { - // return pid; - // } - - // /** - // * @return the component - // */ - // Paintable getPaintable() { - // return paintable; - // } - /** * @return the relativeSize */ diff --git a/src/com/vaadin/terminal/gwt/client/ComponentLocator.java b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java index 9206e3c068..b03bc708e2 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentLocator.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java @@ -78,7 +78,7 @@ public class ComponentLocator { Element e = targetElement; while (true) { - pid = PaintableMap.get(client).getPid(e); + pid = VPaintableMap.get(client).getPid(e); if (pid != null) { break; } @@ -94,7 +94,8 @@ public class ComponentLocator { // 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 @@ -364,7 +365,7 @@ public class ComponentLocator { return null; } - String pid = PaintableMap.get(client).getPid(w.getElement()); + String pid = VPaintableMap.get(client).getPid(w.getElement()); if (isStaticPid(pid)) { return pid; } @@ -437,7 +438,8 @@ public class ComponentLocator { 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 diff --git a/src/com/vaadin/terminal/gwt/client/Console.java b/src/com/vaadin/terminal/gwt/client/Console.java index 483ab8e0fd..cf5402a2af 100644 --- a/src/com/vaadin/terminal/gwt/client/Console.java +++ b/src/com/vaadin/terminal/gwt/client/Console.java @@ -22,8 +22,8 @@ public interface Console { public abstract void printLayoutProblems(ValueMap meta, ApplicationConnection applicationConnection, - Set zeroHeightComponents, - Set zeroWidthComponents); + Set zeroHeightComponents, + Set zeroWidthComponents); public abstract void setQuietMode(boolean quietDebugMode); diff --git a/src/com/vaadin/terminal/gwt/client/Container.java b/src/com/vaadin/terminal/gwt/client/Container.java index 83f104886f..7c92bc261b 100644 --- a/src/com/vaadin/terminal/gwt/client/Container.java +++ b/src/com/vaadin/terminal/gwt/client/Container.java @@ -8,7 +8,7 @@ import java.util.Set; 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. @@ -47,7 +47,7 @@ public interface Container extends Paintable { * @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 @@ -58,7 +58,7 @@ public interface Container extends Paintable { * @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 children); + boolean requestLayout(Set children); /** * Returns the size currently allocated for the child component. diff --git a/src/com/vaadin/terminal/gwt/client/EventHelper.java b/src/com/vaadin/terminal/gwt/client/EventHelper.java index 600baf8c9d..10822f48c9 100644 --- a/src/com/vaadin/terminal/gwt/client/EventHelper.java +++ b/src/com/vaadin/terminal/gwt/client/EventHelper.java @@ -40,7 +40,7 @@ import com.google.gwt.event.shared.HandlerRegistration; */ public class EventHelper { - public static HandlerRegistration updateFocusHandler(Paintable paintable, + public static HandlerRegistration updateFocusHandler(VPaintableWidget paintable, ApplicationConnection client, HandlerRegistration handlerRegistration) { if (client.hasEventListeners(paintable, FOCUS)) { @@ -57,7 +57,7 @@ public class EventHelper { return null; } - public static HandlerRegistration updateBlurHandler(Paintable paintable, + public static HandlerRegistration updateBlurHandler(VPaintableWidget paintable, ApplicationConnection client, HandlerRegistration handlerRegistration) { if (client.hasEventListeners(paintable, BLUR)) { diff --git a/src/com/vaadin/terminal/gwt/client/NullConsole.java b/src/com/vaadin/terminal/gwt/client/NullConsole.java index 12df4b323b..31aa4f74d3 100644 --- a/src/com/vaadin/terminal/gwt/client/NullConsole.java +++ b/src/com/vaadin/terminal/gwt/client/NullConsole.java @@ -32,8 +32,8 @@ public class NullConsole implements Console { public void printLayoutProblems(ValueMap meta, ApplicationConnection applicationConnection, - Set zeroHeightComponents, - Set zeroWidthComponents) { + Set zeroHeightComponents, + Set zeroWidthComponents) { } public void log(Throwable e) { diff --git a/src/com/vaadin/terminal/gwt/client/UIDL.java b/src/com/vaadin/terminal/gwt/client/UIDL.java index 12bbe563d7..b828e644dd 100644 --- a/src/com/vaadin/terminal/gwt/client/UIDL.java +++ b/src/com/vaadin/terminal/gwt/client/UIDL.java @@ -16,7 +16,7 @@ import com.vaadin.ui.Component; /** * 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. *

@@ -55,7 +55,7 @@ public final class UIDL extends JavaScriptObject { * 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 @@ -516,9 +516,9 @@ public final class UIDL extends JavaScriptObject { * 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)); } @@ -529,9 +529,9 @@ public final class UIDL extends JavaScriptObject { * 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)); } diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java index 3b3c761e84..597ca3d49c 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -66,7 +66,7 @@ public class Util { }-*/; private static final int LAZY_SIZE_CHANGE_TIMEOUT = 400; - private static Set latelyChangedWidgets = new HashSet(); + private static Set latelyChangedWidgets = new HashSet(); private static Timer lazySizeChangeTimer = new Timer() { private boolean lazySizeChangeTimerScheduled = false; @@ -105,12 +105,12 @@ public class Util { * @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 widgets = new HashSet(); + Set widgets = new HashSet(); widgets.add(widget); Util.componentSizeUpdated(widgets); } @@ -122,15 +122,14 @@ public class Util { * * @param paintables */ - public static void componentSizeUpdated(Set paintables) { - if (paintables.isEmpty()) { + public static void componentSizeUpdated(Set widgets) { + if (widgets.isEmpty()) { return; } - Map> childWidgets = new HashMap>(); + Map> childWidgets = new HashMap>(); - for (Paintable paintable : paintables) { - Widget widget = (Widget) paintable; + for (Widget widget : widgets) { if (!widget.isAttached()) { continue; } @@ -142,19 +141,19 @@ public class Util { parent = parent.getParent(); } if (parent != null) { - Set set = childWidgets.get(parent); + Set set = childWidgets.get(parent); if (set == null) { - set = new HashSet(); + set = new HashSet(); childWidgets.put((Container) parent, set); } - set.add(paintable); + set.add(widget); } } - Set parentChanges = new HashSet(); + Set parentChanges = new HashSet(); for (Container parent : childWidgets.keySet()) { if (!parent.requestLayout(childWidgets.get(parent))) { - parentChanges.add(parent); + parentChanges.add(parent.getWidgetForPaintable()); } } @@ -614,13 +613,7 @@ public class Util { } 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 @@ -632,7 +625,7 @@ public class Util { client.handleComponentRelativeSize(w); } - HashSet widgets = new HashSet(); + HashSet widgets = new HashSet(); widgets.add(widget); Util.componentSizeUpdated(widgets); } @@ -740,31 +733,27 @@ public class Util { * The widget that contains element. * @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(); @@ -780,7 +769,7 @@ public class Util { * element 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. * @@ -790,19 +779,20 @@ public class Util { * The widget that contains element. * @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); } } @@ -948,7 +938,8 @@ public class Util { private static void printPaintablesVariables(ArrayList 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) { diff --git a/src/com/vaadin/terminal/gwt/client/VCaption.java b/src/com/vaadin/terminal/gwt/client/VCaption.java index 12347b76bd..f6d8ffe58e 100644 --- a/src/com/vaadin/terminal/gwt/client/VCaption.java +++ b/src/com/vaadin/terminal/gwt/client/VCaption.java @@ -14,7 +14,7 @@ public class VCaption extends HTML { public static final String CLASSNAME = "v-caption"; - private final Paintable owner; + private final VPaintableWidget owner; private Element errorIndicatorElement; @@ -48,13 +48,13 @@ public class VCaption extends HTML { * 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); @@ -264,7 +264,8 @@ public class VCaption extends HTML { * 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."); } @@ -293,7 +294,7 @@ public class VCaption extends HTML { * * @return owner Widget */ - public Paintable getOwner() { + public VPaintableWidget getOwner() { return owner; } diff --git a/src/com/vaadin/terminal/gwt/client/VCaptionWrapper.java b/src/com/vaadin/terminal/gwt/client/VCaptionWrapper.java index dbecf96dd0..bc1a240aa9 100644 --- a/src/com/vaadin/terminal/gwt/client/VCaptionWrapper.java +++ b/src/com/vaadin/terminal/gwt/client/VCaptionWrapper.java @@ -5,19 +5,19 @@ 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); } @@ -26,7 +26,7 @@ public class VCaptionWrapper extends FlowPanel { setVisible(!uidl.getBooleanAttribute("invisible")); } - public Paintable getPaintable() { - return widget; + public VPaintableWidget getPaintable() { + return paintable; } } diff --git a/src/com/vaadin/terminal/gwt/client/VConsole.java b/src/com/vaadin/terminal/gwt/client/VConsole.java index a01fa16558..137b6eb2a6 100644 --- a/src/com/vaadin/terminal/gwt/client/VConsole.java +++ b/src/com/vaadin/terminal/gwt/client/VConsole.java @@ -82,8 +82,8 @@ public class VConsole { public static void printLayoutProblems(ValueMap meta, ApplicationConnection applicationConnection, - Set zeroHeightComponents, - Set zeroWidthComponents) { + Set zeroHeightComponents, + Set zeroWidthComponents) { impl.printLayoutProblems(meta, applicationConnection, zeroHeightComponents, zeroWidthComponents); } diff --git a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java index 259f6ea5ce..892260e6ca 100644 --- a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java +++ b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java @@ -90,14 +90,14 @@ public class VDebugConsole extends VOverlay implements Console { 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); @@ -119,7 +119,7 @@ public class VDebugConsole extends VOverlay implements Console { .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, @@ -483,8 +483,8 @@ public class VDebugConsole extends VOverlay implements Console { }-*/; public void printLayoutProblems(ValueMap meta, ApplicationConnection ac, - Set zeroHeightComponents, - Set zeroWidthComponents) { + Set zeroHeightComponents, + Set zeroWidthComponents) { JsArray valueMapArray = meta .getJSValueMapArray("invalidLayouts"); int size = valueMapArray.length(); @@ -521,9 +521,10 @@ public class VDebugConsole extends VOverlay implements Console { } private void printClientSideDetectedIssues( - Set zeroHeightComponents, ApplicationConnection ac) { - for (final Paintable paintable : zeroHeightComponents) { - final Container layout = Util.getLayout((Widget) paintable); + Set 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) @@ -533,7 +534,8 @@ public class VDebugConsole extends VOverlay implements Console { 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()); } @@ -547,7 +549,8 @@ public class VDebugConsole extends VOverlay implements Console { 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(); @@ -565,7 +568,8 @@ public class VDebugConsole extends VOverlay implements Console { 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()); } diff --git a/src/com/vaadin/terminal/gwt/client/VPaintable.java b/src/com/vaadin/terminal/gwt/client/VPaintable.java new file mode 100644 index 0000000000..02b529b428 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/VPaintable.java @@ -0,0 +1,19 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client; + +/** + * TODO + * + */ +public interface VPaintable { + /** + * TODO + * + * @param uidl + * @param client + */ + public void updateFromUIDL(UIDL uidl, ApplicationConnection client); + +} diff --git a/src/com/vaadin/terminal/gwt/client/PaintableMap.java b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java similarity index 68% rename from src/com/vaadin/terminal/gwt/client/PaintableMap.java rename to src/com/vaadin/terminal/gwt/client/VPaintableMap.java index cbdc4efa68..ef355d3cad 100644 --- a/src/com/vaadin/terminal/gwt/client/PaintableMap.java +++ b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java @@ -1,3 +1,6 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ package com.vaadin.terminal.gwt.client; import java.util.Collection; @@ -12,12 +15,18 @@ import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; +import com.vaadin.terminal.Paintable; import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; import com.vaadin.terminal.gwt.client.RenderInformation.Size; -public class PaintableMap { +public class VPaintableMap { - private Map idToPaintable = new HashMap(); + private Map idToPaintable = new HashMap(); + private Map paintableToId = new HashMap(); + + public static VPaintableMap get(ApplicationConnection applicationConnection) { + return applicationConnection.getPaintableMap(); + } @Deprecated private final ComponentDetailMap idToComponentDetail = ComponentDetailMap @@ -31,7 +40,7 @@ public class PaintableMap { * @param id * The Paintable id */ - public Paintable getPaintable(String pid) { + public VPaintable getPaintable(String pid) { return idToPaintable.get(pid); } @@ -41,12 +50,8 @@ public class PaintableMap { * @param element * Root element of the paintable */ - public Paintable getPaintable(Element element) { - return getPaintable(getPid(element)); - } - - public static PaintableMap get(ApplicationConnection applicationConnection) { - return applicationConnection.getPaintableMap(); + public VPaintableWidget getPaintable(Element element) { + return (VPaintableWidget) getPaintable(getPid(element)); } /** @@ -76,24 +81,29 @@ public class PaintableMap { */ public void clear() { idToPaintable.clear(); + paintableToId.clear(); idToComponentDetail.clear(); } @Deprecated - public Widget getWidget(Paintable paintable) { - return (Widget) paintable; + public Widget getWidget(VPaintableWidget paintable) { + return paintable.getWidgetForPaintable(); } @Deprecated - public Paintable getPaintable(Widget widget) { - return (Paintable) widget; + public VPaintableWidget getPaintable(Widget widget) { + return getPaintable(widget.getElement()); } - public void registerPaintable(String pid, Paintable paintable) { + public void registerPaintable(String pid, VPaintable paintable) { ComponentDetail componentDetail = GWT.create(ComponentDetail.class); idToComponentDetail.put(pid, componentDetail); idToPaintable.put(pid, paintable); - setPid(((Widget) paintable).getElement(), pid); + paintableToId.put(paintable, pid); + if (paintable instanceof VPaintableWidget) { + VPaintableWidget pw = (VPaintableWidget) paintable; + setPid(pw.getWidgetForPaintable().getElement(), pid); + } } private native void setPid(Element el, String pid) @@ -113,15 +123,15 @@ public class PaintableMap { * @return the id for the given paintable or null if the paintable could not * be found */ - public String getPid(Paintable paintable) { - return getPid(getWidget(paintable)); + public String getPid(VPaintable paintable) { + if (paintable == null) { + return null; + } + return paintableToId.get(paintable); } @Deprecated public String getPid(Widget widget) { - if (widget == null) { - return null; - } return getPid(widget.getElement()); } @@ -149,7 +159,12 @@ public class PaintableMap { * @return the element for the paintable corresponding to the pid */ public Element getElement(String pid) { - return ((Widget) getPaintable(pid)).getElement(); + VPaintable p = getPaintable(pid); + if (p instanceof VPaintableWidget) { + return ((VPaintableWidget) p).getWidgetForPaintable().getElement(); + } + + return null; } /** @@ -161,7 +176,7 @@ public class PaintableMap { * @param p * the paintable to remove */ - public void unregisterPaintable(Paintable p) { + public void unregisterPaintable(VPaintable p) { // add to unregistry que @@ -170,6 +185,11 @@ public class PaintableMap { return; } String id = getPid(p); + Widget widget = null; + if (p instanceof VPaintableWidget) { + widget = ((VPaintableWidget) p).getWidgetForPaintable(); + } + if (id == null) { /* * Uncomment the following to debug unregistring components. No @@ -180,21 +200,19 @@ public class PaintableMap { // if (!(p instanceof VScrollTableRow)) { // VConsole.log("Trying to unregister Paintable not created by Application Connection."); // } - if (p instanceof HasWidgets) { - unregisterChildPaintables((HasWidgets) p); - } } else { unregistryBag.add(id); - if (p instanceof HasWidgets) { - unregisterChildPaintables((HasWidgets) p); - } } + if (widget != null && widget instanceof HasWidgets) { + unregisterChildPaintables((HasWidgets) widget); + } + } void purgeUnregistryBag(boolean unregisterPaintables) { if (unregisterPaintables) { for (String pid : unregistryBag) { - Paintable paintable = getPaintable(pid); + VPaintable paintable = getPaintable(pid); if (paintable == null) { /* * this should never happen, but it does :-( See e.g. @@ -206,12 +224,18 @@ public class PaintableMap { + ") that is never registered (or already unregistered)"); continue; } + Widget widget = null; + if (paintable instanceof VPaintableWidget) { + widget = ((VPaintableWidget) paintable) + .getWidgetForPaintable(); + } + // check if can be cleaned - Widget component = getWidget(paintable); - if (!component.isAttached()) { + if (widget == null || !widget.isAttached()) { // clean reference to paintable idToComponentDetail.remove(pid); idToPaintable.remove(pid); + paintableToId.remove(paintable); } /* * else NOP : same component has been reattached to another @@ -233,12 +257,16 @@ public class PaintableMap { * @param container */ public void unregisterChildPaintables(HasWidgets container) { + // FIXME: This should be based on the paintable hierarchy final Iterator it = container.iterator(); while (it.hasNext()) { final Widget w = it.next(); - if (w instanceof Paintable) { - unregisterPaintable((Paintable) w); + VPaintableWidget p = getPaintable(w); + if (p != null) { + // This will unregister the paintable and all its children + unregisterPaintable(p); } else if (w instanceof HasWidgets) { + // For normal widget containers, unregister the children unregisterChildPaintables((HasWidgets) w); } } @@ -268,7 +296,7 @@ public class PaintableMap { * @return */ @Deprecated - public Size getOffsetSize(Paintable paintable) { + public Size getOffsetSize(VPaintableWidget paintable) { return getComponentDetail(paintable).getOffsetSize(); } @@ -279,7 +307,7 @@ public class PaintableMap { * @return */ @Deprecated - public FloatSize getRelativeSize(Paintable paintable) { + public FloatSize getRelativeSize(VPaintableWidget paintable) { return getComponentDetail(paintable).getRelativeSize(); } @@ -290,7 +318,7 @@ public class PaintableMap { * @return */ @Deprecated - public void setOffsetSize(Paintable paintable, Size newSize) { + public void setOffsetSize(VPaintableWidget paintable, Size newSize) { getComponentDetail(paintable).setOffsetSize(newSize); } @@ -301,12 +329,13 @@ public class PaintableMap { * @return */ @Deprecated - public void setRelativeSize(Paintable paintable, FloatSize relativeSize) { + public void setRelativeSize(VPaintableWidget paintable, + FloatSize relativeSize) { getComponentDetail(paintable).setRelativeSize(relativeSize); } - private ComponentDetail getComponentDetail(Paintable paintable) { + private ComponentDetail getComponentDetail(VPaintable paintable) { return idToComponentDetail.get(getPid(paintable)); } @@ -321,12 +350,12 @@ public class PaintableMap { * @return */ @Deprecated - public TooltipInfo getTooltipInfo(Paintable paintable, Object key) { + public TooltipInfo getTooltipInfo(VPaintableWidget paintable, Object key) { return getComponentDetail(paintable).getTooltipInfo(key); } - public Collection getPaintables() { - return Collections.unmodifiableCollection(idToPaintable.values()); + public Collection getPaintables() { + return Collections.unmodifiableCollection(paintableToId.keySet()); } /** @@ -336,7 +365,7 @@ public class PaintableMap { * @return */ @Deprecated - public void registerTooltip(Paintable paintable, Object key, + public void registerTooltip(VPaintableWidget paintable, Object key, TooltipInfo tooltip) { getComponentDetail(paintable).putAdditionalTooltip(key, tooltip); @@ -349,8 +378,21 @@ public class PaintableMap { * @return */ @Deprecated - public boolean hasEventListeners(Paintable paintable, String eventIdentifier) { + public boolean hasEventListeners(VPaintable paintable, + String eventIdentifier) { return getComponentDetail(paintable).hasEventListeners(eventIdentifier); } + /** + * Tests if the widget is the root widget of a VPaintableWidget. + * + * @param widget + * The widget to test + * @return true if the widget is the root widget of a VPaintableWidget, + * false otherwise + */ + public boolean isPaintable(Widget w) { + return getPid(w) != null; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/Paintable.java b/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java similarity index 65% rename from src/com/vaadin/terminal/gwt/client/Paintable.java rename to src/com/vaadin/terminal/gwt/client/VPaintableWidget.java index 62abeab5a0..9171fdceda 100644 --- a/src/com/vaadin/terminal/gwt/client/Paintable.java +++ b/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java @@ -4,6 +4,8 @@ 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 @@ -12,7 +14,10 @@ package com.vaadin.terminal.gwt.client; * Updates can be sent back to the server using the * {@link ApplicationConnection#updateVariable()} methods. */ -public interface Paintable { +public interface VPaintableWidget extends VPaintable { - public void updateFromUIDL(UIDL uidl, ApplicationConnection client); + /** + * TODO: Renamed to getWidget + */ + public Widget getWidgetForPaintable(); } diff --git a/src/com/vaadin/terminal/gwt/client/VTooltip.java b/src/com/vaadin/terminal/gwt/client/VTooltip.java index ed8bd2eedd..0709fe531e 100644 --- a/src/com/vaadin/terminal/gwt/client/VTooltip.java +++ b/src/com/vaadin/terminal/gwt/client/VTooltip.java @@ -27,7 +27,7 @@ public class VTooltip extends VOverlay { 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; @@ -110,7 +110,7 @@ public class VTooltip extends VOverlay { } } - 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(); @@ -207,7 +207,7 @@ public class VTooltip extends VOverlay { } - 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) { diff --git a/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java b/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java index dc6fa142d4..bcf7f14a9d 100644 --- a/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java +++ b/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java @@ -97,7 +97,7 @@ public class VUIDLBrowser extends SimpleTree { private String getNodeName(UIDL uidl, ApplicationConfiguration conf, String name) { - Class widgetClassByDecodedTag = conf + Class widgetClassByDecodedTag = conf .getWidgetClassByEncodedTag(name); if (widgetClassByDecodedTag == VUnknownComponent.class) { return conf.getUnknownServerClassNameByEncodedTagName(name) @@ -126,8 +126,8 @@ public class VUIDLBrowser extends SimpleTree { // 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); @@ -239,8 +239,8 @@ public class VUIDLBrowser extends SimpleTree { } } - 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); @@ -257,4 +257,4 @@ public class VUIDLBrowser extends SimpleTree { } } -} \ No newline at end of file +} diff --git a/src/com/vaadin/terminal/gwt/client/WidgetInstantiator.java b/src/com/vaadin/terminal/gwt/client/WidgetInstantiator.java index a5c75d27dd..fef88c38bf 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetInstantiator.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetInstantiator.java @@ -7,5 +7,5 @@ package com.vaadin.terminal.gwt.client; * A helper class used by WidgetMap implementation. Used by the generated code. */ interface WidgetInstantiator { - public Paintable get(); + public VPaintableWidget get(); } diff --git a/src/com/vaadin/terminal/gwt/client/WidgetMap.java b/src/com/vaadin/terminal/gwt/client/WidgetMap.java index 51dac20132..3e02ad23ec 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetMap.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetMap.java @@ -9,15 +9,21 @@ abstract class WidgetMap { protected static HashMap instmap = new HashMap(); - public Paintable instantiate(Class classType) { + // FIXME: Should use Paintable and not VPaintableWidget + public VPaintableWidget instantiate( + Class classType) { return instmap.get(classType).get(); } - public abstract Class getImplementationByServerSideClassName( + // FIXME: Should use Paintable and not VPaintableWidget + public abstract Class getImplementationByServerSideClassName( String fullyqualifiedName); - public abstract Class[] getDeferredLoadedWidgets(); + // FIXME: Should use Paintable and not VPaintableWidget + public abstract Class[] getDeferredLoadedWidgets(); - public abstract void ensureInstantiator(Class classType); + // FIXME: Should use Paintable and not VPaintableWidget + public abstract void ensureInstantiator( + Class classType); } diff --git a/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/src/com/vaadin/terminal/gwt/client/WidgetSet.java index e546761b54..b78091950b 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetSet.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetSet.java @@ -25,7 +25,7 @@ public class WidgetSet { /** * 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. @@ -35,7 +35,7 @@ public class WidgetSet { * @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. @@ -46,7 +46,7 @@ public class WidgetSet { * TODO should try to get rid of these exceptions here */ - final Class classType = resolveWidgetType(uidl, + final Class classType = resolveWidgetType(uidl, conf); if (classType == null || classType == VUnknownComponent.class) { String serverSideName = conf @@ -65,11 +65,11 @@ public class WidgetSet { } - protected Class resolveWidgetType(UIDL uidl, + protected Class resolveWidgetType(UIDL uidl, ApplicationConfiguration conf) { final String tag = uidl.getTag(); - Class widgetClass = conf + Class widgetClass = conf .getWidgetClassByEncodedTag(tag); // add our historical quirks @@ -116,12 +116,12 @@ public class WidgetSet { * @param applicationConfiguration * @return */ - public Class getImplementationByClassName( + public Class getImplementationByClassName( String fullyqualifiedName) { if (fullyqualifiedName == null) { return VUnknownComponent.class; } - Class implementationByServerSideClassName = widgetMap + Class implementationByServerSideClassName = widgetMap .getImplementationByServerSideClassName(fullyqualifiedName); /* @@ -140,11 +140,11 @@ public class WidgetSet { } - public Class[] getDeferredLoadedWidgets() { + public Class[] getDeferredLoadedWidgets() { return widgetMap.getDeferredLoadedWidgets(); } - public void loadImplementation(Class nextType) { + public void loadImplementation(Class nextType) { widgetMap.ensureInstantiator(nextType); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java b/src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java index f87f3dd904..c272f0ea75 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java @@ -17,11 +17,10 @@ import com.google.gwt.event.dom.client.MouseUpHandler; 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 { @@ -31,10 +30,11 @@ public abstract class ClickEventHandler implements DoubleClickHandler, 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; } @@ -82,7 +82,7 @@ public abstract class ClickEventHandler implements DoubleClickHandler, 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, @@ -128,11 +128,7 @@ public abstract class ClickEventHandler implements DoubleClickHandler, * 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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/LayoutClickEventHandler.java b/src/com/vaadin/terminal/gwt/client/ui/LayoutClickEventHandler.java index 1ad69d19cf..896b992afc 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/LayoutClickEventHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/LayoutClickEventHandler.java @@ -10,27 +10,27 @@ import com.google.gwt.dom.client.NativeEvent; 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 parameters = new HashMap(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java b/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java index 934fcaa8b7..38f7878ba4 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java @@ -19,9 +19,10 @@ 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.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; /** @@ -52,12 +53,12 @@ public class ShortcutActionHandler { } /** - * 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 @@ -111,7 +112,7 @@ public class ShortcutActionHandler { } } - 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); @@ -133,16 +134,17 @@ public class ShortcutActionHandler { } 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(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/Table.java b/src/com/vaadin/terminal/gwt/client/ui/Table.java index 4b3ba0422e..018200ab05 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/Table.java +++ b/src/com/vaadin/terminal/gwt/client/ui/Table.java @@ -5,9 +5,9 @@ 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; diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java index dbcfbc26db..e5982b1078 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java @@ -24,11 +24,12 @@ 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.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 { @@ -58,7 +59,7 @@ 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); } @@ -130,15 +131,15 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { } } - public boolean requestLayout(Set children) { + public boolean requestLayout(Set 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); } @@ -243,10 +244,10 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { 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"); } @@ -272,7 +273,7 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { @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); } @@ -286,8 +287,8 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { 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); @@ -295,7 +296,8 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { // 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()); } } @@ -362,8 +364,12 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { * @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; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java b/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java index 8b1fc91185..7fe87713c3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAccordion.java @@ -17,19 +17,20 @@ 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.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 paintables = new HashSet(); + private Set widgets = new HashSet(); private String height; @@ -132,7 +133,7 @@ public class VAccordion extends VTabsheetBase implements 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); @@ -378,12 +379,12 @@ public class VAccordion extends VTabsheetBase implements } 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); } @@ -450,7 +451,7 @@ public class VAccordion extends VTabsheetBase implements return content; } - public Widget getPaintable() { + public Widget getChildWidget() { if (getWidgetCount() > 1) { return getWidget(1); } else { @@ -458,14 +459,17 @@ public class VAccordion extends VTabsheetBase implements } } - 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() { @@ -495,12 +499,13 @@ public class VAccordion extends VTabsheetBase implements } 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")) { @@ -508,7 +513,8 @@ public class VAccordion extends VTabsheetBase implements * 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(); @@ -527,8 +533,8 @@ public class VAccordion extends VTabsheetBase implements 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() { @@ -552,41 +558,42 @@ public class VAccordion extends VTabsheetBase implements @Override @SuppressWarnings("unchecked") - protected Iterator getPaintableIterator() { - return (Iterator) paintables.iterator(); + protected Iterator 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 child) { + public boolean requestLayout(Set 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; @@ -630,9 +637,10 @@ public class VAccordion extends VTabsheetBase implements } @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; @@ -641,4 +649,9 @@ public class VAccordion extends VTabsheetBase implements private StackItem getStackItem(int index) { return (StackItem) getWidget(index); } + + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAudio.java b/src/com/vaadin/terminal/gwt/client/ui/VAudio.java index 1fdfaca831..7fc061184d 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAudio.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAudio.java @@ -8,6 +8,7 @@ import com.google.gwt.dom.client.AudioElement; 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; @@ -46,4 +47,9 @@ public class VAudio extends VMediaBase { protected String getDefaultAltHtml() { return "Your browser does not support the audio element."; } + + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VButton.java b/src/com/vaadin/terminal/gwt/client/ui/VButton.java index de35a46474..074df531a8 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VButton.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VButton.java @@ -19,18 +19,19 @@ import com.google.gwt.user.client.DOM; 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"; @@ -505,4 +506,8 @@ public class VButton extends FocusWidget implements Paintable, ClickHandler, client.updateVariable(id, EventId.BLUR, "", true); } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java index 7a1ee304a6..c1ab3979d9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java @@ -1165,7 +1165,7 @@ public class VCalendarPanel extends FocusableFlexTable implements // elapsed, another timer is triggered to go off every 150ms. Both // timers are cancelled on mouseup or mouseout. if (event.getSource() instanceof VEventButton) { - final Widget sender = (Widget) event.getSource(); + final VEventButton sender = (VEventButton) event.getSource(); processClickEvent(sender); mouseTimer = new Timer() { @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java b/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java index 883c144783..d306bab39e 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java @@ -14,17 +14,18 @@ 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.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"; @@ -157,4 +158,9 @@ public class VCheckBox extends com.google.gwt.user.client.ui.CheckBox implements public void onBlur(BlurEvent arg0) { client.updateVariable(id, EventId.BLUR, "", true); } + + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java index 585180f8f4..ffd7fc49b2 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java @@ -23,16 +23,18 @@ 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.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; @@ -44,7 +46,7 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { this, EventId.LAYOUT_CLICK) { @Override - protected Paintable getChildComponent(Element element) { + protected VPaintableWidget getChildComponent(Element element) { return panel.getComponent(element); } @@ -126,7 +128,7 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { panel.replaceChildComponent(oldComponent, newComponent); } - public void updateCaption(Paintable component, UIDL uidl) { + public void updateCaption(VPaintableWidget component, UIDL uidl) { panel.updateCaption(component, uidl); } @@ -143,7 +145,7 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { public void updateRelativeSizes() { for (Widget w : getChildren()) { - if (w instanceof Paintable) { + if (w instanceof VPaintableWidget) { client.handleComponentRelativeSize(w); } } @@ -169,11 +171,11 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { for (final Iterator 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); @@ -212,8 +214,10 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { // 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); @@ -251,12 +255,12 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { } } - 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++; @@ -267,11 +271,11 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { 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); } @@ -307,7 +311,7 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { return space; } - public boolean requestLayout(Set children) { + public boolean requestLayout(Set children) { if (hasSize()) { return true; } else { @@ -339,4 +343,8 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { } return cssProperty; } + + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java index 1fb3f297ad..39d1ee462c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java @@ -12,10 +12,11 @@ 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.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 { @@ -41,15 +42,17 @@ 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(); @@ -118,11 +121,11 @@ public class VCustomComponent extends SimplePanel implements Container { } } - 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 child) { + public boolean requestLayout(Set children) { // If a child grows in size, it will not necessarily be calculated // correctly unless we remove previous size definitions if (isDynamicWidth()) { @@ -165,4 +168,8 @@ public class VCustomComponent extends SimplePanel implements Container { } } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java index 2a40cd0fe3..787be254f6 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java @@ -20,13 +20,14 @@ 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.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. @@ -34,7 +35,7 @@ import com.vaadin.terminal.gwt.client.VCaptionWrapper; * @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"; @@ -46,7 +47,7 @@ public class VCustomLayout extends ComplexPanel implements Paintable, private final HashMap locationToWidget = new HashMap(); /** Widget to captionwrapper map */ - private final HashMap widgetToCaptionWrapper = new HashMap(); + private final HashMap paintableToCaptionWrapper = new HashMap(); /** Name of the currently rendered style */ String currentTemplateName; @@ -161,15 +162,17 @@ public class VCustomLayout extends ComplexPanel implements Paintable, 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 iterator = oldWidgets.iterator(); iterator @@ -384,24 +387,26 @@ public class VCustomLayout extends ComplexPanel implements Paintable, } /** 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); } } } @@ -421,14 +426,15 @@ public class VCustomLayout extends ComplexPanel implements 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); @@ -447,7 +453,7 @@ public class VCustomLayout extends ComplexPanel implements Paintable, public void clear() { super.clear(); locationToWidget.clear(); - widgetToCaptionWrapper.clear(); + paintableToCaptionWrapper.clear(); } public void iLayout() { @@ -513,7 +519,7 @@ public class VCustomLayout extends ComplexPanel implements Paintable, } }-*/; - public boolean requestLayout(Set child) { + public boolean requestLayout(Set children) { updateRelativeSizedComponents(true, true); if (width.equals("") || height.equals("")) { @@ -642,4 +648,8 @@ public class VCustomLayout extends ComplexPanel implements Paintable, return larger; } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDateField.java b/src/com/vaadin/terminal/gwt/client/ui/VDateField.java index e2c43ef691..d21a20229e 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VDateField.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VDateField.java @@ -1,272 +1,277 @@ -/* -@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.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.Paintable; -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 Paintable, 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; - } -} +/* +@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; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java index f4a876a7ba..da916f262e 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java @@ -26,13 +26,14 @@ import com.google.gwt.xhr.client.ReadyStateChangeHandler; 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; @@ -112,13 +113,13 @@ public class VDragAndDropWrapper extends VCustomComponent implements 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( @@ -130,8 +131,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements if (dragStartMode == WRAPPER) { dragEvent.createDragImage(getElement(), true); } else { - dragEvent.createDragImage(((Widget) paintable).getElement(), - true); + dragEvent.createDragImage(widget.getElement(), true); } return true; } @@ -469,7 +469,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements } private String getPid() { - return PaintableMap.get(client).getPid((Paintable) this); + return VPaintableMap.get(client).getPid((VPaintable) this); } public VDropHandler getDropHandler() { @@ -548,7 +548,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements } @Override - public Paintable getPaintable() { + public VPaintableWidget getPaintable() { return VDragAndDropWrapper.this; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java index 3ea4a9254d..54385c665f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java @@ -21,15 +21,16 @@ 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.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"; @@ -432,4 +433,8 @@ public class VEmbedded extends HTML implements Paintable { } } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java index 9a2caca554..b6bbe5dd19 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java @@ -42,11 +42,12 @@ import com.google.gwt.user.client.ui.PopupPanel; 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; @@ -58,7 +59,7 @@ import com.vaadin.terminal.gwt.client.VTooltip; * 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 { @@ -1933,4 +1934,8 @@ public class VFilterSelect extends Composite implements Paintable, Field, super.onDetach(); suggestionPopup.hide(); } + + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VForm.java b/src/com/vaadin/terminal/gwt/client/ui/VForm.java index a73ac5cad3..a329e1eaef 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VForm.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VForm.java @@ -1,327 +1,335 @@ -/* -@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.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.VErrorMessage; - -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((Widget) newFooter, footerContainer); - footer = newFooter; - } else if (newFooter != footer) { - remove((Widget) footer); - client.unregisterPaintable(footer); - add((Widget) newFooter, 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((Widget) footer); - 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((Widget) lo, fieldContainer); - } else if (lo != newLo) { - client.unregisterPaintable(lo); - remove((Widget) lo); - lo = newLo; - add((Widget) lo, 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) newComponent; - add((Widget) lo, fieldContainer); - } else { - footer = (Container) newComponent; - add((Widget) footer, footerContainer); - } - - } - - public boolean requestLayout(Set 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(Paintable 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); - } - } - - public void onKeyDown(KeyDownEvent event) { - shortcutHandler.handleKeyboardEvent(Event.as(event.getNativeEvent())); - } -} +/* +@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 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; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java index a8559d1d5c..6d068dd11a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java @@ -23,11 +23,12 @@ 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.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; /** @@ -81,8 +82,8 @@ public class VFormLayout extends SimplePanel implements Container { private static final int COLUMN_ERRORFLAG = 1; private static final int COLUMN_WIDGET = 2; - private HashMap componentToCaption = new HashMap(); - private HashMap componentToError = new HashMap(); + private HashMap widgetToCaption = new HashMap(); + private HashMap widgetToError = new HashMap(); public VFormLayoutTable() { DOM.setElementProperty(getElement(), "cellPadding", "0"); @@ -111,27 +112,31 @@ public class VFormLayout extends SimplePanel implements Container { 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"); @@ -145,7 +150,7 @@ public class VFormLayout extends SimplePanel implements Container { CLASSNAME + "-errorcell"); setWidget(i, COLUMN_ERRORFLAG, error); - p.updateFromUIDL(childUidl, client); + childPaintable.updateFromUIDL(childUidl, client); String rowstyles = CLASSNAME + "-row"; if (i == 0) { @@ -160,9 +165,11 @@ public class VFormLayout extends SimplePanel implements Container { } 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); } @@ -170,8 +177,8 @@ public class VFormLayout extends SimplePanel implements Container { * 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); } } @@ -195,16 +202,21 @@ public class VFormLayout extends SimplePanel implements Container { 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); @@ -217,24 +229,26 @@ public class VFormLayout extends SimplePanel implements Container { } 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) { @@ -294,7 +308,7 @@ public class VFormLayout extends SimplePanel implements Container { table.replaceChildComponent(oldComponent, newComponent); } - public void updateCaption(Paintable component, UIDL uidl) { + public void updateCaption(VPaintableWidget component, UIDL uidl) { table.updateCaption(component, uidl); } @@ -302,7 +316,7 @@ public class VFormLayout extends SimplePanel implements Container { public static final String CLASSNAME = "v-caption"; - private final Paintable owner; + private final VPaintableWidget owner; private Element requiredFieldIndicator; @@ -319,8 +333,8 @@ public class VFormLayout extends SimplePanel implements Container { * 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; @@ -423,7 +437,7 @@ public class VFormLayout extends SimplePanel implements Container { * * @return owner Widget */ - public Paintable getOwner() { + public VPaintableWidget getOwner() { return owner; } @@ -440,14 +454,14 @@ public class VFormLayout extends SimplePanel implements Container { 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")) { @@ -475,7 +489,7 @@ public class VFormLayout extends SimplePanel implements Container { } - public boolean requestLayout(Set child) { + public boolean requestLayout(Set children) { if (height.equals("") || width.equals("")) { // A dynamic size might change due to children changes return false; @@ -519,9 +533,14 @@ public class VFormLayout extends SimplePanel implements Container { table.setContentWidths(); if (height.equals("")) { // Width might affect height - Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this); + Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this, + this); } } } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java index 82b3eabf40..b37032e987 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java @@ -24,15 +24,17 @@ 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.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"; @@ -44,7 +46,7 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { protected HashMap widgetToComponentContainer = new HashMap(); - private HashMap paintableToCell = new HashMap(); + private HashMap widgetToCell = new HashMap(); private int spacingPixelsHorizontal; private int spacingPixelsVertical; @@ -74,7 +76,7 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { this, EventId.LAYOUT_CLICK) { @Override - protected Paintable getChildComponent(Element element) { + protected VPaintableWidget getChildComponent(Element element) { return getComponent(element); } @@ -239,10 +241,11 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { 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; @@ -295,8 +298,8 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { } else { expandRows(); layoutCells(); - for (Paintable c : paintableToCell.keySet()) { - client.handleComponentRelativeSize((Widget) c); + for (Widget w : widgetToCell.keySet()) { + client.handleComponentRelativeSize(w); } } } @@ -388,8 +391,8 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { } 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); @@ -699,7 +702,7 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { } public boolean hasChildComponent(Widget component) { - return paintableToCell.containsKey(component); + return widgetToCell.containsKey(component); } public void replaceChildComponent(Widget oldComponent, Widget newComponent) { @@ -709,30 +712,31 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { 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 changedChildren) { + public boolean requestLayout(final Set changedChildren) { boolean needsLayout = false; boolean reDistributeColSpanWidths = false; boolean reDistributeRowSpanHeights = false; @@ -743,9 +747,9 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { } ArrayList dirtyColumns = new ArrayList(); ArrayList dirtyRows = new ArrayList(); - 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 @@ -886,7 +890,7 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { } public RenderSpace getAllocatedSpace(Widget child) { - Cell cell = paintableToCell.get(child); + Cell cell = widgetToCell.get(child); assert cell != null; return cell.getAllocatedSpace(); } @@ -994,12 +998,13 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { 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(""); /* @@ -1007,23 +1012,23 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { * 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() { @@ -1062,17 +1067,19 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { // 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); } } } @@ -1125,8 +1132,12 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { * @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; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VLabel.java b/src/com/vaadin/terminal/gwt/client/ui/VLabel.java index 39d682d404..f259d033c6 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VLabel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VLabel.java @@ -4,26 +4,17 @@ 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; @@ -43,66 +34,15 @@ public class VLabel extends HTML implements Paintable { 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 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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/VLabelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VLabelPaintable.java new file mode 100644 index 0000000000..12f2c639da --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/VLabelPaintable.java @@ -0,0 +1,122 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.PreElement; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.KeyDownEvent; +import com.google.gwt.event.dom.client.KeyDownHandler; +import com.google.gwt.event.dom.client.MouseMoveEvent; +import com.google.gwt.event.dom.client.MouseMoveHandler; +import com.google.gwt.event.dom.client.MouseOutEvent; +import com.google.gwt.event.dom.client.MouseOutHandler; +import com.google.gwt.event.dom.client.MouseOverEvent; +import com.google.gwt.event.dom.client.MouseOverHandler; +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; +import com.vaadin.terminal.gwt.client.VPaintableWidget; + +public class VLabelPaintable implements VPaintableWidget { + + private VLabel widget = GWT.create(VLabel.class); + private ApplicationConnection client; + + class TooltipHandler implements ClickHandler, KeyDownHandler, + MouseOverHandler, MouseOutHandler, MouseMoveHandler { + + public void onClick(ClickEvent event) { + // TODO Auto-generated method stub + + } + + public void onMouseMove(MouseMoveEvent event) { + // TODO Auto-generated method stub + + } + + public void onMouseOut(MouseOutEvent event) { + // TODO Auto-generated method stub + + } + + public void onMouseOver(MouseOverEvent event) { + // TODO Auto-generated method stub + + } + + public void onKeyDown(KeyDownEvent event) { + // TODO Auto-generated method stub + + } + + } + + public VLabelPaintable() { + TooltipHandler handler = new TooltipHandler(); + + widget.addDomHandler(handler, ClickEvent.getType()); + widget.addDomHandler(handler, KeyDownEvent.getType()); + widget.addDomHandler(handler, MouseOverEvent.getType()); + widget.addDomHandler(handler, MouseOutEvent.getType()); + widget.addDomHandler(handler, MouseMoveEvent.getType()); + + } + + public VLabel getWidget() { + return widget; + } + + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + + if (client.updateComponent(getWidget(), uidl, true)) { + return; + } + + this.client = client; + + boolean sinkOnloads = false; + + final String mode = uidl.getStringAttribute("mode"); + if (mode == null || "text".equals(mode)) { + getWidget().setText(uidl.getChildString(0)); + } else if ("pre".equals(mode)) { + PreElement preElement = Document.get().createPreElement(); + preElement.setInnerText(uidl.getChildUIDL(0).getChildString(0)); + // clear existing content + getWidget().setHTML(""); + // add preformatted text to dom + getWidget().getElement().appendChild(preElement); + } else if ("uidl".equals(mode)) { + getWidget().setHTML(uidl.getChildrenAsXML()); + } else if ("xhtml".equals(mode)) { + UIDL content = uidl.getChildUIDL(0).getChildUIDL(0); + if (content.getChildCount() > 0) { + getWidget().setHTML(content.getChildString(0)); + } else { + getWidget().setHTML(""); + } + sinkOnloads = true; + } else if ("xml".equals(mode)) { + getWidget().setHTML(uidl.getChildUIDL(0).getChildString(0)); + } else if ("raw".equals(mode)) { + getWidget().setHTML(uidl.getChildUIDL(0).getChildString(0)); + sinkOnloads = true; + } else { + getWidget().setText(""); + } + if (sinkOnloads) { + Util.sinkOnloadForImages(getWidget().getElement()); + } + } + + public Widget getWidgetForPaintable() { + return getWidget(); + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VLink.java b/src/com/vaadin/terminal/gwt/client/ui/VLink.java index b8030de421..0ade84aaf5 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VLink.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VLink.java @@ -11,13 +11,14 @@ 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.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"; @@ -179,4 +180,8 @@ public class VLink extends HTML implements Paintable, ClickHandler { } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java index cebc4600a2..25bd6f35b2 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VListSelect.java @@ -10,8 +10,9 @@ import java.util.Iterator; 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; @@ -110,6 +111,10 @@ public class VListSelect extends VOptionGroupBase { select.setFocus(true); } + public Widget getWidgetForPaintable() { + return this; + } + } /** @@ -118,7 +123,7 @@ public class VListSelect extends VOptionGroupBase { */ class TooltipListBox extends ListBox { private ApplicationConnection client; - private Paintable pntbl; + private VPaintableWidget pntbl; TooltipListBox(boolean isMultiselect) { super(isMultiselect); @@ -129,7 +134,7 @@ class TooltipListBox extends ListBox { this.client = client; } - public void setSelect(Paintable s) { + public void setSelect(VPaintableWidget s) { pntbl = s; } @@ -140,4 +145,5 @@ class TooltipListBox extends ListBox { client.handleTooltipEvent(event, pntbl); } } + } \ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMediaBase.java b/src/com/vaadin/terminal/gwt/client/ui/VMediaBase.java index 53638917b2..df76b6d878 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMediaBase.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMediaBase.java @@ -9,11 +9,11 @@ import com.google.gwt.dom.client.MediaElement; 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"; diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java index 4311d82802..306086e357 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java @@ -35,14 +35,14 @@ 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.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, ContainerResizedListener, KeyPressHandler, KeyDownHandler, FocusHandler, SubPartAware { @@ -220,7 +220,7 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable, 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"); @@ -1551,4 +1551,8 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable, return null; } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java b/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java index d76f12436c..97d0747496 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java @@ -15,18 +15,19 @@ import com.google.gwt.event.shared.HandlerRegistration; 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"; @@ -197,4 +198,7 @@ public class VNativeButton extends Button implements Paintable, ClickHandler, } } + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java index b212506e00..038b598555 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java @@ -8,6 +8,7 @@ import java.util.ArrayList; 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 { @@ -107,4 +108,7 @@ public class VNativeSelect extends VOptionGroupBase implements Field { select.setFocus(true); } + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java index d110d90e25..0175134355 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroup.java @@ -1,229 +1,234 @@ -/* -@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 optionsToKeys; - - private boolean sendFocusEvents = false; - private boolean sendBlurEvents = false; - private List focusHandlers = null; - private List 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(); - } - - @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(); - blurHandlers = new ArrayList(); - - // 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 = "\"\"" + 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 iterator = panel.iterator(); iterator.hasNext();) { - FocusWidget widget = (FocusWidget) iterator.next(); - widget.setTabIndex(tabIndex); - } - } - - public void focus() { - Iterator 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; - } - } - }); - } - } -} +/* +@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 optionsToKeys; + + private boolean sendFocusEvents = false; + private boolean sendBlurEvents = false; + private List focusHandlers = null; + private List 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(); + } + + @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(); + blurHandlers = new ArrayList(); + + // 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 = "\"\"" + 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 iterator = panel.iterator(); iterator.hasNext();) { + FocusWidget widget = (FocusWidget) iterator.next(); + widget.setTabIndex(tabIndex); + } + } + + public void focus() { + Iterator 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; + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java index 8be0aff3f0..c4d92783c8 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VOptionGroupBase.java @@ -1,227 +1,227 @@ -/* -@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.Paintable; -import com.vaadin.terminal.gwt.client.UIDL; - -abstract class VOptionGroupBase extends Composite implements Paintable, Field, - ClickHandler, ChangeHandler, KeyPressHandler, Focusable { - - public static final String CLASSNAME_OPTION = "v-select-option"; - - protected ApplicationConnection client; - - protected String id; - - protected Set 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; - } - } - -} +/* +@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 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; + } + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java index c719639961..f490e5176d 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java @@ -17,13 +17,13 @@ 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.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; @@ -60,7 +60,7 @@ public class VOrderedLayout extends CellBasedLayout { this, EventId.LAYOUT_CLICK) { @Override - protected Paintable getChildComponent(Element element) { + protected VPaintableWidget getChildComponent(Element element) { return getComponent(element); } @@ -115,15 +115,16 @@ public class VOrderedLayout extends CellBasedLayout { int pos = 0; for (final Iterator 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 @@ -131,7 +132,7 @@ public class VOrderedLayout extends CellBasedLayout { * been invisible. Ensure the childComponentContainer has the * widget attached. See e.g. #5372 */ - childComponentContainer.setWidget(widget); + childComponentContainer.setPaintable(childPaintable); } addOrMoveChild(childComponentContainer, pos++); @@ -704,7 +705,7 @@ public class VOrderedLayout extends CellBasedLayout { 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( @@ -787,10 +788,10 @@ public class VOrderedLayout extends CellBasedLayout { root.getStyle().setPropertyPx("height", activeLayoutSize.getHeight()); } - public boolean requestLayout(Set children) { - for (Paintable p : children) { + public boolean requestLayout(Set 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(); @@ -886,7 +887,7 @@ public class VOrderedLayout extends CellBasedLayout { protected void updateAlignmentsAndExpandRatios(UIDL uidl, ArrayList renderedWidgets) { - /* + /* */ alignments = uidl.getMapAttribute("alignments"); @@ -899,7 +900,7 @@ public class VOrderedLayout extends CellBasedLayout { 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); @@ -941,15 +942,16 @@ public class VOrderedLayout extends CellBasedLayout { } } - 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); } } @@ -963,8 +965,12 @@ public class VOrderedLayout extends CellBasedLayout { * @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; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java index f1298090da..9eec275b59 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java @@ -22,11 +22,12 @@ 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.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, @@ -53,7 +54,7 @@ public class VPanel extends SimplePanel implements Container, private String height; - private Paintable layout; + private VPaintableWidget layout; ShortcutActionHandler shortcutHandler; @@ -222,12 +223,12 @@ public class VPanel extends SimplePanel implements Container, // 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); @@ -329,7 +330,7 @@ public class VPanel extends SimplePanel implements Container, */ int captionWidth = captionText.getOffsetWidth() + getCaptionMarginLeft() + getCaptionPaddingHorizontal(); - int layoutWidth = ((Widget) layout).getOffsetWidth() + int layoutWidth = layout.getWidgetForPaintable().getOffsetWidth() + getContainerBorderWidth(); int width = layoutWidth; if (captionWidth > width) { @@ -469,7 +470,8 @@ public class VPanel extends SimplePanel implements Container, if (height.equals("")) { // Width change may affect height - Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this); + Util.updateRelativeChildrenAndSendSizeUpdateEvent(client, this, + this); } } @@ -508,12 +510,12 @@ public class VPanel extends SimplePanel implements Container, 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) { @@ -537,10 +539,10 @@ public class VPanel extends SimplePanel implements Container, return new RenderSpace(w, h, true); } - public boolean requestLayout(Set child) { + public boolean requestLayout(Set 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 @@ -552,7 +554,7 @@ public class VPanel extends SimplePanel implements Container, 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 } @@ -566,4 +568,8 @@ public class VPanel extends SimplePanel implements Container, return shortcutHandler; } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java index 3717aea127..7de1658c5d 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java @@ -1,462 +1,462 @@ -/* -@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.Paintable; -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. - * - * Note: To change the keyboard assignments used in the popup dialog you - * should extend com.vaadin.terminal.gwt.client.ui.VCalendarPanel - * and then pass set it by calling the - * setCalendarPanel(VCalendarPanel panel) method. - * - */ -public class VPopupCalendar extends VTextualDate implements Paintable, Field, - ClickHandler, CloseHandler, 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 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); - } - -} +/* +@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. + * + * Note: To change the keyboard assignments used in the popup dialog you + * should extend com.vaadin.terminal.gwt.client.ui.VCalendarPanel + * and then pass set it by calling the + * setCalendarPanel(VCalendarPanel panel) method. + * + */ +public class VPopupCalendar extends VTextualDate implements VPaintableWidget, + Field, ClickHandler, CloseHandler, 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 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); + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java index 907e11ac2d..e667489dda 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java @@ -25,13 +25,13 @@ import com.google.gwt.user.client.ui.RootPanel; 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; @@ -84,7 +84,7 @@ public class VPopupView extends HTML implements Container, Iterable { /** * * - * @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) { @@ -230,7 +230,7 @@ public class VPopupView extends HTML implements Container, Iterable { */ protected class CustomPopup extends VOverlay { - private Paintable popupComponentPaintable = null; + private VPaintableWidget popupComponentPaintable = null; private Widget popupComponentWidget = null; private VCaptionWrapper captionWrapper = null; @@ -346,15 +346,13 @@ public class VPopupView extends HTML implements Container, Iterable { 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; } @@ -443,12 +441,12 @@ public class VPopupView extends HTML implements Container, Iterable { popup.popupComponentWidget = newComponent; } - public boolean requestLayout(Set child) { + public boolean requestLayout(Set 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); @@ -462,9 +460,6 @@ public class VPopupView extends HTML implements Container, Iterable { popup.setWidget(popup.popupComponentWidget); } } - - popup.popupComponentWidget = (Widget) component; - popup.popupComponentPaintable = component; } @Override @@ -501,4 +496,8 @@ public class VPopupView extends HTML implements Container, Iterable { }; } + public Widget getWidgetForPaintable() { + return this; + } + }// class VPopupView diff --git a/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java b/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java index d5eac590ad..f7cc4240b7 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java @@ -9,11 +9,11 @@ import com.google.gwt.user.client.Element; 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(); @@ -103,4 +103,8 @@ public class VProgressIndicator extends Widget implements Paintable { } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index 3301e73202..d914355666 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -61,13 +61,13 @@ 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.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; @@ -1305,7 +1305,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, private void purgeUnregistryBag() { for (Iterator iterator = lazyUnregistryBag.iterator(); iterator .hasNext();) { - PaintableMap.get(client).unregisterChildPaintables(iterator.next()); + VPaintableMap.get(client) + .unregisterChildPaintables(iterator.next()); } lazyUnregistryBag.clear(); } @@ -4638,11 +4639,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, 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); } } @@ -4716,7 +4717,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, return index; } - protected void paintComponent(Paintable p, UIDL uidl) { + protected void paintComponent(VPaintableWidget p, UIDL uidl) { if (isAttached()) { p.updateFromUIDL(uidl, client); } else { @@ -4732,7 +4733,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, 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); } } @@ -5510,13 +5512,13 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, } - public boolean requestLayout(Set children) { + public boolean requestLayout(Set 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 } @@ -5525,6 +5527,10 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, // Component container interface faked here to get layouts // render properly } + + public Widget getWidgetForPaintable() { + return this; + } } protected class VScrollTableGeneratedRow extends VScrollTableRow { @@ -5658,7 +5664,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, if (!hasFocus) { scrollBodyPanel.setFocus(true); } + } + } /** @@ -6305,7 +6313,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, } @Override - public Paintable getPaintable() { + public VPaintableWidget getPaintable() { return VScrollTable.this; } @@ -6866,4 +6874,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, VConsole.error(msg); } } + + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java index 5b215cfff4..6b55fa0802 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java @@ -1,568 +1,573 @@ -/* -@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.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.UIDL; -import com.vaadin.terminal.gwt.client.Util; -import com.vaadin.terminal.gwt.client.VConsole; - -public class VSlider extends SimpleFocusablePanel implements Paintable, 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; - } -} +/* +@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; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java index c41bf98b7e..0d44609bb0 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java @@ -28,12 +28,13 @@ 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.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 { @@ -283,24 +284,29 @@ public class VSplitPanel extends ComplexPanel implements Container, 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()); @@ -762,11 +768,11 @@ public class VSplitPanel extends ComplexPanel implements Container, } } - public boolean requestLayout(Set child) { + public boolean requestLayout(Set 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) { /* @@ -785,7 +791,7 @@ public class VSplitPanel extends ComplexPanel implements Container, } - public void updateCaption(Paintable component, UIDL uidl) { + public void updateCaption(VPaintableWidget component, UIDL uidl) { // TODO Implement caption handling } @@ -839,4 +845,8 @@ public class VSplitPanel extends ComplexPanel implements Container, public boolean isEnabled() { return enabled; } + + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java b/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java index d3cb3130b0..cf35dc8e88 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java @@ -24,14 +24,14 @@ import com.google.gwt.user.client.ui.SimplePanel; 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(); @@ -199,10 +199,10 @@ public class VTablePaging extends Composite implements Table, Paintable, 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++; @@ -443,4 +443,8 @@ public class VTablePaging extends Composite implements Table, Paintable, // TODO Auto-generated method stub return false; } + + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java index 5414b96acd..bee28a97cf 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java @@ -23,13 +23,14 @@ 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.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 { @@ -800,22 +801,24 @@ 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 */ @@ -839,10 +842,10 @@ public class VTabsheet extends VTabsheetBase { } 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()); } @@ -865,30 +868,32 @@ public class VTabsheet extends VTabsheetBase { } 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"); @@ -1089,7 +1094,7 @@ public class VTabsheet extends VTabsheetBase { } @Override - protected Iterator getPaintableIterator() { + protected Iterator getWidgetIterator() { return tp.iterator(); } @@ -1105,19 +1110,19 @@ public class VTabsheet extends VTabsheetBase { 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 child) { + public boolean requestLayout(Set 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; } @@ -1165,9 +1170,10 @@ public class VTabsheet extends VTabsheetBase { } @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; } @@ -1184,4 +1190,7 @@ public class VTabsheet extends VTabsheetBase { } } + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java index 7304f62f41..9dd74474f3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheetBase.java @@ -13,8 +13,9 @@ 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.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 { @@ -50,10 +51,10 @@ abstract class VTabsheetBase extends ComplexPanel implements Container { final UIDL tabs = uidl.getChildUIDL(0); // Paintables in the TabSheet before update - ArrayList oldPaintables = new ArrayList(); - for (Iterator iterator = getPaintableIterator(); iterator + ArrayList oldWidgets = new ArrayList(); + for (Iterator iterator = getWidgetIterator(); iterator .hasNext();) { - oldPaintables.add(iterator.next()); + oldWidgets.add(iterator.next()); } // Clear previous values @@ -86,21 +87,24 @@ abstract class VTabsheetBase extends ComplexPanel implements Container { } 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 iterator = oldPaintables.iterator(); iterator + for (Iterator 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); } } @@ -112,7 +116,7 @@ abstract class VTabsheetBase extends ComplexPanel implements Container { * {@link #updateFromUIDL(UIDL, ApplicationConnection)} checks if * instanceof Paintable. Therefore set to */ - abstract protected Iterator getPaintableIterator(); + abstract protected Iterator getWidgetIterator(); /** * Clears current tabs and contents @@ -143,7 +147,7 @@ abstract class VTabsheetBase extends ComplexPanel implements Container { * 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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java index 5142dda357..26c7430e74 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java @@ -21,10 +21,11 @@ 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.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; @@ -36,7 +37,7 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutAct * @author Vaadin Ltd. * */ -public class VTextField extends TextBoxBase implements Paintable, Field, +public class VTextField extends TextBoxBase implements VPaintableWidget, Field, ChangeHandler, FocusHandler, BlurHandler, BeforeShortcutActionListener, KeyDownHandler { @@ -606,4 +607,8 @@ public class VTextField extends TextBoxBase implements Paintable, Field, valueChange(false); } } + + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java index 98b47ecb1f..ed4953d463 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java @@ -20,11 +20,11 @@ import com.vaadin.terminal.gwt.client.EventId; 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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTree.java b/src/com/vaadin/terminal/gwt/client/ui/VTree.java index 66943591b4..de7f6c652a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTree.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTree.java @@ -40,7 +40,7 @@ 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.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; @@ -58,7 +58,7 @@ import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; /** * */ -public class VTree extends FocusElementPanel implements Paintable, +public class VTree extends FocusElementPanel implements VPaintableWidget, VHasDropHandler, FocusHandler, BlurHandler, KeyPressHandler, KeyDownHandler, SubPartAware, ActionOwner { @@ -464,7 +464,7 @@ public class VTree extends FocusElementPanel implements Paintable, } @Override - public Paintable getPaintable() { + public VPaintableWidget getPaintable() { return VTree.this; } @@ -2242,4 +2242,8 @@ public class VTree extends FocusElementPanel implements Paintable, event.preventDefault(); } } + + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java index b1018783df..3a5d5f3b41 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java @@ -1,630 +1,635 @@ -/* -@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.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(""); - 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 selectedItemKeys = new ArrayList(); - 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 movedItems = moveSelectedItems(options, selections); - selectedKeys.addAll(movedItems); - - client.updateVariable(id, "selected", - selectedKeys.toArray(new String[selectedKeys.size()]), - isImmediate()); - } - - private void removeItem() { - Set movedItems = moveSelectedItems(selections, options); - selectedKeys.removeAll(movedItems); - - client.updateVariable(id, "selected", - selectedKeys.toArray(new String[selectedKeys.size()]), - isImmediate()); - } - - private Set moveSelectedItems(ListBox source, ListBox target) { - final boolean[] sel = getSelectionBitmap(source); - final Set movedItems = new HashSet(); - 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; - } -} +/* +@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(""); + 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 selectedItemKeys = new ArrayList(); + 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 movedItems = moveSelectedItems(options, selections); + selectedKeys.addAll(movedItems); + + client.updateVariable(id, "selected", + selectedKeys.toArray(new String[selectedKeys.size()]), + isImmediate()); + } + + private void removeItem() { + Set movedItems = moveSelectedItems(selections, options); + selectedKeys.removeAll(movedItems); + + client.updateVariable(id, "selected", + selectedKeys.toArray(new String[selectedKeys.size()]), + isImmediate()); + } + + private Set moveSelectedItems(ListBox source, ListBox target) { + final boolean[] sel = getSelectionBitmap(source); + final Set movedItems = new HashSet(); + 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; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java b/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java index c7442e4436..5b3790f521 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java @@ -6,13 +6,14 @@ package com.vaadin.terminal.gwt.client.ui; 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; @@ -56,4 +57,8 @@ public class VUnknownComponent extends Composite implements Paintable { public void setCaption(String c) { caption.getElement().setInnerHTML(c); } + + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java index 4e3b9843dc..3d49b8d9d1 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java @@ -21,9 +21,10 @@ import com.google.gwt.user.client.ui.FormPanel; 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; @@ -34,7 +35,7 @@ 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 @@ -354,4 +355,8 @@ public class VUpload extends SimplePanel implements Paintable { } } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVideo.java b/src/com/vaadin/terminal/gwt/client/ui/VVideo.java index 92b93ac96b..71be059319 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VVideo.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VVideo.java @@ -8,6 +8,7 @@ import com.google.gwt.dom.client.Document; 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; @@ -74,4 +75,8 @@ public class VVideo extends VMediaBase { protected String getDefaultAltHtml() { return "Your browser does not support the video element."; } + + public Widget getWidgetForPaintable() { + return this; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VView.java b/src/com/vaadin/terminal/gwt/client/ui/VView.java index 9dc282b683..8eabf6c625 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VView.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VView.java @@ -37,11 +37,11 @@ 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.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; /** @@ -58,7 +58,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, private String theme; - private Paintable layout; + private VPaintableWidget layout; private final LinkedHashSet subWindows = new LinkedHashSet(); @@ -334,18 +334,18 @@ public class VView extends SimplePanel implements Container, ResizeHandler, // 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; } @@ -377,7 +377,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, } } else { // subwindows - final Paintable w = client.getPaintable(childUidl); + final VPaintableWidget w = client.getPaintable(childUidl); if (subWindows.contains(w)) { removedSubWindows.remove(w); } else { @@ -400,9 +400,11 @@ public class VView extends SimplePanel implements Container, ResizeHandler, // 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 @@ -475,9 +477,10 @@ public class VView extends SimplePanel implements Container, ResizeHandler, 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(); } }); } @@ -643,7 +646,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, 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); @@ -661,7 +664,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, 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); } @@ -714,10 +717,10 @@ public class VView extends SimplePanel implements Container, ResizeHandler, } setWidget(newComponent); - layout = (Paintable) newComponent; + layout = (VPaintableWidget) newComponent; } - public boolean requestLayout(Set child) { + public boolean requestLayout(Set children) { /* * Can never propagate further and we do not want need to re-layout the * layout which has caused this request. @@ -725,7 +728,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, updateParentFrameSize(); // layout size change may affect its available space (scrollbars) - connection.handleComponentRelativeSize((Widget) layout); + connection.handleComponentRelativeSize(layout.getWidgetForPaintable()); return true; @@ -758,7 +761,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, 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) } @@ -820,4 +823,8 @@ public class VView extends SimplePanel implements Container, ResizeHandler, getElement().focus(); } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java index e6f3312976..c1ef2bbac4 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java @@ -37,10 +37,10 @@ import com.vaadin.terminal.gwt.client.Console; 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; @@ -88,7 +88,7 @@ public class VWindow extends VOverlay implements Container, public static final int Z_INDEX = 10000; - private Paintable layout; + private VPaintableWidget layout; private Element contents; @@ -365,20 +365,20 @@ public class VWindow extends VOverlay implements Container, 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; } @@ -947,8 +947,9 @@ public class VWindow extends VOverlay implements Container, 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()); @@ -1136,7 +1137,7 @@ public class VWindow extends VOverlay implements Container, 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(); @@ -1184,7 +1185,7 @@ public class VWindow extends VOverlay implements Container, contentPanel.setWidget(newComponent); } - public boolean requestLayout(Set child) { + public boolean requestLayout(Set children) { if (dynamicWidth && !layoutRelativeWidth) { setNaturalWidth(); } @@ -1193,11 +1194,11 @@ public class VWindow extends VOverlay implements Container, } 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 } @@ -1242,4 +1243,8 @@ public class VWindow extends VOverlay implements Container, contentPanel.focus(); } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java index 6280031d84..4d752d4527 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java @@ -9,7 +9,7 @@ import com.google.gwt.user.client.Command; 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 { @@ -129,6 +129,6 @@ 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(); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java index dbeff243a8..b86a404678 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java @@ -24,9 +24,9 @@ import com.google.gwt.user.client.ui.RootPanel; 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; /** @@ -333,10 +333,10 @@ public class VDragAndDropManager { } 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); } }; @@ -499,8 +499,8 @@ public class VDragAndDropManager { * 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() { @@ -543,8 +543,9 @@ public class VDragAndDropManager { } - 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() { @@ -578,7 +579,7 @@ public class VDragAndDropManager { if (currentDropHandler == null) { return; } - Paintable paintable = currentDropHandler.getPaintable(); + VPaintableWidget paintable = currentDropHandler.getPaintable(); ApplicationConnection client = currentDropHandler .getApplicationConnection(); /* diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragSourceIs.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragSourceIs.java index e0c0cafd63..2be75ae3d9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragSourceIs.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragSourceIs.java @@ -3,9 +3,9 @@ */ 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! @@ -17,15 +17,15 @@ final public class VDragSourceIs extends VAcceptCriterion { @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; diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDropHandler.java index a597e9ed30..d84dea4833 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VDropHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDropHandler.java @@ -4,7 +4,7 @@ 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 @@ -61,7 +61,7 @@ public interface VDropHandler { /** * Returns the Paintable into which this DragHandler is associated */ - public Paintable getPaintable(); + public VPaintableWidget getPaintable(); /** * Returns the application connection to which this {@link VDropHandler} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VHasDropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VHasDropHandler.java index 0195862431..48f748a4f3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VHasDropHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VHasDropHandler.java @@ -3,13 +3,13 @@ */ 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 { diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VIsOverId.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VIsOverId.java index 78974f060e..3ea7d1a482 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VIsOverId.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VIsOverId.java @@ -6,9 +6,9 @@ */ 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 { @@ -19,8 +19,8 @@ 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); diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VItemIdIs.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VItemIdIs.java index 80f140a458..16de428d9c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VItemIdIs.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VItemIdIs.java @@ -6,9 +6,9 @@ */ 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 { @@ -16,10 +16,11 @@ 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)) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VSourceIsTarget.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VSourceIsTarget.java index ff4c4f1d35..55c1110546 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VSourceIsTarget.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VSourceIsTarget.java @@ -6,15 +6,15 @@ */ 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; diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java index fe51ea82e4..f81567f906 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java @@ -8,7 +8,7 @@ import java.util.HashMap; 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 @@ -16,7 +16,7 @@ import com.vaadin.terminal.gwt.client.Paintable; */ public class VTransferable { - private Paintable component; + private VPaintableWidget component; private final Map variables = new HashMap(); @@ -26,7 +26,7 @@ public class VTransferable { * * @return the component */ - public Paintable getDragSource() { + public VPaintableWidget getDragSource() { return component; } @@ -41,7 +41,7 @@ public class VTransferable { * @param component * the component to set */ - public void setDragSource(Paintable component) { + public void setDragSource(VPaintableWidget component) { this.component = component; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java index 2ca58a38c2..85f48859a4 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/CellBasedLayout.java @@ -17,8 +17,9 @@ 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.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 { @@ -375,8 +376,9 @@ 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); } } @@ -389,8 +391,10 @@ public abstract class CellBasedLayout extends ComplexPanel implements Container 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); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java b/src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java index fcbe1d8f9f..92464cd459 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java @@ -13,13 +13,13 @@ 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.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 { @@ -68,10 +68,11 @@ 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(); @@ -99,11 +100,15 @@ public class ChildComponentContainer extends Panel { 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; @@ -187,7 +192,7 @@ public class ChildComponentContainer extends Panel { if (fixedWidth < 0 && BrowserInfo.get().isOpera()) { setUnlimitedContainerWidth(); } - ((Paintable) widget).updateFromUIDL(childUIDL, client); + paintable.updateFromUIDL(childUIDL, client); } public void setUnlimitedContainerWidth() { @@ -404,7 +409,7 @@ public class ChildComponentContainer extends Panel { 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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java index bf0a423474..35d3247f9b 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java +++ b/src/com/vaadin/terminal/gwt/client/ui/richtextarea/VRichTextArea.java @@ -27,7 +27,7 @@ import com.google.gwt.user.client.ui.RichTextArea; 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; @@ -41,7 +41,7 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan * @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 { @@ -394,4 +394,8 @@ public class VRichTextArea extends Composite implements Paintable, Field, rta.setTabIndex(index); } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index ca79dcfc44..86f2c7a2de 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -78,7 +78,7 @@ import com.vaadin.ui.Root; * 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)}). diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java index d20ac42812..aeef1951c8 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java @@ -23,6 +23,7 @@ import com.google.gwt.core.ext.typeinfo.TypeOracle; 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; @@ -70,6 +71,8 @@ import com.vaadin.ui.Root; */ public class WidgetMapGenerator extends Generator { + private static String paintableClassName = VPaintableWidget.class.getName(); + private String packageName; private String className; @@ -162,7 +165,7 @@ public class WidgetMapGenerator extends Generator { .iterator(); iterator.hasNext();) { Class class1 = iterator.next(); - Class clientClass = getClientClass(class1); + Class clientClass = getClientClass(class1); if (typeOracle.findType(clientClass.getName()) == null) { // GWT widget not inherited logger.log(Type.WARN, "Widget class " + clientClass.getName() @@ -241,18 +244,18 @@ public class WidgetMapGenerator extends Generator { // 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 classType) {"); + sourceWriter.println("public void ensureInstantiator(Class classType) {"); sourceWriter.println("if(!instmap.containsKey(classType)){"); boolean first = true; ArrayList> lazyLoadedWidgets = new ArrayList>(); - - HashSet> widgetsWithInstantiator = new HashSet>(); - + + HashSet> widgetsWithInstantiator = new HashSet>(); + for (Class class1 : paintablesHavingWidgetAnnotation) { - Class clientClass = getClientClass(class1); - if(widgetsWithInstantiator.contains(clientClass)) { + Class clientClass = getClientClass(class1); + if (widgetsWithInstantiator.contains(clientClass)) { continue; } if (clientClass == VView.class) { @@ -267,7 +270,8 @@ public class WidgetMapGenerator extends Generator { 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); @@ -302,8 +306,8 @@ public class WidgetMapGenerator extends Generator { sourceWriter.println("}"); - sourceWriter - .println("public Class[] getDeferredLoadedWidgets() {"); + sourceWriter.println("public Class[] getDeferredLoadedWidgets() {"); sourceWriter.println("return new Class[] {"); first = true; @@ -313,7 +317,7 @@ public class WidgetMapGenerator extends Generator { } first = false; ClientWidget annotation = class2.getAnnotation(ClientWidget.class); - Class value = annotation + Class value = annotation .value(); sourceWriter.print(value.getName() + ".class"); } @@ -328,11 +332,12 @@ public class WidgetMapGenerator extends Generator { // TODO an index of last ensured widget in array - sourceWriter - .println("public Paintable instantiate(Class classType) {"); + sourceWriter.println("public " + paintableClassName + + " instantiate(Class 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(); @@ -350,14 +355,16 @@ public class WidgetMapGenerator extends Generator { SourceWriter sourceWriter, Collection> paintablesHavingWidgetAnnotation) { sourceWriter - .println("public Class " + .println("public Class " + "getImplementationByServerSideClassName(String fullyQualifiedName) {"); sourceWriter.indent(); sourceWriter .println("fullyQualifiedName = fullyQualifiedName.intern();"); for (Class class1 : paintablesHavingWidgetAnnotation) { - Class clientClass = getClientClass(class1); + Class clientClass = getClientClass(class1); sourceWriter.print("if ( fullyQualifiedName == \""); sourceWriter.print(class1.getName()); sourceWriter.print("\" ) { ensureInstantiator(" @@ -373,9 +380,9 @@ public class WidgetMapGenerator extends Generator { } - private static Class getClientClass( + private static Class getClientClass( Class class1) { - Class clientClass; + Class clientClass; if (Root.class == class1) { clientClass = VView.class; } else { diff --git a/src/com/vaadin/ui/ClientWidget.java b/src/com/vaadin/ui/ClientWidget.java index 8817f8f776..d944e8b3c8 100644 --- a/src/com/vaadin/ui/ClientWidget.java +++ b/src/com/vaadin/ui/ClientWidget.java @@ -11,7 +11,7 @@ import java.lang.annotation.Retention; 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; @@ -36,7 +36,7 @@ public @interface ClientWidget { /** * @return the client side counterpart for the annotated component */ - Class value(); + Class value(); /** * Depending on the used WidgetMap generator, these optional hints may be diff --git a/src/com/vaadin/ui/Label.java b/src/com/vaadin/ui/Label.java index ace1df4f8c..29eb6df766 100644 --- a/src/com/vaadin/ui/Label.java +++ b/src/com/vaadin/ui/Label.java @@ -10,7 +10,7 @@ import com.vaadin.data.Property; 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; /** @@ -38,7 +38,7 @@ 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, diff --git a/tests/testbench/com/vaadin/tests/dd/VMyDragSource.java b/tests/testbench/com/vaadin/tests/dd/VMyDragSource.java index 350ee064f3..eb77bfefd7 100644 --- a/tests/testbench/com/vaadin/tests/dd/VMyDragSource.java +++ b/tests/testbench/com/vaadin/tests/dd/VMyDragSource.java @@ -10,8 +10,9 @@ import com.google.gwt.event.dom.client.MouseOutHandler; 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; @@ -19,7 +20,7 @@ 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; @@ -89,4 +90,8 @@ public class VMyDragSource extends Composite implements Paintable, mDownEvent = null; } + public Widget getWidgetForPaintable() { + return this; + } + } diff --git a/tests/testbench/com/vaadin/tests/dd/VMyDropTarget.java b/tests/testbench/com/vaadin/tests/dd/VMyDropTarget.java index 743cce3095..8efec186cb 100644 --- a/tests/testbench/com/vaadin/tests/dd/VMyDropTarget.java +++ b/tests/testbench/com/vaadin/tests/dd/VMyDropTarget.java @@ -1,15 +1,16 @@ 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; @@ -30,7 +31,7 @@ public class VMyDropTarget extends Composite implements VHasDropHandler, return false; } - public Paintable getPaintable() { + public VPaintableWidget getPaintable() { // Drophandler implemented by Paintable itself return this; } @@ -49,4 +50,8 @@ public class VMyDropTarget extends Composite implements VHasDropHandler, } + public Widget getWidgetForPaintable() { + return this; + } + } -- 2.39.5