This patch also adds body cell click selecting to single selection model to test this feature. Change-Id: I06819799c97457dc0e7bd38dd5855eb33ba91943tags/7.4.0.beta1
@@ -38,6 +38,7 @@ import com.google.gwt.dom.client.TableRowElement; | |||
import com.google.gwt.dom.client.Touch; | |||
import com.google.gwt.event.dom.client.KeyCodes; | |||
import com.google.gwt.event.dom.client.KeyEvent; | |||
import com.google.gwt.event.dom.client.MouseEvent; | |||
import com.google.gwt.event.logical.shared.ValueChangeEvent; | |||
import com.google.gwt.event.logical.shared.ValueChangeHandler; | |||
import com.google.gwt.event.shared.HandlerRegistration; | |||
@@ -55,15 +56,20 @@ import com.vaadin.client.data.DataSource; | |||
import com.vaadin.client.ui.SubPartAware; | |||
import com.vaadin.client.ui.grid.EditorRow.State; | |||
import com.vaadin.client.ui.grid.events.AbstractGridKeyEventHandler; | |||
import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler; | |||
import com.vaadin.client.ui.grid.events.BodyClickHandler; | |||
import com.vaadin.client.ui.grid.events.BodyKeyDownHandler; | |||
import com.vaadin.client.ui.grid.events.BodyKeyPressHandler; | |||
import com.vaadin.client.ui.grid.events.BodyKeyUpHandler; | |||
import com.vaadin.client.ui.grid.events.FooterClickHandler; | |||
import com.vaadin.client.ui.grid.events.FooterKeyDownHandler; | |||
import com.vaadin.client.ui.grid.events.FooterKeyPressHandler; | |||
import com.vaadin.client.ui.grid.events.FooterKeyUpHandler; | |||
import com.vaadin.client.ui.grid.events.GridClickEvent; | |||
import com.vaadin.client.ui.grid.events.GridKeyDownEvent; | |||
import com.vaadin.client.ui.grid.events.GridKeyPressEvent; | |||
import com.vaadin.client.ui.grid.events.GridKeyUpEvent; | |||
import com.vaadin.client.ui.grid.events.HeaderClickHandler; | |||
import com.vaadin.client.ui.grid.events.HeaderKeyDownHandler; | |||
import com.vaadin.client.ui.grid.events.HeaderKeyPressHandler; | |||
import com.vaadin.client.ui.grid.events.HeaderKeyUpHandler; | |||
@@ -919,7 +925,7 @@ public class Grid<T> extends ResizeComposite implements | |||
extends KeyEvent<HANDLER> { | |||
/** | |||
* Enum describing different section of Grid. | |||
* Enum describing different sections of Grid. | |||
*/ | |||
public enum GridSection { | |||
HEADER, BODY, FOOTER | |||
@@ -973,7 +979,91 @@ public class Grid<T> extends ResizeComposite implements | |||
} | |||
} | |||
protected abstract void doDispatch(HANDLER handler, GridSection seciton); | |||
protected abstract void doDispatch(HANDLER handler, GridSection section); | |||
@Override | |||
public Type<HANDLER> getAssociatedType() { | |||
return associatedType; | |||
} | |||
} | |||
public static abstract class AbstractGridMouseEvent<HANDLER extends AbstractGridMouseEventHandler> | |||
extends MouseEvent<HANDLER> { | |||
/** | |||
* Enum describing different sections of Grid. | |||
*/ | |||
public enum GridSection { | |||
HEADER, BODY, FOOTER | |||
} | |||
private Grid<?> grid; | |||
protected Cell targetCell; | |||
private final Type<HANDLER> associatedType = new Type<HANDLER>( | |||
getBrowserEventType(), this); | |||
public AbstractGridMouseEvent(Grid<?> grid) { | |||
this.grid = grid; | |||
} | |||
protected abstract String getBrowserEventType(); | |||
/** | |||
* Gets the Grid instance for this event. | |||
* | |||
* @return grid | |||
*/ | |||
public Grid<?> getGrid() { | |||
return grid; | |||
} | |||
/** | |||
* Gets the target cell for this event. | |||
* | |||
* @return target cell | |||
*/ | |||
public Cell getTargetCell() { | |||
return targetCell; | |||
} | |||
@Override | |||
protected void dispatch(HANDLER handler) { | |||
EventTarget target = getNativeEvent().getEventTarget(); | |||
if (!Element.is(target)) { | |||
// Target is not an element | |||
return; | |||
} | |||
Element targetElement = Element.as(target); | |||
if (grid.isElementInChildWidget(targetElement)) { | |||
// Target is some widget inside of Grid | |||
return; | |||
} | |||
final RowContainer container = grid.escalator | |||
.findRowContainer(targetElement); | |||
if (container == null) { | |||
// No container for given element | |||
return; | |||
} | |||
targetCell = container.getCell(targetElement); | |||
if (targetCell == null) { | |||
// Is not a cell in given container. | |||
return; | |||
} | |||
GridSection section = GridSection.FOOTER; | |||
if (container == grid.escalator.getHeader()) { | |||
section = GridSection.HEADER; | |||
} else if (container == grid.escalator.getBody()) { | |||
section = GridSection.BODY; | |||
} | |||
doDispatch(handler, section); | |||
} | |||
protected abstract void doDispatch(HANDLER handler, GridSection section); | |||
@Override | |||
public Type<HANDLER> getAssociatedType() { | |||
@@ -986,6 +1076,7 @@ public class Grid<T> extends ResizeComposite implements | |||
private GridKeyDownEvent keyDown = new GridKeyDownEvent(this); | |||
private GridKeyUpEvent keyUp = new GridKeyUpEvent(this); | |||
private GridKeyPressEvent keyPress = new GridKeyPressEvent(this); | |||
private GridClickEvent clickEvent = new GridClickEvent(this); | |||
private class CellFocusHandler { | |||
@@ -3415,7 +3506,7 @@ public class Grid<T> extends ResizeComposite implements | |||
return; | |||
} | |||
// Fire GridKeyEvents and pass the event to escalator. | |||
// Fire GridKeyEvents and GridClickEvents. Pass the event to escalator. | |||
super.onBrowserEvent(event); | |||
if (!isElementInChildWidget(e)) { | |||
@@ -4212,6 +4303,42 @@ public class Grid<T> extends ResizeComposite implements | |||
return addHandler(handler, keyPress.getAssociatedType()); | |||
} | |||
/** | |||
* Register a BodyClickHandler to this Grid. The event for this handler is | |||
* fired when a Click event occurs in the Body of this Grid. | |||
* | |||
* @param handler | |||
* the click handler to register | |||
* @return the registration for the event | |||
*/ | |||
public HandlerRegistration addBodyClickHandler(BodyClickHandler handler) { | |||
return addHandler(handler, clickEvent.getAssociatedType()); | |||
} | |||
/** | |||
* Register a HeaderClickHandler to this Grid. The event for this handler is | |||
* fired when a Click event occurs in the Header of this Grid. | |||
* | |||
* @param handler | |||
* the click handler to register | |||
* @return the registration for the event | |||
*/ | |||
public HandlerRegistration addHeaderClickHandler(HeaderClickHandler handler) { | |||
return addHandler(handler, clickEvent.getAssociatedType()); | |||
} | |||
/** | |||
* Register a FooterClickHandler to this Grid. The event for this handler is | |||
* fired when a Click event occurs in the Footer of this Grid. | |||
* | |||
* @param handler | |||
* the click handler to register | |||
* @return the registration for the event | |||
*/ | |||
public HandlerRegistration addFooterClickHandler(FooterClickHandler handler) { | |||
return addHandler(handler, clickEvent.getAssociatedType()); | |||
} | |||
/** | |||
* Apply sorting to data source. | |||
*/ |
@@ -0,0 +1,34 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.client.ui.grid.events; | |||
import com.google.gwt.event.shared.EventHandler; | |||
import com.vaadin.client.ui.grid.Grid.AbstractGridMouseEvent; | |||
/** | |||
* Base interface of all handlers for {@link AbstractGridMouseEvent}s. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
*/ | |||
public abstract interface AbstractGridMouseEventHandler extends EventHandler { | |||
public abstract interface GridClickHandler extends | |||
AbstractGridMouseEventHandler { | |||
public void onClick(GridClickEvent event); | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.client.ui.grid.events; | |||
import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler.GridClickHandler; | |||
/** | |||
* Handler for {@link GridClickEvent}s that happen in the body of the Grid. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
*/ | |||
public interface BodyClickHandler extends GridClickHandler { | |||
} |
@@ -0,0 +1,28 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.client.ui.grid.events; | |||
import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler.GridClickHandler; | |||
/** | |||
* Handler for {@link GridClickEvent}s that happen in the footer of the Grid. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
*/ | |||
public interface FooterClickHandler extends GridClickHandler { | |||
} |
@@ -0,0 +1,48 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.client.ui.grid.events; | |||
import com.google.gwt.dom.client.BrowserEvents; | |||
import com.vaadin.client.ui.grid.Grid; | |||
import com.vaadin.client.ui.grid.Grid.AbstractGridMouseEvent; | |||
import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler.GridClickHandler; | |||
/** | |||
* Represents native mouse click event in Grid. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
*/ | |||
public class GridClickEvent extends AbstractGridMouseEvent<GridClickHandler> { | |||
public GridClickEvent(Grid<?> grid) { | |||
super(grid); | |||
} | |||
@Override | |||
protected String getBrowserEventType() { | |||
return BrowserEvents.CLICK; | |||
} | |||
@Override | |||
protected void doDispatch(GridClickHandler handler, GridSection section) { | |||
if ((section == GridSection.BODY && handler instanceof BodyClickHandler) | |||
|| (section == GridSection.HEADER && handler instanceof HeaderClickHandler) | |||
|| (section == GridSection.FOOTER && handler instanceof FooterClickHandler)) { | |||
handler.onClick(this); | |||
} | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.client.ui.grid.events; | |||
import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler.GridClickHandler; | |||
/** | |||
* Handler for {@link GridClickEvent}s that happen in the header of the Grid. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
*/ | |||
public interface HeaderClickHandler extends GridClickHandler { | |||
} |
@@ -0,0 +1,63 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.client.ui.grid.selection; | |||
import com.google.gwt.event.shared.HandlerRegistration; | |||
import com.vaadin.client.ui.grid.Grid; | |||
import com.vaadin.client.ui.grid.events.BodyClickHandler; | |||
import com.vaadin.client.ui.grid.events.GridClickEvent; | |||
/** | |||
* Generic class to perform selections when clicking on cells in body of Grid. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
*/ | |||
public class ClickSelectHandler<T> { | |||
private Grid<T> grid; | |||
private HandlerRegistration clickHandler; | |||
private class RowClickHandler implements BodyClickHandler { | |||
@Override | |||
public void onClick(GridClickEvent event) { | |||
T row = grid.getDataSource().getRow(event.getTargetCell().getRow()); | |||
if (!grid.isSelected(row)) { | |||
grid.select(row); | |||
} | |||
} | |||
} | |||
/** | |||
* Constructor for ClickSelectHandler. This constructor will add all | |||
* necessary handlers for selecting rows by clicking cells. | |||
* | |||
* @param grid | |||
* grid to attach to | |||
*/ | |||
public ClickSelectHandler(Grid<T> grid) { | |||
this.grid = grid; | |||
clickHandler = grid.addBodyClickHandler(new RowClickHandler()); | |||
} | |||
/** | |||
* Clean up function for removing all now obsolete handlers. | |||
*/ | |||
public void removeHandler() { | |||
clickHandler.removeHandler(); | |||
} | |||
} |
@@ -33,9 +33,13 @@ public class SelectionModelSingle<T> extends AbstractRowHandleSelectionModel<T> | |||
private Grid<T> grid; | |||
private RowHandle<T> selectedRow; | |||
/** Event handling for selection with space key */ | |||
private SpaceSelectHandler<T> spaceSelectHandler; | |||
/** Event handling for selection by clicking cells */ | |||
private ClickSelectHandler<T> clickSelectHandler; | |||
@Override | |||
public boolean isSelected(T row) { | |||
return selectedRow != null | |||
@@ -61,9 +65,12 @@ public class SelectionModelSingle<T> extends AbstractRowHandleSelectionModel<T> | |||
this.grid = grid; | |||
if (this.grid != null) { | |||
spaceSelectHandler = new SpaceSelectHandler<T>(grid); | |||
clickSelectHandler = new ClickSelectHandler<T>(grid); | |||
} else { | |||
spaceSelectHandler.removeHandler(); | |||
clickSelectHandler.removeHandler(); | |||
spaceSelectHandler = null; | |||
clickSelectHandler = null; | |||
} | |||
} | |||
@@ -114,13 +114,13 @@ public class GridSelectionTest extends GridBasicFeaturesTest { | |||
grid.getCell(5, 0).click(); | |||
assertTrue("Fifth row was not selected.", getRow(5).isSelected()); | |||
assertFalse("First row was still selected.", getRow(0).isSelected()); | |||
grid.getCell(0, 0).click(); | |||
grid.getCell(0, 6).click(); | |||
toggleFirstRowSelection(); | |||
assertFalse("First row was still selected.", getRow(0).isSelected()); | |||
assertFalse("Fifth row was still selected.", getRow(5).isSelected()); | |||
grid.scrollToRow(600); | |||
grid.getCell(595, 0).click(); | |||
grid.getCell(595, 3).click(); | |||
assertTrue("Row 595 was not selected.", getRow(595).isSelected()); | |||
toggleFirstRowSelection(); | |||
assertFalse("Row 595 was still selected.", getRow(595).isSelected()); | |||
@@ -159,21 +159,25 @@ public class GridSelectionTest extends GridBasicFeaturesTest { | |||
GridElement grid = getGridElement(); | |||
grid.getCell(3, 1).click(); | |||
assertTrue("Grid row 3 was not selected with clicking.", grid.getRow(3) | |||
.isSelected()); | |||
new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); | |||
assertTrue("Grid row 3 was not selected with space key.", grid | |||
assertTrue("Grid row 3 was not deselected with space key.", !grid | |||
.getRow(3).isSelected()); | |||
new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); | |||
assertTrue("Grid row 3 was not deselected with space key.", !grid | |||
assertTrue("Grid row 3 was not selected with space key.", grid | |||
.getRow(3).isSelected()); | |||
grid.scrollToRow(500); | |||
new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); | |||
assertTrue("Grid row 3 was not selected with space key.", grid | |||
assertTrue("Grid row 3 was not deselected with space key.", !grid | |||
.getRow(3).isSelected()); | |||
} | |||