| package org.eclipse.nebula.widgets.nattable.core.layer.axis.impl |
| |
| import java.io.Serializable |
| import java.math.BigDecimal |
| 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 |
| BigDecimal defaultSegmentSize |
| val segmentSizeMap = new TreeMap<Long, BigDecimal> // segment Position -> pixel size |
| |
| new() {} |
| |
| new(long segmentCount, double defaultSegmentSize) { |
| this(segmentCount, new BigDecimal(defaultSegmentSize)) |
| } |
| |
| new(long segmentCount, BigDecimal defaultSegmentSize) { |
| setSegmentCount(segmentCount) |
| setDefaultSegmentSize(defaultSegmentSize) |
| } |
| |
| def void setSegmentCount(long segmentCount) { |
| this.segmentCount = segmentCount |
| } |
| |
| def void setDefaultSegmentSize(BigDecimal defaultSegmentSize) { |
| this.defaultSegmentSize = defaultSegmentSize |
| } |
| |
| // Axis interface |
| |
| override getSegmentCount() { |
| segmentCount |
| } |
| |
| override getStartPixelOfSegmentPosition(long segmentPosition) { |
| if (segmentPosition < 0) return -BigDecimal::ONE |
| else if (segmentPosition == 0) return BigDecimal::ZERO |
| else if (segmentSizeMap.empty) return new BigDecimal(segmentPosition) * defaultSegmentSize |
| else { |
| var numResizedSegments = 0 |
| var resizeAggregate = BigDecimal::ZERO |
| |
| for (resizedSegmentPosition : segmentSizeMap.subMap(0L, segmentPosition).keySet) { |
| numResizedSegments = numResizedSegments + 1 |
| resizeAggregate = resizeAggregate + segmentSizeMap.get(resizedSegmentPosition) |
| } |
| |
| return (new BigDecimal(segmentPosition - numResizedSegments) * defaultSegmentSize) + resizeAggregate |
| } |
| } |
| |
| override getSegmentPositionOfPixelLocation(BigDecimal pixelLocation) { |
| if (pixelLocation < BigDecimal::ZERO) return -1 |
| else if (pixelLocation == 0) return 0 |
| else if (pixelLocation >= pixelSize) return segmentCount |
| else if (segmentSizeMap.empty) return (pixelLocation / defaultSegmentSize).longValue |
| else return findSegmentPositionOfPixelLocation(pixelLocation, BigDecimal::ZERO, pixelSize, 0, segmentCount) |
| } |
| |
| def private long findSegmentPositionOfPixelLocation(BigDecimal pixelLocation, BigDecimal fromPixel, BigDecimal toPixel, long fromSegmentPosition, long toSegmentPosition) { |
| // guess segment position = pixelLocation / size of guess region |
| val guessSegmentSize = (toPixel - fromPixel) / new BigDecimal(toSegmentPosition - fromSegmentPosition) |
| val guessSegmentPosition = fromSegmentPosition + ((pixelLocation - fromPixel) / guessSegmentSize).longValue |
| |
| // 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 Number).longValue |
| else |
| return -1 |
| } |
| |
| // |
| |
| def void setPixelSizeOfSegmentPosition(double size, long segmentPosition) { |
| setPixelSizeOfSegmentPosition(new BigDecimal(size), segmentPosition) |
| } |
| |
| def void setPixelSizeOfSegmentPosition(BigDecimal size, long segmentPosition) { |
| if (!containsSegmentPosition(segmentPosition)) throw new IllegalArgumentException('''segment position «segmentPosition» is not contained in this axis''') |
| if (size < BigDecimal::ZERO) throw new IllegalArgumentException("size must be >= 0") |
| |
| segmentSizeMap.put(segmentPosition, size) |
| } |
| |
| } |