efficient viewport
diff --git a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/viewport/ViewportAxisTest.xtend b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/viewport/ViewportAxisTest.xtend
index c3a7bc2..287d776 100644
--- a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/viewport/ViewportAxisTest.xtend
+++ b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/viewport/ViewportAxisTest.xtend
@@ -105,7 +105,7 @@
}
@Test
- def void midpointToEnd() {
+ def void beforeMidpointToEnd() {
// segment position: | 0 | 1 | 2 | 3 |
// pixel location: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
// visible pixel range: |---------------------------------|
@@ -120,6 +120,21 @@
}
@Test
+ def void afterMidpointToEnd() {
+ // segment position: | 0 | 1 | 2 | 3 |
+ // pixel location: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
+ // visible pixel range: |-------------------|
+ // |4 5 6 7 8 9 0 1 2 3 4 5 6|
+ viewportAxis.pixelOrigin = 17
+ viewportAxis.visiblePixelRange = 10
+ testAxis(
+ viewportAxis,
+ #[ 3 ],
+ #[ -5, 8 ]
+ )
+ }
+
+ @Test
def void midpointToMidpoint() {
// segment position: | 0 | 1 | 2 | 3 |
// pixel location: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
@@ -187,8 +202,6 @@
testAxis(
"after expand",
viewportAxis,
-// #[ 1, 2, 3 ],
-// #[ -2, 1, 8, 21 ]
#[ 0, 1, 2, 3 ],
#[ -1, 1, 4, 11, 24 ]
)
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/geometry/PixelRectangleInvariants.xtend b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/geometry/PixelRectangleInvariants.xtend
index 4de3334..138a1b1 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/geometry/PixelRectangleInvariants.xtend
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/geometry/PixelRectangleInvariants.xtend
@@ -1,13 +1,19 @@
package org.eclipse.nebula.widgets.nattable.core.geometry
+import static java.lang.Math.*
+
class PixelRectangleInvariants {
static def PixelRectangle intersect(PixelRectangle rect1, PixelRectangle rect2) {
- val startX = Math::max(rect1.x, rect2.x)
- val startY = Math::max(rect1.y, rect2.y)
- val endX = Math::min(rect1.x + rect1.width, rect2.x + rect2.width)
- val endY = Math::min(rect1.y + rect1.height, rect2.y + rect2.height)
- new PixelRectangle(startX, startY, endX - startX, endY - startY)
+ val startX = max(rect1.x, rect2.x)
+ val startY = max(rect1.y, rect2.y)
+ val endX = min(rect1.x + rect1.width, rect2.x + rect2.width)
+ val endY = min(rect1.y + rect1.height, rect2.y + rect2.height)
+ new PixelRectangle(startX, startY, max(endX - startX, 0), max(endY - startY, 0))
+ }
+
+ static def boolean isEmpty(PixelRectangle rect) {
+ rect.width == 0 || rect.height == 0
}
}
\ No newline at end of file
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/CellLayerPainter.xtend b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/CellLayerPainter.xtend
index f05d3d0..82371c4 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/CellLayerPainter.xtend
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/CellLayerPainter.xtend
@@ -7,6 +7,8 @@
import org.eclipse.nebula.widgets.nattable.core.layer.cell.Cell
import org.eclipse.nebula.widgets.nattable.core.layer.cell.impl.DefaultCellPainter
+import static java.lang.Math.*
+
import static extension org.eclipse.nebula.widgets.nattable.core.geometry.PixelRectangleInvariants.*
import static extension org.eclipse.nebula.widgets.nattable.core.layer.LayerInvariants.*
import static extension org.eclipse.nebula.widgets.nattable.core.layer.cell.CellInvariants.*
@@ -22,25 +24,27 @@
val clipBounds = gc.clipBounds
- val fromColumnPosition = Math::max(layer.getColumnPositionOfXPixel(clipBounds.x), 0)
- val toColumnPosition = Math::min(layer.getColumnPositionOfXPixel(clipBounds.x + clipBounds.width - 1), layer.columnCount - 1)
- val fromRowPosition = Math::max(layer.getRowPositionOfYPixel(clipBounds.y), 0)
- val toRowPosition = Math::min(layer.getRowPositionOfYPixel(clipBounds.y + clipBounds.height - 1), layer.rowCount - 1)
+ val fromColumnPosition = max(layer.getColumnPositionOfXPixel(clipBounds.x), 0)
+ val toColumnPosition = min(layer.getColumnPositionOfXPixel(clipBounds.x + clipBounds.width - 1), layer.columnCount - 1)
+ val fromRowPosition = max(layer.getRowPositionOfYPixel(clipBounds.y), 0)
+ val toRowPosition = min(layer.getRowPositionOfYPixel(clipBounds.y + clipBounds.height - 1), layer.rowCount - 1)
- for (columnPosition : fromColumnPosition .. toColumnPosition)
- for (rowPosition : fromRowPosition .. toRowPosition) {
- val cell = layer.getCell(columnPosition, rowPosition)
-
- gc.pushState
-
- val cellPaintBounds = cell.paintBounds
- gc.clipBounds = cellPaintBounds.intersect(paintBounds)
- gc.translate(cellPaintBounds.x, cellPaintBounds.y)
- val localCellPaintBounds = new PixelRectangle(0, 0, cellPaintBounds.width, cellPaintBounds.height)
- cellPainter.paintCell(cell, localCellPaintBounds, gc)
-
- gc.popState
- }
+ if (fromColumnPosition <= toColumnPosition)
+ for (columnPosition : fromColumnPosition .. toColumnPosition)
+ if (fromRowPosition <= toRowPosition)
+ for (rowPosition : fromRowPosition .. toRowPosition) {
+ val cell = layer.getCell(columnPosition, rowPosition)
+
+ gc.pushState
+
+ val cellPaintBounds = cell.paintBounds
+ gc.clipBounds = cellPaintBounds.intersect(paintBounds)
+ gc.translate(cellPaintBounds.x, cellPaintBounds.y)
+ val localCellPaintBounds = new PixelRectangle(0, 0, cellPaintBounds.width, cellPaintBounds.height)
+ cellPainter.paintCell(cell, localCellPaintBounds, gc)
+
+ gc.popState
+ }
}
//
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/GridLineCellLayerPainter.xtend b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/GridLineCellLayerPainter.xtend
index c03f8a4..02ec24d 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/GridLineCellLayerPainter.xtend
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/GridLineCellLayerPainter.xtend
@@ -6,6 +6,8 @@
import org.eclipse.nebula.widgets.nattable.core.layer.Layer
import org.eclipse.nebula.widgets.nattable.core.layer.cell.Cell
+import static java.lang.Math.*
+
import static extension org.eclipse.nebula.widgets.nattable.core.layer.LayerInvariants.*
class GridLineCellLayerPainter extends CellLayerPainter {
@@ -41,32 +43,34 @@
gc.foregroundColor = new Color(0, 0, 255, 0)
// Draw
+ val clipBounds = gc.clipBounds
+
val pixelWidth = layer.getPixelWidth
val pixelHeight = layer.getPixelHeight
- val clipBounds = gc.clipBounds
-
// Draw horizontal grid lines
- val fromRowPosition = Math::max(layer.getRowPositionOfYPixel(clipBounds.y) + 1, 1)
- val toRowPosition = Math::min(layer.getRowPositionOfYPixel(clipBounds.y + clipBounds.height), layer.rowCount)
- for (rowPosition : fromRowPosition .. toRowPosition) {
- val startY = layer.getStartYPixelOfRowPosition(rowPosition) - 1
- gc.drawLine(
- 0, startY,
- pixelWidth, startY
- )
- }
+ val fromRowPosition = max(layer.getRowPositionOfYPixel(clipBounds.y) + 1, 1)
+ val toRowPosition = min(layer.getRowPositionOfYPixel(clipBounds.y + clipBounds.height), layer.rowCount)
+ if (fromRowPosition <= toRowPosition)
+ for (rowPosition : fromRowPosition .. toRowPosition) {
+ val y = layer.getStartYPixelOfRowPosition(rowPosition) - 1
+ gc.drawLine(
+ 0, y,
+ pixelWidth, y
+ )
+ }
// Draw vertical grid lines
- val fromColumnPosition = Math::max(layer.getColumnPositionOfXPixel(clipBounds.x) + 1, 1)
- val toColumnPosition = Math::min(layer.getColumnPositionOfXPixel(clipBounds.x + clipBounds.width), layer.columnCount)
- for (columnPosition : fromColumnPosition .. toColumnPosition) {
- val startX = layer.getStartXPixelOfColumnPosition(columnPosition) - 1
- gc.drawLine(
- startX, 0,
- startX, pixelHeight
- )
- }
+ val fromColumnPosition = max(layer.getColumnPositionOfXPixel(clipBounds.x) + 1, 1)
+ val toColumnPosition = min(layer.getColumnPositionOfXPixel(clipBounds.x + clipBounds.width), layer.columnCount)
+ if (fromColumnPosition <= toColumnPosition)
+ for (columnPosition : fromColumnPosition .. toColumnPosition) {
+ val x = layer.getStartXPixelOfColumnPosition(columnPosition) - 1
+ gc.drawLine(
+ x, 0,
+ x, pixelHeight
+ )
+ }
gc.popState
}
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/viewport/ViewportAxis.xtend b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/viewport/ViewportAxis.xtend
index edaa6ae..71109d3 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/viewport/ViewportAxis.xtend
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/core/layer/impl/viewport/ViewportAxis.xtend
@@ -69,7 +69,7 @@
override getSegmentPositionOfPixelLocation(int pixelLocation) {
val underlyingPixelLocation = pixelOrigin + pixelLocation
if (underlyingPixelLocation < 0) return -1
- if (underlyingPixelLocation >= pixelSize) return segmentCount
+ if (underlyingPixelLocation >= underlyingAxis.pixelSize) return segmentCount
underlyingAxis.getSegmentPositionOfPixelLocation(underlyingPixelLocation) - originSegmentPosition
}