blob: b3acc9ea3e6e4f4a957af8ee27005621b059dff1 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 2021 Original NatTable 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 NatTable authors and others - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ecommons.waltable.painter.cell;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Display;
import org.eclipse.statet.ecommons.waltable.NatTable;
import org.eclipse.statet.ecommons.waltable.config.IConfigRegistry;
import org.eclipse.statet.ecommons.waltable.coordinate.LRectangle;
import org.eclipse.statet.ecommons.waltable.layer.ILayer;
import org.eclipse.statet.ecommons.waltable.layer.cell.ILayerCell;
import org.eclipse.statet.ecommons.waltable.layer.event.CellVisualChangeEvent;
import org.eclipse.statet.ecommons.waltable.painter.cell.decorator.BeveledBorderDecorator;
import org.eclipse.statet.ecommons.waltable.ui.NatEventData;
import org.eclipse.statet.ecommons.waltable.ui.action.IMouseAction;
/**
* 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 long columnPosClicked;
private long 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(final 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(final ICellPainter buttonRaisedPainter, final ICellPainter buttonPressedPainter) {
this.buttonRaisedPainter= buttonRaisedPainter;
this.buttonPressedPainter= buttonPressedPainter;
}
@Override
public void paintCell(final ILayerCell cell, final GC gc, final LRectangle 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 long getPreferredHeight(final ILayerCell cell, final GC gc, final IConfigRegistry configRegistry) {
return cell.getBounds().height;
}
@Override
public long getPreferredWidth(final ILayerCell cell, final GC gc, final 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(new Runnable() {
@Override
public void run() {
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, final MouseEvent event) {
final 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 (final IMouseAction listener : this.clickLiseners) {
listener.run(natTable, event);
}
}
public void addClickListener(final IMouseAction mouseAction){
this.clickLiseners.add(mouseAction);
}
public void removeClickListener(final IMouseAction mouseAction){
this.clickLiseners.remove(mouseAction);
}
public void setButtonFlashTime(final int flashTimeInMS) {
this.buttonFlashTime= flashTimeInMS;
}
}