| package org.eclipse.nebula.widgets.nattable.core.layer.axis.impl |
| |
| import java.io.Serializable |
| import java.util.TreeMap |
| |
| import static extension org.eclipse.nebula.widgets.nattable.core.layer.axis.AxisInvariants.* |
| |
| /** |
| * A simple Axis implementation. |
| */ |
| class AxisImpl extends AbstractAxis { |
| |
| long segmentCount |
| double defaultSegmentSize |
| val segmentSizeMap = new TreeMap<Long, Double> // segment Position -> pixel size |
| |
| new() {} |
| |
| new(long segmentCount, double defaultSegmentSize) { |
| setSegmentCount(segmentCount) |
| setDefaultSegmentSize(defaultSegmentSize) |
| } |
| |
| def void setSegmentCount(long segmentCount) { |
| this.segmentCount = segmentCount |
| } |
| |
| def void setDefaultSegmentSize(double defaultSegmentSize) { |
| this.defaultSegmentSize = defaultSegmentSize |
| } |
| |
| // Axis interface |
| |
| override getSegmentCount() { |
| segmentCount |
| } |
| |
| override getStartPixelOfSegmentPosition(long segmentPosition) { |
| if (segmentPosition < 0) return -1 |
| else if (segmentPosition == 0) return 0 |
| else if (segmentSizeMap.empty) return segmentPosition * defaultSegmentSize |
| else { |
| var numResizedSegments = 0 |
| var resizeAggregate = 0.0 |
| |
| for (resizedSegmentPosition : segmentSizeMap.subMap(0L, segmentPosition).keySet) { |
| numResizedSegments = numResizedSegments + 1 |
| resizeAggregate = resizeAggregate + segmentSizeMap.get(resizedSegmentPosition) |
| } |
| |
| return ((segmentPosition - numResizedSegments) * defaultSegmentSize) + resizeAggregate |
| } |
| } |
| |
| override getSegmentPositionOfPixelLocation(double pixelLocation) { |
| if (pixelLocation < 0) return -1 |
| else if (pixelLocation == 0) return 0 |
| else if (pixelLocation >= pixelSize) return segmentCount |
| else if (segmentSizeMap.empty) return (pixelLocation / defaultSegmentSize) as long |
| else return findSegmentPositionOfPixelLocation(pixelLocation, 0, pixelSize, 0, segmentCount) |
| } |
| |
| def private long findSegmentPositionOfPixelLocation(double pixelLocation, double fromPixel, double toPixel, long fromSegmentPosition, long toSegmentPosition) { |
| // guess segment position = pixelLocation / size of guess region |
| val guessSegmentSize = (toPixel - fromPixel) / (toSegmentPosition - fromSegmentPosition) |
| val guessSegmentPosition = fromSegmentPosition + ((pixelLocation - fromPixel) / guessSegmentSize) as long |
| |
| // find start/end pixel of guessed segment position |
| val startPixel = getStartPixelOfSegmentPosition(guessSegmentPosition) |
| val endPixel = startPixel + getPixelSizeOfSegmentPosition(guessSegmentPosition) |
| |
| if (pixelLocation < startPixel) |
| return findSegmentPositionOfPixelLocation(pixelLocation, fromPixel, startPixel, fromSegmentPosition, guessSegmentPosition) |
| else if (pixelLocation >= endPixel) |
| return findSegmentPositionOfPixelLocation(pixelLocation, endPixel, toPixel, guessSegmentPosition + 1, toSegmentPosition) |
| else |
| return guessSegmentPosition |
| } |
| |
| override getIdOfSegmentPosition(long segmentPosition) { |
| segmentPosition |
| } |
| |
| override getSegmentPositionOfId(Serializable segmentId) { |
| if (segmentId != null) |
| return segmentId as Long |
| else |
| return -1 |
| } |
| |
| // |
| |
| def void setPixelSizeOfSegmentPosition(double size, long segmentPosition) { |
| if (!containsSegmentPosition(segmentPosition)) throw new IllegalArgumentException('''segment position «segmentPosition» is not contained in this axis''') |
| if (size < 0) throw new IllegalArgumentException("size must be >= 0") |
| |
| segmentSizeMap.put(segmentPosition, size) |
| } |
| |
| } |