summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2012-04-19 11:55:21 +0300
committerArtur Signell <artur@vaadin.com>2012-04-19 11:59:20 +0300
commit8e079ff78720c8c8c7de9671f8924a089a9ad2b4 (patch)
treeb95ce18511fd44c2d09c0ae044c74b34e1af4a6f
parent05b47da0b174531b37d90297bd84579eb3d2a58e (diff)
downloadvaadin-framework-8e079ff78720c8c8c7de9671f8924a089a9ad2b4.tar.gz
vaadin-framework-8e079ff78720c8c8c7de9671f8924a089a9ad2b4.zip
Handled enabled state cascading on client side (#8507)
Now avoids repainting the full hierarchy if the enabled state of a component container changes.
-rw-r--r--src/com/vaadin/terminal/gwt/client/ComponentConnector.java8
-rw-r--r--src/com/vaadin/terminal/gwt/client/ServerConnector.java8
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java17
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java22
-rw-r--r--src/com/vaadin/ui/AbstractComponentContainer.java11
-rw-r--r--tests/testbench/com/vaadin/tests/components/DisableEnableCascade.html86
-rw-r--r--tests/testbench/com/vaadin/tests/components/DisableEnableCascade.java90
7 files changed, 220 insertions, 22 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ComponentConnector.java
index 34f3f13f03..5f9171084e 100644
--- a/src/com/vaadin/terminal/gwt/client/ComponentConnector.java
+++ b/src/com/vaadin/terminal/gwt/client/ComponentConnector.java
@@ -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);
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ServerConnector.java b/src/com/vaadin/terminal/gwt/client/ServerConnector.java
index 559238b512..b331f1f07d 100644
--- a/src/com/vaadin/terminal/gwt/client/ServerConnector.java
+++ b/src/com/vaadin/terminal/gwt/client/ServerConnector.java
@@ -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
*/
diff --git a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java
index a56f5f5525..a68875a7d5 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java
@@ -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();
diff --git a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java
index d6ffc0f091..526631e4b2 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java
@@ -23,6 +23,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
*/
public AbstractComponentContainerConnector() {
@@ -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());
+ }
+ }
}
diff --git a/src/com/vaadin/ui/AbstractComponentContainer.java b/src/com/vaadin/ui/AbstractComponentContainer.java
index b597451a57..e3466e90d3 100644
--- a/src/com/vaadin/ui/AbstractComponentContainer.java
+++ b/src/com/vaadin/ui/AbstractComponentContainer.java
@@ -215,17 +215,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) {
return;
diff --git a/tests/testbench/com/vaadin/tests/components/DisableEnableCascade.html b/tests/testbench/com/vaadin/tests/components/DisableEnableCascade.html
new file mode 100644
index 0000000000..029da64754
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/DisableEnableCascade.html
@@ -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
index 0000000000..aa83ff7a42
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/DisableEnableCascade.java
@@ -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;
+ }
+
+}