blob: b964b8a7977d637d08e005657f0b375a3e1a8e9c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2010 Wind River Systems, Inc. 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
*******************************************************************************/
package com.google.eclipse.elt.emulator.textcanvas;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
/**
* A Grid based Canvas. The canvas has rows and columns. CellPainting is done with the abstract method drawCell
*/
public abstract class GridCanvas extends VirtualCanvas {
private int cellWidth;
private int cellHeight;
public GridCanvas(Composite parent, int style) {
super(parent, style);
addListener(SWT.MouseWheel, new Listener() {
@Override public void handleEvent(Event event) {
if (getVerticalBar().isVisible()) {
int delta = -cellHeight;
if (event.count < 0) {
delta = -delta;
}
scrollYDelta(delta);
}
event.doit = false;
}
});
}
@Override protected void paint(GC gc) {
Rectangle clipping = gc.getClipping();
if (clipping.width == 0 || clipping.height == 0) {
return;
}
Rectangle clientArea = getScreenRectInVirtualSpace();
// Beginning coordinates.
int xOffset = clientArea.x;
int yOffset = clientArea.y;
int colFirst = virtualXToCell(xOffset + clipping.x);
if (colFirst > getCols()) {
colFirst = getCols();
} else if (colFirst < 0) {
colFirst = 0;
}
int rowFirst = virtualYToCell(yOffset + clipping.y);
// End coordinates.
int colLast = virtualXToCell(xOffset + clipping.x + clipping.width + cellWidth);
if (colLast > getCols()) {
colLast = getCols();
}
int rowLast = virtualYToCell(yOffset + clipping.y + clipping.height + cellHeight);
if (rowLast > getRows()) {
rowLast = getRows();
}
// Draw the cells.
for (int row = rowFirst; row <= rowLast; row++) {
int cx = colFirst * cellWidth - xOffset;
int cy = row * cellHeight - yOffset;
drawLine(gc, row, cx, cy, colFirst, colLast);
}
paintUnoccupiedSpace(gc, clipping);
}
abstract void drawLine(GC gc, int row, int x, int y, int colFirst, int colLast);
abstract protected int getRows();
abstract protected int getCols();
protected void setCellWidth(int cellWidth) {
this.cellWidth = cellWidth;
getHorizontalBar().setIncrement(this.cellWidth);
}
public int getCellWidth() {
return cellWidth;
}
protected void setCellHeight(int cellHeight) {
this.cellHeight = cellHeight;
getVerticalBar().setIncrement(this.cellHeight);
}
public int getCellHeight() {
return cellHeight;
}
int virtualXToCell(int x) {
return x / cellWidth;
}
int virtualYToCell(int y) {
return y / cellHeight;
}
protected Point screenPointToCell(int x, int y) {
x = screenXtoVirtual(x) / cellWidth;
y = screenYtoVirtual(y) / cellHeight;
return new Point(x, y);
}
Point screenPointToCell(Point point) {
return screenPointToCell(point.x, point.y);
}
protected Point cellToOriginOnScreen(int x, int y) {
x = virtualXtoScreen(cellWidth * x);
y = virtualYtoScreen(cellHeight * y);
return new Point(x, y);
}
Point cellToOriginOnScreen(Point cell) {
return cellToOriginOnScreen(cell.x, cell.y);
}
Rectangle getCellScreenRect(Point cell) {
return getCellScreenRect(cell.x, cell.y);
}
Rectangle getCellScreenRect(int x, int y) {
x = cellWidth * virtualXtoScreen(x);
y = cellHeight * virtualYtoScreen(y);
return new Rectangle(x, y, cellWidth, cellHeight);
}
protected Rectangle getCellVirtualRect(Point cell) {
return getCellVirtualRect(cell.x, cell.y);
}
Rectangle getCellVirtualRect(int x, int y) {
x = cellWidth * x;
y = cellHeight * y;
return new Rectangle(x, y, cellWidth, cellHeight);
}
@Override protected void viewRectangleChanged(int x, int y, int width, int height) {
int cellX = virtualXToCell(x);
int cellY = virtualYToCell(y);
// End coordinates
int xE = virtualXToCell(x + width);
// if(xE>getCols())
// xE=getCols();
int yE = virtualYToCell(y + height);
// if(yE>getRows())
// yE=getRows();
visibleCellRectangleChanged(cellX, cellY, xE - cellX, yE - cellY);
}
protected void visibleCellRectangleChanged(int x, int y, int width, int height) {}
@Override protected void setVirtualExtend(int width, int height) {
int cellHeight = getCellHeight();
if (cellHeight > 0) {
height -= height % cellHeight;
}
super.setVirtualExtend(width, height);
}
@Override protected void setVirtualOrigin(int x, int y) {
int cellHeight = getCellHeight();
if (cellHeight > 0) {
int remainder = y % cellHeight;
if (remainder < 0) {
y -= (cellHeight + remainder);
} else {
y -= remainder;
}
}
super.setVirtualOrigin(x, y);
}
@Override protected void scrollY(ScrollBar vBar) {
int vSelection = vBar.getSelection();
Rectangle bounds = getVirtualBounds();
int y = -vSelection;
int cellHeight = getCellHeight();
if (cellHeight > 0) {
int remainder = y % cellHeight;
if (remainder < 0) {
y -= (cellHeight + remainder);
} else {
y -= remainder;
}
}
int deltaY = y - bounds.y;
if (deltaY != 0) {
scrollSmart(0, deltaY);
setVirtualOrigin(bounds.x, bounds.y += deltaY);
}
if (-bounds.y + getRows() * getCellHeight() >= bounds.height) {
// Scrolled to bottom - need to redraw bottom area
Rectangle clientRect = getClientArea();
redraw(0, clientRect.height - this.cellHeight, clientRect.width, this.cellHeight, false);
}
}
}