]> source.dussan.org Git - vaadin-framework.git/commitdiff
Handled enabled state cascading on client side (#8507)
authorArtur Signell <artur@vaadin.com>
Thu, 19 Apr 2012 08:55:21 +0000 (11:55 +0300)
committerArtur Signell <artur@vaadin.com>
Thu, 19 Apr 2012 08:59:20 +0000 (11:59 +0300)
Now avoids repainting the full hierarchy if the enabled state of a
component container changes.

src/com/vaadin/terminal/gwt/client/ComponentConnector.java
src/com/vaadin/terminal/gwt/client/ServerConnector.java
src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java
src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java
src/com/vaadin/ui/AbstractComponentContainer.java
tests/testbench/com/vaadin/tests/components/DisableEnableCascade.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/DisableEnableCascade.java [new file with mode: 0644]

index 34f3f13f031e14115855aa27d7e9e46d886185cf..5f9171084e1708d047e42e61c5ba57b67ea4f36f 100644 (file)
@@ -119,4 +119,12 @@ public interface ComponentConnector extends ServerConnector {
      */
     public boolean delegateCaptionHandling();
 
+    /**
+     * Sets the enabled state of the widget associated to this connector.
+     * 
+     * @param widgetEnabled
+     *            true if the widget should be enabled, false otherwise
+     */
+    public void setWidgetEnabled(boolean widgetEnabled);
+
 }
index 559238b51235956923a714665522ff67889cd109..b331f1f07d54004ee0bbc70004736ea41fc7430e 100644 (file)
@@ -46,11 +46,9 @@ public interface ServerConnector extends Connector {
     public ApplicationConnection getConnection();
 
     /**
-     * Tests whether the connector is enabled or not. Disabled connectors will
-     * ignore all attempts at communications. Received messages will be
-     * discarded. This method must check that the connector is enabled in
-     * context, that is if it's parent is disabled, this method must return
-     * false.
+     * Tests whether the connector is enabled or not. This method checks that
+     * the connector is enabled in context, i.e. if the parent connector is
+     * disabled, this method must return false.
      * 
      * @return true if the connector is enabled, false otherwise
      */
index a56f5f552526d8691776598b8f5c79c857d3a465..a68875a7d544cf51c1bf2f7980dacc3a8e6b4f9a 100644 (file)
@@ -5,8 +5,8 @@ package com.vaadin.terminal.gwt.client.ui;
 
 import java.util.Set;
 
-import com.google.gwt.user.client.ui.FocusWidget;
 import com.google.gwt.user.client.ui.Focusable;
+import com.google.gwt.user.client.ui.HasEnabled;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
@@ -93,6 +93,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector
 
         }
 
+        setWidgetEnabled(isEnabled());
         /*
          * Disabled state may affect (override) tabindex so the order must be
          * first setting tabindex, then enabled state.
@@ -102,11 +103,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector
                     .getTabIndex());
         }
 
-        if (getWidget() instanceof FocusWidget) {
-            FocusWidget fw = (FocusWidget) getWidget();
-            fw.setEnabled(isEnabled());
-        }
-
         // Style names
         String styleName = getStyleNames(getWidget().getStylePrimaryName());
         getWidget().setStyleName(styleName);
@@ -141,6 +137,15 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         updateComponentSize();
     }
 
+    public void setWidgetEnabled(boolean widgetEnabled) {
+        if (getWidget() instanceof HasEnabled) {
+            HasEnabled hasEnabled = (HasEnabled) getWidget();
+            if (hasEnabled.isEnabled() != widgetEnabled) {
+                hasEnabled.setEnabled(widgetEnabled);
+            }
+        }
+    }
+
     private void updateComponentSize() {
         String newWidth = getState().getWidth();
         String newHeight = getState().getHeight();
index d6ffc0f0915e605d752384169fbf9d2d03e87500..526631e4b2197265fc792f325cc0fdf6c421b3bd 100644 (file)
@@ -22,6 +22,14 @@ public abstract class AbstractComponentContainerConnector extends
 
     private final boolean debugLogging = false;
 
+    /**
+     * Temporary storage for last enabled state to be able to see if it has
+     * changed. Can be removed once we are able to listen specifically for
+     * enabled changes in the state. Widget.isEnabled() cannot be used as all
+     * Widgets do not implement HasEnabled
+     */
+    private boolean lastWidgetEnabledState = true;
+
     /**
      * Default constructor
      */
@@ -85,4 +93,18 @@ public abstract class AbstractComponentContainerConnector extends
                 ConnectorHierarchyChangeEvent.TYPE, handler);
     }
 
