blob: 03530d79f65f2db63930f9899fc9e6d79cd35d05 [file] [log] [blame]
package org.eclipse.nebula.widgets.nattable.core.layer.axis.impl.reorder
import java.io.Serializable
import java.math.BigDecimal
import java.util.HashMap
import java.util.TreeMap
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 static extension org.eclipse.nebula.widgets.nattable.core.math.BigDecimalExtensions.*
/**
* 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 reorderedSegmentPositionToIdMap = new TreeMap<Long, Serializable>
val reorderedSegmentIdToPositionMap = new HashMap<Serializable, Long>
val segmentPositionToStartPixelMap = new TreeMap<Long, BigDecimal>
Axis underlyingAxis
new() {}
new(Axis underlyingAxis) {
setUnderlyingAxis(underlyingAxis)
}
def void setUnderlyingAxis(Axis underlyingAxis) {
this.underlyingAxis = underlyingAxis
var segmentPosition = 0L
while (segmentPosition < underlyingAxis.segmentCount) {
reorderedSegmentPositionToIdMap.put(segmentPosition, underlyingAxis.getIdOfSegmentPosition(segmentPosition))
reorderedSegmentIdToPositionMap.put(underlyingAxis.getIdOfSegmentPosition(segmentPosition), 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 = new BigDecimal(0.0)
var position = 0L
while (position < segmentPosition) {
val segmentId = reorderedSegmentPositionToIdMap.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 < new BigDecimal(0)) return -1
var segmentPosition = 0L
while (segmentPosition <= segmentCount) {
val startPixel = getStartPixelOfSegmentPosition(segmentPosition)
if (startPixel > pixelLocation)
return segmentPosition - 1
segmentPosition = segmentPosition + 1
}
return segmentCount
}
override getIdOfSegmentPosition(long segmentPosition) {
reorderedSegmentPositionToIdMap.get(segmentPosition)
}
override getSegmentPositionOfId(Serializable segmentId) {
reorderedSegmentIdToPositionMap.get(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(long fromSegmentPosition, long toSegmentPosition) {
val segmentId = reorderedSegmentPositionToIdMap.get(fromSegmentPosition)
reorderedSegmentPositionToIdMap.remove(fromSegmentPosition)
reorderedSegmentIdToPositionMap.remove(segmentId)
reorderedSegmentPositionToIdMap.put(toSegmentPosition, segmentId)
reorderedSegmentIdToPositionMap.put(segmentId, toSegmentPosition)
segmentPositionToStartPixelMap.clear
}
}