blob: 03d891e79d43f1cad22c4df5a0542eafd4eaeed9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2020 Original authors and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Original authors and others - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.ui.matcher;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
/**
* Matches a mouse click on an {@link ICellPainter} within a cell in a specified
* region.
*/
public class CellPainterMouseEventMatcher extends MouseEventMatcher {
private ICellPainter targetCellPainter;
private Class<? extends ICellPainter> targetCellPainterClass;
/**
* Creates a {@link CellPainterMouseEventMatcher} for a given region name,
* mouse button and a specific target cellPainter instance. Can be used in
* case one single painter instance is registered that should be checked
* for.
*
* @param regionName
* The name of the region where this matcher should react on.
* Typically a {@link GridRegion} if a default grid is used. Can
* also be another value in case a custom region label is defined
* in a custom composition.
* @param button
* The mouse button this matcher should react on, e.g.
* {@link MouseEventMatcher#LEFT_BUTTON} and
* {@link MouseEventMatcher#RIGHT_BUTTON}
* @param targetCellPainter
* The {@link ICellPainter} instance that should be used for the
* check.
*/
public CellPainterMouseEventMatcher(String regionName, int button, ICellPainter targetCellPainter) {
super(regionName, button);
this.targetCellPainter = targetCellPainter;
}
/**
* Creates a {@link CellPainterMouseEventMatcher} for a given region name,
* mouse button and a target cellPainter class. Can be used in case every
* instance of a painter should be treated the same way, e.g. checkboxes.
*
* @param regionName
* The name of the region where this matcher should react on.
* Typically a {@link GridRegion} if a default grid is used. Can
* also be another value in case a custom region label is defined
* in a custom composition.
* @param button
* The mouse button this matcher should react on, e.g.
* {@link MouseEventMatcher#LEFT_BUTTON} and
* {@link MouseEventMatcher#RIGHT_BUTTON}
* @param targetCellPainterClass
* The concrete type of the {@link ICellPainter} that should be
* used for the check.
*/
public CellPainterMouseEventMatcher(String regionName, int button, Class<? extends ICellPainter> targetCellPainterClass) {
super(regionName, button);
this.targetCellPainterClass = targetCellPainterClass;
}
@Override
public boolean matches(NatTable natTable, MouseEvent event, LabelStack regionLabels) {
if (super.matches(natTable, event, regionLabels)) {
int columnPosition = natTable.getColumnPositionByX(event.x);
int rowPosition = natTable.getRowPositionByY(event.y);
ILayerCell cell = natTable.getCellByPosition(columnPosition, rowPosition);
// Bug 407598: only perform a check if the click in the body region
// was performed on a cell
// cell == null can happen if the viewport is quite large and
// contains not enough cells to fill it.
if (cell != null) {
IConfigRegistry configRegistry = natTable.getConfigRegistry();
ICellPainter cellPainter = cell.getLayer().getCellPainter(
columnPosition,
rowPosition,
cell,
configRegistry);
GC gc = new GC(natTable.getDisplay());
try {
Rectangle adjustedCellBounds = natTable.getLayerPainter().adjustCellBounds(
columnPosition,
rowPosition,
cell.getBounds());
ICellPainter clickedCellPainter = cellPainter.getCellPainterAt(
event.x,
event.y,
cell,
gc,
adjustedCellBounds,
configRegistry);
if (clickedCellPainter != null) {
if ((this.targetCellPainter != null && this.targetCellPainter == clickedCellPainter)
|| (this.targetCellPainterClass != null && this.targetCellPainterClass.isInstance(clickedCellPainter))) {
return true;
}
}
} finally {
gc.dispose();
}
}
}
return false;
}
}