blob: 0cd6eae8d4efbe50e084984d9536f4ad6032628d [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.painter.cell;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.layer.event.CellVisualChangeEvent;
import org.eclipse.nebula.widgets.nattable.painter.cell.decorator.BeveledBorderDecorator;
import org.eclipse.nebula.widgets.nattable.ui.NatEventData;
import org.eclipse.nebula.widgets.nattable.ui.action.IMouseAction;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
/**
* Paints a button and simulates a button click. It also notifies its listeners
* when it is clicked.
*/
public class ButtonCellPainter extends AbstractCellPainter implements
IMouseAction {
private final ICellPainter buttonRaisedPainter;
private final ICellPainter buttonPressedPainter;
private int buttonFlashTime = 150;
private int columnPosClicked;
private int rowPosClicked;
private boolean recentlyClicked;
private final List<IMouseAction> clickLiseners = new ArrayList<>();
/**
* @param interiorPainter
* to paint the contents of the cell. This will be decorated with
* a button like look and feel.
*/
public ButtonCellPainter(ICellPainter interiorPainter) {
this.buttonPressedPainter = new BeveledBorderDecorator(interiorPainter,
false);
this.buttonRaisedPainter = new BeveledBorderDecorator(interiorPainter);
}
/**
* @param buttonRaisedPainter
* cell painter to use for painting the button raised state.
* @param buttonPressedPainter
* cell painter to use for painting the button pressed state.
*/
public ButtonCellPainter(ICellPainter buttonRaisedPainter,
ICellPainter buttonPressedPainter) {
this.buttonRaisedPainter = buttonRaisedPainter;
this.buttonPressedPainter = buttonPressedPainter;
}
@Override
public void paintCell(final ILayerCell cell, final GC gc,
final Rectangle bounds, final IConfigRegistry configRegistry) {
if (this.recentlyClicked && this.columnPosClicked == cell.getColumnPosition()
&& this.rowPosClicked == cell.getRowPosition()) {
this.buttonPressedPainter.paintCell(cell, gc, bounds, configRegistry);
} else {
this.buttonRaisedPainter.paintCell(cell, gc, bounds, configRegistry);
}
}
@Override
public int getPreferredHeight(ILayerCell cell, GC gc,
IConfigRegistry configRegistry) {
return cell.getBounds().height;
}
@Override
public int getPreferredWidth(ILayerCell cell, GC gc,
IConfigRegistry configRegistry) {
return cell.getBounds().width;
}
private TimerTask getButtonFlashTimerTask(final ILayer layer) {
return new TimerTask() {
@Override
public void run() {
ButtonCellPainter.this.recentlyClicked = false;
Display.getDefault().asyncExec(() -> layer.fireLayerEvent(new CellVisualChangeEvent(layer,
ButtonCellPainter.this.columnPosClicked, ButtonCellPainter.this.rowPosClicked)));
}
};
}
/**
* Respond to mouse click. Simulate button press.
*/
@Override
public void run(final NatTable natTable, MouseEvent event) {
NatEventData eventData = (NatEventData) event.data;
this.columnPosClicked = eventData.getColumnPosition();
this.rowPosClicked = eventData.getRowPosition();
this.recentlyClicked = true;
new Timer()
.schedule(getButtonFlashTimerTask(natTable), this.buttonFlashTime);
natTable.fireLayerEvent(new CellVisualChangeEvent(natTable,
this.columnPosClicked, this.rowPosClicked));
for (IMouseAction listener : this.clickLiseners) {
listener.run(natTable, event);
}
}
public void addClickListener(IMouseAction mouseAction) {
this.clickLiseners.add(mouseAction);
}
public void removeClickListener(IMouseAction mouseAction) {
this.clickLiseners.remove(mouseAction);
}
public void setButtonFlashTime(int flashTimeInMS) {
this.buttonFlashTime = flashTimeInMS;
}
}