Now avoids repainting the full hierarchy if the enabled state of a component container changes.tags/7.0.0.alpha2
*/ | */ | ||||
public boolean delegateCaptionHandling(); | 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); | |||||
} | } |
public ApplicationConnection getConnection(); | 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 | * @return true if the connector is enabled, false otherwise | ||||
*/ | */ |
import java.util.Set; | 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.Focusable; | ||||
import com.google.gwt.user.client.ui.HasEnabled; | |||||
import com.google.gwt.user.client.ui.Widget; | import com.google.gwt.user.client.ui.Widget; | ||||
import com.vaadin.terminal.gwt.client.ApplicationConnection; | import com.vaadin.terminal.gwt.client.ApplicationConnection; | ||||
import com.vaadin.terminal.gwt.client.ComponentConnector; | import com.vaadin.terminal.gwt.client.ComponentConnector; | ||||
} | } | ||||
setWidgetEnabled(isEnabled()); | |||||
/* | /* | ||||
* Disabled state may affect (override) tabindex so the order must be | * Disabled state may affect (override) tabindex so the order must be | ||||
* first setting tabindex, then enabled state. | * first setting tabindex, then enabled state. | ||||
.getTabIndex()); | .getTabIndex()); | ||||
} | } | ||||
if (getWidget() instanceof FocusWidget) { | |||||
FocusWidget fw = (FocusWidget) getWidget(); | |||||
fw.setEnabled(isEnabled()); | |||||
} | |||||
// Style names | // Style names | ||||
String styleName = getStyleNames(getWidget().getStylePrimaryName()); | String styleName = getStyleNames(getWidget().getStylePrimaryName()); | ||||
getWidget().setStyleName(styleName); | getWidget().setStyleName(styleName); | ||||
updateComponentSize(); | updateComponentSize(); | ||||
} | } | ||||
public void setWidgetEnabled(boolean widgetEnabled) { | |||||
if (getWidget() instanceof HasEnabled) { | |||||
HasEnabled hasEnabled = (HasEnabled) getWidget(); | |||||
if (hasEnabled.isEnabled() != widgetEnabled) { | |||||
hasEnabled.setEnabled(widgetEnabled); | |||||
} | |||||
} | |||||
} | |||||
private void updateComponentSize() { | private void updateComponentSize() { | ||||
String newWidth = getState().getWidth(); | String newWidth = getState().getWidth(); | ||||
String newHeight = getState().getHeight(); | String newHeight = getState().getHeight(); |
private final boolean debugLogging = false; | 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 | * Default constructor | ||||
*/ | */ | ||||
ConnectorHierarchyChangeEvent.TYPE, handler); | 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()); | |||||
} | |||||
} | |||||
} | } |
} | } | ||||
} | } | ||||
@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 | @Override | ||||
public void setVisible(boolean visible) { | public void setVisible(boolean visible) { | ||||
if (getState().isVisible() == visible) { | if (getState().isVisible() == visible) { |
<?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> |
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; | |||||
} | |||||
} |