blob: e339c2b109f6f04b8d036f8dd9468da1ccb70a1a [file] [log] [blame]
package org.eclipse.nebula.widgets.nattable.core.layer.axis.impl.reorder
import java.io.Serializable
import java.util.List
import java.util.Map
import org.eclipse.nebula.widgets.nattable.core.layer.axis.Axis
import org.eclipse.nebula.widgets.nattable.core.layer.axis.impl.AbstractAxis
import static extension org.eclipse.nebula.widgets.nattable.core.layer.axis.AxisInvariants.*
import java.math.BigDecimal
/**
* An axis that allows reordering of its segments.
* <p>
* NOTE: This axis implementation is not performant for large numbers (e.g. thousands) of segments.
*/
class ReorderAxis extends AbstractAxis {
val List<Serializable> reorderedSegmentIds = newArrayList
val Map<Long, BigDecimal> segmentPositionToStartPixelMap = newHashMap
Axis underlyingAxis
new() {}
new(Axis underlyingAxis) {
setUnderlyingAxis(underlyingAxis)
}
def void setUnderlyingAxis(Axis underlyingAxis) {
this.underlyingAxis = underlyingAxis
var segmentPosition = 0
while (segmentPosition < underlyingAxis.segmentCount) {
reorderedSegmentIds += underlyingAxis.getIdOfSegmentPosition(segmentPosition)
segmentPosition = segmentPosition + 1
}
}
// Axis interface
override getSegmentCount() {
underlyingAxis.segmentCount
}
override getStartPixelOfSegmentPosition(long segmentPosition) {
val startPixel = segmentPositionToStartPixelMap.get(segmentPosition)
if (startPixel != null)
return startPixel
else {
var aggregateSize = BigDecimal::ZERO
var position = 0
while (position < segmentPosition) {
val segmentId = reorderedSegmentIds.get(position)
val underlyingSegmentPosition = underlyingAxis.getSegmentPositionOfId(segmentId)
aggregateSize = aggregateSize + underlyingAxis.getPixelSizeOfSegmentPosition(underlyingSegmentPosition)
position = position + 1
}
segmentPositionToStartPixelMap.put(segmentPosition, aggregateSize)
return aggregateSize
}
}
override getSegmentPositionOfPixelLocation(BigDecimal pixelLocation) {
if (pixelLocation < BigDecimal::ZERO) return -1
var segmentPosition = 0
while (segmentPosition <= segmentCount) {
val startPixel = getStartPixelOfSegmentPosition(segmentPosition)
if (startPixel > pixelLocation)
return segmentPosition - 1
segmentPosition = segmentPosition + 1
}
return segmentCount
}
override getIdOfSegmentPosition(long segmentPosition) {
reorderedSegmentIds.get(segmentPosition as int)
}
override getSegmentPositionOfId(Serializable segmentId) {
reorderedSegmentIds.indexOf(segmentId)
}
//
/**
* Moves a segment from a given position to a new position.
* @param fromSegmentPosition The segment position to move.
* @param toSegmentPosition The new position to move the segment to.
*/
def void reorderSegmentPosition(int fromSegmentPosition, int toSegmentPosition) {
val segmentId = reorderedSegmentIds.get(fromSegmentPosition)
reorderedSegmentIds.remove(segmentId)
reorderedSegmentIds.add(toSegmentPosition, segmentId)
segmentPositionToStartPixelMap.clear
}
}