+    @Override
+    public void setWidgetEnabled(boolean widgetEnabled) {
+        if (lastWidgetEnabledState == widgetEnabled) {
+            return;
+        }
+        lastWidgetEnabledState = widgetEnabled;
+
+        super.setWidgetEnabled(widgetEnabled);
+        for (ComponentConnector c : getChildren()) {
+            // Update children as they might be affected by the enabled state of
+            // their parent
+            c.setWidgetEnabled(c.isEnabled());
+        }
+    }
 }
index b597451a57547c0e1a35724e40a30791a5b65b31..e3466e90d34c66a3e89aeb04e15cff71abddc220 100644 (file)
@@ -214,17 +214,6 @@ public abstract class AbstractComponentContainer extends AbstractComponent
         }
     }
 
-    @Override
-    public void setEnabled(boolean enabled) {
-        super.setEnabled(enabled);
-        if (getParent() != null && !getParent().isEnabled()) {
-            // some ancestor still disabled, don't update children
-            return;
-        } else {
-            requestRepaintAll();
-        }
-    }
-
     @Override
     public void setVisible(boolean visible) {
         if (getState().isVisible() == visible) {
diff --git a/tests/testbench/com/vaadin/tests/components/DisableEnableCascade.html b/tests/testbench/com/vaadin/tests/components/DisableEnableCascade.html
new file mode 100644 (file)
index 0000000..029da64
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>DisableEnableCascade</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">DisableEnableCascade</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.DisableEnableCascade?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsDisableEnableCascade::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>panel-disabled</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsDisableEnableCascade::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsDisableEnableCascade::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>tabsheet-disabled</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsDisableEnableCascade::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>all-enabled</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsDisableEnableCascade::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[2]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsDisableEnableCascade::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>tabsheet-button-disabled</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsDisableEnableCascade::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[2]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsDisableEnableCascade::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>all-enabled2</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/DisableEnableCascade.java b/tests/testbench/com/vaadin/tests/components/DisableEnableCascade.java
new file mode 100644 (file)
index 0000000..aa83ff7
--- /dev/null
@@ -0,0 +1,90 @@
+package com.vaadin.tests.components;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.TabSheet;
+
+public class DisableEnableCascade extends TestBase {
+
+    private Panel outerPanel;
+    private TabSheet innerTabsheet;
+    private Button button;
+    private Button enableDisablePanelButton;
+    private Button enableDisableTabSheetButton;
+    private Button enableDisableButtonButton;
+
+    @Override
+    protected void setup() {
+
+        outerPanel = new Panel("Outer panel, enabled");
+        innerTabsheet = new TabSheet();
+        innerTabsheet.setCaption("Inner Tabsheet, enabled");
+
+        button = new Button("Button, enabled");
+
+        outerPanel.setContent(innerTabsheet);
+        innerTabsheet.addTab(button, "Tab containing button");
+
+        addComponent(outerPanel);
+
+        enableDisablePanelButton = new Button("Disable panel",
+                new ClickListener() {
+
+                    public void buttonClick(ClickEvent event) {
+                        enableDisable(outerPanel, enableDisablePanelButton);
+
+                    }
+                });
+
+        enableDisableTabSheetButton = new Button("Disable TabSheet",
+                new ClickListener() {
+
+                    public void buttonClick(ClickEvent event) {
+                        enableDisable(innerTabsheet,
+                                enableDisableTabSheetButton);
+
+                    }
+                });
+
+        enableDisableButtonButton = new Button("Disable Button",
+                new ClickListener() {
+
+                    public void buttonClick(ClickEvent event) {
+                        enableDisable(button, enableDisableButtonButton);
+
+                    }
+                });
+
+        addComponent(enableDisablePanelButton);
+        addComponent(enableDisableTabSheetButton);
+        addComponent(enableDisableButtonButton);
+    }
+
+    protected void enableDisable(Component target, Button button) {
+        if (target.isEnabled()) {
+            target.setEnabled(false);
+            button.setCaption(button.getCaption().replace("Disable", "Enable"));
+            target.setCaption(target.getCaption()
+                    .replace("enabled", "disabled"));
+        } else {
+            target.setEnabled(true);
+            button.setCaption(button.getCaption().replace("Enable", "Disable"));
+            target.setCaption(target.getCaption()
+                    .replace("disabled", "enabled"));
+        }
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Tests the disable state is cascaded correctly to children. Disabling a parent should disabled its children aswell. The buttons only toggle the state of the target component.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 8507;
+    }
+
+}