/*******************************************************************************
* Copyright (c) 2012, 2016 Original authors and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Original authors and others - initial API and implementation
* Dirk Fauth <dirk.fauth@googlemail.com - Bug 449764
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.resize.mode;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.painter.IOverlayPainter;
import org.eclipse.nebula.widgets.nattable.resize.command.RowResizeCommand;
import org.eclipse.nebula.widgets.nattable.ui.action.IDragMode;
import org.eclipse.nebula.widgets.nattable.ui.util.CellEdgeDetectUtil;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
/**
* Drag mode that will implement the row resizing process.
*/
public class RowResizeDragMode implements IDragMode {
private static final int DEFAULT_ROW_HEIGHT_MINIMUM = 18;
protected int gridRowPositionToResize;
protected int originalRowHeight;
protected int startY;
protected int currentY;
protected int lastY = -1;
protected int gridRowStartY;
protected boolean checkMinimumWidth = true;
protected final IOverlayPainter overlayPainter = new RowResizeOverlayPainter();
@Override
public void mouseDown(NatTable natTable, MouseEvent event) {
natTable.forceFocus();
this.gridRowPositionToResize =
CellEdgeDetectUtil.getRowPositionToResize(natTable, new Point(event.x, event.y));
if (this.gridRowPositionToResize > 0) {
this.gridRowStartY = natTable.getStartYOfRowPosition(this.gridRowPositionToResize);
this.originalRowHeight = natTable.getRowHeightByPosition(this.gridRowPositionToResize);
this.startY = event.y;
natTable.addOverlayPainter(this.overlayPainter);
}
}
@Override
public void mouseMove(NatTable natTable, MouseEvent event) {
this.currentY = event.y;
// redraw the space after the bottom of the last row
// to be able to render the resize drag indicator
natTable.repaintVerticalLeftOver();
if (this.checkMinimumWidth
&& this.currentY < this.gridRowStartY + getRowHeightMinimum()) {
this.currentY = this.gridRowStartY + getRowHeightMinimum();
} else {
int overlayExtent = RowResizeOverlayPainter.ROW_RESIZE_OVERLAY_HEIGHT / 2;
Set<Integer> rowsToRepaint = new HashSet<Integer>();
rowsToRepaint.add(natTable.getRowPositionByY(this.currentY - overlayExtent));
rowsToRepaint.add(natTable.getRowPositionByY(this.currentY + overlayExtent));
if (this.lastY >= 0) {
rowsToRepaint.add(natTable.getRowPositionByY(this.lastY - overlayExtent));
rowsToRepaint.add(natTable.getRowPositionByY(this.lastY + overlayExtent));
}
for (Integer rowToRepaint : rowsToRepaint) {
natTable.repaintRow(rowToRepaint.intValue());
}
this.lastY = this.currentY;
}
}
@Override
public void mouseUp(NatTable natTable, MouseEvent event) {
natTable.removeOverlayPainter(this.overlayPainter);
updateRowHeight(natTable, event);
}
private void updateRowHeight(ILayer natLayer, MouseEvent e) {
int dragHeight = e.y - this.startY;
int newRowHeight = this.originalRowHeight + dragHeight;
if (newRowHeight < getRowHeightMinimum()) {
newRowHeight = getRowHeightMinimum();
}
natLayer.doCommand(
new RowResizeCommand(
natLayer,
this.gridRowPositionToResize,
GUIHelper.convertHorizontalDpiToPixel(newRowHeight)));
}
// XXX: should ask the layer for its minimum row height
public int getRowHeightMinimum() {
return DEFAULT_ROW_HEIGHT_MINIMUM;
}
private class RowResizeOverlayPainter implements IOverlayPainter {
static final int ROW_RESIZE_OVERLAY_HEIGHT = 2;
@Override
public void paintOverlay(GC gc, ILayer layer) {
Color originalBackgroundColor = gc.getBackground();
gc.setBackground(GUIHelper.COLOR_DARK_GRAY);
gc.fillRectangle(0, RowResizeDragMode.this.currentY - (ROW_RESIZE_OVERLAY_HEIGHT / 2),
layer.getWidth(), ROW_RESIZE_OVERLAY_HEIGHT);
gc.setBackground(originalBackgroundColor);
}
}
}